rtp/rtpstack/src/rtpstppacket.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 /*
       
     2 * Copyright (c) 2002-2003 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDES
       
    22 
       
    23 #include <e32base.h>
       
    24 #include <e32std.h>
       
    25 
       
    26 #include "rtpstppacket.h"
       
    27 
       
    28 //
       
    29 // RTPLite header
       
    30 //
       
    31 // ****************************************
       
    32 // Extract from "PoC Core Network RTP RP01" 
       
    33 // ****************************************
       
    34 //                       1                   2                   3
       
    35 //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
    36 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    37 //   |F M R C S|  PT | Sequence nbr  |      Checksum (optional)      |
       
    38 //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    39 //
       
    40 //  Full header indication (F)  1 bit
       
    41 //                              If this bit is set to zero then header format
       
    42 //                              is reduced (otherwise full)
       
    43 //
       
    44 //  Marker (M)                  1 bit
       
    45 //                              Indication of the start of speech item (value 1).
       
    46 //                              It is set on the Nth first RTP packets including 
       
    47 //                              speech frames within the RTP payload. N is expected
       
    48 //                              to have a constant value in the order of 3 to 5. 
       
    49 //                              Note: M-bit is zero for all embedded control packets.
       
    50 //
       
    51 //  Reserved bit (R)            1 bit
       
    52 //                              This bit is reserved for future use. Default value is 1. 
       
    53 //
       
    54 //  Checksum indication (C)     1 bit
       
    55 //                              C-bit is an indication if header includes at the end an
       
    56 //                              optional checksum field. Value 1 indicates that checksum
       
    57 //                              field exist on the header.
       
    58 //
       
    59 //  Speech Item toggle indication (S)   1 bit
       
    60 //                              S-bit is used as an indication (toggled value) that speech
       
    61 //                              item has been changed (toggled between two speech items 
       
    62 //                              from same source; toggled between two speech items from 
       
    63 //                              different users; toggled between two speech items from 
       
    64 //                              different groups 1-to-1 call). This bit is on the same
       
    65 //                              position for the respective leader, speech and trailing
       
    66 //                              packets.
       
    67 //
       
    68 //  Payload Type (PT)           3 bits
       
    69 //                              PT-field indicates what kind of information
       
    70 //                              is carried on the paylaod area. Only two codes
       
    71 //                              (000 and 001) are reserved at the first phase, 
       
    72 //                              other values are reserved for future use.000 is
       
    73 //                              used to indicate that embedded control signal
       
    74 //                              information is in payload area and 001 indicates
       
    75 //                              that payload contains speech packets coded with
       
    76 //                              IETF AMR speech coding 8. In case of embedded 
       
    77 //                              control signal coding then the first byte on the payload
       
    78 //                              area has special coding rules, which are defined on section 5.3.4.
       
    79 //                              Note: GSM HR (HalfRate) will be used for 1st integration testing 
       
    80 //                              and related PT is 010.
       
    81 //                              Note: Standard RTP header uses 7 bits for the same indication.
       
    82 //
       
    83 // Sequence Nbr (SN)            8 bits
       
    84 //                              The sequence nbr increments by one for each
       
    85 //                              RTP data packet sent, and may be used by the
       
    86 //                              receiver to detect packet loss and restore
       
    87 //                              packet sequence. The initial value (when S 
       
    88 //                              bit is toggled) of the sequence number is zero. 
       
    89 //                              Note one exception: during talkspurt 
       
    90 //                              (for 1-to-1 call or group call) if one/few 
       
    91 //                              RTP packets are not sent (on N*20ms interval)
       
    92 //                              due to DTX usage (silence periods not sent) 
       
    93 //                              the sequency number at the originator side 
       
    94 //                              is anyhow incremented by one with the N*20ms 
       
    95 //                              frequency. The value for N is 3 by default. 
       
    96 //                              Very probably RTP packets are always sent in
       
    97 //                              GPRS terminals during talkspurt to avoid TBF
       
    98 //                              drop. RTP packet payload contains during 
       
    99 //                              silence periods three NO_DATA -indication
       
   100 //                              bytes to AMR decoder. In the future extented
       
   101 //                              TFB timer feature may change this behaviour, 
       
   102 //                              i.e. the sending of NO_DATA -indication bytes
       
   103 //                              might be dropped (over GPRS).Within standard
       
   104 //                              version of RTP header the length of SN is 16
       
   105 //                              bits , but within PoC application it is enough
       
   106 //                              to have 8 bits; it provides 7.62s (127*3*20ms)
       
   107 //                              jitter buffering without any special number wrap
       
   108 //                              control tricks (shown values are valid with N=3). 
       
   109 //                              Note: On the uplink direction on each speech item,
       
   110 //                              the Sequency Nbr is zero for all leading packets
       
   111 //                              (the first leading packet is replicated few times,
       
   112 //                              but the replicated messages are identical 
       
   113 //                              (even concerning the SN field)) and the first RTP
       
   114 //                              packet containing speech has SN value one.
       
   115 //                              Note: for all embedded control signals the SN
       
   116 //                              is set to zero.
       
   117 //
       
   118 //  CheckSum (CS)               16 bits (optional)
       
   119 //                              Checksum field is optional and the existence
       
   120 //                              of this field is indicated on the first octet
       
   121 //                              by C-bit.  Checksum will be needed with RP01
       
   122 //                              interface if RLC/LLC/UDP checksums are not
       
   123 //                              available/used. UDP checksum is optional 
       
   124 //                              with IPv4. Further more by using RTP level
       
   125 //                              CRC in combination of UDP-lite it would be 
       
   126 //                              possible to implement more efficient unequal
       
   127 //                              error protection on AMR bits than UDP-lite 
       
   128 //                              alone would offer.If checksum error is detected
       
   129 //                              then whole RTP packet is discarded.
       
   130 //                              Note: Checksum information is not available 
       
   131 //                              within standard RTP header.
       
   132 //                              Note: Taking the other aspects (header compression
       
   133 //                              with Degermark) into account it currently means 
       
   134 //                              that if checksum is included on RTPLite header
       
   135 //                              the whole packet does fit to 8 kbit/s channel
       
   136 //                              on the AIR interface only with AMR 4.75 coding.
       
   137 
       
   138 // ================= MEMBER FUNCTIONS =======================
       
   139 
       
   140 // ---------------------------------------------------------------------------
       
   141 // C++ default constructor can NOT contain any code, that
       
   142 // might leave.
       
   143 // ---------------------------------------------------------------------------
       
   144 // 
       
   145 CRtpStpPacket::CRtpStpPacket() :
       
   146     iSize( 0 ),
       
   147     iData( 0 ),
       
   148     iDataPtr( 0 ),
       
   149     iSessionId( 0 )
       
   150     {
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // Symbian 2nd phase constructor can leave.
       
   155 // ---------------------------------------------------------------------------
       
   156 //
       
   157 void CRtpStpPacket::ConstructL( TUint aPacketSize, TRtpId aSessionId )
       
   158     {
       
   159     iBuf = HBufC8::NewL( aPacketSize );
       
   160     iData = ( TUint8* ) iBuf->Des().Ptr();
       
   161     iSize = 0;
       
   162     iDataPtr = iData;
       
   163     iSessionId = aSessionId;
       
   164     }
       
   165 
       
   166 // ---------------------------------------------------------------------------
       
   167 // Destructor
       
   168 // ---------------------------------------------------------------------------
       
   169 // 
       
   170 CRtpStpPacket::~CRtpStpPacket()
       
   171     {
       
   172     delete iBuf;
       
   173     }
       
   174 
       
   175 // ---------------------------------------------------------------------------
       
   176 // CRtpStpPacket::Close()
       
   177 // works as destructor
       
   178 // ---------------------------------------------------------------------------
       
   179 //
       
   180 void CRtpStpPacket::Close()
       
   181     {
       
   182     delete this;
       
   183     }
       
   184 
       
   185 // ---------------------------------------------------------------------------
       
   186 // CRtpStpPacket::RtpPacketReset()
       
   187 // 
       
   188 // ---------------------------------------------------------------------------
       
   189 //
       
   190 void CRtpStpPacket::RtpPacketReset()
       
   191     {
       
   192     iSize = 0;
       
   193     iDataPtr = iData;
       
   194     }
       
   195 
       
   196 // ---------------------------------------------------------------------------
       
   197 // CRtpStpPacket::RtpPacketResetPtr()
       
   198 // 
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 void CRtpStpPacket::RtpPacketResetPtr()
       
   202     {
       
   203     iDataPtr = iData;
       
   204     }
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // TInt CRtpStpPacket::RtpPacketBuild()
       
   208 // 
       
   209 // ---------------------------------------------------------------------------
       
   210 //
       
   211 TInt CRtpStpPacket::RtpPacketBuild( const TRtpSendHeader& aHeader, const TDesC8& aPayloadData )
       
   212     {
       
   213     TUint8* dataP;
       
   214 
       
   215     dataP = iData;
       
   216 
       
   217     // build the packet content
       
   218     Mem::FillZ( dataP, 4 );
       
   219 
       
   220     // Full header indication (F)
       
   221     dataP[0] |= ( 0 << 7 );
       
   222 
       
   223     // Marker (M) 
       
   224     dataP[0] |= static_cast<TUint8>( aHeader.iMarker << 6 );
       
   225 
       
   226     // Padding bit (P) = 1
       
   227     dataP[0] |= static_cast<TUint8>( aHeader.iPadding << 5 );
       
   228 
       
   229     // Checksum indecation (C)  if checkSumInd == 1, need checksum in the header
       
   230     dataP[0] |= static_cast<TUint8>( aHeader.iChecksumInd << 4 );
       
   231 
       
   232     // Speech Item toggle indication (S)
       
   233     dataP[0] |= static_cast<TUint8>( aHeader.iSpeechItemToggle << 3 );
       
   234 
       
   235     // payload type
       
   236     dataP[0] |= ( aHeader.iPayloadType & 0x07 );
       
   237 
       
   238     // sequence number
       
   239     dataP[1] = aHeader.iSeqNum;
       
   240     dataP += 2;
       
   241 
       
   242     // Optinal checksum
       
   243     if ( aHeader.iChecksumInd == 1 )
       
   244         {
       
   245         write16( dataP, aHeader.iChecksum );
       
   246         dataP += 2;
       
   247         }
       
   248 
       
   249     // copy payload data 
       
   250     Mem::Copy( dataP, aPayloadData.Ptr(), aPayloadData.Length() );
       
   251     iSize = aPayloadData.Length() + ( dataP - iData );
       
   252 
       
   253     return 0;
       
   254     }
       
   255 
       
   256 // ---------------------------------------------------------------------------
       
   257 // CRtpStpPacket::RtpPacketProcess()
       
   258 // Return Value:
       
   259 //    KErrNone if STP packet has been processed OK, or
       
   260 //    KErrCorrupt if packet is invalid or some other error has occured
       
   261 // ---------------------------------------------------------------------------
       
   262 //
       
   263 TInt CRtpStpPacket::RtpPacketProcess( TUint8* aBuf, TInt* aLength )
       
   264     {
       
   265     TRtpRecvHeader header;
       
   266     TUint8* dataP;
       
   267 
       
   268     dataP = iData;
       
   269 
       
   270     // Full header indication (F) 
       
   271     if ( ( dataP[0] & 0x80 ) != 0 )
       
   272         return KErrCorrupt;
       
   273 
       
   274     // Marker (M)
       
   275     header.iMarker = ( TUint8 ) ( ( dataP[0] & 0x40 ) >> 6 );
       
   276 
       
   277     // Padding bit (P)
       
   278     header.iPadding = ( TUint8 ) ( ( dataP[0] & 0x20 ) >> 5 );
       
   279 
       
   280     // Checksum indication (C) 
       
   281     header.iChecksumInd = ( TUint8 ) ( ( dataP[0] & 0x10 ) >> 4 );
       
   282 
       
   283     // Speech item toggle indication (S) 
       
   284     header.iSpeechItemToggle = ( TUint8 ) ( ( dataP[0] & 0x08 ) >> 3 );
       
   285 
       
   286     // Payload type (PT)
       
   287     header.iPayloadType = ( TUint8 ) ( ( dataP[0] & 0x07 ) );
       
   288 
       
   289     // Sequence number
       
   290     header.iSeqNum = ( TUint8 ) ( dataP[1] );
       
   291     dataP += 2;
       
   292 
       
   293     // Optinal checksum
       
   294     if ( header.iChecksumInd == 1 )
       
   295         {
       
   296         header.iChecksum = ( TUint16 ) read16( dataP ); 
       
   297         dataP += 2;
       
   298         }
       
   299 
       
   300     *aLength = iSize - ( dataP - iData );
       
   301     aBuf = ( TUint8 * ) dataP;
       
   302 
       
   303     TPtrC8 buf( aBuf, *aLength );
       
   304 
       
   305     if ( iObserver )
       
   306         iObserver->RtpPacketReceived( iSessionId /* streamId */, header, buf );
       
   307 
       
   308     return KErrNone;
       
   309     }
       
   310 
       
   311 // ---------------------------------------------------------------------------
       
   312 // Write a 16-bit value as 2 consecutive bytes in MSB order
       
   313 // Memory (at least 2 bytes) must have been allocated to pointer
       
   314 // before the function is called.
       
   315 // ---------------------------------------------------------------------------
       
   316 //
       
   317 void CRtpStpPacket::write16( TUint8* const aPointer, TUint32 aValue )
       
   318     {
       
   319     // check value range (16 bits)
       
   320     aPointer[0] = ( TUint8 ) ( ( aValue & 0xFF00 ) >> 8 );
       
   321     aPointer[1] = ( TUint8 ) ( aValue & 0x00FF );
       
   322     }
       
   323 
       
   324 // ---------------------------------------------------------------------------
       
   325 // Read a 16-bit value given as 2 consecutive bytes in MSB order
       
   326 // Memory (at least 2 bytes) must have been allocated to pointer
       
   327 // before the function is called.
       
   328 // ---------------------------------------------------------------------------
       
   329 //
       
   330 TUint32 CRtpStpPacket::read16( const TUint8* const aPointer )
       
   331     {
       
   332     return( aPointer[1] + ( ( TUint32 ) aPointer[0] << 8 ) );
       
   333     }
       
   334 
       
   335 
       
   336 #if !defined ( EKA2 ) && !defined ( RTP_UNIT_TEST )
       
   337 // The E32Dll() entry point function
       
   338 GLDEF_C TInt E32Dll( TDllReason /*aReason*/ )
       
   339     {
       
   340     return( KErrNone );
       
   341     }
       
   342 #endif // EKA2
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // Function to construct a CRtpPacketExt object. Note that this function
       
   346 // is exported at ordinal 1 and is not a member of any class.
       
   347 // ---------------------------------------------------------------------------
       
   348 //
       
   349 EXPORT_C MRtpPacketExt* NewL()
       
   350     {
       
   351     return new ( ELeave ) CRtpStpPacket;
       
   352     }
       
   353 
       
   354 
       
   355 // End of File