diff -r 000000000000 -r 307788aac0a8 rtp/rtpstack/src/rtpstppacket.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtp/rtpstack/src/rtpstppacket.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,355 @@ +/* +* Copyright (c) 2002-2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + + +// INCLUDES + +#include +#include + +#include "rtpstppacket.h" + +// +// RTPLite header +// +// **************************************** +// Extract from "PoC Core Network RTP RP01" +// **************************************** +// 1 2 3 +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |F M R C S| PT | Sequence nbr | Checksum (optional) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Full header indication (F) 1 bit +// If this bit is set to zero then header format +// is reduced (otherwise full) +// +// Marker (M) 1 bit +// Indication of the start of speech item (value 1). +// It is set on the Nth first RTP packets including +// speech frames within the RTP payload. N is expected +// to have a constant value in the order of 3 to 5. +// Note: M-bit is zero for all embedded control packets. +// +// Reserved bit (R) 1 bit +// This bit is reserved for future use. Default value is 1. +// +// Checksum indication (C) 1 bit +// C-bit is an indication if header includes at the end an +// optional checksum field. Value 1 indicates that checksum +// field exist on the header. +// +// Speech Item toggle indication (S) 1 bit +// S-bit is used as an indication (toggled value) that speech +// item has been changed (toggled between two speech items +// from same source; toggled between two speech items from +// different users; toggled between two speech items from +// different groups 1-to-1 call). This bit is on the same +// position for the respective leader, speech and trailing +// packets. +// +// Payload Type (PT) 3 bits +// PT-field indicates what kind of information +// is carried on the paylaod area. Only two codes +// (000 and 001) are reserved at the first phase, +// other values are reserved for future use.000 is +// used to indicate that embedded control signal +// information is in payload area and 001 indicates +// that payload contains speech packets coded with +// IETF AMR speech coding 8. In case of embedded +// control signal coding then the first byte on the payload +// area has special coding rules, which are defined on section 5.3.4. +// Note: GSM HR (HalfRate) will be used for 1st integration testing +// and related PT is 010. +// Note: Standard RTP header uses 7 bits for the same indication. +// +// Sequence Nbr (SN) 8 bits +// The sequence nbr increments by one for each +// RTP data packet sent, and may be used by the +// receiver to detect packet loss and restore +// packet sequence. The initial value (when S +// bit is toggled) of the sequence number is zero. +// Note one exception: during talkspurt +// (for 1-to-1 call or group call) if one/few +// RTP packets are not sent (on N*20ms interval) +// due to DTX usage (silence periods not sent) +// the sequency number at the originator side +// is anyhow incremented by one with the N*20ms +// frequency. The value for N is 3 by default. +// Very probably RTP packets are always sent in +// GPRS terminals during talkspurt to avoid TBF +// drop. RTP packet payload contains during +// silence periods three NO_DATA -indication +// bytes to AMR decoder. In the future extented +// TFB timer feature may change this behaviour, +// i.e. the sending of NO_DATA -indication bytes +// might be dropped (over GPRS).Within standard +// version of RTP header the length of SN is 16 +// bits , but within PoC application it is enough +// to have 8 bits; it provides 7.62s (127*3*20ms) +// jitter buffering without any special number wrap +// control tricks (shown values are valid with N=3). +// Note: On the uplink direction on each speech item, +// the Sequency Nbr is zero for all leading packets +// (the first leading packet is replicated few times, +// but the replicated messages are identical +// (even concerning the SN field)) and the first RTP +// packet containing speech has SN value one. +// Note: for all embedded control signals the SN +// is set to zero. +// +// CheckSum (CS) 16 bits (optional) +// Checksum field is optional and the existence +// of this field is indicated on the first octet +// by C-bit. Checksum will be needed with RP01 +// interface if RLC/LLC/UDP checksums are not +// available/used. UDP checksum is optional +// with IPv4. Further more by using RTP level +// CRC in combination of UDP-lite it would be +// possible to implement more efficient unequal +// error protection on AMR bits than UDP-lite +// alone would offer.If checksum error is detected +// then whole RTP packet is discarded. +// Note: Checksum information is not available +// within standard RTP header. +// Note: Taking the other aspects (header compression +// with Degermark) into account it currently means +// that if checksum is included on RTPLite header +// the whole packet does fit to 8 kbit/s channel +// on the AIR interface only with AMR 4.75 coding. + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------------------------- +// +CRtpStpPacket::CRtpStpPacket() : + iSize( 0 ), + iData( 0 ), + iDataPtr( 0 ), + iSessionId( 0 ) + { + } + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------------------------- +// +void CRtpStpPacket::ConstructL( TUint aPacketSize, TRtpId aSessionId ) + { + iBuf = HBufC8::NewL( aPacketSize ); + iData = ( TUint8* ) iBuf->Des().Ptr(); + iSize = 0; + iDataPtr = iData; + iSessionId = aSessionId; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CRtpStpPacket::~CRtpStpPacket() + { + delete iBuf; + } + +// --------------------------------------------------------------------------- +// CRtpStpPacket::Close() +// works as destructor +// --------------------------------------------------------------------------- +// +void CRtpStpPacket::Close() + { + delete this; + } + +// --------------------------------------------------------------------------- +// CRtpStpPacket::RtpPacketReset() +// +// --------------------------------------------------------------------------- +// +void CRtpStpPacket::RtpPacketReset() + { + iSize = 0; + iDataPtr = iData; + } + +// --------------------------------------------------------------------------- +// CRtpStpPacket::RtpPacketResetPtr() +// +// --------------------------------------------------------------------------- +// +void CRtpStpPacket::RtpPacketResetPtr() + { + iDataPtr = iData; + } + +// --------------------------------------------------------------------------- +// TInt CRtpStpPacket::RtpPacketBuild() +// +// --------------------------------------------------------------------------- +// +TInt CRtpStpPacket::RtpPacketBuild( const TRtpSendHeader& aHeader, const TDesC8& aPayloadData ) + { + TUint8* dataP; + + dataP = iData; + + // build the packet content + Mem::FillZ( dataP, 4 ); + + // Full header indication (F) + dataP[0] |= ( 0 << 7 ); + + // Marker (M) + dataP[0] |= static_cast( aHeader.iMarker << 6 ); + + // Padding bit (P) = 1 + dataP[0] |= static_cast( aHeader.iPadding << 5 ); + + // Checksum indecation (C) if checkSumInd == 1, need checksum in the header + dataP[0] |= static_cast( aHeader.iChecksumInd << 4 ); + + // Speech Item toggle indication (S) + dataP[0] |= static_cast( aHeader.iSpeechItemToggle << 3 ); + + // payload type + dataP[0] |= ( aHeader.iPayloadType & 0x07 ); + + // sequence number + dataP[1] = aHeader.iSeqNum; + dataP += 2; + + // Optinal checksum + if ( aHeader.iChecksumInd == 1 ) + { + write16( dataP, aHeader.iChecksum ); + dataP += 2; + } + + // copy payload data + Mem::Copy( dataP, aPayloadData.Ptr(), aPayloadData.Length() ); + iSize = aPayloadData.Length() + ( dataP - iData ); + + return 0; + } + +// --------------------------------------------------------------------------- +// CRtpStpPacket::RtpPacketProcess() +// Return Value: +// KErrNone if STP packet has been processed OK, or +// KErrCorrupt if packet is invalid or some other error has occured +// --------------------------------------------------------------------------- +// +TInt CRtpStpPacket::RtpPacketProcess( TUint8* aBuf, TInt* aLength ) + { + TRtpRecvHeader header; + TUint8* dataP; + + dataP = iData; + + // Full header indication (F) + if ( ( dataP[0] & 0x80 ) != 0 ) + return KErrCorrupt; + + // Marker (M) + header.iMarker = ( TUint8 ) ( ( dataP[0] & 0x40 ) >> 6 ); + + // Padding bit (P) + header.iPadding = ( TUint8 ) ( ( dataP[0] & 0x20 ) >> 5 ); + + // Checksum indication (C) + header.iChecksumInd = ( TUint8 ) ( ( dataP[0] & 0x10 ) >> 4 ); + + // Speech item toggle indication (S) + header.iSpeechItemToggle = ( TUint8 ) ( ( dataP[0] & 0x08 ) >> 3 ); + + // Payload type (PT) + header.iPayloadType = ( TUint8 ) ( ( dataP[0] & 0x07 ) ); + + // Sequence number + header.iSeqNum = ( TUint8 ) ( dataP[1] ); + dataP += 2; + + // Optinal checksum + if ( header.iChecksumInd == 1 ) + { + header.iChecksum = ( TUint16 ) read16( dataP ); + dataP += 2; + } + + *aLength = iSize - ( dataP - iData ); + aBuf = ( TUint8 * ) dataP; + + TPtrC8 buf( aBuf, *aLength ); + + if ( iObserver ) + iObserver->RtpPacketReceived( iSessionId /* streamId */, header, buf ); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Write a 16-bit value as 2 consecutive bytes in MSB order +// Memory (at least 2 bytes) must have been allocated to pointer +// before the function is called. +// --------------------------------------------------------------------------- +// +void CRtpStpPacket::write16( TUint8* const aPointer, TUint32 aValue ) + { + // check value range (16 bits) + aPointer[0] = ( TUint8 ) ( ( aValue & 0xFF00 ) >> 8 ); + aPointer[1] = ( TUint8 ) ( aValue & 0x00FF ); + } + +// --------------------------------------------------------------------------- +// Read a 16-bit value given as 2 consecutive bytes in MSB order +// Memory (at least 2 bytes) must have been allocated to pointer +// before the function is called. +// --------------------------------------------------------------------------- +// +TUint32 CRtpStpPacket::read16( const TUint8* const aPointer ) + { + return( aPointer[1] + ( ( TUint32 ) aPointer[0] << 8 ) ); + } + + +#if !defined ( EKA2 ) && !defined ( RTP_UNIT_TEST ) +// The E32Dll() entry point function +GLDEF_C TInt E32Dll( TDllReason /*aReason*/ ) + { + return( KErrNone ); + } +#endif // EKA2 + +// --------------------------------------------------------------------------- +// Function to construct a CRtpPacketExt object. Note that this function +// is exported at ordinal 1 and is not a member of any class. +// --------------------------------------------------------------------------- +// +EXPORT_C MRtpPacketExt* NewL() + { + return new ( ELeave ) CRtpStpPacket; + } + + +// End of File