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 // ---------------------------------------------------------------------- 19 // 20 // This Software is an original work of authorship of PacketVideo Corporation. 21 // Portions of the Software were developed in collaboration with NTT DoCoMo, 22 // Inc. or were derived from the public domain or materials licensed from 23 // third parties. Title and ownership, including all intellectual property 24 // rights in and to the Software shall remain with PacketVideo Corporation 25 // and NTT DoCoMo, Inc. 26 // 27 // ----------------------------------------------------------------------- 28 29 #include "h223.h" 30 #include "tsc_h324m_config.h" 31 #include "tsc_component.h" 32 #include "tsc_constants.h" 33 #include "tsc_statemanager.h" 34 #include "tsc_capability.h" 35 #include "tsc_lc.h" 36 #include "tsc_blc.h" 37 #include "tsc_clc.h" 38 #include "tsc_channelcontrol.h" 39 #include "tsc_mt.h" 40 #ifdef MEM_TRACK 41 #include "oscl_mem.h" 42 #include "oscl_mem_audit.h" 43 #endif 44 45 46 47 #define PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_ID "PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER" 48 #define PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_INTERVAL 1 /* 1 s */ 49 50 #define TSC_MAX_OUTSTANDING_PREFMSG_PDUS 32 51 52 53 TSC_component::TSC_component(TSC_statemanager& aTSCStateManager, 54 TSC_capability& aTSCcapability, 55 TSC_lc& aTSClc, 56 TSC_blc& aTSCblc, 57 TSC_clc& aTSCclc, 58 TSC_mt& aTSCmt): 59 iTSCstatemanager(aTSCStateManager), 60 iTSCcapability(aTSCcapability), 61 iTSClc(aTSClc), 62 iTSCblc(aTSCblc), 63 iTSCclc(aTSCclc), 64 iTSCmt(aTSCmt), 65 iH245(NULL), 66 iH223(NULL), 67 iLocalTcs(NULL), 68 iWaitingForOblcTimer(NULL), 69 iOutgoingChannelConfig(NULL), 70 iIncomingChannelConfig(NULL), 71 iTSCObserver(NULL), 72 iTSCchannelcontrol(iOlcs, aTSCStateManager, aTSCblc, 73 aTSCmt, aTSClc, aTSCcapability, aTSCclc, *this) 74 { 75 iLogger = PVLogger::GetLoggerObject("3g324m.h245user"); 76 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 77 (0, "TSC_component::TSC_component")); 78 79 } 80 81 void TSC_component::SetMembers(H245* aH245, H223* aH223, TSCObserver* aTSCObserver) 82 { 83 iTSCObserver = aTSCObserver; 84 iTSCchannelcontrol.SetMembers(aH223, aTSCObserver); 85 iH245 = aH245; 86 iH223 = aH223; 87 MembersSet(); 88 } 89 90 91 void TSC_component::InitVarsSession() 92 { 93 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 94 (0, "TSC_component::InitVarsSession")); 95 iRemoteAl1Audio = OFF; 96 iRemoteAl2Audio = OFF; 97 iRemoteAl3Audio = OFF; 98 iRemoteAl1Video = OFF; 99 iRemoteAl2Video = OFF; 100 iRemoteAl3Video = OFF; 101 iVideoLayer = PVT_AL_UNKNOWN; 102 if (iLocalTcs) 103 { 104 Delete_TerminalCapabilitySet(iLocalTcs); 105 OSCL_DEFAULT_FREE(iLocalTcs); 106 iLocalTcs = NULL; 107 } 108 iRemoteTcs.Unbind(); 109 110 iOlcs.SetCurrLcn(FIRST_OUTGOING_LCN); 111 } 112 113 void TSC_component::InitVarsLocal() 114 { 115 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 116 (0, "TSC_component::InitVarsLocal")); 117 iAl3ControlFieldOctets = DEFAULT_AL3_CONTROL_FIELD_OCTETS; 118 iAl2WithSn = true; 119 120 iAllowAl1Video = ON; 121 iAllowAl2Video = ON; 122 iAllowAl3Video = ON; 123 iAllowAl1Audio = OFF; 124 iAllowAl2Audio = ON; 125 iAllowAl3Audio = OFF; 126 iUseAl1Video = true; 127 iUseAl2Video = true; 128 iUseAl3Video = true; 129 } 130 131 void TSC_component::InitTsc() 132 { 133 iWaitingForOblcTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>, 134 (PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_ID, PV_2WAY_TSC_WAIT_FOR_OBLC_TIMER_INTERVAL)); 135 iWaitingForOblcTimer->SetObserver(this); 136 } 137 138 void TSC_component::ResetTsc() 139 { 140 if (iOutgoingChannelConfig) 141 { 142 OSCL_DELETE(iOutgoingChannelConfig); 143 iOutgoingChannelConfig = NULL; 144 } 145 146 if (iIncomingChannelConfig) 147 { 148 OSCL_DELETE(iIncomingChannelConfig); 149 iIncomingChannelConfig = NULL; 150 } 151 152 if (iWaitingForOblcTimer) 153 { 154 iWaitingForOblcTimer->Clear(); 155 OSCL_DELETE(iWaitingForOblcTimer); 156 iWaitingForOblcTimer = NULL; 157 } 158 } 159 160 void TSC_component::Disconnect() 161 { 162 163 iWaitingForOblcTimer->Clear(); 164 } 165 166 CPVMultiplexEntryDescriptor* TSC_component::GenerateSingleDescriptor(uint8 entry_num, 167 TPVChannelId lcn1) 168 { 169 PS_MultiplexEntryDescriptor h245_desc = 170 (PS_MultiplexEntryDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexEntryDescriptor)); 171 h245_desc->multiplexTableEntryNumber = entry_num; 172 h245_desc->option_of_elementList = true; 173 h245_desc->size_of_elementList = 1; 174 h245_desc->elementList = 175 (PS_MultiplexElement)OSCL_DEFAULT_MALLOC(sizeof(S_MultiplexElement)); 176 177 PS_MultiplexElement elem = h245_desc->elementList; 178 elem->muxType.index = 0; // logical channel = 0, 1 = sub-elem list 179 elem->muxType.logicalChannelNumber = (uint16)lcn1; 180 elem->muxType.size = 1; // size of element list 181 elem->repeatCount.index = 1; // ucf 182 elem->repeatCount.finite = 0; 183 184 CPVMultiplexEntryDescriptor* ret = 185 CPVMultiplexEntryDescriptor::NewL(h245_desc, 128); 186 Delete_MultiplexEntryDescriptor(h245_desc); 187 OSCL_DEFAULT_FREE(h245_desc); 188 189 return ret; 190 } 191 192 PS_AdaptationLayerType 193 TSC_component::GetOutgoingLayer(PV2WayMediaType media_type, uint32 max_sample_size) 194 { 195 PS_AdaptationLayerType al_type = 196 (PS_AdaptationLayerType)OSCL_DEFAULT_MALLOC(sizeof(S_AdaptationLayerType)); 197 int room_for_sn = 0; 198 199 oscl_memset(al_type, 0, sizeof(S_AdaptationLayerType)); 200 uint32 max_sdu_size = 0; 201 switch (media_type) 202 { 203 case PV_AUDIO: 204 if (iRemoteAl2Audio) 205 { 206 max_sdu_size = iH223->GetSduSize(OUTGOING, E_EP_MEDIUM); 207 room_for_sn = max_sdu_size - max_sample_size - 1; /* 1 byte for CRC */ 208 room_for_sn = (room_for_sn > 1) ? 1 : room_for_sn; 209 if (room_for_sn >= 0) 210 { 211 al_type->index = (uint16)(3 + room_for_sn); 212 return al_type; 213 } 214 } 215 if (iRemoteAl3Audio) 216 { 217 max_sdu_size = iH223->GetSduSize(OUTGOING, E_EP_HIGH); 218 room_for_sn = max_sdu_size - max_sample_size - 2; /* 2 bytes for CRC */ 219 if (room_for_sn >= 0) 220 { 221 PS_Al3 al3 = (PS_Al3)OSCL_DEFAULT_MALLOC(sizeof(S_Al3)); 222 al3->controlFieldOctets = (int8)((room_for_sn > 223 (int)iAl3ControlFieldOctets) ? iAl3ControlFieldOctets : room_for_sn); 224 al3->sendBufferSize = DEF_AL3_SEND_BUFFER_SIZE; 225 al_type->index = 5; 226 al_type->al3 = al3; 227 return al_type; 228 } 229 } 230 if (iRemoteAl1Audio) 231 { 232 max_sdu_size = iH223->GetSduSize(OUTGOING, E_EP_LOW); 233 room_for_sn = max_sdu_size - max_sample_size; 234 room_for_sn = (room_for_sn > 1) ? 1 : room_for_sn; 235 if (max_sdu_size >= max_sample_size) 236 { 237 al_type->index = 1; 238 return al_type; 239 } 240 } 241 break; 242 case PV_VIDEO: 243 if (iUseAl2Video && iRemoteAl2Video) 244 { 245 al_type->index = (uint16)(iAl2WithSn ? 4 : 3); 246 return al_type; 247 } 248 if (iUseAl3Video && iRemoteAl3Video) 249 { 250 PS_Al3 al3 = (PS_Al3)OSCL_DEFAULT_MALLOC(sizeof(S_Al3)); 251 al3->controlFieldOctets = (int8)iAl3ControlFieldOctets; 252 al3->sendBufferSize = DEF_AL3_SEND_BUFFER_SIZE; 253 al_type->index = 5; 254 al_type->al3 = al3; 255 return al_type; 256 } 257 if (iUseAl1Video && iRemoteAl1Video) 258 { 259 al_type->index = 1; 260 return al_type; 261 } 262 break; 263 default: 264 break; 265 } 266 OSCL_DEFAULT_FREE(al_type); 267 return NULL; 268 } 269 270 void TSC_component::SetAlConfig(PV2WayMediaType media_type, 271 TPVAdaptationLayer layer, 272 bool allow) 273 { 274 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 275 (0, "TSC_component::SetAlConfig")); 276 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 277 (0, "TSC_component::SetAlConfig media type(%d), layer(%d), allow(%d)", 278 media_type, layer, allow)); 279 280 switch (media_type) 281 { 282 case PV_AUDIO: 283 if (layer == PVT_AL1) 284 iAllowAl1Audio = allow; 285 else if (layer == PVT_AL2) 286 iAllowAl2Audio = allow; 287 else if (layer == PVT_AL3) 288 iAllowAl3Audio = allow; 289 break; 290 case PV_VIDEO: 291 if (layer == PVT_AL1) 292 iAllowAl1Video = allow; 293 else if (layer == PVT_AL2) 294 iAllowAl2Video = allow; 295 else if (layer == PVT_AL3) 296 iAllowAl3Video = allow; 297 break; 298 case PV_DATA: 299 default: 300 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 301 (0, "TSC_component::SetAlConfig Invalid media type")); 302 } 303 } 304 305 ////////////////////////////////////////////////////////////////////////// 306 // Start the CE process by sending this terminals capabilites to the peer terminal 307 ////////////////////////////////////////////////////////////////////////// 308 bool TSC_component::CEStart() 309 { 310 if (!iIncomingChannelConfig || !iIncomingChannelConfig->size()) 311 { 312 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 313 (0, "TSC_component::CEStart- Incoming channel config not set")); 314 return false; 315 } 316 317 iTSCstatemanager.WriteState(TSC_CE_SEND, STARTED); 318 319 MultiplexCapabilityInfo mux_cap_info; 320 mux_cap_info.iAllowAl1Video = iAllowAl1Video; 321 mux_cap_info.iAllowAl2Video = iAllowAl2Video; 322 mux_cap_info.iAllowAl3Video = iAllowAl3Video; 323 mux_cap_info.iAllowAl1Audio = iAllowAl1Audio; 324 mux_cap_info.iAllowAl2Audio = iAllowAl2Audio; 325 mux_cap_info.iAllowAl3Audio = iAllowAl3Audio; 326 mux_cap_info.iMaximumAl2SDUSize = iH223->GetSduSize(INCOMING, E_EP_MEDIUM); 327 mux_cap_info.iMaximumAl3SDUSize = iH223->GetSduSize(INCOMING, E_EP_HIGH); 328 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> outgoing_codecs; 329 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> incoming_codecs; 330 for (unsigned n = 0; n < iIncomingChannelConfig->size(); n++) 331 { 332 Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* codecs = 333 (*iIncomingChannelConfig)[n].GetCodecs(); 334 if (!codecs) 335 { 336 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 337 (0, "TSC_component::CEStart No codecs specified for format type(%d)", 338 (*iIncomingChannelConfig)[n].GetMediaType())); 339 continue; 340 } 341 for (unsigned m = 0; m < codecs->size(); m++) 342 { 343 CodecCapabilityInfo* info = NULL; 344 PVCodecType_t codec_type = PVMFFormatTypeToPVCodecType((*codecs)[m].format); 345 TPVDirection dir = (*codecs)[m].dir; 346 if (GetMediaType(codec_type) == PV_VIDEO) 347 { 348 info = new VideoCodecCapabilityInfo; 349 ((VideoCodecCapabilityInfo*)info)->resolutions = 350 iTSCcapability.GetResolutions(dir); 351 } 352 else 353 { 354 info = new CodecCapabilityInfo; 355 } 356 info->codec = codec_type; 357 info->dir = dir; 358 incoming_codecs.push_back(info); 359 } 360 } 361 if (iLocalTcs) 362 { 363 Delete_TerminalCapabilitySet(iLocalTcs); 364 OSCL_DEFAULT_FREE(iLocalTcs); 365 iLocalTcs = NULL; 366 } 367 iLocalTcs = GenerateTcs(mux_cap_info, outgoing_codecs, incoming_codecs); 368 CustomGenerateTcs(iLocalTcs); 369 370 CE* Ce = iH245->GetCE(); 371 if (Ce) Ce->TransferRequest(iLocalTcs); 372 373 for (unsigned i = 0; i < incoming_codecs.size(); i++) 374 { 375 delete incoming_codecs[i]; 376 } 377 return true; 378 } 379 380 TPVStatusCode TSC_component::SetTerminalParam(CPVTerminalParam& params) 381 { 382 CPVH324MParam* h324params = (CPVH324MParam*) & params; 383 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 384 (0, "TSC_component:SetTerminalParam - AL1(%d), AL2(%d), AL3(%d)", 385 h324params->iAllowAl1Video, 386 h324params->iAllowAl2Video, 387 h324params->iAllowAl3Video)); 388 389 iAllowAl1Video = h324params->iAllowAl1Video; 390 iAllowAl2Video = h324params->iAllowAl2Video; 391 iAllowAl3Video = h324params->iAllowAl3Video; 392 iUseAl1Video = h324params->iUseAl1Video; 393 iUseAl2Video = h324params->iUseAl2Video; 394 iUseAl3Video = h324params->iUseAl3Video; 395 396 iVideoLayer = h324params->iVideoLayer; 397 398 return EPVT_Success; 399 } 400 401 void TSC_component::GetTerminalParam(CPVH324MParam& ah324param) 402 { 403 ah324param.iAllowAl1Video = iAllowAl1Video ? true : false; 404 ah324param.iAllowAl2Video = iAllowAl2Video ? true : false; 405 ah324param.iAllowAl3Video = iAllowAl3Video ? true : false; 406 ah324param.iVideoLayer = iVideoLayer; 407 } 408 409 bool TSC_component::IsSupported(TPVDirection dir, 410 PVCodecType_t codec, 411 FormatCapabilityInfo& capability_info) 412 { 413 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 414 (0, "TSC_component::IsSupported dir(%d), codec(%d)", dir, codec)); 415 if (codec == PV_CODEC_TYPE_NONE) 416 { 417 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 418 (0, "TSC_component::IsSupported No codec is always ok")); 419 return true; 420 } 421 Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>* config = (dir == OUTGOING) ? 422 iOutgoingChannelConfig : iIncomingChannelConfig; 423 if (!config) 424 { 425 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 426 (0, "TSC_component::IsSupported No config available")); 427 return false; 428 } 429 for (unsigned n = 0; n < config->size(); n++) 430 { 431 H324ChannelParameters& param = (*config)[n]; 432 if (param.GetMediaType() != GetMediaType(codec)) 433 continue; 434 Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* codecs = param.GetCodecs(); 435 if (!codecs) 436 { 437 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 438 (0, "TSC_component::IsSupported No codecs specified")); 439 return false; 440 } 441 for (unsigned m = 0; m < codecs->size(); m++) 442 { 443 if ((*codecs)[m].format == PVCodecTypeToPVMFFormatType(codec)) 444 { 445 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 446 (0, "TSC_component::IsSupported Match found")); 447 capability_info = (*codecs)[m]; 448 return true; 449 } 450 } 451 } 452 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 453 (0, "TSC_component::IsSupported No match found")); 454 return false; 455 } 456 457 bool TSC_component::IsSupported(TPVDirection dir, 458 PV2WayMediaType media_type, 459 CodecCapabilityInfo& codec_info) 460 { 461 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 462 (0, "TSC_component::IsSupported dir(%d), media_type(%d)", dir, media_type)); 463 if (media_type == PV_MEDIA_NONE) 464 { 465 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 466 (0, "TSC_component::IsSupported No media is always ok")); 467 return true; 468 } 469 Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>* config = (dir == OUTGOING) ? 470 iOutgoingChannelConfig : iIncomingChannelConfig; 471 if (!config) 472 { 473 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 474 (0, "TSC_component::IsSupported No config available")); 475 return false; 476 } 477 for (unsigned n = 0; n < config->size(); n++) 478 { 479 H324ChannelParameters& param = (*config)[n]; 480 if (param.GetMediaType() != media_type) 481 continue; 482 Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* codecs = param.GetCodecs(); 483 if (!codecs) 484 { 485 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 486 (0, "TSC_component::IsSupported No codecs specified")); 487 return false; 488 } 489 codec_info.codec = PVMFFormatTypeToPVCodecType((*codecs)[0].format); 490 codec_info.dir = (*codecs)[0].dir; 491 return true; 492 } 493 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 494 (0, "TSC_component::IsSupported No match found")); 495 return false; 496 } 497 //////////////////////////////////////////////////////////////////////////// 498 // ExtractTcsParameters() (RAN-32K) 499 // 500 // This routine takes the incoming TerminalCapabilitySet 501 // and extracts the following useful parameters: 502 // {h263_qcifMPI, h263_maxBitRate, mpeg4_maxBitRate} 503 // The parameters are stored in globals and may be sent 504 // later to the application. 505 //////////////////////////////////////////////////////////////////////////// 506 void TSC_component::ExtractTcsParameters(PS_TerminalCapabilitySet pTcs) 507 { 508 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 509 (0, "TSC_component::ExtractTcsParameters")); 510 511 if (pTcs->option_of_multiplexCapability) 512 { 513 PS_MultiplexCapability muxcaps = &pTcs->multiplexCapability; 514 if (muxcaps->index == 2) 515 { 516 517 PS_H223Capability h223caps = muxcaps->h223Capability; 518 iRemoteAl1Audio = h223caps->audioWithAL1; 519 iRemoteAl2Audio = h223caps->audioWithAL2; 520 iRemoteAl3Audio = h223caps->audioWithAL3; 521 iRemoteAl1Video = h223caps->videoWithAL1; 522 iRemoteAl2Video = h223caps->videoWithAL2; 523 iRemoteAl3Video = h223caps->videoWithAL3; 524 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 525 (0, "TSC_component::ExtractTcsParameters Remote audio caps AL1(%d), AL2(%d), AL3(%d)", 526 iRemoteAl1Audio, iRemoteAl2Audio, iRemoteAl3Audio)); 527 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 528 (0, "TSC_component::ExtractTcsParameters Remote video caps AL1(%d), AL2(%d), AL3(%d)", 529 iRemoteAl1Video, iRemoteAl2Video, iRemoteAl3Video)); 530 // ------------------------------------- 531 // Decide which Video Layer to use (RAN) 532 // ------------------------------------- 533 /* If both terminals support AL2, use AL2 */ 534 if (iUseAl2Video && iRemoteAl2Video) 535 { 536 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 537 (0, "TSC_component::ExtractTcsParameters Video Layer Decision is AL2")); 538 iVideoLayer = PVT_AL2; 539 } 540 /* If not, check for mutual AL3 support */ 541 else if (iUseAl3Video && iRemoteAl3Video) 542 { 543 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 544 (0, "TSC_component::ExtractTcsParameters Video Layer Decision is AL3")); 545 iVideoLayer = PVT_AL3; 546 } 547 /* If not, check for mutual AL1 support */ 548 else if (iUseAl1Video && iRemoteAl1Video) 549 { 550 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 551 (0, "TSC_component::ExtractTcsParameters Video Layer Decision is AL1")); 552 iVideoLayer = PVT_AL1; 553 } 554 } 555 } 556 } 557 558 //////////////////////////////////////////////////////////////////////// 559 // CE User - Transfer.Indication primitive received from H.245 560 //////////////////////////////////////////////////////////////////////// 561 void TSC_component::CETransferIndication(OsclSharedPtr<S_TerminalCapabilitySet> tcs, 562 uint32 aTerminalStatus) 563 { 564 if (aTerminalStatus == PhaseD_CSUP) 565 { 566 iRemoteTcs = tcs; 567 } 568 569 else if (aTerminalStatus == PhaseE_Comm) 570 { 571 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 572 (0, "TSC_component::CETransferIndication TCS received during PhaseE_Comm")); 573 if (tcs->option_of_multiplexCapability) 574 { 575 /* Save any required CE data */ 576 iRemoteAl2Video = 577 tcs->multiplexCapability.h223Capability->videoWithAL2; 578 iRemoteAl3Video = 579 tcs->multiplexCapability.h223Capability->videoWithAL3; 580 } 581 } 582 } 583 584 // ======================================================== 585 // SetAl2Al3VideoFlags() (RAN) 586 // 587 // New API from application layer. Sets the flags as follows: 588 // INPUT gAllowAl2Video gAllowAl3Video 589 // 0 ON OFF 590 // 1 OFF ON 591 // 2 ON ON 592 // ======================================================== 593 void TSC_component::SetAl2Al3VideoFlags(int32 userInput) 594 { 595 iAllowAl2Video = iAllowAl3Video = ON; 596 if (userInput == 0) 597 { 598 iAllowAl3Video = OFF; 599 } 600 else if (userInput == 1) 601 { 602 iAllowAl2Video = OFF; 603 } 604 } 605 606 // ======================================================== 607 // GetAl2Al3VideoFlags() (RAN) 608 // 609 // Complements SetAl2Al3VideoFlags() 610 // ======================================================== 611 int32 TSC_component::GetAl2Al3VideoFlags(void) 612 { 613 return(iAllowAl2Video + 2 * iAllowAl3Video - 1); 614 } 615 616 //////////////////////////////////////////////// 617 // 618 //////////////////////////////////////////////// 619 Oscl_Vector < H324ChannelParameters, 620 PVMFTscAlloc > * TSC_component::GetChannelConfig(TPVDirection dir) 621 { 622 if (dir == OUTGOING) 623 { 624 return iOutgoingChannelConfig; 625 } 626 return iIncomingChannelConfig; 627 } 628 629 void TSC_component::SetAl3ControlFieldOctets(unsigned cfo) 630 { 631 iAl3ControlFieldOctets = cfo; 632 } 633 634 void TSC_component::SetAl2Sn(int width) 635 { 636 iAl2WithSn = width ? true : false; 637 } 638 639 640 /*****************************************************************************/ 641 /* function name : LcEtbIdc E_PtvId_Lc_Etb_Idc */ 642 /* function outline : Status04/Event09 procedure */ 643 /* function discription : Status04Event09( pReceiveInf ) */ 644 /* input data : PS_ControlMsgHeader Receive InfHeader Pointer */ 645 /* output data : uint32 Terminal Status */ 646 /* draw time : '96.10.09 */ 647 /*---------------------------------------------------------------------------*/ 648 /* amendment career(x) : */ 649 /* */ 650 /* Copyright (C) 1996 NTT DoCoMo */ 651 /*****************************************************************************/ 652 uint32 TSC_component::LcEtbIdc(PS_ControlMsgHeader pReceiveInf) 653 { 654 TPVChannelId OpenLcn = (TPVChannelId)pReceiveInf->InfSupplement1 + 655 TSC_INCOMING_CHANNEL_MASK; 656 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 657 (0, "TSC_component::LcEtbIdc lcn(%d)", OpenLcn)); 658 PS_ForwardReverseParam pLcParam = (PS_ForwardReverseParam) pReceiveInf->pParameter; 659 /* validate forRevParams */ 660 PVMFStatus forRevCheck = iTSCcapability.ValidateForwardReverseParams(pLcParam, INCOMING); 661 if (forRevCheck != PVMFSuccess) 662 { 663 PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_EMERG, 664 (0, "TSC_component::LcEtbIdc ERROR - Incoming forRevParams not supported. Rejecting.")); 665 uint16 reason = (uint16)((forRevCheck == PVMFErrNotSupported) ? 2/* dataTypeNotSupported */ : 0/*unspecified*/); 666 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, reason); 667 RemoveOlc(dir, OpenLcn); 668 return PhaseE_Comm; 669 } 670 PS_H223LogicalChannelParameters pH223Lcp = 671 pLcParam->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters; 672 PS_DataType pDataType = &pLcParam->forwardLogicalChannelParameters.dataType; 673 PV2WayMediaType media_type = PV_MEDIA_NONE; 674 PVCodecType_t incoming_codec_type = PV_CODEC_TYPE_NONE; 675 676 incoming_codec_type = ::GetCodecType(pDataType); 677 media_type = ::GetMediaType(pDataType); 678 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 679 (0, "TSC_component::LcEtbIdc lcn(%d), media type(%d), codec type(%d)", 680 OpenLcn, media_type, incoming_codec_type)); 681 682 OlcKey key(INCOMING, OpenLcn); 683 684 if (iOlcs.count(key)) 685 { 686 if (iOlcs[key]->GetState() == OLC_ESTABLISHED) 687 { 688 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 689 (0, "TSC_component::LcEtbIdc Established incoming OLC found for same channel id. Rejecting OLC(%d)", 690 media_type, OpenLcn)); 691 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 0); // unspecified 692 RemoveOlc(dir, OpenLcn); 693 return PhaseE_Comm; 694 } 695 else 696 { 697 ReleasePendingIncomingChannel(OpenLcn); 698 } 699 } 700 701 /* pending incoming OLC for the same media type */ 702 Oscl_Vector<OlcParam*, OsclMemAllocator> pending_olc_list; 703 // Search for pending and established channels 704 if (iOlcs.FindOlcs(INCOMING, media_type, OLC_PENDING | OLC_ESTABLISHED, 705 pending_olc_list)) 706 { 707 for (unsigned i = 0; i < pending_olc_list.size(); i++) 708 { 709 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 710 (0, "TSC_component::LcEtbIdc Pending incoming OLC found for media type=%d, lcn=%d", 711 media_type, pending_olc_list[i]->GetChannelId())); 712 if (!ReleasedPendingIncomingChannel(pending_olc_list[i])) 713 { 714 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 715 (0, "TSC_component::LcEtbIdc Established incoming OLC found for same media type. Rejecting OLC(%d)", 716 media_type, OpenLcn)); 717 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 0); /* unspecified */ 718 RemoveOlc(dir, OpenLcn); 719 return PhaseE_Comm; 720 } 721 } 722 } 723 724 OlcParam* pending_outgoing_olc = NULL; 725 PVCodecType_t to_be_opened_codec = PV_CODEC_TYPE_NONE; 726 727 // Add pending olc to list 728 iOlcs.AppendOlc(INCOMING, OpenLcn, pDataType, pH223Lcp); 729 // is there is a pending outgoing OLC for the same media type ? 730 if (iOlcs.FindOlcs(OUTGOING, media_type, OLC_PENDING, pending_olc_list)) 731 { 732 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 733 (0, "TSC_component::LcEtbIdc Pending outgoing OLCs(%d) found for incoming media type(%d).", 734 pending_olc_list.size(), media_type, OpenLcn)); 735 OSCL_ASSERT(pending_olc_list.size() == 1); 736 OlcParam* param = pending_outgoing_olc = pending_olc_list[0]; 737 if (param->GetDirectionality() == EPVT_BI_DIRECTIONAL) 738 { 739 pending_outgoing_olc = NULL; 740 // There is an OLC/OBLC conflict 741 if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == MASTER) 742 { 743 // We are master, hence we reject the OLC 744 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 745 (0, "TSC_component::LcEtbIdc BLC Already initiated by local. Rejecting OLC cause we are Master")); 746 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 10); // Master slave conflict 747 RemoveOlc(dir, OpenLcn); 748 return PhaseE_Comm; 749 } 750 else // We are Slave 751 { 752 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 753 (0, "TSC_component::LcEtbIdc BLC Already initiated by local. Closing BLC cause we are Slave")); 754 to_be_opened_codec = GetCodecType(param->GetForwardParams()->GetDataType());; 755 // Release the pending blc 756 iTSCblc.BlcRlsReq(RELEASE_CLOSE, param->GetChannelId(), 0); 757 ChannelReleased(OUTGOING, param->GetChannelId(), PVMFErrCancelled); 758 // Logical channel will be deleted from the mux when the engine calls ReleasePort 759 } 760 } 761 } 762 763 764 PVMFStatus tscCheck = ValidateOlcsWithTcs(); 765 if (tscCheck != PVMFSuccess) 766 { 767 if (pending_outgoing_olc) 768 { 769 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 770 (0, "TSC_component::LcEtbIdc pending olcs.")); 771 if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == MASTER) 772 { 773 // We are master, hence we reject the incoming OLC with code M/S conflict 774 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 775 (0, "TSC_component::LcEtbIdc TCS violated with pending olcs from Master.")); 776 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 10); // Master slave conflict 777 RemoveOlc(dir, OpenLcn); 778 return PhaseE_Comm; 779 } 780 /* We should close the conflicting codec and reopen a replacement. Assumption here is that the 781 conflict is due to the media type of the current incoming channel. This will not work if there 782 are symmetry inter-dependencies between audio and video codecs in the TCS. */ 783 pending_outgoing_olc->GetForwardParams()->GetBitrate(); 784 iTSClc.LcRlsReq(RELEASE_CLOSE, 785 pending_outgoing_olc->GetChannelId(), 0); 786 ChannelReleased(OUTGOING, 787 pending_outgoing_olc->GetChannelId(), PVMFErrCancelled); 788 FormatCapabilityInfo codec_caps; 789 if (IsSupported(OUTGOING, incoming_codec_type, codec_caps)) 790 { 791 /* Verify if the capability sets can support it */ 792 TPVChannelId tmp_lcn = iOlcs.GetNextAvailLcn(); 793 iOlcs.AppendOlc(OUTGOING, tmp_lcn, pDataType, pH223Lcp); 794 if (ValidateOlcsWithTcs() == PVMFSuccess) 795 { 796 to_be_opened_codec = incoming_codec_type; 797 } 798 else 799 { 800 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 801 (0, "TSC_component::LcEtbIdc Cannot open a replacement channel as incoming codec is not supported")); 802 } 803 RemoveOlc(OUTGOING, tmp_lcn); 804 } 805 else 806 { 807 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 808 (0, "TSC_component::LcEtbIdc Incoming codec not supported for transmit")); 809 } 810 } 811 else 812 { 813 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 814 (0, "TSC_component::LcEtbIdc no pending olcs.")); 815 // There were no pending OLCs from the local terminal. 816 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 3); // dataTypeNotAvailable 817 RemoveOlc(dir, OpenLcn); 818 return PhaseE_Comm; 819 } 820 } 821 822 int leave_status = OpenLogicalChannel(OpenLcn, pDataType, pH223Lcp); 823 if (leave_status != 0) 824 { 825 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 826 (0, "TSC_component::LcEtbIdc - Memory Allocation Failed.")); 827 return leave_status; 828 } 829 830 uint8* fsi = NULL; 831 uint32 fsi_len = ::GetFormatSpecificInfo(pDataType, fsi); 832 iTSCObserver->IncomingChannel(OpenLcn, incoming_codec_type, fsi, fsi_len); 833 834 // ESTABLISH.response(LC) Primitive Send 835 iTSClc.LcEtbRps(OpenLcn); 836 837 SetCustomMultiplex(pReceiveInf, media_type); 838 if (to_be_opened_codec == PV_CODEC_TYPE_NONE) 839 return PhaseE_Comm; 840 FormatCapabilityInfo fci; 841 IsSupported(OUTGOING, to_be_opened_codec, fci); 842 PS_AdaptationLayerType al_type = GetOutgoingLayer(media_type, fci.max_sample_size); 843 if (al_type == NULL) 844 { 845 OSCL_LEAVE(PVMFErrNoMemory); 846 } 847 OpenOutgoingChannel(to_be_opened_codec, al_type); 848 Delete_AdaptationLayerType(al_type); 849 OSCL_DEFAULT_FREE(al_type); 850 iTSCmt.MtTrfReq(iOlcs); 851 return PhaseE_Comm; 852 } 853 854 uint32 TSC_component::OpenLogicalChannel(TPVChannelId OpenLcn, 855 PS_DataType pDataType, 856 PS_H223LogicalChannelParameters pH223Lcp) 857 { 858 int leave_status = 0; 859 OlcParam* param = NULL; 860 OSCL_TRY(leave_status, param = OpenLogicalChannel(INCOMING, 861 OpenLcn, CHANNEL_ID_UNKNOWN, pDataType, pH223Lcp)); 862 OSCL_FIRST_CATCH_ANY(leave_status, void()); 863 if (leave_status != 0) 864 { 865 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcn, 0); // unspecified 866 RemoveOlc(dir, OpenLcn); 867 return PhaseE_Comm; 868 } 869 param->SetState(OLC_ESTABLISHED); 870 return leave_status; 871 } 872 873 /*****************************************************************************/ 874 /* function name : Status04Event14 E_PtvId_Blc_Etb_Idc */ 875 /* function outline : Status04/Event14 procedure */ 876 /* function discription : Status04Event14( pReceiveInf ) */ 877 /* input data : PS_ControlMsgHeader Receive InfHeader Pointer */ 878 /* output data : uint32 Terminal Status */ 879 /* draw time : '96.10.09 */ 880 /*---------------------------------------------------------------------------*/ 881 /* amendment career(x) : */ 882 /* */ 883 /* Copyright (C) 1996 NTT DoCoMo */ 884 /*****************************************************************************/ 885 uint32 TSC_component::BlcEtbIdc(PS_ControlMsgHeader pReceiveInf) 886 { 887 TPVChannelId OpenLcnB = pReceiveInf->InfSupplement1 + TSC_INCOMING_CHANNEL_MASK; /* incoming lcn */ 888 TPVChannelId OpenLcnF = CHANNEL_ID_UNKNOWN; /* outgoing lcn */ 889 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 890 (0, "TSC_component::BlcEtbIdc lcn(%d)", OpenLcnB)); 891 /* Function prototypes */ 892 uint8* GetDecoderConfigFromOLC(PS_ForwardReverseParam pPara, uint32 forRev, uint16 *nOctets); 893 PS_ForwardReverseParam forRevParams = (PS_ForwardReverseParam)pReceiveInf->pParameter; 894 895 /* validate forRevParams */ 896 PVMFStatus forRevCheck = iTSCcapability.ValidateForwardReverseParams(forRevParams, INCOMING); 897 if (forRevCheck != PVMFSuccess) 898 { 899 PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_EMERG, 900 (0, "TSC_component::BlcEtbIdc ERROR - Incoming forRevParams not supported. Rejecting.")); 901 uint16 reason = (uint16)((forRevCheck == PVMFErrNotSupported) ? 2/* dataTypeNotSupported */ : 0/*unspecified*/); 902 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_REJECT, OpenLcnB, reason); 903 RemoveOlc(dir, OpenLcnB); 904 return PhaseE_Comm; 905 } 906 907 PS_ForwardLogicalChannelParameters forwardParams = &forRevParams->forwardLogicalChannelParameters; 908 PS_ReverseLogicalChannelParameters reverseParams = &forRevParams->reverseLogicalChannelParameters; 909 PVCodecType_t in_codec_type = ::GetCodecType(&forwardParams->dataType); 910 PVCodecType_t out_codec_type = ::GetCodecType(&reverseParams->dataType); 911 PV2WayMediaType out_media_type = ::GetMediaType(&reverseParams->dataType); 912 OSCL_UNUSED_ARG(out_media_type); 913 PV2WayMediaType in_media_type = ::GetMediaType(&forwardParams->dataType); 914 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 915 (0, "TSC_component::BlcEtbIdc in media type(%d), in codec type(%d), out media type(%d), out codec type(%d)", in_media_type, in_codec_type, out_media_type, out_codec_type)); 916 917 /* Do we support the outgoing codec ? */ 918 FormatCapabilityInfo codec_caps; 919 if (!IsSupported(OUTGOING, out_codec_type, codec_caps) || 920 !IsSupported(INCOMING, in_codec_type, codec_caps)) 921 { 922 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 923 (0, "TSC_component::BlcEtbIdc Outgoing/incoming codec not supported for transmit")); 924 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 2); /* dataTypeNotSupported */ 925 RemoveOlc(dir, OpenLcnB); 926 return(PhaseE_Comm); 927 } 928 929 unsigned outgoing_bitrate = 0; 930 if (out_codec_type != PV_CODEC_TYPE_NONE) 931 { 932 outgoing_bitrate = GetOutgoingBitrate(out_codec_type); 933 if (outgoing_bitrate <= 0) 934 { 935 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 936 (0, "TSC_component::BlcEtbIdc No bandwidth allocated for outgoing media type(%d)", 937 out_media_type)); 938 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 3); /* dataTypeNotAvailable */ 939 RemoveOlc(dir, OpenLcnB); 940 return PhaseE_Comm ; 941 } 942 } 943 944 /* Cancel waiting for OBLC */ 945 if (iWaitingForOblc) 946 { 947 if (out_codec_type != iWaitingForOblcCodec) 948 { 949 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 950 (0, "TSC_component::BlcEtbIdc Reverse codec in BLC(%d) does not match iWaitingForOblcCodec(%d)", 951 out_codec_type, iWaitingForOblcCodec)); 952 } 953 } 954 iWaitingForOblc = false; 955 iWaitingForOblcTimer->Clear(); 956 iWaitingForOblcCodec = PV_CODEC_TYPE_NONE; 957 958 Oscl_Vector<OlcParam*, OsclMemAllocator> pending_olc_list; 959 /* Pending incoming OLC for the same media type */ 960 if (iOlcs.FindOlcs(INCOMING, in_media_type, OLC_PENDING | OLC_ESTABLISHED, pending_olc_list)) 961 { 962 for (unsigned i = 0; i < pending_olc_list.size(); i++) 963 { 964 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 965 (0, "TSC_component::BlcEtbIdc Pending incoming OLC found for media type=%d, lcn=%d", 966 in_media_type, pending_olc_list[i]->GetChannelId())); 967 if (!ReleasedPendingIncomingChannel(pending_olc_list[i])) 968 { 969 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 970 (0, "TSC_component::BlcEtbIdc Established incoming OLC found for same media type. Rejecting OLC(%d)", in_media_type, OpenLcnB)); 971 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 0); /* unspecified */ 972 RemoveOlc(dir, OpenLcnB); 973 return PhaseE_Comm; 974 } 975 976 } 977 } 978 979 /* if there are established outgoing channels for the same media type, close them */ 980 if (out_codec_type != PV_CODEC_TYPE_NONE && 981 iOlcs.FindOlcs(OUTGOING, in_media_type, OLC_ESTABLISHED, pending_olc_list)) 982 { 983 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 984 (0, "TSC_component::BlcEtbIdc Established outgoing OLC found for same media type(%d). Closing down the OLCS", in_media_type)); 985 for (unsigned i = 0; i < pending_olc_list.size(); i++) 986 { 987 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 988 (0, "TSC_component::BlcEtbIdc Established outgoing OLC found for media type=%d, lcn=%d", 989 in_media_type, pending_olc_list[i]->GetChannelId())); 990 ChannelReleased(OUTGOING, pending_olc_list[i]->GetChannelId(), PVMFFailure); 991 } 992 } 993 994 PVCodecType_t to_be_opened_codec = PV_CODEC_TYPE_NONE; 995 /* is there is a pending outgoing OLC for the same media type ?*/ 996 if (iOlcs.FindOlcs(OUTGOING, in_media_type, OLC_PENDING, pending_olc_list)) 997 { 998 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 999 (0, "TSC_component::BlcEtbIdc Pending outgoing OLCs(%d) found for incoming media type(%d).", 1000 pending_olc_list.size(), in_media_type, OpenLcnB)); 1001 OSCL_ASSERT(pending_olc_list.size() == 1); 1002 OlcParam* param = pending_olc_list[0]; 1003 if (param->GetDirectionality() == EPVT_BI_DIRECTIONAL || /* Bi-dir: always causes conflict*/ 1004 out_codec_type != PV_CODEC_TYPE_NONE) /*Uni-dir: no conflict if reverse params are NULL */ 1005 { 1006 /* OLCs are conflicting */ 1007 if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == MASTER) 1008 { 1009 /* We are master, hence we reject the incoming OLC */ 1010 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1011 (0, "TSC_component::BlcEtbIdc BLC Already initiated by local. Rejecting OBLC cause we are Master")); 1012 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 10); /* Master slave conflict */ 1013 RemoveOlc(dir, OpenLcnB); 1014 return PhaseE_Comm ; 1015 } 1016 /* we are slave */ 1017 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1018 (0, "TSC_component::BlcEtbIdc LC Already initiated by local. Closing it cause we are Slave")); 1019 if (out_codec_type == PV_CODEC_TYPE_NONE) 1020 { 1021 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1022 (0, "TSC_component::BlcEtbIdc Reverse DataType==NULL; Need to open replacement OLC/OBLC")); 1023 to_be_opened_codec = GetCodecType(param->GetForwardParams()->GetDataType()); 1024 } 1025 ReleaseOlc(param, 0); 1026 ChannelReleased(OUTGOING, param->GetChannelId(), PVMFErrCancelled); 1027 } 1028 } 1029 pending_olc_list.clear(); 1030 /* Generate logical channel number */ 1031 OpenLcnF = iOlcs.GetNextAvailLcn(); 1032 OlcParam* prm = iOlcs.AppendOlc(INCOMING, OpenLcnB, 1033 &forwardParams->dataType, 1034 forwardParams->multiplexParameters.h223LogicalChannelParameters, 1035 OpenLcnF, 1036 &reverseParams->dataType, 1037 reverseParams->rlcMultiplexParameters.h223LogicalChannelParameters); 1038 1039 prm->GetReverseParams()->SetChannelId(OpenLcnF); 1040 /* Validate the TCS's */ 1041 PVMFStatus tscCheck = ValidateOlcsWithTcs(); 1042 bool transfer_mux_tables = false; 1043 if (tscCheck != PVMFSuccess) 1044 { 1045 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1046 (0, "TSC_component::BlcEtbIdc TCS check failed")); 1047 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 2); /* dataTypeNotSupported */ 1048 RemoveOlc(dir, OpenLcnB); 1049 } 1050 else 1051 { 1052 PVMFStatus RvsParametersOkay = VerifyReverseParameters(forRevParams, iTSCObserver); 1053 if (RvsParametersOkay == PVMFSuccess) 1054 { 1055 AcceptBLCRequest(OpenLcnF, OpenLcnB, forRevParams); 1056 } 1057 else 1058 { 1059 /* RvsParameters are unsuitable; reject the OLC */ 1060 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1061 (0, "TSC_component::BlcEtbIdc - Rejecting BLC request (%d). Reverse parameters not ok.", 1062 OpenLcnB)); 1063 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_REJECT, OpenLcnB, 1); /* unsuitableReverseParameters */ 1064 RemoveOlc(dir, OpenLcnB); 1065 /* Fill the data type for the outgoing codec */ 1066 PS_DataType pDataType = GetOutgoingDataType(out_codec_type, outgoing_bitrate); 1067 /* Fill the outgoing h223 logical channel parameters */ 1068 PS_H223LogicalChannelParameters pH223Params = 1069 GetH223LogicalChannelParameters((uint8)IndexForAdaptationLayer(PVT_AL3), 1070 iTSCcapability.IsSegmentable(OUTGOING, in_media_type), 1071 iAl3ControlFieldOctets); 1072 1073 // Use AL3 for OBLC 1074 PS_AdaptationLayerType al_type = (PS_AdaptationLayerType)OSCL_DEFAULT_MALLOC(sizeof(S_AdaptationLayerType)); 1075 if (al_type == NULL) 1076 { 1077 OSCL_LEAVE(PVMFErrNoMemory); 1078 } 1079 PS_Al3 al3 = (PS_Al3)OSCL_DEFAULT_MALLOC(sizeof(S_Al3)); 1080 al3->controlFieldOctets = iAl3ControlFieldOctets; 1081 al3->sendBufferSize = DEF_AL3_SEND_BUFFER_SIZE; 1082 al_type->index = 5; 1083 al_type->al3 = al3; 1084 1085 OpenOutgoingChannel(out_codec_type, 1086 al_type, 1087 &forRevParams->forwardLogicalChannelParameters.dataType, 1088 forRevParams->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters); 1089 1090 iOlcs.AppendOlc(OUTGOING, OpenLcnF, pDataType, pH223Params, 1091 CHANNEL_ID_UNKNOWN, &forRevParams->forwardLogicalChannelParameters.dataType, 1092 forRevParams->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters); 1093 transfer_mux_tables = true; 1094 Delete_AdaptationLayerType(al_type); 1095 OSCL_DEFAULT_FREE(al_type); 1096 Delete_DataType(pDataType); 1097 OSCL_DEFAULT_FREE(pDataType); 1098 Delete_H223LogicalChannelParameters(pH223Params); 1099 OSCL_DEFAULT_FREE(pH223Params); 1100 } 1101 } 1102 1103 if (to_be_opened_codec != PV_CODEC_TYPE_NONE) 1104 { 1105 FormatCapabilityInfo fci; 1106 IsSupported(OUTGOING, to_be_opened_codec, fci); 1107 PS_AdaptationLayerType al_type = GetOutgoingLayer(::GetMediaType(to_be_opened_codec), 1108 fci.max_sample_size); 1109 if (al_type == NULL) 1110 { 1111 OSCL_LEAVE(PVMFErrNoMemory); 1112 } 1113 OpenOutgoingChannel(to_be_opened_codec, al_type); 1114 Delete_AdaptationLayerType(al_type); 1115 OSCL_DEFAULT_FREE(al_type); 1116 transfer_mux_tables = true; 1117 } 1118 if (transfer_mux_tables) 1119 { 1120 iTSCmt.MtTrfReq(iOlcs); 1121 } 1122 return(PhaseE_Comm); 1123 } 1124 1125 PVMFStatus TSC_component::VerifyReverseParameters(PS_ForwardReverseParam forRevParams, 1126 TSCObserver* aObserver) 1127 { 1128 OSCL_UNUSED_ARG(aObserver); 1129 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1130 (0, "TSC_capability::VerifyReverseParameters")); 1131 PVMFStatus status; 1132 bool returnNow = iTSCcapability.VerifyReverseParameters(forRevParams, iTSCObserver, status); 1133 1134 if (returnNow) 1135 { 1136 return status; 1137 } 1138 PVCodecType_t codec = GetCodecType(&forRevParams->reverseLogicalChannelParameters.dataType); 1139 PV2WayMediaType media_type = GetMediaType(codec); 1140 uint8* decodeConfigInfoOblc = NULL; 1141 unsigned decodeConfigInfoSzOblc = 1142 ::GetFormatSpecificInfo(&forRevParams->reverseLogicalChannelParameters.dataType, 1143 decodeConfigInfoOblc); 1144 // get the outgoing FSI if any 1145 for (unsigned n = 0; n < iOutgoingChannelConfig->size(); n++) 1146 { 1147 PV2WayMediaType channelMediaType = (*iOutgoingChannelConfig)[n].GetMediaType(); 1148 if (channelMediaType != media_type) 1149 { 1150 continue; 1151 } 1152 Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* formats = 1153 (*iOutgoingChannelConfig)[n].GetCodecs(); 1154 if (!formats) 1155 { 1156 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1157 (0, "TSC_component::VerifyReverseParameters No formats specified for media type(%d)", 1158 channelMediaType)); 1159 continue; 1160 } 1161 for (unsigned m = 0; m < formats->size(); m++) 1162 { 1163 PVCodecType_t codec_type_outgoing = PVMFFormatTypeToPVCodecType((*formats)[m].format); 1164 if (codec_type_outgoing != codec) 1165 continue; 1166 if ((*formats)[m].fsi == NULL || (*formats)[m].fsi_len == 0) 1167 { 1168 // There are no FSI restrictions 1169 return PVMFSuccess; 1170 } 1171 if (decodeConfigInfoSzOblc == (*formats)[m].fsi_len && 1172 oscl_memcmp(decodeConfigInfoOblc, (*formats)[m].fsi, decodeConfigInfoSzOblc) == 0) 1173 { 1174 return PVMFSuccess; 1175 } 1176 } 1177 } 1178 1179 return PVMFFailure; 1180 } 1181 1182 1183 PVMFStatus TSC_component::ValidateOlcsWithTcs() 1184 { 1185 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1186 (0, "TSC_component::ValidateOlcsWithTcs")); 1187 /* Verify if local TCS is satisfied */ 1188 Oscl_Vector<OlcFormatInfo, OsclMemAllocator> incoming_codecs; 1189 if (!iOlcs.FindCodecs(INCOMING, PV_MEDIA_NONE, OLC_ESTABLISHED, 1190 PV_DIRECTION_BOTH, incoming_codecs)) 1191 return PVMFSuccess; 1192 /* Set symmetry info in the codecs */ 1193 unsigned n = 0; 1194 for (n = 0; n < incoming_codecs.size(); n++) 1195 { 1196 PV2WayMediaType media_type = GetMediaType(incoming_codecs[n].iCodec); 1197 incoming_codecs[n].isSymmetric = iOlcs.IsSymmetric(media_type, 1198 PV_DIRECTION_BOTH, OLC_PENDING | OLC_ESTABLISHED, 1199 PV_DIRECTION_BOTH, OLC_PENDING | OLC_ESTABLISHED); 1200 } 1201 PVMFStatus status = VerifyCodecs(iLocalTcs, incoming_codecs, iLogger); 1202 if (status != PVMFSuccess) 1203 { 1204 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1205 (0, "TSC_component::ValidateOlcsWithTcs Codecs not compatible with local TCS")); 1206 return status; 1207 } 1208 1209 /* Verify if remote TCS is satisfied */ 1210 Oscl_Vector<OlcFormatInfo, OsclMemAllocator> outgoing_codecs; 1211 if (!iOlcs.FindCodecs(OUTGOING, PV_MEDIA_NONE, 1212 OLC_PENDING | OLC_ESTABLISHED, PV_DIRECTION_BOTH, outgoing_codecs)) 1213 return PVMFSuccess; 1214 /* Set symmetry info in the codecs */ 1215 for (n = 0; n < outgoing_codecs.size(); n++) 1216 { 1217 PV2WayMediaType media_type = GetMediaType(outgoing_codecs[n].iCodec); 1218 outgoing_codecs[n].isSymmetric = iOlcs.IsSymmetric(media_type, 1219 PV_DIRECTION_BOTH, 1220 OLC_PENDING | OLC_ESTABLISHED, 1221 PV_DIRECTION_BOTH, 1222 OLC_PENDING | OLC_ESTABLISHED); 1223 } 1224 status = VerifyCodecs(iRemoteTcs, outgoing_codecs, iLogger); 1225 if (status != PVMFSuccess) 1226 { 1227 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1228 (0, "TSC_component::ValidateOlcsWithTcs Codecs not compatible with remote TCS")); 1229 } 1230 return status; 1231 } 1232 1233 OsclAny TSC_component::TcsMsdComplete() 1234 { 1235 ClipCodecs(iRemoteTcs); 1236 1237 if (!iOutgoingChannelConfig || iOutgoingChannelConfig->size() == 0) 1238 { 1239 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1240 (0, "TSC_component::TcsMsdComplete No outgoing channels configured(%x)", 1241 iOutgoingChannelConfig)); 1242 return; 1243 } 1244 1245 //Oscl_Vector<OlcParam*, OsclMemAllocator> olc_list; 1246 CPVMultiplexEntryDescriptorVector descriptors; 1247 1248 // start OLCs 1249 for (unsigned olcnum = 0; olcnum < iOutgoingChannelConfig->size(); olcnum++) 1250 { 1251 int index = -1; 1252 PV2WayMediaType media_type = (*iOutgoingChannelConfig)[olcnum].GetMediaType(); 1253 if (!FindCodecForMediaType(media_type, iOutCodecList, &index)) 1254 { 1255 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1256 (0, "TSC_component::TcsMsdComplete No outgoing codec selected for media type=%d", 1257 media_type)); 1258 continue; 1259 } 1260 if (AlreadyAssigned(media_type)) 1261 { 1262 continue; 1263 } 1264 1265 1266 PVCodecType_t incoming_codec = PV_CODEC_TYPE_NONE; 1267 FormatCapabilityInfo fci; 1268 IsSupported(OUTGOING, iOutCodecList[index]->codec, fci); 1269 PS_AdaptationLayerType al_type = GetOutgoingLayer(media_type, fci.max_sample_size); 1270 if (al_type == NULL) 1271 { 1272 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1273 (0, "TSC_component::TcsMsdComplete Failed to allocate adaptation layer for media type=%d", 1274 media_type)); 1275 continue; 1276 } 1277 PS_DataType pDataTypeRvs = NULL; 1278 PS_H223LogicalChannelParameters pH223ParamsRvs = NULL; 1279 if (al_type->index == 5) /* AL3 */ 1280 { 1281 incoming_codec = iOutCodecList[index]->codec; 1282 pDataTypeRvs = GetOutgoingDataType(incoming_codec, 1283 GetOutgoingBitrate(incoming_codec)); 1284 pH223ParamsRvs = GetH223LogicalChannelParameters((uint8)IndexForAdaptationLayer(PVT_AL3), 1285 iTSCcapability.IsSegmentable(INCOMING, media_type), 1286 iAl3ControlFieldOctets); 1287 } 1288 1289 OlcParam* olc_param = OpenOutgoingChannel(iOutCodecList[index]->codec, 1290 al_type, pDataTypeRvs, pH223ParamsRvs); 1291 if (pH223ParamsRvs) 1292 { 1293 Delete_H223LogicalChannelParameters(pH223ParamsRvs); 1294 OSCL_DEFAULT_FREE(pH223ParamsRvs); 1295 } 1296 if (pDataTypeRvs) 1297 { 1298 Delete_DataType(pDataTypeRvs); 1299 OSCL_DEFAULT_FREE(pDataTypeRvs); 1300 } 1301 Delete_AdaptationLayerType(al_type); 1302 OSCL_DEFAULT_FREE(al_type); 1303 StartOlc(olc_param, media_type, descriptors); 1304 } 1305 if (FinishTcsMsdComplete(descriptors)) 1306 { 1307 iTSCmt.MtTrfReq(iOlcs); 1308 } 1309 // Reset flags used to force AL 1310 iUseAl1Video = true; 1311 iUseAl2Video = true; 1312 iUseAl3Video = true; 1313 #ifdef MEM_TRACK 1314 printf("\n Memory Stats After TcsMsdComplete"); 1315 MemStats(); 1316 #endif 1317 } 1318 1319 void TSC_component::SetOutgoingChannelConfig(Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>& out_channel_config) 1320 { 1321 if (iOutgoingChannelConfig) 1322 { 1323 OSCL_DELETE(iOutgoingChannelConfig); 1324 iOutgoingChannelConfig = NULL; 1325 } 1326 iOutgoingChannelConfig = new Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>(out_channel_config); 1327 1328 } 1329 1330 void TSC_component::SetIncomingChannelConfig(Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>& in_channel_config) 1331 { 1332 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1333 (0, "TSC_component::SetIncomingChannelConfig size(%d)\n", in_channel_config.size())); 1334 if (iIncomingChannelConfig) 1335 { 1336 OSCL_DELETE(iIncomingChannelConfig); 1337 iIncomingChannelConfig = NULL; 1338 } 1339 iIncomingChannelConfig = new Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>(in_channel_config); 1340 } 1341 1342 /*****************************************************************************/ 1343 /* function name : Status04Event10 E_PtvId_Lc_Etb_Cfm */ 1344 /* function outline : Status04/Event10 procedure */ 1345 /* function discription : Status04Event10( pReceiveInf ) */ 1346 /* input data : PS_ControlMsgHeader Receive InfHeader Pointer */ 1347 /* output data : uint32 Terminal Status */ 1348 /* draw time : '96.10.09 */ 1349 /*---------------------------------------------------------------------------*/ 1350 /* amendment career(x) : */ 1351 /* */ 1352 /* Copyright (C) 1996 NTT DoCoMo */ 1353 /*****************************************************************************/ 1354 uint32 TSC_component::LcEtbCfm(PS_ControlMsgHeader pReceiveInf) 1355 { 1356 TPVChannelId lcn = pReceiveInf->InfSupplement1; 1357 /*OlcParam* olc_param = OpenLogicalChannel(OUTGOING, lcn); 1358 } 1359 return PhaseE_Comm; 1360 */ 1361 OlcParam* olc_param = iOlcs.FindOlcGivenChannel(OUTGOING, lcn); 1362 if (olc_param == NULL) 1363 { 1364 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1365 (0, "TSC_component::LcEtbCfm ERROR Unable to lookup channel")); 1366 return (PhaseE_Comm); 1367 } 1368 olc_param->SetState(OLC_ESTABLISHED); 1369 CheckOutgoingChannel(olc_param, PVMFSuccess); 1370 return PhaseE_Comm; 1371 1372 } 1373 1374 unsigned TSC_component::GetOutgoingBitrate(PVCodecType_t codec_type) 1375 { 1376 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1377 (0, "TSC_component::GetOutgoingBitrate codec_type=%d", codec_type)); 1378 PV2WayMediaType media_type = GetMediaType(codec_type); 1379 if (!iOutgoingChannelConfig || !iOutgoingChannelConfig->size()) 1380 { 1381 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1382 (0, "TSC_component::GetOutgoingBitrate outgoing channel config not found.")); 1383 return 0; 1384 } 1385 uint32 bitrate = 0; 1386 for (unsigned n = 0; n < iOutgoingChannelConfig->size(); n++) 1387 { 1388 H324ChannelParameters& params = (*iOutgoingChannelConfig)[n]; 1389 if (params.GetMediaType() == media_type) 1390 { 1391 bitrate = params.GetBandwidth(); 1392 break; 1393 } 1394 } 1395 if (bitrate == 0) 1396 { 1397 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1398 (0, "TSC_component::GetOutgoingBitrate outgoing channel bitrate=0.")); 1399 return bitrate; 1400 } 1401 // lookup the bitrate from remote capabilities 1402 uint32 br = iTSCcapability.GetRemoteBitrate(codec_type); 1403 bitrate = (bitrate > br) ? br : bitrate; 1404 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1405 (0, "TSC_component::GetOutgoingBitrate outgoing channel bitrate=%d.", bitrate)); 1406 return bitrate; 1407 } 1408 1409 void TSC_component::GetChannelFormatAndCapabilities(TPVDirection dir, 1410 Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>& formats) 1411 { 1412 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1413 (0, "TSC_component::GetChannelFormatAndCapabilities")); 1414 OlcList::iterator it = iOlcs.begin(); 1415 1416 while (it != iOlcs.end()) 1417 { 1418 OlcList::value_type& val = (*it++); 1419 OlcParam* olc = val.second; 1420 H223ChannelParam* param = NULL; 1421 if (olc->GetDirection() == dir) 1422 { 1423 param = olc->GetForwardParams(); 1424 } 1425 else if (olc->GetReverseParams()) 1426 { 1427 param = olc->GetReverseParams(); 1428 } 1429 FormatCapabilityInfo fci; 1430 fci.id = param->GetChannelId(); 1431 fci.dir = dir; 1432 fci.format = PVCodecTypeToPVMFFormatType(param->GetMediaParam()->GetCodecType()); 1433 fci.bitrate = param->GetBitrate(); 1434 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1435 (0, "TSC_component::GetChannelFormatAndCapabilities Adding(%d,%d,%s,%d) to list", 1436 fci.dir, fci.id, fci.format.getMIMEStrPtr(), fci.bitrate)); 1437 formats.push_back(fci); 1438 } 1439 } 1440 1441 bool TSC_component::HasOlc(TPVDirection direction, 1442 TPVChannelId id, 1443 unsigned state) 1444 { 1445 if (state) 1446 { 1447 return iOlcs.HasOlc(direction, id, state); 1448 } 1449 else 1450 { 1451 return iOlcs.HasOlc(direction, id); 1452 } 1453 } 1454 1455 OlcParam* TSC_component::FindOlcGivenChannel(TPVDirection direction, 1456 TPVChannelId id) 1457 { 1458 return iOlcs.FindOlcGivenChannel(direction, id); 1459 } 1460 1461 OlcParam* TSC_component::FindOlc(TPVDirection direction, 1462 PV2WayMediaType media_type, 1463 unsigned state) 1464 { 1465 return iOlcs.FindOlc(direction, media_type, state); 1466 } 1467 1468 void TSC_component::LcnDataDetected(TPVChannelId lcn) 1469 { 1470 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1471 (0, "TSC_component::LcnDataDetected - lcn=%d", lcn)); 1472 OlcParam* param = iOlcs.FindOlcGivenChannel(INCOMING, lcn); 1473 if (param == NULL) 1474 { 1475 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1476 (0, "TSC_component::LcnDataDetected - Failed to lookup channel, lcn=%d", lcn)); 1477 return; 1478 } 1479 if (param->GetReplacementFor() != CHANNEL_ID_UNKNOWN) 1480 { 1481 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1482 (0, "TSC_component::LcnDataDetected - Replaced channel id=%d", 1483 param->GetReplacementFor())); 1484 ChannelReleased(INCOMING, param->GetReplacementFor(), PV2WayErrReplaced); 1485 param->SetReplacementFor((TPVChannelId)NULL); 1486 } 1487 } 1488 1489 // ======================================================= 1490 // AcceptBLCRequest() 1491 // 1492 // WWUAPI - New Function 1493 // ======================================================= 1494 OsclAny TSC_component::AcceptBLCRequest(TPVChannelId OpenLcnF, 1495 TPVChannelId OpenLcnB, 1496 PS_ForwardReverseParam forRevParams) 1497 { 1498 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1499 (0, "TSC: AcceptBLCRequest reverse(%d), forward(%d)\n", OpenLcnB, OpenLcnF)); 1500 /* RvsParameters are okay; accept the OLC */ 1501 iTSCblc.BlcEtbRps(OpenLcnB - TSC_INCOMING_CHANNEL_MASK, OpenLcnF); 1502 // Open the incoming and outgoing logical channels in the mux 1503 OlcParam* param = OpenLogicalChannel(INCOMING, 1504 OpenLcnB, 1505 OpenLcnF, 1506 &forRevParams->forwardLogicalChannelParameters.dataType, 1507 forRevParams->forwardLogicalChannelParameters.multiplexParameters.h223LogicalChannelParameters, 1508 &forRevParams->reverseLogicalChannelParameters.dataType, 1509 forRevParams->reverseLogicalChannelParameters.rlcMultiplexParameters.h223LogicalChannelParameters); 1510 param->SetState(OLC_ESTABLISHED); 1511 /* Send updated MuxTable for outgoing part of the BLC */ 1512 iTSCmt.MtTrfReq(iOlcs); 1513 1514 uint8* fsi = NULL; 1515 uint32 fsi_len = ::GetFormatSpecificInfo(&forRevParams->forwardLogicalChannelParameters.dataType, fsi); 1516 iTSCObserver->IncomingChannel(OpenLcnB, 1517 GetCodecType(&forRevParams->forwardLogicalChannelParameters.dataType), 1518 fsi, fsi_len); 1519 1520 if (OpenLcnF == CHANNEL_ID_UNKNOWN || 1521 GetCodecType(param->GetReverseParams()->GetDataType()) == PV_CODEC_TYPE_NONE) 1522 return; 1523 1524 // Pause the channel untill OlcAck+MtAck is received 1525 H223OutgoingChannelPtr outgoing_channel; 1526 iH223->GetOutgoingChannel(OpenLcnF, outgoing_channel); 1527 outgoing_channel->Pause(); 1528 // Notify outgoing channel 1529 fsi_len = GetFormatSpecificInfo(&forRevParams->reverseLogicalChannelParameters.dataType, fsi); 1530 iTSCObserver->OutgoingChannelEstablished(OpenLcnF, 1531 GetCodecType(&forRevParams->reverseLogicalChannelParameters.dataType), 1532 fsi, fsi_len); 1533 } 1534 1535 // ============================================================= 1536 // Status04Event11() E_PtvId_Lc_Rls_Idc 1537 // 1538 // This is LCSE RELEASE.indication. 1539 // ============================================================= 1540 uint32 TSC_component::LcRlsIdc(PS_ControlMsgHeader pReceiveInf) 1541 { 1542 TPVDirection dir = (pReceiveInf->Dir == S_ControlMsgHeader::INCOMING) ? INCOMING : OUTGOING; 1543 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1544 (0, "TSC_component::LcRlsIdc dir(%d), lcn(%d).", 1545 dir, pReceiveInf->InfSupplement1)); 1546 TPVChannelId lcn = (dir == INCOMING) ? (TPVChannelId)(pReceiveInf->InfSupplement1 + 1547 TSC_INCOMING_CHANNEL_MASK) : (TPVChannelId)pReceiveInf->InfSupplement1; 1548 PS_SourceCause_LcBlc sourceCause = (PS_SourceCause_LcBlc)pReceiveInf->pParameter; 1549 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1550 (0, "TSC_component::LcRlsIdc sourceCause(%x), cause index(%d)", 1551 sourceCause, sourceCause->Cause.index)); 1552 PVMFStatus status = PVMFSuccess; 1553 1554 OlcParam* olc_param = iOlcs.FindOlcGivenChannel(dir, lcn); 1555 if (olc_param == NULL) 1556 { 1557 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1558 (0, "TSC_component::LcRlsIdc ERROR Unable to lookup channel")); 1559 return (PhaseE_Comm); 1560 } 1561 1562 if (dir == OUTGOING) 1563 { 1564 if (olc_param->GetState() == OLC_PENDING) 1565 { 1566 // only valid rejection code is m/s conflict 1567 if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == SLAVE && 1568 sourceCause->Cause.index == 10) 1569 { 1570 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1571 (0, "TSC_component::LcRlsIdc Reject due to M/S conflict")); 1572 } 1573 else 1574 { 1575 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1576 (0, "TSC_component::LcRlsIdc Olc failure")); 1577 status = PVMFFailure; 1578 } 1579 } 1580 } 1581 else if (dir == INCOMING) 1582 { 1583 RemoveMultiplex(olc_param); 1584 } 1585 ChannelReleased(dir, lcn, status); 1586 return(PhaseE_Comm); 1587 } 1588 1589 // ============================================================= 1590 // Status04Event16() E_PtvId_Blc_Rls_Idc 1591 // 1592 // This is BLCSE RELEASE.indication. It is called when 1593 // a Bi-Dir OLCReject is received. It could be from an incoming or outgoing SE 1594 // ============================================================= 1595 uint32 TSC_component::BlcRlsIdc(PS_ControlMsgHeader pReceiveInf) 1596 { 1597 PS_SourceCause_LcBlc sourceCause = (PS_SourceCause_LcBlc)pReceiveInf->pParameter; 1598 int32 causeIndex = sourceCause->Cause.index; 1599 TPVDirection dir = OUTGOING; 1600 TPVChannelId lcn = (TPVChannelId)pReceiveInf->InfSupplement1;; 1601 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1602 (0, "TSC_component::BlcRlsIdc BLC rejected. dir(%d), forward lcn(%d), reverse lcn(%d), cause index(%d)", 1603 dir, pReceiveInf->InfSupplement1, pReceiveInf->InfSupplement2, causeIndex)); 1604 1605 if (pReceiveInf->Dir == S_ControlMsgHeader::INCOMING) 1606 { 1607 dir = INCOMING; 1608 lcn += TSC_INCOMING_CHANNEL_MASK; 1609 } 1610 1611 PVMFStatus status = PVMFSuccess; 1612 PVCodecType_t to_be_opened_codec = PV_CODEC_TYPE_NONE; 1613 PV2WayMediaType media_type = PV_MEDIA_NONE; 1614 1615 if (dir == OUTGOING) 1616 { 1617 OlcParam* olc_param = iOlcs.FindOlcGivenChannel(OUTGOING, lcn); 1618 if (olc_param != NULL) 1619 { 1620 media_type = GetMediaType(olc_param->GetForwardParams()->GetDataType()); 1621 if (olc_param->GetState() == OLC_PENDING) 1622 { 1623 if (causeIndex == 1) 1624 { 1625 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1626 (0, "TSC_component::BlcRlsIdc UnsuitableReverseParams. Entering wait state ...")); 1627 /* Cause is unsuitableReverseParameters; Enter wait state */ 1628 iWaitingForOblc = true; 1629 iWaitingForOblcCodec = GetCodecType(olc_param->GetForwardParams()->GetDataType()); 1630 iWaitingForOblcTimer->Request(PV_TSC_WAITING_FOR_OBLC_TIMER_ID, 1631 PV_TSC_WAITING_FOR_OBLC_TIMER_ID , WAITING_FOR_OBLC_TIMEOUT_SECONDS, this); 1632 } 1633 else if (iTSCstatemanager.ReadState(TSC_MSD_DECISION) == SLAVE && 1634 causeIndex == 10) 1635 { 1636 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1637 (0, "TSC_component::BlcRlsIdc Master/Slave conflict")); 1638 // is there is a pending outgoing OLC for the same media type ? 1639 Oscl_Vector<OlcParam*, OsclMemAllocator> pending_olc_list; 1640 if (iOlcs.FindOlcs(OUTGOING, media_type, OLC_PENDING, pending_olc_list)) 1641 { 1642 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1643 (0, "TSC_component::BlcRlsIdc Pending outgoing OLCs(%d) found for incoming media type(%d).", 1644 pending_olc_list.size(), media_type)); 1645 OSCL_ASSERT(pending_olc_list.size() == 1); 1646 OlcParam* param = pending_olc_list[0]; 1647 to_be_opened_codec = GetCodecType(param->GetForwardParams()->GetDataType()); 1648 } 1649 } 1650 else 1651 { 1652 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1653 (0, "TSC_component::BlcRlsIdc Olc failure")); 1654 status = PVMFFailure; 1655 } 1656 } 1657 } 1658 } 1659 else if (dir == INCOMING) 1660 { 1661 lcn += TSC_INCOMING_CHANNEL_MASK; 1662 } 1663 ChannelReleased(dir, lcn, status); 1664 1665 if (to_be_opened_codec == PV_CODEC_TYPE_NONE) 1666 return PhaseE_Comm; 1667 FormatCapabilityInfo fci; 1668 IsSupported(OUTGOING, to_be_opened_codec, fci); 1669 PS_AdaptationLayerType al_type = GetOutgoingLayer(media_type, fci.max_sample_size); 1670 if (al_type == NULL) 1671 { 1672 OSCL_LEAVE(PVMFErrNoMemory); 1673 } 1674 OpenOutgoingChannel(to_be_opened_codec, al_type); 1675 Delete_AdaptationLayerType(al_type); 1676 OSCL_DEFAULT_FREE(al_type); 1677 iTSCmt.MtTrfReq(iOlcs); 1678 return(PhaseE_Comm); 1679 } 1680 1681 OsclAny TSC_component::MuxTableSendComplete(uint32 sn, PVMFStatus status) 1682 { 1683 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1684 (0, "TSC::MuxTableSendComplete sn(%d), status(%d)", sn, status)); 1685 if (!iTSCmt.MuxTableSendComplete(sn)) 1686 { 1687 return; 1688 } 1689 Oscl_Vector<OlcParam*, OsclMemAllocator> olc_list; 1690 unsigned num_pending = iOlcs.FindOutgoingOlcsByMtState(MT_PENDING, olc_list); 1691 for (unsigned lcn = 0; lcn < num_pending; lcn++) 1692 { 1693 //OSCL_ASSERT(olc_list[lcn]->GetMtSn()==sn); 1694 olc_list[lcn]->SetMtState(status == PVMFSuccess ? MT_COMPLETE : MT_RELEASED); 1695 if (olc_list[lcn]->GetState() == OLC_ESTABLISHED) 1696 { 1697 CheckOutgoingChannel(olc_list[lcn], status); 1698 } 1699 else 1700 { 1701 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1702 (0, "TSC_component::MuxTableSendComplete Mux table completed, but channel still pending. channel id=(%d)", olc_list[lcn]->GetChannelId())); 1703 } 1704 } 1705 iTSCmt.ReleaseMuxTables(); 1706 } 1707 1708 // =============================================================== 1709 // StopData() 1710 // 1711 // Sets flags in the H324 system table which stop data transmission 1712 // for each open, outgoing logical channel. 1713 // ================================================================ 1714 OsclAny TSC_component::StopData() 1715 { 1716 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1717 (0, "TSC_component::StopData")); 1718 OlcList::iterator it = iOlcs.begin(); 1719 while (it != iOlcs.end()) 1720 { 1721 OlcParam* olc = (*it++).second; 1722 iH223->StopChannel(olc->GetDirection(), olc->GetChannelId()); 1723 if (olc->GetReverseParams()) 1724 { 1725 iH223->StopChannel(olc->GetReverseParams()->GetDirection(), 1726 olc->GetReverseParams()->GetChannelId()); 1727 } 1728 } 1729 } 1730 1731 // bool whether level is unknown 1732 bool TSC_component::Connect1LevelKnown() 1733 { 1734 PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iLogger, PVLOGMSG_NOTICE, 1735 (0, "TSC_component::Connect")); 1736 bool levelknown = true; 1737 iWaitingForOblc = false; 1738 iWaitingForOblcCodec = PV_CODEC_TYPE_NONE; 1739 1740 1741 if (iOutgoingChannelConfig == NULL) 1742 { 1743 OSCL_LEAVE(PVMFErrNoMemory); 1744 } 1745 1746 if (iIncomingChannelConfig == NULL) 1747 { 1748 OSCL_LEAVE(PVMFErrNoMemory); 1749 } 1750 1751 iWaitingForOblcTimer->Clear(); 1752 return levelknown; 1753 } 1754 1755 void TSC_component::Connect2() 1756 { 1757 H223PduParcomSharedPtr parcom; 1758 iH223->Start(parcom); 1759 } 1760 1761 // ======================================================= 1762 // ClipCodecs() (RAN-32K) 1763 // 1764 // This one reconciles the desired outgoing codecs with the 1765 // capabilities of the remote terminal. The outgoing 1766 // codecs have been specified by the application via calls 1767 // to pH324.SetVideoType(), pH324.SetAudioType(). The 1768 // remote terminal capabilities from the received 1769 // TerminalCapabilitySet are passed in (pTcs). 1770 // If insufficient capabilities are found, the routine will 1771 // modify the outgoing codecs stored in pH324. 1772 // ======================================================= 1773 OsclAny TSC_component::ClipCodecs(PS_TerminalCapabilitySet pTcs) 1774 { 1775 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1776 (0, "TSC_component::ClipCodecs(%d,%d)", 1777 pTcs->size_of_capabilityTable, 1778 pTcs->size_of_capabilityDescriptors)); 1779 if (!(pTcs->option_of_capabilityTable && pTcs->option_of_capabilityDescriptors)) 1780 { 1781 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1782 (0, "TSC_component::ClipCodecs - Remote terminal is incapable of decoding anything")); 1783 return; 1784 } 1785 if (!iOutgoingChannelConfig || iOutgoingChannelConfig->size() == 0) 1786 { 1787 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1788 (0, "TSC_component::ClipCodecs - We dont want to send anything. Skip ClipCodecs.")); 1789 return; 1790 } 1791 PS_CapabilityDescriptor pCapDesc = NULL; 1792 PS_AlternativeCapabilitySet pAltCapSet = NULL; 1793 for (unsigned i = 0; i < pTcs->size_of_capabilityDescriptors; ++i) 1794 { 1795 pCapDesc = pTcs->capabilityDescriptors + i; 1796 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1797 (0, "TSC_component::ClipCodecs - descriptor(%d),size_of_simultaneousCapabilities(%d)", 1798 i, pCapDesc->size_of_simultaneousCapabilities)); 1799 /* Temporary list of selected codecs. Retain the codecs for descriptor with most matching codecs */ 1800 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> codec_list; 1801 /* A changing list of available media for outgoing channels. Once a codec is selected, 1802 the entry for that media is removed from this list */ 1803 Oscl_Vector<H324ChannelParameters, PVMFTscAlloc> outgoing_media(*iOutgoingChannelConfig); 1804 if (pCapDesc->size_of_simultaneousCapabilities != iOutgoingChannelConfig->size()) 1805 { 1806 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1807 (0, "TSC_component::ClipCodecs - descriptor(%d),size_of_simultaneousCapabilities does not match num channels(%d)", i, iOutgoingChannelConfig->size())); 1808 } 1809 1810 for (unsigned j = 0; j < pCapDesc->size_of_simultaneousCapabilities; ++j) 1811 { 1812 bool txOnly = true; 1813 pAltCapSet = pCapDesc->simultaneousCapabilities + j; 1814 // Get the list of codecs in this ACS 1815 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> codecs_acs; 1816 uint16 num_media_types = GetCodecCapabilityInfo(pTcs, pAltCapSet, codecs_acs); 1817 if (num_media_types != 1) 1818 { 1819 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1820 (0, "TSC_component::ClipCodecs - ERROR: Badly formed AlternativeCapabilitySet j=%d, num media types=%d", j, num_media_types)); 1821 Deallocate(codecs_acs); 1822 continue; 1823 } 1824 1825 //Check for tx only capabilities 1826 for (unsigned k = 0; k < codecs_acs.size(); ++k) 1827 { 1828 if (codecs_acs[k]->dir != OUTGOING) 1829 { 1830 txOnly = false; 1831 break; 1832 } 1833 } 1834 if (txOnly) 1835 { 1836 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1837 (0, "TSC_component::ClipCodecs: tx only codecs")); 1838 Deallocate(codecs_acs); 1839 continue; 1840 } 1841 1842 PV2WayMediaType mediaType = GetMediaType(codecs_acs[0]->codec); 1843 if (mediaType != PV_AUDIO && mediaType != PV_VIDEO) 1844 { 1845 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1846 (0, "TSC_component::ClipCodecs: Media type in AlternativeCapabilitySet j=%d is neither audio/video, media type=%d", j, mediaType)); 1847 Deallocate(codecs_acs); 1848 continue; 1849 } 1850 // Get the list of our incoming codecs for this media type 1851 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator> in_codecs_for_media_type; 1852 iTSCcapability.GetSupportedCodecCapabilityInfo(INCOMING, mediaType, in_codecs_for_media_type); 1853 1854 // Do either side have symmetry constraints ? 1855 bool local_has_symmetry_constraint = iTSCcapability.HasSymmetryConstraint(in_codecs_for_media_type); 1856 bool remote_has_symmetry_constraint = iTSCcapability.HasSymmetryConstraint(codecs_acs); 1857 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1858 (0, "TSC_component::ClipCodecs mediaType=%d, local_has_symmetry_constraint=%d, remote_has_symmetry_constraint=%d", mediaType, local_has_symmetry_constraint, remote_has_symmetry_constraint)); 1859 CodecCapabilityInfo* selected_codec_info; 1860 if (local_has_symmetry_constraint || remote_has_symmetry_constraint) 1861 { 1862 selected_codec_info = iTSCcapability.SelectOutgoingCodec(&codecs_acs, 1863 &in_codecs_for_media_type); 1864 } 1865 else 1866 { 1867 selected_codec_info = iTSCcapability.SelectOutgoingCodec(&codecs_acs); 1868 } 1869 if (selected_codec_info) 1870 codec_list.push_back(selected_codec_info->Copy()); 1871 Deallocate(codecs_acs); 1872 Deallocate(in_codecs_for_media_type); 1873 } 1874 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1875 (0, "TSC_component::ClipCodecs codec_list size=%d, iOutCodecList size=%d", 1876 codec_list.size(), iOutCodecList.size())); 1877 if (codec_list.size() > iOutCodecList.size()) 1878 { 1879 /* found a match */ 1880 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1881 (0, "TSC_component::ClipCodecs Match found for descriptor(%d), size(%d)", 1882 i, pCapDesc->size_of_simultaneousCapabilities)); 1883 Deallocate(iOutCodecList); 1884 iOutCodecList = codec_list; 1885 for (unsigned num = 0; num < iOutCodecList.size(); num++) 1886 { 1887 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1888 (0, "TSC_component::ClipCodecs Selected codec(%d)=%d", 1889 num, codec_list[num]->codec)); 1890 } 1891 } 1892 else 1893 { 1894 Deallocate(codec_list); 1895 } 1896 } 1897 } 1898 1899 void TSC_component::Start() 1900 { 1901 if (iOutgoingChannelConfig == NULL || iIncomingChannelConfig == NULL) 1902 { 1903 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1904 (0, "TSC_component::Start here")); 1905 } 1906 1907 } 1908 1909 void TSC_component::StartDisconnect(bool terminate) 1910 { 1911 if (terminate) 1912 { 1913 StopData(); 1914 CloseChannels(); 1915 Deallocate(iOutCodecList); 1916 } 1917 } 1918 1919 void TSC_component::TimeoutOccurred(int32 timerID, int32 timeoutInfo) 1920 { 1921 OSCL_UNUSED_ARG(timeoutInfo); 1922 if (timerID == PV_TSC_WAITING_FOR_OBLC_TIMER_ID) 1923 { 1924 iWaitingForOblc = false; 1925 iWaitingForOblcCodec = PV_CODEC_TYPE_NONE; 1926 } 1927 } 1928 1929 /*****************************************************************************/ 1930 /* function name : Status08Event19 E_PtvId_Clc_Cls_Idc */ 1931 /* function outline : Status08/Event19 procedure */ 1932 /* function discription : Status08Event19( pReceiveInf ) */ 1933 /* input data : PS_ControlMsgHeader Receive InfHeader Pointer */ 1934 /* output data : uint32 Terminal Status */ 1935 /* draw time : '96.10.09 */ 1936 /*---------------------------------------------------------------------------*/ 1937 /* amendment career(x) : */ 1938 /* */ 1939 /* Copyright (C) 1996 NTT DoCoMo */ 1940 /*****************************************************************************/ 1941 uint32 TSC_component::Status08Event19(PS_ControlMsgHeader pReceiveInf) 1942 { 1943 TPVChannelId ClcLcn = CHANNEL_ID_UNKNOWN; 1944 uint32 Directional = 0; /* UNI=1, BI=2 */ 1945 1946 /* (RECEIVED AN INCOMING RequestChannelClose) */ 1947 /* Input parameters */ 1948 ClcLcn = (TPVChannelId)pReceiveInf->InfSupplement1; /* Channel requested to be closed */ 1949 Directional = pReceiveInf->InfSupplement2; /* Directionality */ 1950 if (Directional != 1 && Directional != 2) 1951 { 1952 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1953 (0, "TSC_component::Status08Event19 Invalid directionality")); 1954 iTSCclc.ClcRjtReq(ClcLcn); 1955 return (PhaseE_Comm); 1956 } 1957 1958 if (!HasOlc(OUTGOING, ClcLcn)) 1959 { 1960 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1961 (0, "TSC_component::Status08Event19 unable to lookup outgoing channel id(%d)", 1962 ClcLcn)); 1963 iTSCclc.ClcRjtReq(ClcLcn); 1964 return (PhaseE_Comm); 1965 } 1966 1967 /* Primitive Send */ 1968 iTSCclc.ClcClsRps(ClcLcn); /* Send RCCAck Message */ 1969 1970 ChannelReleased(OUTGOING, ClcLcn, PVMFSuccess); 1971 1972 /* Send the H.245 CloseLogicalChannel message */ 1973 if (Directional == 1) /* UniDirectional */ 1974 { 1975 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_CLOSE, ClcLcn, 0); 1976 RemoveOlc(dir, ClcLcn); 1977 } 1978 else if (Directional == 2) /* BiDirectional */ 1979 { 1980 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_CLOSE, ClcLcn, 0); 1981 RemoveOlc(dir, ClcLcn); 1982 } 1983 return(PhaseE_Comm); 1984 } 1985 1986 /*****************************************************************************/ 1987 /* function name : Status04Event15 E_PtvId_Blc_Etb_Cfm */ 1988 /* function outline : Status04/Event15 procedure */ 1989 /* function discription : Status04Event15( pReceiveInf ) */ 1990 /* input data : PS_ControlMsgHeader Receive InfHeader Pointer */ 1991 /* output data : uint32 Terminal Status */ 1992 /* draw time : '96.10.09 */ 1993 /*---------------------------------------------------------------------------*/ 1994 /* amendment career(x) : */ 1995 /* */ 1996 /* Copyright (C) 1996 NTT DoCoMo */ 1997 /*****************************************************************************/ 1998 uint32 TSC_component::BlcEtbCfm(PS_ControlMsgHeader pReceiveInf) 1999 { 2000 TPVChannelId incoming_lcn = pReceiveInf->InfSupplement2 + TSC_INCOMING_CHANNEL_MASK; 2001 OlcParam* olc_param = iOlcs.FindOlcGivenChannel(OUTGOING, pReceiveInf->InfSupplement1); 2002 if (olc_param == NULL) 2003 { 2004 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2005 (0, "TSC_component::BlcEtbCfm ERROR Unable to lookup channel")); 2006 return PhaseE_Comm; 2007 } 2008 olc_param->SetState(OLC_ESTABLISHED); 2009 2010 // Resume the channel if MT is also complete 2011 CheckOutgoingChannel(olc_param, PVMFSuccess); 2012 2013 if (olc_param->GetReverseParams()) 2014 { 2015 // Set the incoming logical channel number 2016 olc_param->GetReverseParams()->SetChannelId(incoming_lcn); 2017 // Open the incoming channel in the mux 2018 OpenPort(INCOMING, 2019 olc_param->GetReverseParams()->GetChannelId(), 2020 olc_param->GetReverseParams()); 2021 2022 uint8* fsi = NULL; 2023 uint32 fsi_len = ::GetFormatSpecificInfo(olc_param->GetReverseParams()->GetDataType(), fsi); 2024 iTSCObserver->IncomingChannel(incoming_lcn, 2025 GetCodecType(olc_param->GetReverseParams()->GetDataType()), 2026 fsi, fsi_len); 2027 } 2028 return PhaseE_Comm; 2029 } 2030 2031 2032 // ============================================================= 2033 // Status04Event50() E_PtvId_Blc_Etb_Cfm2 2034 // 2035 // This is "BLCSE ESTABLISH.confirm2" 2036 // It is called when SE receives an OLCConfirm (Bi-Dir). 2037 // ============================================================= 2038 uint32 TSC_component::BlcEtbCfm2(PS_ControlMsgHeader pReceiveInf) 2039 { 2040 OSCL_UNUSED_ARG(pReceiveInf); 2041 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2042 (0, "TSC_component::BlcEtbCfm2 forward(%d), reverse(%d))\n", 2043 pReceiveInf->InfSupplement1, pReceiveInf->InfSupplement2)); 2044 OlcParam* olc_param = iOlcs.FindOlcGivenChannel(INCOMING, 2045 pReceiveInf->InfSupplement1 + TSC_INCOMING_CHANNEL_MASK); 2046 if (olc_param == NULL) 2047 { 2048 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2049 (0, "TSC_component::BlcEtbCfm ERROR Unable to lookup channel")); 2050 return PhaseE_Comm; 2051 } 2052 olc_param->SetState(OLC_ESTABLISHED); 2053 // Resume the channel if MT is also complete 2054 CheckOutgoingChannel(olc_param, PVMFSuccess); 2055 return PhaseE_Comm; 2056 } 2057 2058 2059 /*****************************************************************************/ 2060 /* function name : Status08Event12 E_PtvId_Lc_Rls_Cfm */ 2061 /* function outline : Status08/Event12 procedure */ 2062 /* function discription : Status08Event12( pReceiveInf ) */ 2063 /* input data : PS_ControlMsgHeader Receive InfHeader Pointer */ 2064 /* output data : uint32 Terminal Status */ 2065 /* draw time : '00.4.13 */ 2066 /*---------------------------------------------------------------------------*/ 2067 uint32 TSC_component::LcRlsCfm(PS_ControlMsgHeader pReceiveInf) 2068 { 2069 TPVChannelId lcn = (TPVChannelId) pReceiveInf->InfSupplement1; 2070 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2071 (0, "TSC_component::LcRlsCfm - lcn(%d)\n", lcn)); 2072 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2073 (0, "TSC_component::LcRlsCfm - lcn(%d)\n", lcn)); 2074 ChannelReleased(OUTGOING, lcn, PVMFSuccess); 2075 return(PhaseE_Comm); 2076 } 2077 2078 /*****************************************************************************/ 2079 /* function name : Status08Event17 E_PtvId_Blc_Rls_Cfm */ 2080 /* function outline : Status08/Event17 procedure */ 2081 /* function discription : Status08Event17( pReceiveInf ) */ 2082 /* input data : PS_ControlMsgHeader Receive InfHeader Pointer */ 2083 /* output data : uint32 Terminal Status */ 2084 /* draw time : '00.4.13 */ 2085 /*---------------------------------------------------------------------------*/ 2086 /* RAN - Bi-Dir OLCAck */ 2087 uint32 TSC_component::BlcRlsCfm(PS_ControlMsgHeader pReceiveInf) 2088 { 2089 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2090 (0, "TSC_component::BlcRlsCfm - forward(%d), reverse(%d)", 2091 pReceiveInf->InfSupplement1, pReceiveInf->InfSupplement2)); 2092 ChannelReleased(OUTGOING, 2093 pReceiveInf->InfSupplement1, PVMFSuccess); 2094 return PhaseE_Comm; 2095 } 2096 2097 LogicalChannelInfo* TSC_component::GetLogicalChannelInfo(PVMFPortInterface& port) 2098 { 2099 return iTSCchannelcontrol.GetLogicalChannelInfo(port); 2100 } 2101 2102 void TSC_component::ReceivedFormatSpecificInfo(TPVChannelId channel_id, 2103 uint8* fsi, 2104 uint32 fsi_len) 2105 { 2106 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2107 (0, "TSC_component::ReceivedFormatSpecificInfo lcn=%d, len=%d", 2108 channel_id, fsi_len)); 2109 iTSCchannelcontrol.ReceivedFormatSpecificInfo(channel_id, fsi, fsi_len); 2110 } 2111 2112 bool TSC_component::IsEstablishedLogicalChannel(TPVDirection aDir, 2113 TPVChannelId aChannelId) 2114 { 2115 return iTSCchannelcontrol.IsEstablishedLogicalChannel(aDir, aChannelId); 2116 } 2117 2118 2119 void TSC_component::RemoveOlc(TPVDirection dir, TPVChannelId lcn) 2120 { 2121 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2122 (0, "TSC_component::RemoveOlc lcn(%d), dir(%d)", lcn, dir)); 2123 OlcKey key(dir, lcn); 2124 OlcList::iterator iter = iOlcs.find(key); 2125 if (iter == iOlcs.end()) 2126 return; 2127 OlcParam* param = (*iter).second; 2128 2129 if ((dir == OUTGOING || param->GetReverseParams()) && 2130 (param->GetMtNum() && (param->GetMtSn() >= 0)) && 2131 IsRemovable(lcn)) 2132 { 2133 iTSCmt.DeleteMuxEntry(param->GetMtNum()); 2134 } 2135 2136 iTSCmt.ReleaseMuxTables(); 2137 2138 if (iter != iOlcs.end()) 2139 { 2140 delete(*iter).second; 2141 iOlcs.erase(iter); 2142 } 2143 } 2144 2145 void TSC_component::ReleaseOlc(OlcParam* olc, uint16 cause) 2146 { 2147 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2148 (0, "TSC_channelcontrol::ReleaseOlc olc(%x), reason(%d))", olc, cause)); 2149 int release_type = (olc->GetDirection() == OUTGOING) ? RELEASE_CLOSE : RELEASE_REJECT; 2150 2151 if (olc->GetDirectionality() == EPVT_UNI_DIRECTIONAL) 2152 { 2153 iTSClc.LcRlsReq(release_type, olc->GetChannelId(), cause); 2154 } 2155 else 2156 { 2157 iTSCblc.BlcRlsReq(release_type, olc->GetChannelId(), cause); 2158 } 2159 } 2160 2161 /* This function just does the h.245 signalling for closing a logical channel - incoming/outgoing */ 2162 void TSC_component::SignalChannelClose(TPVDirection dir, 2163 TPVChannelId lcn, 2164 TPVDirectionality directionality) 2165 { 2166 /* Multiplex entries must have failed. Close the channel */ 2167 if (dir == OUTGOING) 2168 { 2169 if (directionality == EPVT_BI_DIRECTIONAL) 2170 { 2171 TPVDirection dir = iTSCblc.BlcRlsReq(RELEASE_CLOSE, lcn, 0); 2172 RemoveOlc(dir, lcn); 2173 } 2174 else 2175 { 2176 TPVDirection dir = iTSClc.LcRlsReq(RELEASE_CLOSE, lcn, 0); 2177 RemoveOlc(dir, lcn); 2178 } 2179 } 2180 else 2181 { 2182 iTSCclc.ClcClsReq(lcn); 2183 } 2184 } 2185 2186 void TSC_component::CheckOutgoingChannel(OlcParam* olc_param, PVMFStatus status) 2187 { 2188 TPVChannelId id = (olc_param->GetDirection() == OUTGOING) ? 2189 olc_param->GetChannelId() : olc_param->GetReverseParams()->GetChannelId(); 2190 PVCodecType_t codec_type = olc_param->GetDirection() == OUTGOING ? 2191 GetCodecType(olc_param->GetForwardParams()->GetDataType()) : 2192 GetCodecType(olc_param->GetReverseParams()->GetDataType()); 2193 OSCL_UNUSED_ARG(codec_type); 2194 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2195 (0, "TSC_channelcontrol::CheckOutgoingChannel channel id=%d, codec type=%d, status=%d", 2196 olc_param->GetChannelId(), codec_type, status)); 2197 if (status != PVMFSuccess) 2198 { 2199 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2200 (0, "TSC_component::CheckOutgoingChannel Channel open failed")); 2201 ChannelReleased(OUTGOING, olc_param->GetChannelId(), status); 2202 return; 2203 } 2204 if (olc_param->GetMtState() != MT_COMPLETE) 2205 { 2206 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2207 (0, "TSC_component::CheckOutgoingChannel channel id=%d Mux table send not complete", 2208 olc_param->GetChannelId())); 2209 return; 2210 } 2211 // OLC+MT is complete. Resume the channel. 2212 H223OutgoingChannelPtr outgoing_channel; 2213 status = iH223->GetOutgoingChannel(id, outgoing_channel); 2214 if (status != PVMFSuccess) 2215 { 2216 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2217 (0, "TSC_component::CheckOutgoingChannel ERROR Failed to lookup channel.")); 2218 return; 2219 } 2220 outgoing_channel->Resume(); 2221 // Request fast update from the engine 2222 iTSCObserver->RequestFrameUpdate(outgoing_channel); 2223 } 2224 2225 OsclAny TSC_component::ChannelReleased(TPVDirection dir, TPVChannelId lcn, PVMFStatus status) 2226 { 2227 OSCL_UNUSED_ARG(status); 2228 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2229 (0, "TSC_channelcontrol::ChannelReleased dir(%d), lcn(%d), status(%d)", 2230 dir, lcn, status)); 2231 OlcParam* olc_param = iOlcs.FindOlcGivenChannel(dir, lcn); 2232 if (olc_param == NULL) 2233 { 2234 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2235 (0, "TSC_channelcontrol::ChannelReleased Failed to lookup channel(%d), lcn(%d)\n", 2236 dir, lcn)); 2237 return; 2238 } 2239 2240 if (dir == OUTGOING || olc_param->GetState() == OLC_ESTABLISHED) 2241 { 2242 iTSCObserver->ChannelClosed(dir, 2243 lcn, 2244 ::GetCodecType(olc_param->GetForwardParams()->GetDataType()), 2245 status); 2246 } 2247 if (olc_param->GetDirectionality() == EPVT_BI_DIRECTIONAL) 2248 { 2249 TPVChannelId rvs_lcn = olc_param->GetReverseParams()->GetChannelId(); 2250 if (rvs_lcn && 2251 (rvs_lcn != CHANNEL_ID_UNKNOWN) && 2252 (dir == INCOMING || olc_param->GetState() == OLC_ESTABLISHED)) 2253 { 2254 iTSCObserver->ChannelClosed(REVERSE_DIR(dir), 2255 rvs_lcn, 2256 ::GetCodecType(olc_param->GetReverseParams()->GetDataType()), 2257 status); 2258 } 2259 } 2260 2261 RemoveOlc(dir, lcn); 2262 } 2263 2264 void TSC_component::CloseChannels() 2265 { 2266 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2267 (0, "TSC_channelcontrol::CloseChannels ")); 2268 OlcList::iterator it = iOlcs.begin(); 2269 while (it != iOlcs.end()) 2270 { 2271 OlcParam* olc = (*it++).second; 2272 ChannelReleased(olc->GetDirection(), olc->GetChannelId(), PVMFSuccess); 2273 it = iOlcs.begin(); 2274 } 2275 } 2276 2277 2278 OlcParam* TSC_component::OpenLogicalChannel(TPVDirection dir, 2279 TPVChannelId lcn, 2280 TPVChannelId lcnRvs, 2281 PS_DataType dt, 2282 PS_H223LogicalChannelParameters lcp, 2283 PS_DataType dtRvs, 2284 PS_H223LogicalChannelParameters lcpRvs) 2285 { 2286 2287 OSCL_UNUSED_ARG(lcpRvs); 2288 OSCL_UNUSED_ARG(dtRvs); 2289 OSCL_UNUSED_ARG(lcp); 2290 OSCL_UNUSED_ARG(dt); 2291 2292 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2293 (0, "TSC_channelcontrol::OpenLogicalChannel dir(%d), lcn(%d), dt(%x), lcp(%x), lcnRvs(%d), dtRvs(%x), lcpRvs(%x)\n", dir, lcn, dt, lcp, lcnRvs, dtRvs, lcpRvs)); 2294 // add to list of channels 2295 OlcParam* olc_param = iOlcs.FindOlcGivenChannel(dir, lcn); 2296 if (olc_param == NULL) 2297 { 2298 SignalChannelClose(dir, lcn, lcnRvs == CHANNEL_ID_UNKNOWN ? EPVT_UNI_DIRECTIONAL : EPVT_BI_DIRECTIONAL); 2299 return NULL; 2300 } 2301 2302 /* Is this a replacement channel outgoing channel ? */ 2303 if (dir == OUTGOING && olc_param->GetReplacementFor() != CHANNEL_ID_UNKNOWN) 2304 { 2305 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2306 (0, "TSC_channelcontrol::OpenLogicalChannel Replacement for outgoing channel id=%d", 2307 olc_param->GetReplacementFor())); 2308 ChannelReleased(OUTGOING, olc_param->GetReplacementFor(), PV2WayErrReplaced); 2309 olc_param->SetReplacementFor(0); 2310 } 2311 2312 if (olc_param->GetReverseParams()) 2313 olc_param->GetReverseParams()->SetChannelId(lcnRvs); 2314 2315 TPVDirection rvs_dir = REVERSE_DIR(dir); 2316 OpenPort(dir, lcn, olc_param->GetForwardParams()); 2317 if (olc_param->GetReverseParams() && 2318 olc_param->GetReverseParams()->GetChannelId() != CHANNEL_ID_UNKNOWN) 2319 { 2320 OpenPort(rvs_dir, olc_param->GetReverseParams()->GetChannelId(), 2321 olc_param->GetReverseParams()); 2322 } 2323 return olc_param; 2324 } 2325 void TSC_component::OpenPort(TPVDirection dir, TPVChannelId lcn, H223ChannelParam* param) 2326 { 2327 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2328 (0, "TSC_channelcontrol::OpenPort dir(%d), lcn(%d), param(%x)\n", 2329 dir, lcn, param)); 2330 PVCodecType_t codec_type = ::GetCodecType(param->GetDataType()); 2331 if (codec_type == PV_CODEC_TYPE_NONE) 2332 { 2333 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2334 (0, "TSC_channelcontrol::OpenPort codec_type==NONE", codec_type)); 2335 return; 2336 } 2337 iH223->OpenChannel(dir, lcn, param); 2338 } 2339 2340 2341 PS_DataType TSC_component::GetOutgoingDataType(PVCodecType_t codecType, 2342 uint32 bitrate) 2343 { 2344 uint8* csi = NULL; 2345 uint16 csi_len = 0; 2346 return iTSCcapability.GetOutgoingDataType(codecType, bitrate, csi_len, csi); 2347 } 2348 2349 OlcParam* TSC_component::OpenOutgoingChannel(PVCodecType_t out_codec_type, 2350 PS_AdaptationLayerType adaptation_layer, 2351 PS_DataType pDataTypeRvs, 2352 PS_H223LogicalChannelParameters pH223ParamsRvs) 2353 { 2354 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2355 (0, "TSC_component::OpenOutgoingChannel codec(%d), layer(%x)", 2356 out_codec_type, adaptation_layer)); 2357 OlcParam* ret = NULL; 2358 // allocate a channel id for this channel 2359 TPVChannelId channel_id = iOlcs.GetNextAvailLcn(); 2360 uint32 bitrate = GetOutgoingBitrate(out_codec_type); 2361 2362 /* Fill the data type for the outgoing codec */ 2363 PS_DataType pDataType = GetOutgoingDataType(out_codec_type, bitrate); 2364 2365 /* Fill the outgoing h223 logical channel parameters */ 2366 PS_H223LogicalChannelParameters pH223Params = 2367 iTSCcapability.GetOutgoingLcnParams(GetMediaType(out_codec_type), 2368 adaptation_layer); 2369 if (adaptation_layer->index == 5) 2370 { /* AL3 */ 2371 S_DataType nullDataType; 2372 if (pDataTypeRvs == NULL) 2373 { 2374 nullDataType.index = 1; 2375 pDataTypeRvs = &nullDataType; 2376 } 2377 if (pH223ParamsRvs == NULL) 2378 { 2379 pH223ParamsRvs = pH223Params; 2380 } 2381 PVCodecType_t in_codec_type = GetCodecType(pDataTypeRvs); 2382 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2383 (0, "TSC_component::OpenOutgoingChannel reverse codec(%d)", in_codec_type)); 2384 if (in_codec_type != out_codec_type) 2385 { 2386 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2387 (0, "TSC_component::OpenOutgoingChannel in codec type != out codec type")); 2388 } 2389 if (!CodecRequiresFsi(out_codec_type)) 2390 { 2391 iTSCblc.BlcEtbReq(channel_id, pDataType, pH223Params, 2392 pDataTypeRvs, pH223ParamsRvs); 2393 } 2394 ret = iOlcs.AppendOlc(OUTGOING, channel_id, pDataType, pH223Params, 2395 CHANNEL_ID_UNKNOWN, pDataTypeRvs, 2396 pH223ParamsRvs); 2397 } 2398 else 2399 { 2400 if (!CodecRequiresFsi(out_codec_type)) 2401 { 2402 iTSClc.LcEtbReq(channel_id, pDataType, pH223Params); 2403 } 2404 2405 ret = iOlcs.AppendOlc(OUTGOING, channel_id, pDataType, pH223Params); 2406 } 2407 2408 // Open the channel in the mux 2409 OpenLogicalChannel(OUTGOING, ret->GetChannelId()); 2410 // Pause the channel untill OlcAck+MtAck is received 2411 H223OutgoingChannelPtr outgoing_channel; 2412 iH223->GetOutgoingChannel(ret->GetChannelId(), outgoing_channel); 2413 if (Pausable()) 2414 { 2415 outgoing_channel->Pause(); 2416 } 2417 // Notify outgoing channel 2418 iTSCObserver->OutgoingChannelEstablished(ret->GetChannelId(), out_codec_type, 2419 NULL, 0); /* FSI will be generated by video source/encoder */ 2420 2421 Delete_DataType(pDataType); 2422 OSCL_DEFAULT_FREE(pDataType); 2423 Delete_H223LogicalChannelParameters(pH223Params); 2424 OSCL_DEFAULT_FREE(pH223Params); 2425 return ret; 2426 } 2427 2428 2429 bool TSC_component::queryInterface(const PVUuid& uuid, PVInterface*& iface) 2430 { 2431 // Only returns the component interface 2432 if (uuid == PVUuidH324ComponentInterface) 2433 { 2434 PVMFComponentInterface* myInterface = OSCL_STATIC_CAST(PVMFComponentInterface*, this); 2435 iface = OSCL_STATIC_CAST(PVInterface*, myInterface); 2436 } 2437 else 2438 { 2439 return false; 2440 } 2441 2442 return true; 2443 } 2444 2445 #ifdef MEM_TRACK 2446 void TSC_component::MemStats() 2447 { 2448 #if !(OSCL_BYPASS_MEMMGT) 2449 2450 OsclAuditCB auditCB; 2451 OsclMemInit(auditCB); 2452 if (auditCB.pAudit) 2453 { 2454 MM_Stats_t* stats = auditCB.pAudit->MM_GetStats(""); 2455 if (stats) 2456 { 2457 printf("\n###################Memory Stats Start#################\n"); 2458 printf(" numBytes %d\n", stats->numBytes); 2459 printf(" peakNumBytes %d\n", stats->peakNumBytes); 2460 printf(" numAllocs %d\n", stats->numAllocs); 2461 printf(" peakNumAllocs %d\n", stats->peakNumAllocs); 2462 printf(" numAllocFails %d\n", stats->numAllocFails); 2463 printf(" totalNumAllocs %d\n", stats->totalNumAllocs); 2464 printf(" totalNumBytes %d\n", stats->totalNumBytes); 2465 printf("\n###################Memory Stats End###################\n"); 2466 } 2467 2468 } 2469 #endif 2470 } 2471 #endif 2472 2473