1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #include "adaptationlayer.h" 19 #define SREJ 0 20 #define DRTX 255 21 #define PV2WAY_H223_AL2_SN_WRAPAROUND 256 22 #define PV2WAY_H223_AL2_CRC_SIZE 1 23 #define PV2WAY_H223_AL3_CRC_SIZE 2 24 #define PV2WAY_MAX_PACKET_MEM_FRAG 32 25 #define PV2WAY_H223_AL2_MAX_HDR_TRLR_FRAG_SIZE 4 26 #define PV2WAY_H223_AL3_SNPOS1_BITLEN 7 27 #define PV2WAY_H223_AL3_SNPOS1_VRMAX 0x7F 28 #define PV2WAY_H223_AL3_SNPOS2_VRMAX 0x7FFF 29 #define PV2WAY_H223_AL3_SNPOS2_PT_LEN 1 30 31 32 void AdaptationLayer1::Construct() 33 { 34 iLogger = PVLogger::GetLoggerObject("3g324m.h223.AdaptationLayer1"); 35 } 36 37 void AdaptationLayer1::ParsePacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt, IncomingALPduInfo& info) 38 { 39 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer1::ParsePacket, pdu_size(%d)", pkt->getFilledSize())); 40 oscl_memset(&info, 0, sizeof(IncomingALPduInfo)); 41 info.sdu_size = (int16)pkt->getFilledSize(); 42 43 } 44 45 46 PVMFStatus AdaptationLayer1::CompletePacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt) 47 { 48 OSCL_UNUSED_ARG(pkt); 49 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer1::CompletePacket packet size(%d)", pkt->getFilledSize())); 50 return PVMFSuccess; 51 } 52 53 void AdaptationLayer2::Construct() 54 { 55 iLogger = PVLogger::GetLoggerObject("3g324m.h223.AdaptationLayer2"); 56 // Do not Leave on allocation failure 57 iMemFragmentAlloc.SetLeaveOnAllocFailure(false); 58 iMemFragmentAlloc.size((uint16)iMaxNumSdus, PV2WAY_H223_AL2_MAX_HDR_TRLR_FRAG_SIZE); 59 } 60 61 void AdaptationLayer2::SetSeqnum(bool on_off) 62 { 63 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer2::SetSeqnum(%d)", on_off)); 64 if (on_off) 65 { 66 iSNPos = 1; 67 iHdrSz = 1; 68 } 69 else 70 { 71 iSNPos = 0; 72 iHdrSz = 0; 73 } 74 } 75 76 PVMFStatus AdaptationLayer2::StartPacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt) 77 { 78 if (iSNPos) 79 { 80 OsclRefCounterMemFrag hdr_frag = iMemFragmentAlloc.get(); 81 if (hdr_frag.getMemFragPtr() == NULL) 82 { 83 return PVMFErrNoMemory; 84 } 85 hdr_frag.getMemFrag().len = 1; 86 pkt->appendMediaFragment(hdr_frag); 87 } 88 return PVMFSuccess; 89 } 90 91 92 93 PVMFStatus AdaptationLayer2::CompletePacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt) 94 { 95 int Size = pkt->getFilledSize(); 96 uint8 Crc; 97 uint8* pos = NULL; 98 OsclRefCounterMemFrag hdr_frag; 99 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer2::CompletePacket packet, size(%d)", Size)); 100 101 OsclRefCounterMemFrag trlr_frag = iMemFragmentAlloc.get(); 102 if (trlr_frag.getMemFragPtr() == NULL) 103 { 104 return PVMFErrNoMemory; 105 } 106 trlr_frag.getMemFrag().len = 1; 107 108 if (iSNPos) 109 { 110 pkt->getMediaFragment(0, hdr_frag); 111 Size += iSNPos; 112 pos = (uint8*)hdr_frag.getMemFragPtr(); 113 *pos = (uint8)(iSeqNum); 114 if (iSeqNum != 0xff) 115 iSeqNum ++; 116 else 117 iSeqNum = 0; 118 } 119 120 Crc = crc.Crc8Check(pkt); 121 pkt->appendMediaFragment(trlr_frag); 122 pos = (uint8*)trlr_frag.getMemFragPtr(); 123 124 *pos = Crc; 125 Size ++; 126 127 return PVMFSuccess; 128 } 129 130 #define WINSIZE 10 131 132 void AdaptationLayer2::ParsePacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt, IncomingALPduInfo& info) 133 { 134 OsclRefCounterMemFrag frag; 135 uint8 Crc = 0; 136 info.crc_error = false; // No CRC error. 137 info.seq_num_error = 0; // No sequence number error. 138 uint8 SeqNum = 0; 139 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer2::ParsePacket pdu size(%d)", pkt->getFilledSize())); 140 info.sdu_size = (uint16)(pkt->getFilledSize() - iSNPos - PV2WAY_H223_AL2_CRC_SIZE); 141 if (info.sdu_size <= 0) 142 { 143 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "AdaptationLayer2::ParsePacket sdu size(%d) < 0", info.sdu_size)); 144 return; 145 } 146 OsclRefCounterMemFrag last_frag; 147 pkt->getMediaFragment(pkt->getNumFragments() - 1, last_frag); 148 Crc = *((uint8*)last_frag.getMemFragPtr() + last_frag.getMemFragSize() - 1); 149 pkt->setMediaFragFilledLen(pkt->getNumFragments() - 1, last_frag.getMemFrag().len - PV2WAY_H223_AL2_CRC_SIZE); 150 151 OsclRefCounterMemFrag first_frag; 152 pkt->getMediaFragment(0, first_frag); 153 154 uint16 CrcCheck = crc.Crc8Check(pkt, false); 155 if (Crc != CrcCheck) 156 { 157 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "AdaptationLayer2::ParsePacket CRC error sn(%d)", iSeqNum)); 158 info.crc_error = true; 159 //Update expected sequence number. 160 iSeqNum = (iSeqNum + 1) % PV2WAY_H223_AL2_SN_WRAPAROUND; 161 } 162 else 163 { 164 if (iSNPos == 1) 165 { 166 SeqNum = *((uint8*)first_frag.getMemFragPtr()); 167 first_frag.getMemFrag().len -= iSNPos; 168 first_frag.getMemFrag().ptr = (uint8*)first_frag.getMemFrag().ptr + iSNPos; 169 170 //If sequence number is good. 171 if (iSeqNum == SeqNum) 172 { 173 iSeqNum = (iSeqNum + 1) % PV2WAY_H223_AL2_SN_WRAPAROUND; 174 } 175 //Else sequence number is not good. 176 else 177 { 178 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "AdaptationLayer2::ParsePacket Sequence number error expected(%d), received(%d)", iSeqNum, SeqNum)); 179 180 //Check the difference between expected seq number and actual seq number. 181 182 //Check if sequence number wrapped. 183 if (iSeqNum > SeqNum) 184 { 185 info.seq_num_error = (PV2WAY_H223_AL2_SN_WRAPAROUND - iSeqNum) + SeqNum; 186 } 187 //Else no wrap. 188 { 189 info.seq_num_error = SeqNum - iSeqNum; 190 } 191 192 //Update expected seq number based on actual seq number received. 193 iSeqNum = (SeqNum + 1) % PV2WAY_H223_AL2_SN_WRAPAROUND; 194 } 195 } 196 } 197 if (iSNPos) 198 { 199 OsclRefCounterMemFrag frags[PV2WAY_MAX_PACKET_MEM_FRAG]; 200 unsigned int num_frags = pkt->getNumFragments(); 201 if (num_frags <= PV2WAY_MAX_PACKET_MEM_FRAG) 202 { 203 unsigned int fragnum; 204 frags[0] = first_frag; 205 for (fragnum = 1; fragnum < num_frags; fragnum++) 206 { 207 pkt->getMediaFragment(fragnum, frags[fragnum]); 208 } 209 pkt->clearMediaFragments(); 210 for (fragnum = 0; fragnum < num_frags; fragnum++) 211 { 212 pkt->appendMediaFragment(frags[fragnum]); 213 } 214 } 215 else 216 { 217 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer2::ParsePacket pkt->getNumFragments() is greater then PV2WAY_MAX_PACKET_MEM_FRAG")); 218 } 219 } 220 } 221 222 void AdaptationLayer3::Construct() 223 { 224 iLogger = PVLogger::GetLoggerObject("3g324m.h223.AdaptationLayer3"); 225 // Do not Leave on allocation failure 226 iMemFragmentAlloc.SetLeaveOnAllocFailure(false); 227 iMemFragmentAlloc.size((uint16)(iMaxNumSdus*2), 4); 228 } 229 230 void AdaptationLayer3::SetSeqnumSz(uint16 sz) 231 { 232 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer3::SetSeqnumSz(%d)", sz)); 233 iSNPos = sz; 234 iHdrSz = sz; 235 } 236 237 PVMFStatus AdaptationLayer3::StartPacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt) 238 { 239 if (iSNPos) 240 { 241 OsclRefCounterMemFrag hdr_frag = iMemFragmentAlloc.get(); 242 if (hdr_frag.getMemFragPtr() == NULL) 243 { 244 return PVMFErrNoMemory; 245 } 246 hdr_frag.getMemFrag().len = iSNPos; 247 pkt->appendMediaFragment(hdr_frag); 248 } 249 return PVMFSuccess; 250 } 251 252 PVMFStatus AdaptationLayer3::CompletePacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt) 253 { 254 int Size = pkt->getFilledSize(); 255 unsigned Crc = 0, usTmp = 0; 256 uint8* pos = NULL; 257 OsclRefCounterMemFrag hdr_frag; 258 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer3::CompletePacket(%d)", pkt->getFilledSize())); 259 OsclRefCounterMemFrag trlr_frag = iMemFragmentAlloc.get(); 260 if (trlr_frag.getMemFragPtr() == NULL) 261 { 262 return PVMFErrNoMemory; 263 } 264 265 trlr_frag.getMemFrag().len = 2; 266 Size += iSNPos; 267 268 switch (iSNPos) 269 { 270 case 0: 271 break; 272 case 1: 273 usTmp = (uint16)iSeqNum; 274 pkt->getMediaFragment(0, hdr_frag); 275 pos = (uint8*)hdr_frag.getMemFragPtr(); 276 277 *pos = (uint8)((usTmp << 1) | 1); 278 if (usTmp != PV2WAY_H223_AL3_SNPOS1_VRMAX) 279 iSeqNum ++; 280 else 281 iSeqNum = 0; 282 break; /* SN( 7bit ) */ 283 case 2: 284 usTmp = iSeqNum; 285 pkt->getMediaFragment(0, hdr_frag); 286 pos = (uint8*)hdr_frag.getMemFragPtr(); 287 288 *pos = (uint8)((usTmp >> 7) | 1); 289 *(pos + 1) = (uint8)(usTmp & 0xff); 290 if (usTmp != PV2WAY_H223_AL3_SNPOS2_VRMAX) 291 iSeqNum ++; 292 else 293 iSeqNum = 0; 294 break; /* SN( 15bit )*/ 295 } 296 297 Crc = crc.Crc16Check(pkt); 298 pkt->appendMediaFragment(trlr_frag); 299 pos = (uint8*)trlr_frag.getMemFragPtr(); 300 301 *(pos) = (uint8)(Crc & 0xff); 302 *(pos + 1) = (uint8)(Crc >> 8); 303 Size += 2; 304 return PVMFSuccess; 305 } 306 307 #define WINSIZE 10 308 309 void AdaptationLayer3::ParsePacket(OsclSharedPtr<PVMFMediaDataImpl>& pkt, IncomingALPduInfo& info) 310 { 311 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "AdaptationLayer3::ParsePacket pdu_size(%d)", pkt->getFilledSize())); 312 OsclRefCounterMemFrag frag; 313 uint16 SeqNum = 0; 314 uint16 Crc = 0, VrMax = 0; 315 iPktNum++; 316 info.crc_error = false; 317 info.seq_num_error = 0; 318 info.sdu_size = (uint16)(pkt->getFilledSize() - iSNPos - PV2WAY_H223_AL3_CRC_SIZE); 319 if (info.sdu_size <= 0) 320 { 321 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "AdaptationLayer3::ParsePacket sdu size(%d) < 0", info.sdu_size)); 322 return; 323 } 324 325 OsclRefCounterMemFrag first_frag, last_frag; 326 pkt->getMediaFragment(0, first_frag); 327 pkt->getMediaFragment(pkt->getNumFragments() - 1, last_frag); 328 329 switch (iSNPos) 330 { 331 case 0: 332 // not used currently 333 break; 334 case 1: 335 SeqNum = (uint16)(((uint8*)first_frag.getMemFragPtr())[0] >> (sizeof(uint8))); 336 VrMax = PV2WAY_H223_AL3_SNPOS1_VRMAX; /* 0-127 */ 337 break; 338 case 2: 339 SeqNum = (uint16)((((uint8*)first_frag.getMemFragPtr())[0] >> 1) << 8 | ((uint8*)first_frag.getMemFragPtr())[1]); 340 VrMax = PV2WAY_H223_AL3_SNPOS2_VRMAX; /* 0-32767 */ 341 break; 342 } 343 344 if (last_frag.getMemFragSize() >= PV2WAY_H223_AL3_CRC_SIZE) 345 { 346 Crc = (uint16)(((*((uint8*)last_frag.getMemFragPtr() + last_frag.getMemFragSize() - 1)) << 8) | 347 (*((uint8*)last_frag.getMemFragPtr() + last_frag.getMemFragSize() - 2))); 348 pkt->setMediaFragFilledLen(pkt->getNumFragments() - 1, last_frag.getMemFrag().len - PV2WAY_H223_AL3_CRC_SIZE); 349 } 350 else // in the rare case that the last fragment contains only 1 byte of the CRC 351 { 352 OsclRefCounterMemFrag second_last_frag; 353 pkt->getMediaFragment(pkt->getNumFragments() - 2, second_last_frag); 354 Crc = (uint16)(((*((uint8*)last_frag.getMemFragPtr())) << 8) | 355 (*((uint8*)second_last_frag.getMemFragPtr() + second_last_frag.getMemFragSize() - 1))); 356 pkt->setMediaFragFilledLen(pkt->getNumFragments() - 1, last_frag.getMemFrag().len - 1); 357 pkt->setMediaFragFilledLen(pkt->getNumFragments() - 2, second_last_frag.getMemFrag().len - 1); 358 } 359 if (Crc != crc.Crc16Check(pkt, false)) 360 { 361 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "AdaptationLayer3::ParsePacket CRC error, sn(%d)", iSeqNum)); 362 363 info.crc_error = true; 364 365 //Update sequence number. 366 if (iSeqNum == VrMax) 367 { 368 iSeqNum = 0; 369 } 370 else 371 { 372 iSeqNum++; 373 } 374 } 375 else 376 { 377 //If sequence number is good. 378 if (iSeqNum == SeqNum) 379 { 380 if (iSeqNum == VrMax) 381 { 382 iSeqNum = 0; 383 } 384 else 385 { 386 iSeqNum++; 387 } 388 } 389 //Else sequence number is not good. 390 else 391 { /* missing or mis-delivered packets, send them anyway */ 392 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "AdaptationLayer3::ParsePacket Sequence number error - Expected(%d), Received(%d)", iSeqNum, SeqNum)); 393 //Check the difference between expected seq number and actual seq number. 394 395 //Check if sequence number wrapped. 396 if (iSeqNum > SeqNum) 397 { 398 info.seq_num_error = ((VrMax + 1) - iSeqNum) + SeqNum; 399 } 400 //Else no wrap. 401 { 402 info.seq_num_error = SeqNum - iSeqNum; 403 } 404 405 //Update 406 iSeqNum = (uint16)((SeqNum + 1) % (VrMax + 1)); 407 } 408 } 409 410 if (iSNPos) 411 { 412 pkt->getMediaFragment(0, first_frag);// do this in case first frag == last frag 413 first_frag.getMemFrag().len -= iSNPos; 414 first_frag.getMemFrag().ptr = (uint8*)first_frag.getMemFrag().ptr + iSNPos; 415 OsclRefCounterMemFrag frags[PV2WAY_MAX_PACKET_MEM_FRAG]; 416 unsigned int num_frags = pkt->getNumFragments(); 417 unsigned int fragnum; 418 frags[0] = first_frag; 419 for (fragnum = 1; fragnum < num_frags; fragnum++) 420 { 421 pkt->getMediaFragment(fragnum, frags[fragnum]); 422 } 423 pkt->clearMediaFragments(); 424 for (fragnum = 0; fragnum < num_frags; fragnum++) 425 { 426 pkt->appendMediaFragment(frags[fragnum]); 427 } 428 } 429 430 } 431