diff -r 000000000000 -r ff3b6d0fd310 cbs/CbsServer/ServerSrc/CCbsMessage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbs/CbsServer/ServerSrc/CCbsMessage.cpp Tue Feb 02 01:11:09 2010 +0200 @@ -0,0 +1,788 @@ +/* +* Copyright (c) 2004 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: Implementation of CCbsMessage class. +* +*/ + + +// INCLUDE FILES +#include "CbsServerPanic.h" +#include "CCbsMessage.h" +#include "CbsLogger.h" + + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// CCbsMessage::CCbsMessage +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CCbsMessage::CCbsMessage() + { + } + +// Destructor +CCbsMessage::~CCbsMessage() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMessage::~CCbsMessage()"); + CBSLOGSTRING("CBSSERVER: <<< CCbsMessage::~CCbsMessage()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::Alphabet +// Returns the alphabet set of this message. +// Decides the alphabet set of this message by examining DCS field. +// Note that DCS value "unspecified" isn't used anymore. +// All messages are considered to have "default" representation. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsRecAlphabet CCbsMessage::Alphabet() const + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMessage::Alphabet()"); + CBSLOGSTRING2("CBSSERVER: CCbsMessage::Alphabet(): iDCS: %d", iDCS ); + + TCbsRecAlphabet alphabet( ECbsRecAlphabetUnspecified ); + + // Check for Message preceded by language indication/UCS2 and + // General Data Coding Indication/UCS2 + if ( + ( iDCS & DCS_MASK_LANGUAGE_INDICATION_PRECEDES ) == DCS_MPLI_UCS2 || + ( iDCS & DCS_MASK_GENERAL_DATA_CODING_INDICATION ) == DCS_GDCI_UCS2 ) + { + alphabet = ECbsRecAlphabetUCS2; + } + // Check for 8-bit DCSs + else if ( + ( iDCS & DCS_MASK_GENERAL_DATA_CODING_INDICATION ) == DCS_GDCI_8BIT || + ( iDCS & DCS_MASK_MESSAGE_HANDLING )== DCS_DCMH_8BIT || + ( iDCS & DCS_MASK_UDH ) == DCS_UDH_8BIT ) + { + alphabet = ECbsRecAlphabet8bit; + } + // Else assume that alphabet is default + else + { + alphabet = ECbsRecAlphabetDefault; + } + + CBSLOGSTRING("CBSSERVER: <<< CCbsMessage::Alphabet(), returning alphabet."); + return alphabet; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::AppendContent +// Appends another message's content to this message's content. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::AppendContent( + const TDesC& aMsg ) + { + iMessage->Des().Append( aMsg ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::AppendContent8 +// Appends another message's content to this message's content. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::AppendContent8( + const TDesC8& aMsg ) + { + iMessage8->Des().Append( aMsg ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::CellId +// Returns identifier of the cell in which the phone was when this message was received. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint CCbsMessage::CellId() const + { + return iLocationArea.iCellId; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::Contents +// Returns a pointer descriptor to the Unicode contents of the message. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +const TDesC& CCbsMessage::Contents() const + { + __ASSERT_DEBUG( iMessage != 0, CbsServerPanic( ECbsMsgRepUnprepared ) ); + return *iMessage; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::Contents8 +// Returns a pointer descriptor to 8-bit descriptor representation +// of the message body. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +const TDesC8& CCbsMessage::Contents8() const + { + __ASSERT_DEBUG( iMessage8 != 0, CbsServerPanic( ECbsMsgRepUnprepared ) ); + return *iMessage8; + } + + +// ----------------------------------------------------------------------------- +// CCbsMessage::DCS +// Returns the Data Coding Scheme of this message page. +// Refer to GSM specification 03.38 for details on DCS. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsRecDCS CCbsMessage::DCS() const + { + return iDCS; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::GeographicalScope +// Returns the geographical scope of the message. +// This is a 16-bit value containing Geographical +// Scope (2 bits), Message Code (10 bits) and Update Number (4 bits). +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsRecGeographicalScope CCbsMessage::GeographicalScope() const + { + TInt gs( Key() >> 14 ); + if ( gs == KGeographicalScopeCellImmediate || + gs == KGeographicalScopeCellNormal ) + { + return ECbsRecGeographicalScopeCell; + } + else if ( gs == KGeographicalScopePLMNNormal ) + { + return ECbsRecGeographicalScopePLMN; + } + else + { + return ECbsRecGeographicalScopeLAC; + } + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::GetPLMN +// Returns operator information. +// On return, aNetworkInfo contains identity of the network +// in which the phone was when this message was received. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::GetPLMN( + RMobilePhone::TMobilePhoneNetworkInfoV1& aNetworkInfo ) const + { + aNetworkInfo.iCountryCode = iNetworkInfo.iCountryCode; + aNetworkInfo.iNetworkId = iNetworkInfo.iNetworkId; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::IsChildSubindex +// Returns boolean value indicating if this message is a child subindex message. +// Child subindex messages have message code 1010101010b and +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsMessage::IsChildSubindex() const + { + return IsIndexMessage() && ( TopicNumber() != 0 ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::IsClass0 +// Returns ETrue, if this message is a Class 0 message according to +// ETSI GSM specification 03.38. +// Message is of class 0 if the 6th and 7th bit of Geographical Scope +// are both zero. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsMessage::IsClass0() const + { + // Examine bits 0, 1, 4, 6 and 7 of DCS. + TUint8 class0( DCS() ); + class0 &= DCS_MASK_CLASS0; + // Check Class 0 indication. + return class0 == DCS_CLASS0; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::IsCompressed +// Returns ETrue, if the message is compressed. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsMessage::IsCompressed() const + { + // The CB message is compressed only if the value of DCS is 011xxxxx. + return ( TUint8( iDCS >> 5 ) == 3 ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::IsIndexMessage +// Returns boolean value indicating if this is the index message. +// Index messages have message code 1010101010b. +// Refer to GSM specifications to for details. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsMessage::IsIndexMessage() const + { + return MessageCode() == KIndexMessageCode; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::Key +// Returns the key of the message (serial number). +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsDbMessageKey CCbsMessage::Key() const + { + return TCbsDbMessageKey( iSerialNumber ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::LAC +// Returns location area information. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint CCbsMessage::LAC() const + { + return iLocationArea.iLocationAreaCode; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::Language +// Returns the language specified in this message. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsDbLanguage CCbsMessage::Language() const + { + __ASSERT_DEBUG( iLanguage != -1, + CbsServerPanic( ECbsLanguageNotResolved ) ); + + return iLanguage; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::LanguagePrecedingMessage +// Determines and returns the language of this message +// based on first two characters of message content. +// Assumes that the message content contains language +// indication and that the content has been decoded +// into UCS-2 representation. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsDbLanguage CCbsMessage::LanguagePrecedingMessage() const + { + /// Mapping of ISO639 codes to server internal language representation + const TCbsIso639ToLangMapElement KLanguageMap[ KNumberOfLanguageMappings ] = + { + TCbsIso639ToLangMapElement( KIso639Danish, ECbsDanish ), + TCbsIso639ToLangMapElement( KIso639German, ECbsGerman ), + TCbsIso639ToLangMapElement( KIso639Greek, ECbsGreek ), + TCbsIso639ToLangMapElement( KIso639English, ECbsEnglish ), + TCbsIso639ToLangMapElement( KIso639Spanish, ECbsSpanish ), + TCbsIso639ToLangMapElement( KIso639Finnish, ECbsFinnish ), + TCbsIso639ToLangMapElement( KIso639French, ECbsFrench ), + TCbsIso639ToLangMapElement( KIso639Italian, ECbsItalian ), + TCbsIso639ToLangMapElement( KIso639Dutch, ECbsDutch ), + TCbsIso639ToLangMapElement( KIso639Norwegian, ECbsNorwegian ), + TCbsIso639ToLangMapElement( KIso639Portuguese, ECbsPortuguese ), + TCbsIso639ToLangMapElement( KIso639Swedish, ECbsSwedish ), + TCbsIso639ToLangMapElement( KIso639Turkish, ECbsTurkish ), + TCbsIso639ToLangMapElement( KIso639Hungarian, ECbsHungarian ), + TCbsIso639ToLangMapElement( KIso639Polish, ECbsPolish ), + TCbsIso639ToLangMapElement( KIso639Czech, ECbsCzech ), + TCbsIso639ToLangMapElement( KIso639Hebrew, ECbsHebrew ), + TCbsIso639ToLangMapElement( KIso639Arabic, ECbsArabic ), + TCbsIso639ToLangMapElement( KIso639Russian, ECbsRussian ), + TCbsIso639ToLangMapElement( KIso639Icelandic, ECbsIcelandic ) + }; + + __ASSERT_DEBUG( iMessage != NULL , CbsServerPanic( ECbsMsgRepUnprepared ) ); + + TPtrC isoCode( + Contents().Left( KLanguageIndicationLengthWithoutCR ) ); + + for ( TInt i( 0 ); i> 4 ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::MessageClass +// Returns the class of the message. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CCbsMessage::MessageClass() const + { + TUint8 msgclass; + msgclass = TUint8( iDCS >> 4 ); + TInt messageClass( 0 ); + + if ( msgclass == 0x05 || msgclass == 0x07 || msgclass == 0x0f ) // 0000 0101 or 0000 0111 or 0000 1111 + { + msgclass = 0x03; // 0000 0011 + + // Lets find out last two bits + msgclass = TUint8( msgclass & iDCS ); + switch ( msgclass ) + { + case 1: + messageClass = 1; + break; + case 2: + messageClass = 2; + break; + case 3: + messageClass = 3; + break; + case 0: + default: + messageClass = 0; + break; + } + } + return messageClass; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::MessagePrecededByLanguageIndication +// Returns ECbsRecLanguageIndicationBody if message's content is preceded +// by language indication (see GSM 03.38). +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsRecLanguageIndication CCbsMessage::MessagePrecededByLanguageIndication() const + { + TCbsRecLanguageIndication indication( ECbsRecLanguageIndicationHeader ); + if ( iDCS == 0x10 || iDCS == 0x11 ) + { + indication = ECbsRecLanguageIndicationBody; + } + return indication; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::NetworkMode +// Returns current network mode (GSM/WCDMA) +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsNetworkMode CCbsMessage::NetworkMode() const + { + return iNetworkMode; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::PageParameter +// Returns the Page Parameter of the message page +// +// Page Parameter is a 8-bit field describing the number +// of pages in a message and the index of this page in a +// sequence of pages comprising a message. +// For single-page messages this value is 00010001b. +// Value 0 (zero) is reserved with coding beginning at 0001b. +// Thus there can be 1..15 pages in one message. +// Total and this page -fields can be accessed with +// methods TotalPages() and ThisPage(). +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsRecPageParameter CCbsMessage::PageParameter() const + { + return iPageParameter; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::ReleaseEightBitRepresentation +// Frees the memory allocated for 8-bit representation of message content. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::ReleaseEightBitRepresentation() + { + delete iMessage8; + iMessage8 = NULL; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::RemoveIndexHeaderL +// Removes any index header prefix from the message body. +// +// This method assumes that the index header is contained in the +// first line of message body. This line, including trailing +// is removed. +// +// Index header prefix is assumed to contain "EIn", where n +// specifies the version number this index message claims to +// follow and is a carriage return + line feed. +// +// It is also assumed that any language indication prefix has +// already been removed prior to this operation. +// +// Message must be in UCS-2 representation. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::RemoveIndexHeaderL() + { + __ASSERT_DEBUG( IsIndexMessage(), CbsServerPanic( ECbsNotIndexMessage ) ); + + if ( iMessage->Length() < KIndexHeaderLength ) + { + User::Leave( KErrUnderflow ); // Msg too short to contain ix header. + } + + iMessage->Des().Delete( KIndexHeaderPosition, KIndexHeaderLength ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::RemoveLanguageIndicationFromBodyL +// Removes language indication field from the message body. +// +// Presence of an indication is verified with the DCS value +// according to ETSI specifications. Message is assumed to +// contain valid indication, i.e., three bytes preceding the message +// body specifying the language code. +// +// The correctness of this operation is not checked. If the +// indication is invalid, the message body is likely to either have +// a couple of characters too many or few. +// +// Message is assumed to be decoded into UCS-2. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::RemoveLanguageIndicationFromBodyL() + { + if ( MessagePrecededByLanguageIndication() == + ECbsRecLanguageIndicationBody ) + { + if ( iMessage->Length() < KLanguageIndicationPosition + + KLanguageIndicationLength ) + { + User::Leave( KErrUnderflow ); + } + + iMessage->Des().Delete( KLanguageIndicationPosition, + KLanguageIndicationLength ); + } + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::RequiresImmediateDisplay +// Returns ETrue, if this message requires to be displayed immediately. +// +// The CB message has to be displayed immediately +// if either it is flagged as a Class 0 message (see GSM 03.38) +// or has a geographical scope of the type "Immediate" +// (see GSM 03.41). +// +// This function always returns EFalse for Base station ID messages +// (message identifier = 50). +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsMessage::RequiresImmediateDisplay() const + { + return IsClass0(); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::ReserveContentSizeL +// Increases the space allocated for message content. +// Reallocates message content to match parameter aLength. +// Should be used before AppendContent()-call. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::ReserveContentSizeL( + TInt aLength ) + { + if ( iMessage == NULL ) + { + iMessage = HBufC::NewL( aLength ); + } + else if ( ( iMessage ) && ( aLength < iMessage->Length() ) ) + { + User::Leave( KErrArgument ); + } + else + { + iMessage = iMessage->ReAllocL( aLength ); + } + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::ReserveContentSize8L +// Increases the space allocated for message content. +// Reallocates message content to match parameter aLength. +// Should be used before AppendContent()-call. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::ReserveContentSize8L( + TInt aLength ) + { + if ( iMessage8 == NULL ) + { + iMessage8 = HBufC8::NewL( aLength ); + } + else if ( ( iMessage8 ) && ( aLength < iMessage8->Length() ) ) + { + User::Leave( KErrArgument ); + } + else + { + iMessage8 = iMessage8->ReAllocL( aLength ); + } + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::ResolveLanguage +// Determines language of this message so that calls to Language() +// will return the correct value. +// +// Language information may be determined from Data Coding Scheme +// of message header or from the first characters in message body. +// For the latter to succeed, the message has to be decoded into UCS-2. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::ResolveLanguage() + { + if ( iDCS <= ECbsRecLanguageUnspecified || // 0000xxxx + ( iDCS >= ECbsRecLanguageCzech && iDCS < ECbsRecLanguageMax ) ) + { + // Default alphabet, bits 0-3 specify language. + iLanguage = LanguageWithDefaultAlphabet(); + } + else if ( MessagePrecededByLanguageIndication() == + ECbsRecLanguageIndicationBody ) + { + iLanguage = LanguagePrecedingMessage(); + } + else + { + iLanguage = ECbsOther; + } + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::SetNetworkInfo +// Sets the network information of this message. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMessage::SetNetworkInfo( + const RMobilePhone::TMobilePhoneNetworkInfoV1& aNetworkInfo, + const RMobilePhone::TMobilePhoneLocationAreaV1& aArea ) + { + iNetworkInfo = aNetworkInfo; + iLocationArea = aArea; + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::TopicNumber +// Returns the 16-bit Message Identifier containing the topic number. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsDbTopicNumber CCbsMessage::TopicNumber() const + { + return TCbsDbTopicNumber( iMessageIdentifier ); + } + +// ----------------------------------------------------------------------------- +// CCbsMessage::UpdateNumber +// Returns the update number of the message +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TCbsRecUpdateNumber CCbsMessage::UpdateNumber() const + { + return TCbsRecUpdateNumber( Key() & 0xF ); // 00001111b + } + + +// ----------------------------------------------------------------------------- +// CCbsMessage::IsLivecastMessage +// Checks if this message is a Livecast message. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsMessage::IsLivecastMessage() const + { + TBool isLivecastMsg( EFalse ); + + // Check if this message is a Livecast message (just check the topic number) + if ( TopicNumber() >= KCbsLivecastTopicMin && + TopicNumber() <= KCbsLivecastTopicMax ) + { + // This is a Livecast msg + isLivecastMsg = ETrue; + } + + return isLivecastMsg; + } + + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File