1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #include "oscl_mem.h" 19 #include "muxtbl.h" 20 #include "h245_deleter.h" 21 #include "h245_copier.h" 22 #include "oscl_mem.h" 23 #ifndef _h324utils_h 24 #include "h324utils.h" 25 #endif 26 #define ON 1 27 #define OFF 0 28 #define ACTIVATE 1 29 #define DEACTIVATE 0 30 31 #define SRP_MUX_ENTRY_NUMBER 0 32 #define WNSRP_MUX_ENTRY_NUMBER 15 33 34 MuxTableMgr::MuxTableMgr(): iOutgoingDescriptors(NULL) 35 { 36 iLogger = PVLogger::GetLoggerObject("3g324m.h223.muxtable"); 37 iOutgoingMuxTblCount = 0; 38 iIncomingMuxTblCount = 0; 39 40 uint16 entry_num; 41 for (entry_num = 0; entry_num < MAX_MUX_ENTRIES; entry_num ++) 42 { 43 iMuxDescriptorR[entry_num] = NULL; 44 } 45 46 AddIncomingControlDescriptor(); 47 iOutgoingDescriptors = OSCL_NEW(CPVMultiplexEntryDescriptorVector, ()); 48 AddControlDescriptor(*iOutgoingDescriptors); 49 50 ResetStats(); 51 } 52 53 MuxTableMgr::~MuxTableMgr() 54 { 55 for (int32 entry_num = 0; entry_num < MAX_MUX_ENTRIES; entry_num ++) 56 { 57 if (iMuxDescriptorR[entry_num]) 58 { 59 Delete_MultiplexEntryDescriptor(iMuxDescriptorR[entry_num]); 60 OSCL_DEFAULT_FREE(iMuxDescriptorR[entry_num]); 61 iMuxDescriptorR[entry_num] = NULL; 62 } 63 } 64 65 if (iOutgoingDescriptors) 66 { 67 OSCL_DELETE(iOutgoingDescriptors); 68 iOutgoingDescriptors = NULL; 69 } 70 } 71 72 PS_MultiplexEntryDescriptor MuxTableMgr::GetControlDescriptor(uint16 mux_entry_num) 73 { 74 PS_MultiplexEntryDescriptor desc; 75 76 desc = (PS_MultiplexEntryDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexEntryDescriptor)); 77 desc->multiplexTableEntryNumber = (uint8)mux_entry_num; 78 desc->option_of_elementList = true; 79 desc->size_of_elementList = 1; 80 desc->elementList = (PS_MultiplexElement)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexElement)); 81 82 PS_MultiplexElement elem = desc->elementList; 83 elem->muxType.index = 0; /* logical channel, 1 = sub-elem list */ 84 elem->muxType.logicalChannelNumber = 0; 85 elem->muxType.size = 1; /* size of element list */ 86 elem->repeatCount.index = 1; /* ucf */ 87 elem->repeatCount.finite = 0; 88 89 return desc; 90 } 91 92 OsclAny MuxTableMgr::AddIncomingControlDescriptor() 93 { 94 iMuxDescriptorR[SRP_MUX_ENTRY_NUMBER] = GetControlDescriptor(SRP_MUX_ENTRY_NUMBER); 95 iMuxDescriptorFlagR[SRP_MUX_ENTRY_NUMBER] = ACTIVATE; 96 iMuxDescriptorR[WNSRP_MUX_ENTRY_NUMBER] = GetControlDescriptor(WNSRP_MUX_ENTRY_NUMBER); 97 iMuxDescriptorFlagR[WNSRP_MUX_ENTRY_NUMBER] = ACTIVATE; 98 } 99 100 void MuxTableMgr::AddControlDescriptor(CPVMultiplexEntryDescriptorVector& descriptors) 101 { 102 // PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"MuxTableMgr::AddControlDescriptor\n")); 103 PS_MultiplexEntryDescriptor h245_desc = GetControlDescriptor(SRP_MUX_ENTRY_NUMBER); 104 CPVMultiplexEntryDescriptor* descriptor = CPVMultiplexEntryDescriptor::NewL(h245_desc, 128); 105 descriptors.push_back(descriptor); 106 Delete_MultiplexEntryDescriptor(h245_desc); 107 OSCL_DEFAULT_FREE(h245_desc); 108 } 109 110 OsclAny MuxTableMgr::SetIncomingDescriptors(PS_MuxDescriptor mux_desc) 111 { 112 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::SetIncomingDescriptors")); 113 PS_MultiplexEntryDescriptor descriptor = mux_desc->multiplexEntryDescriptors; 114 uint8 entry_num = 0; 115 for (int32 num = 0; num < mux_desc->size_of_multiplexEntryDescriptors; num++) 116 { 117 entry_num = descriptor->multiplexTableEntryNumber; 118 if (iMuxDescriptorR[entry_num]) 119 { 120 RemoveDescriptorR(entry_num); 121 iMuxDescriptorFlagR[entry_num] = DEACTIVATE; 122 } 123 124 if (descriptor->option_of_elementList == true) 125 { 126 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::SetIncomingDescriptors Adding mux entry=%d", entry_num)); 127 iMuxDescriptorR[entry_num] = Copy_MultiplexEntryDescriptor(descriptor); 128 iMuxDescriptorFlagR[entry_num] = ACTIVATE; 129 } 130 else 131 { 132 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::SetIncomingDescriptors Removing mux entry=%d", entry_num)); 133 } 134 descriptor++; 135 } 136 } 137 138 OsclAny MuxTableMgr::SetIncomingMuxDescriptors(CPVMultiplexEntryDescriptorVector& descriptors, bool replace) 139 { 140 for (unsigned n = 0; n < descriptors.size(); n++) 141 { 142 uint8 entry_num = descriptors[n]->GetH245descriptor()->multiplexTableEntryNumber; 143 if (iMuxDescriptorR[entry_num]) 144 { 145 if (!replace) 146 { 147 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "MuxTableMgr::SetIncomingDescriptors descriptor already exists for mux entry=%d and we are not to replace it!", entry_num)); 148 continue; 149 } 150 RemoveDescriptorR(entry_num); 151 iMuxDescriptorFlagR[entry_num] = DEACTIVATE; 152 } 153 if (descriptors[n]->GetH245descriptor()->option_of_elementList == true) 154 { 155 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::SetIncomingDescriptors Adding mux entry=%d", entry_num)); 156 iMuxDescriptorR[entry_num] = Copy_MultiplexEntryDescriptor(descriptors[n]->GetH245descriptor()); 157 iMuxDescriptorFlagR[entry_num] = ACTIVATE; 158 } 159 else 160 { 161 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::SetIncomingDescriptors Removing mux entry=%d", entry_num)); 162 } 163 } 164 } 165 166 void MuxTableMgr::SetOutgoingMuxDescriptors(CPVMultiplexEntryDescriptorVector& descriptors) 167 { 168 if (!iOutgoingDescriptors) 169 { 170 iOutgoingDescriptors = OSCL_NEW(CPVMultiplexEntryDescriptorVector, ()); 171 } 172 for (unsigned n = 0; n < descriptors.size(); n++) 173 { 174 iOutgoingDescriptors->push_back(OSCL_NEW(CPVMultiplexEntryDescriptor, (*descriptors[n]))); 175 } 176 } 177 178 void MuxTableMgr::RemoveOutgoingMuxDescriptor(uint8 muxTblNum) 179 { 180 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::RemoveOutgoingMuxDescriptor muxTblNum(%d)", muxTblNum)); 181 if (iOutgoingDescriptors == NULL) 182 { 183 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::RemoveOutgoingMuxDescriptor iOutgoingDescriptors==NULL")); 184 return; 185 } 186 CPVMultiplexEntryDescriptorVector::iterator iter = iOutgoingDescriptors->begin(); 187 while (iter != iOutgoingDescriptors->end()) 188 { 189 if ((*iter)->GetH245descriptor()->multiplexTableEntryNumber == muxTblNum) 190 { 191 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::RemoveOutgoingMuxDescriptor Found the mux table entry")); 192 OSCL_DELETE(*iter); 193 iOutgoingDescriptors->erase(iter); 194 return; 195 } 196 iter++; 197 } 198 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::RemoveOutgoingMuxDescriptor Failed to lookup multiplex entry")); 199 } 200 201 void MuxTableMgr::RemoveIncomingMuxDescriptor(uint8 muxTblNum) 202 { 203 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "MuxTableMgr::RemoveIncomingMuxDescriptor muxTblNum(%d)", muxTblNum)); 204 RemoveDescriptorR(muxTblNum); 205 } 206 207 bool MuxTableMgr::RemoveDescriptorR(uint8 entry_num) 208 { 209 if (iMuxDescriptorR[entry_num]) 210 { 211 Delete_MultiplexEntryDescriptor(iMuxDescriptorR[entry_num]); 212 OSCL_DEFAULT_FREE(iMuxDescriptorR[entry_num]); 213 iMuxDescriptorR[entry_num] = NULL; 214 iMuxDescriptorFlagR[entry_num] = DEACTIVATE; 215 } 216 return true; 217 } 218 219 PS_MultiplexEntryDescriptor 220 MuxTableMgr::GetOutgoingDescriptor(MuxSduDataList& data_list) 221 { 222 unsigned num_lcns_with_data = data_list.size(); 223 for (unsigned desc_num = 0; desc_num < iOutgoingDescriptors->size(); desc_num++) 224 { 225 // check for num lcns match 226 if ((*iOutgoingDescriptors)[desc_num]->NumLcns() == num_lcns_with_data) 227 { 228 // check for individual lcns 229 MuxSduDataList::iterator it = data_list.begin(); 230 bool found_match = true; 231 while (it != data_list.end()) 232 { 233 MuxSduData& sdu_data = (*it++); 234 TPVMuxDescriptorSlot slot; 235 if (!(*iOutgoingDescriptors)[desc_num]->FindLcn((uint16)sdu_data.lcn->GetLogicalChannelNumber(), (uint16)(sdu_data.lcn->IsSegmentable() ? 0 : sdu_data.size), slot)) 236 { 237 found_match = false; 238 break; 239 } 240 if (sdu_data.lcn->GetLogicalChannelNumber() == 0) 241 { 242 (*iOutgoingDescriptors)[desc_num]->GetH245descriptor()->multiplexTableEntryNumber = 0; 243 OsclRefCounterMemFrag fsi; 244 bool fsi_available = sdu_data.sdu->getFormatSpecificInfo(fsi); 245 if (fsi_available && fsi.getMemFragSize()) 246 { 247 uint8* fsi_ptr = (uint8*)fsi.getMemFragPtr(); 248 (*iOutgoingDescriptors)[desc_num]->GetH245descriptor()->multiplexTableEntryNumber = fsi_ptr[0]; 249 } 250 } 251 } 252 if (found_match) 253 { 254 return (*iOutgoingDescriptors)[desc_num]->GetH245descriptor(); 255 } 256 } 257 } 258 return NULL; 259 } 260 261 PS_MultiplexEntryDescriptor MuxTableMgr::GetOutgoingDescriptor(OsclSharedPtr<H223OutgoingChannel>& lcn, 262 PVMFSharedMediaDataPtr sdu) 263 { 264 MuxSduData sdu_data; 265 sdu_data.lcn = lcn; 266 sdu_data.size = 0; 267 sdu_data.sdu = sdu; 268 iMuxSduDataList.push_back(sdu_data); 269 PS_MultiplexEntryDescriptor ret = GetOutgoingDescriptor(iMuxSduDataList); 270 iMuxSduDataList.clear(); 271 return ret; 272 } 273 274 PS_MultiplexEntryDescriptor MuxTableMgr::GetIncomingDescriptor(uint8 tblNum) 275 { 276 int lookup = tblNum & 0x0F; 277 PS_MultiplexEntryDescriptor desc = iMuxDescriptorR[lookup]; 278 PV_STAT_INCR_COND(iNumCorruptMcRx, 1, (desc == NULL)) 279 PV_STAT_INCR_COND(iMcAccessCntR[lookup], 1, desc); 280 return desc; 281 } 282 283 OsclAny MuxTableMgr::ResetStats() 284 { 285 iNumCorruptMcRx = 0; 286 for (int32 entry_num = 0; entry_num < MAX_MUX_ENTRIES; entry_num ++) 287 { 288 iMcAccessCnt[entry_num] = 0; 289 iMcAccessCntR[entry_num] = 0; 290 } 291 } 292 293 OsclAny MuxTableMgr::LogStats(TPVDirection dir) 294 { 295 if ((dir & OUTGOING) && iOutgoingDescriptors) 296 { 297 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Mux-table(O) Statistics:\n")); 298 for (unsigned entry = 0; entry < iOutgoingDescriptors->size(); entry++) 299 { 300 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num outgoing pdus using descriptor %d = %d\n", 301 (*iOutgoingDescriptors)[entry]->GetH245descriptor()->multiplexTableEntryNumber, 302 iMcAccessCnt[(*iOutgoingDescriptors)[entry]->GetH245descriptor()->multiplexTableEntryNumber])); 303 } 304 } 305 if (dir & INCOMING) 306 { 307 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Mux-table(I) Statistics:\n")); 308 for (int32 entry_num = 0; entry_num < MAX_MUX_ENTRIES; entry_num ++) 309 { 310 if (iMuxDescriptorR[entry_num]) 311 { 312 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num incoming pdus using descriptor %d = %d\n", entry_num, iMcAccessCntR[entry_num])); 313 } 314 } 315 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num invalid descriptors - %d\n", iNumCorruptMcRx)); 316 } 317 } 318 uint32 MuxTableMgr::GetMuxEntryAccessCount(TPVDirection dir, uint8 tblNum) 319 { 320 if (tblNum >= MAX_MUX_ENTRIES) 321 return 0; 322 uint32* table = (dir == OUTGOING) ? iMcAccessCnt : iMcAccessCntR; 323 return table[tblNum]; 324 } 325