Home | History | Annotate | Download | only in src
      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