--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/smsprotocols/smsstack/wapprot/Src/wapdgrm.cpp Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,708 @@
+// Copyright (c) 1997-2009 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:
+//
+
+#include "gsmubuf.h"
+#include "gsmuset.h"
+#include "Gsmuelem.h"
+#include "Gsmumsg.h"
+#include "gsmusar.h"
+#include "gsmupdu.h"
+#include "WAPDGRM.H"
+#include "ws_main.h"
+#include "smsstackutils.h"
+
+//
+// For incoming short message
+//
+CWapDatagram* CWapDatagram::NewL(const CSmsMessage& aSms)
+ {
+ LOGWAPPROT2("CWapDatagram::NewL(): aSms=0x%08x", (TInt) &aSms);
+
+ CWapDatagram* datagram = new (ELeave)CWapDatagram();
+
+ CleanupStack::PushL(datagram);
+ datagram->ConstructL(aSms);
+ CleanupStack::Pop();
+
+ LOGWAPPROT2("CWapDatagram::NewL(): iFromPort: %d", datagram->iFromPort);
+ LOGWAPPROT2("CWapDatagram::NewL(): iToPort: %d", datagram->iToPort);
+ LOGWAPPROT2("CWapDatagram::NewL(): iReference: %d", datagram->iReference);
+ LOGWAPPROT2("CWapDatagram::NewL(): iTotalSegments: %d", datagram->iTotalSegments);
+ LOGWAPPROT2("CWapDatagram::NewL(): iSegmentNumber: %d", datagram->iSegmentNumber);
+ LOGWAPPROT2("CWapDatagram::NewL(): iIsComplete: %d", datagram->iIsComplete);
+ LOGWAPPROT2("CWapDatagram::NewL(): iReference: %d", datagram->iReference);
+ LOGWAPPROT2("CWapDatagram::NewL(): iIsTextHeader: %d", datagram->iIsTextHeader);
+ LOGWAPPROT2("CWapDatagram::NewL(): iLogServerId: %d", datagram->iLogServerId);
+ LOGWAPPROT2("CWapDatagram::NewL(): i16BitPorts: %d", datagram->i16BitPorts);
+
+ // assert destination port
+ if (datagram->i16BitPorts)
+ {
+ if (datagram->iToPort>=0 && datagram->iToPort<=65535)
+ {
+ LOGWAPPROT1("iToPort OK");
+ }
+ else
+ {
+ LOGWAPPROT1("iToPort FAILED");
+ }
+ }
+ else
+ {
+ if (datagram->iToPort>=0 && datagram->iToPort<=255)
+ {
+ LOGWAPPROT1("iToPort OK");
+ }
+ else
+ {
+ LOGWAPPROT1("iToPort FAILED");
+ }
+ }
+
+ if (datagram->i16BitPorts)
+ {
+ if (datagram->iFromPort>=0 && datagram->iFromPort<=65535)
+ {
+ LOGWAPPROT1("iFromPort OK");
+ }
+ else
+ {
+ LOGWAPPROT1("iFromPort FAILED");
+ }
+ }
+ else
+ {
+ if (datagram->iFromPort>=0 && datagram->iFromPort<=255)
+ {
+ LOGWAPPROT1("iFromPort OK");
+ }
+ else
+ {
+ LOGWAPPROT1("iFromPort FAILED");
+ }
+ }
+
+ return datagram;
+ } // CWapDatagram::NewL
+
+
+//
+// For outgoing short messages
+//
+CWapDatagram* CWapDatagram::NewL(const TDesC8& aSendBuffer)
+ {
+ LOGWAPPROT2("CWapDatagram::NewL(): aSendBuffer=0x%08x", (TInt) &aSendBuffer);
+
+ CWapDatagram* datagram = new (ELeave)CWapDatagram();
+
+ CleanupStack::PushL(datagram);
+ datagram->Construct(aSendBuffer);
+ CleanupStack::Pop();
+
+ return datagram;
+ } // CWapDatagram::NewL
+
+
+CWapDatagram::~CWapDatagram()
+ {
+ LOGWAPPROT1("CWapDatagram::~CWapDatagram()");
+
+ delete iRecvbuf;
+ delete iBuffer;
+ delete iSegment;
+ } // CWapDatagram::~CWapDatagram
+
+
+//
+// What about service centre address ?
+// aSmsMessageArray contains CSmsMessage objects
+//
+void CWapDatagram::EncodeConcatenatedMessagesL(RFs& aFs, CArrayPtr<CSmsMessage>& aSmsMessageArray)
+ {
+ LOGWAPPROT2("CWapDatagram::EncodeConcatenatedMessagesL(): %d messages", aSmsMessageArray.Count());
+
+ // Couple of checkings makes sense
+ __ASSERT_DEBUG(iToPort >=0 && iToAddress.Length()>=0
+ && (iUserDataSettings.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet8Bit
+ || iUserDataSettings.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit),
+ Panic(KPanicUsageError));
+
+ // Determine CSmsMessage encoding by character width
+ if (iUserDataSettings.Alphabet() == TSmsDataCodingScheme::ESmsAlphabet8Bit)
+ {
+ CSmsBufferBase* SmsBuffer = CSmsBuffer::NewL();
+
+ CleanupStack::PushL(SmsBuffer);
+ ConvertL(iSendBuffer,*SmsBuffer);
+ CleanupStack::Pop(); // SmsBuffer, popped here since it is pushed again in the following NewL call
+ CSmsMessage* SmsMessage = CSmsMessage::NewL(aFs, CSmsPDU::ESmsSubmit,SmsBuffer,EFalse);
+ CleanupStack::PushL(SmsMessage);
+ // one and only object
+ aSmsMessageArray.AppendL(SmsMessage);
+ CleanupStack::Pop(); // SmsMessage
+
+ SetSmsMessageSettingsL(*SmsMessage,ETrue);
+ }
+ else
+ {
+ // contruct TWapTextMessage object
+ TWapTextMessage* Segment = new (ELeave) TWapTextMessage(KNullDesC8);
+ CleanupStack::PushL(Segment);
+ CArrayPtrFlat<HBufC8>* SegmentArray = new (ELeave) CArrayPtrFlat<HBufC8> (8);
+ CleanupStack::PushL(SegmentArray);
+ CleanupResetAndDestroyPushL(*SegmentArray);
+
+ Segment->SetDestinationPort(iToPort,i16BitPorts);
+ Segment->SetSourcePort(iFromPort,i16BitPorts);
+ Segment->SetReferenceNumber(iReference);
+ Segment->SetUserData(iSendBuffer);
+ Segment->SetOtherHeader(iOtherHeader);
+ Segment->EncodeSegmentsL(*SegmentArray);
+
+ // contruct array of CSmsMessages
+ TInt Count = SegmentArray->Count();
+ for (TInt i=0; i<Count; i++)
+ {
+ CSmsBufferBase* SmsBuffer = CSmsBuffer::NewL();
+
+ CleanupStack::PushL(SmsBuffer);
+ ConvertL(*(SegmentArray->At(i)),*SmsBuffer);
+ CleanupStack::Pop(); // SmsBuffer, popped here since it is pushed again in the following NewL call
+ CSmsMessage* SmsMessage=CSmsMessage::NewL(aFs, CSmsPDU::ESmsSubmit,SmsBuffer,EFalse);
+ CleanupStack::PushL(SmsMessage);
+ aSmsMessageArray.AppendL(SmsMessage);
+ CleanupStack::Pop(); // SmsMessage
+
+ SetSmsMessageSettingsL(*SmsMessage,EFalse);
+ }
+ CleanupStack::PopAndDestroy(3, Segment); // SegmentArray elements (Reset and Destroy), SegmentArray, Segment
+
+ }
+ } // CWapDatagram::EncodeConcatenatedMessagesL
+
+void CWapDatagram::DecodeConcatenatedMessagesL(CArrayPtr<TSegmentData>& aSmsMessageArray)
+ {
+ LOGWAPPROT1("CWapDatagram::DecodeConcatenatedMessagesL()");
+
+ // The TSegmentData elements are in the random order in the array
+ TInt Count = aSmsMessageArray.Count();
+ TInt i=0;
+
+ if (Count > 0)
+ {
+ TInt DataLength = 0; // total length of data
+ TInt TempLength = 0;
+
+ // Every TSegmentData should be equal length except last segment
+ // Use that 'constant' segment length as indexes
+ // Count the actual data length
+ for(i=0; i<Count; i++)
+ {
+ TempLength = aSmsMessageArray.At(i)->iData.Length();
+ DataLength += TempLength;
+ }
+
+ TSegmentData* Segment = NULL;
+
+ if (iBuffer)
+ {
+ delete iBuffer;
+ iBuffer = NULL;
+ }
+ iBuffer = HBufC8::NewL(DataLength );
+
+ TPtr8 BufferPtr(iBuffer->Des());
+ BufferPtr.SetLength(DataLength );
+
+ TInt segmentStartPosition=0;
+
+ for(i=0; i<Count; i++)
+ {
+ if (segmentStartPosition >= DataLength)
+ {
+ // Once the start position is out of range,
+ // there is no point in continuing reconstructing the
+ // wapdatagram.
+ break;
+ }
+
+ Segment = aSmsMessageArray.At(i);
+ TPtr8 CopyBufferPtr(&(BufferPtr[segmentStartPosition]),0,160);
+ CopyBufferPtr.Copy(Segment->iData);
+ segmentStartPosition+=Segment->iData.Length();
+ }
+ }
+ iIsComplete = ETrue;
+ } // CWapDatagram::DecodeConcatenatedMessagesL
+
+
+void CWapDatagram::InternalizeL(RReadStream& aStream)
+ {
+ aStream >> iUserDataSettings;
+ aStream >> iToAddress;
+ iToPort = aStream.ReadInt32L();
+ aStream >> iFromAddress;
+ iFromPort = aStream.ReadInt32L();
+ TInt64 time;
+ aStream >> time;
+ iTime = time;
+ iUTCOffset = aStream.ReadInt32L();
+ iIsTextHeader = aStream.ReadInt32L();
+ iReference = aStream.ReadInt32L();
+ iTotalSegments = aStream.ReadInt32L();
+ iSegmentNumber = aStream.ReadInt32L();
+ iLogServerId = aStream.ReadInt32L();
+ iVersionNumber = aStream.ReadInt32L();
+ iSpare1 = aStream.ReadInt32L();
+ iSpare2 = aStream.ReadInt32L();
+ iSpare3 = aStream.ReadInt32L();
+
+ // Required for version 1, which is reading and internalizing extra SMS parameters from stream
+ if(iVersionNumber == EFirstVersion)
+ {
+ TInt length = aStream.ReadInt32L();
+ if(length>0)
+ {
+ HBufC8* smsBuffer=HBufC8::NewMaxLC(length);
+ TPtr8 recvbuftmp = smsBuffer->Des();
+ aStream >> recvbuftmp;
+ if(!iRecvbuf)
+ {
+ iRecvbuf = CBufFlat::NewL(KSmsBufferExpansion);
+ }
+ iRecvbuf->ResizeL(recvbuftmp.Size());
+ iRecvbuf->Write(0, recvbuftmp);
+ CleanupStack::PopAndDestroy(smsBuffer);
+ }
+ }
+
+ } // CWapDatagram::InternalizeL
+
+
+//
+// Reads iBuffer from stream (for 8Bit messages)
+//
+void CWapDatagram::InternalizeBufferL(RReadStream& aStream)
+ {
+ TInt length;
+ length=aStream.ReadInt32L();
+ iBuffer=HBufC8::NewMaxL(length);
+ TPtr8 tmp = iBuffer->Des();
+ aStream >> tmp;
+ iIsComplete = ETrue;
+ }
+
+
+void CWapDatagram::ExternalizeL(RWriteStream& aStream) const
+ {
+ aStream << iUserDataSettings;
+ aStream << iToAddress;
+ aStream.WriteInt32L(iToPort);
+
+ aStream << iFromAddress;
+ aStream.WriteInt32L(iFromPort);
+ aStream << iTime.Int64();
+ aStream.WriteInt32L(iUTCOffset.Int());
+
+ aStream.WriteInt32L(iIsTextHeader);
+ aStream.WriteInt32L(iReference);
+ aStream.WriteInt32L(iTotalSegments);
+ aStream.WriteInt32L(iSegmentNumber);
+
+ aStream.WriteInt32L(iLogServerId);
+
+ aStream.WriteInt32L(iVersionNumber);
+ aStream.WriteInt32L(iSpare1);
+ aStream.WriteInt32L(iSpare2);
+ aStream.WriteInt32L(iSpare3);
+
+ // Externalizing the SMS params if exists
+ if(iRecvbuf)
+ {
+ TPtr8 recvbuftmp = iRecvbuf->Ptr(0);
+ aStream.WriteInt32L(recvbuftmp.Length());
+ aStream << recvbuftmp;
+ }
+ else
+ {
+ aStream.WriteInt32L(0);
+ }
+ }
+
+
+//
+// writes iBuffer to writeStream for 8-bit incomming messages
+//
+void CWapDatagram::ExternalizeBufferL(RWriteStream& aStream) const
+ {
+ TInt length= WapDatagramLength();
+ aStream.WriteInt32L(length);
+ TPtr8 tmp= iBuffer->Des();
+ aStream << tmp;
+
+ } // CWapDatagram::ExternalizeBufferL
+
+
+//
+// Outgoing
+//
+void CWapDatagram::Construct(const TDesC8& aSendBuffer)
+ {
+ LOGWAPPROT1("CWapDatagram::Construct()");
+
+ // Set version number to 1, as we have had to make
+ // changes to CWapDatagram for CR0929
+ iVersionNumber = EFirstVersion;
+
+ iSendBuffer.Set(aSendBuffer);
+ } // CWapDatagram::Construct
+
+
+//
+// Incoming
+// code actualy supports 7-bit characters and port numbers
+// encoded in information elements (IE) although it is not
+// a requirement
+//
+void CWapDatagram::ConstructL(const CSmsMessage& aSms)
+ {
+ LOGWAPPROT1("CWapDatagram::ConstructL()");
+
+ // Set version number to 1, as we have had to make
+ // changes to CWapDatagram for CR0929
+ iVersionNumber = EFirstVersion;
+
+ iRecvbuf = CBufFlat::NewL(KSmsBufferExpansion);
+
+ RBufWriteStream writestream(*iRecvbuf);
+ writestream.Open(*iRecvbuf);
+ CleanupClosePushL(writestream);
+
+ // Externalizing everything within CSMSMessage except buffer
+ aSms.ExternalizeWithoutBufferL(writestream);
+
+ CleanupStack::PopAndDestroy(); // writestream
+
+ iRecvbuf->Compress();
+
+ const CSmsBufferBase& SmsBufferBase = aSms.Buffer();
+
+ GetDatagramSettings(aSms);
+
+ // Get the data from CSmsMessage and convert
+ // SmsBuffer store Unicode short message from CSmsMessage
+ ConvertL(SmsBufferBase,&iBuffer);
+ GetDatagramSettingsL();
+
+ iIsComplete = ETrue;
+ if (iUserDataSettings.Alphabet() == TSmsDataCodingScheme::ESmsAlphabet7Bit)
+ {
+ // this is a good candidate to include a text header.
+ if (iIsTextHeader)
+ {
+ // there is still a minor chance that message is complete:
+ // one fragment long datagram
+ if (iTotalSegments == 1)
+ {
+ // Get the segment data
+ TPtr8 PtrNarrow = iBuffer->Des();
+ PtrNarrow.Zero();
+ iSegment->UserData(PtrNarrow);
+ }
+ else
+ {
+ iIsComplete = EFalse;
+ // delete incomplete message from iBuffer;
+ delete iBuffer;
+ iBuffer = 0;
+ }
+ }
+ else
+ // This means that IEs with 7-bits are used
+ // Happily we support it
+ // But what TODO if we are here due to an error, because
+ // 7-bit with IEs should never happen ?
+ iIsComplete = ETrue;
+
+ }
+ } // CWapDatagram::ConstructL
+
+
+//
+// Set WAP datagram private members from a text based concatenated message
+// Copies contents of iBuffer to iSmsBuffer
+// Allocates iSegment object
+//
+void CWapDatagram::GetDatagramSettingsL()
+ {
+ LOGWAPPROT1("CWapDatagram::GetDatagramSettingsL()");
+
+ /* The WAP stack always receives 8 bit WAP datagrams from the SMS Stack as a single CSmsMessage.
+ This is because 8 bit WAP messages which cannot be encoded into a single PDU are sent in a segmented SMS
+ message which is reassembled inside the SMS Stack; the SMS Stack always passes the WAP stack
+ a single CSmsMessage containing a single WAP message regardless of the message length.
+ The WAP stack can receive 7 Bit WAP datagrams either as a single CSmsMessage or as a number of CSmsMessages
+ which need to be reassembled into a single WAP message by the WAP stack. The latter method is provided to maintain backward
+ compatibility with early versions of the WAP stack which were implemented before the concatenation function was
+ available in the SMS stack.*/
+
+ /* 160 is the maximum number of character that can be fitted in a single PDU using 7 bit encoding */
+ if((iUserDataSettings.Alphabet()== TSmsDataCodingScheme::ESmsAlphabet8Bit) ||
+ (iUserDataSettings.Alphabet()== TSmsDataCodingScheme::ESmsAlphabet7Bit && iBuffer->Length()>160 ))
+ {
+ iSegment = new (ELeave)TWapTextMessage(*iBuffer);
+ }
+ else if (iBuffer->Length()<=160)
+ {
+ iSmsBuffer = *iBuffer;
+ iSegment = new (ELeave)TWapTextMessage(iSmsBuffer);
+ iIsTextHeader = iSegment->Parse();
+
+ if (iIsTextHeader)
+ {
+ iFromPort = iSegment->SourcePort(&i16BitPorts);
+ iToPort = iSegment->DestinationPort(&i16BitPorts);
+ iReference = iSegment->ReferenceNumber();
+ iTotalSegments = iSegment->TotalSegments();
+ iSegmentNumber = iSegment->SegmentNumber();
+ }
+ }
+ else
+ {
+ delete iSegment;
+ iSegment = 0;
+ }
+ } // CWapDatagram::GetDatagramSettingsL
+
+
+//
+// Set WAP datagram private members from information element structures
+//
+void CWapDatagram::GetDatagramSettings(const CSmsMessage& aSms)
+ {
+ LOGWAPPROT1("CWapDatagram::GetDatagramSettings()");
+
+ const CSmsPDU& Pdu = aSms.SmsPDU();
+
+ __ASSERT_DEBUG(Pdu.Type()==CSmsPDU::ESmsDeliver || Pdu.Type()==CSmsPDU::ESmsSubmit, // this line is testing purposes only
+ Panic(KPanicUsageError));
+
+ aSms.UserDataSettings(iUserDataSettings);
+
+ Pdu.ApplicationPortAddressing(iToPort,iFromPort,&i16BitPorts);
+ if (iFromPort == (-1))
+ iFromPort = iToPort;
+
+ // From WAP datagram point of view following numbers are applicable
+ iReference = 0;
+ iTotalSegments = 1;
+ iSegmentNumber = 1;
+
+ iFromAddress = aSms.ToFromAddress();
+ iToAddress = KNullDesC;
+ iTime = aSms.Time();
+
+ TBool result = SetUTCOffset(aSms.UTCOffset());
+ __ASSERT_DEBUG(result, Panic(KPanicSmsMsgTimeZoneOutOfRange));
+ } // CWapDatagram::GetDatagramSettings
+
+
+//
+// Set Alphabet information of iUserDataSettings before calling the method
+// Converts from 7/8-bit to UNICODE
+//
+void CWapDatagram::ConvertL(const TDesC8& aNarrowChars,CSmsBufferBase& aSmsBuffer) const
+ {
+ LOGWAPPROT1("CWapDatagram::ConvertL()");
+
+ // Convert the data in segments of specified max size
+ const TInt KMaxSegmentSize=CSmsBufferBase::EMaxBufLength;
+
+ // Create converter and reassembler
+ RFs fs;
+ CCnvCharacterSetConverter* charConv=CCnvCharacterSetConverter::NewLC();
+ CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(*charConv,fs,iUserDataSettings.Alphabet(),ETrue);
+ TSmsBufferReassembler reassembler(*converter,aSmsBuffer);
+
+ // Rassemble
+ TInt elementsRemaining=aNarrowChars.Length();
+ while (elementsRemaining)
+ {
+ TInt segmentLength=Min(KMaxSegmentSize,elementsRemaining);
+ TPtrC8 ptr(aNarrowChars.Ptr()+aNarrowChars.Length()-elementsRemaining,segmentLength);
+ reassembler.ReassembleNextL(ptr, ESmsEncodingNone,
+ elementsRemaining==segmentLength);
+ elementsRemaining-=segmentLength;
+ }
+
+ CleanupStack::PopAndDestroy(2); // charConv,
+ } // CWapDatagram::ConvertL
+
+
+//
+// Converts from UNICODE to 7/8-bit
+//
+void CWapDatagram::ConvertL(const CSmsBufferBase& aSmsBuffer,HBufC8** aNarrowChars) const
+ {
+ LOGWAPPROT1("CWapDatagram::ConvertL()");
+
+ // Convert the data in segments of specified max size
+ const TInt KMaxSegmentSize=CSmsBufferBase::EMaxBufLength;
+
+ // Delete the existing buffer
+ if (*aNarrowChars)
+ {
+ delete *aNarrowChars;
+ *aNarrowChars=NULL;
+ }
+
+ // Create converter and segmenter
+ RFs fs;
+ CCnvCharacterSetConverter* charConv=CCnvCharacterSetConverter::NewLC();
+ CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(*charConv,fs,iUserDataSettings.Alphabet(),ETrue);
+ CSmsBufferSegmenter* segmenter=CSmsBufferSegmenter::NewLC(*converter,aSmsBuffer,KMaxSegmentSize);
+
+ // Create a new buffer based on converted length
+ TInt convertedLength=segmenter->TotalConvertedLengthL(ESmsEncodingNone);
+ *aNarrowChars=HBufC8::NewMaxL(((convertedLength+KMaxSegmentSize-1)/KMaxSegmentSize)*KMaxSegmentSize);
+ TPtr8 narrowPtr=(*aNarrowChars)->Des();
+
+ // Now do the conversion
+ TInt elementsConverted=0;
+ TInt unconvertedChars=0;
+ TInt downgradedChars=0;
+ TBool complete=EFalse;
+ while (elementsConverted<convertedLength)
+ {
+ __ASSERT_DEBUG(elementsConverted<convertedLength,Panic(KPanicTooLongData));
+ TPtr8 ptr((TUint8*)narrowPtr.Ptr()+elementsConverted,0,KMaxSegmentSize);
+ complete=segmenter->SegmentNextL(ptr, unconvertedChars, downgradedChars, ESmsEncodingNone);
+ elementsConverted+=ptr.Length();
+ }
+ if((!complete || (convertedLength!=elementsConverted)) && convertedLength)
+ User::Leave( KErrCorrupt );
+ narrowPtr.SetLength(convertedLength);
+
+ CleanupStack::PopAndDestroy(3); // charConv,converter,segmenter
+ } // CWapDatagram::ConvertL
+
+
+void CWapDatagram::SetSmsMessageSettingsL(CSmsMessage& aSmsMessage, TBool aSetPorts)
+ {
+ LOGWAPPROT1("CWapDatagram::SetSmsMessageSettingsL()");
+
+ CSmsPDU& Pdu = aSmsMessage.SmsPDU();
+
+ aSmsMessage.SetToFromAddressL(iToAddress);
+ aSmsMessage.SetUserDataSettingsL(iUserDataSettings);
+ aSmsMessage.SetTime(iTime);
+
+ TBool result = aSmsMessage.SetUTCOffset(iUTCOffset);
+ __ASSERT_DEBUG(result, Panic(KPanicWapDgrmTimeZoneOutOfRange));
+
+ if (aSetPorts)
+ {
+ if (iFromPort == (-1))
+ iFromPort = iToPort;
+
+ // Determine whether long or short form is used
+ if (iFromPort > 255 || iToPort>255)
+ i16BitPorts = ETrue;
+
+ Pdu.SetApplicationPortAddressingL(ETrue,iToPort,iFromPort,i16BitPorts);
+ // WAP implementation guidelines recommend DCS of 0x15, however
+ // some gateways / SCs will only accept DCS 0xf5
+ Pdu.SetBits7To4(TSmsDataCodingScheme::ESmsDCSTextUncompressed7BitOr8Bit);
+ Pdu.SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet8Bit);
+ Pdu.SetClass(ETrue,TSmsDataCodingScheme::ESmsClass1);
+ }
+ } // CWapDatagram::SetSmsMessageSettingsL
+
+
+CWapDatagram::CWapDatagram():
+ iUserDataSettings(),
+ iToAddress(KNullDesC),
+ iFromAddress(KNullDesC),
+ i16BitPorts(EFalse),
+ iFromPort(-1),
+ iToPort(-1),
+ iTime(),
+ iUTCOffset(0),
+ iIsComplete(EFalse),
+ iReference(0),
+ iTotalSegments(0),
+ iSegmentNumber(0),
+ iIsTextHeader(EFalse),
+ iSegment(NULL),
+ iSmsBuffer(KNullDesC8),
+ iBuffer(NULL),
+ iSendBuffer(KNullDesC8),
+ iOtherHeader(KNullDesC8),
+ iLogServerId(0),
+ iVersionNumber(EBaseVersion),// Set version number to EBaseVersion by default.
+ iSpare1(0),
+ iSpare2(0),
+ iSpare3(0),
+ iRecvbuf(NULL)
+ {
+ iTime.UniversalTime();
+
+ TBool result = SetUTCOffset(User::UTCOffset());
+ __ASSERT_DEBUG(result, Panic(KPanicUserSuppliedTimeZoneOutOfRange));
+
+ iUserDataSettings.SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet8Bit);
+ __DECLARE_NAME(_S("CWapDatagram"));
+ } // CWapDatagram::CWapDatagram
+
+
+//
+// Return the location of the link
+//
+TInt CWapDatagram::LinkOffset()
+ {
+ LOGWAPPROT1("CWapDatagram::LinkOffset()");
+
+
+ return _FOFF(CWapDatagram,iLink);
+ } // CWapDatagram::LinkOffset
+
+
+TBool CWapDatagram::SetUTCOffset(const TTimeIntervalSeconds& aUTCOffset)
+ {
+ LOGWAPPROT1("CWapDatagram::SetUTCOffset()");
+
+ TBool rc = ETrue;
+ TInt utcOffset = aUTCOffset.Int();
+
+ if ((utcOffset <= CSmsMessage::EMaximumSeconds) &&
+ (utcOffset >= -CSmsMessage::EMaximumSeconds))
+ {
+ iUTCOffset = utcOffset;
+ }
+ else
+ {
+ LOGWAPPROT2("CWapDatagram:SetUTCOffset offset [out of range] = %d",utcOffset);
+ rc = EFalse;
+ }
+
+ return rc;
+ } // CWapDatagram::SetUTCOffset
+
+
+
+CBufFlat* CWapDatagram::SmsExternalisedStream() const
+ {
+ return iRecvbuf;
+ }