--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/wma/sms_cbs/pushplugin/cbs/src.s60/cbsserverconnection.cpp Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,719 @@
+/*
+* Copyright (c) 2008 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 <fstream>
+
+#include "logger.h"
+#include "monitor.h"
+#include "pushexception.h"
+#include "pusherrorcodes.h"
+#include "applicationinfo.h"
+#include "cbsserverconnection.h"
+#include "connectionlistener.h"
+#include "cbsserverconnectionfactory.h"
+
+//custom error code for filter mismatches
+const TInt KErrDoesNotMatchMessageId = -20012;
+
+// Default array granularity, ~half of 15 pages
+const TInt KDefaultArrayGranularity = 8;
+
+using namespace java::util;
+namespace java
+{
+namespace wma
+{
+OS_EXPORT CbsServerConnection::CbsServerConnection(const std::wstring& aUri,
+ const std::wstring& aFilter)
+ :CActive(EPriorityStandard),ServerConnectionBase(aUri, aFilter),
+ mCbsMessageReceived(EFalse),mCbsPartiallyReceived(EFalse),
+ mBroadcastMsgAttributePackage(mBroadcastMsgAttributes),
+ mBroadcastPhoneCapsPckg(mBroadcastPhoneCaps)
+{
+ JELOG2(EWMA);
+ std::wstring port = aUri.substr(KPortFieldStartIndex); // "cbs://:"
+ mPort = JavaCommonUtils::wstringToInt(port);
+ LOG1(EWMA, EInfo, "created CbsServerConnection on ID %d", mPort);
+}
+
+ServerConnection* ServerConnectionBase::getServerConnection(
+ const std::wstring& aUri, const std::wstring& aFilter)
+{
+ JELOG2(EWMA);
+ CbsServerConnection* cbsConn = new CbsServerConnection(aUri, aFilter);
+ return cbsConn;
+}
+
+CbsServerConnection::~CbsServerConnection()
+{
+ JELOG2(EWMA);
+ removeDir(mMessageStoreDirName);
+}
+
+void CbsServerConnection::initializeL()
+{
+ JELOG2(EWMA);
+ TUint32 modemNo = 0;
+ // get the name of the TSY
+ mTsyName = HBufC16::NewL(KCommsDbSvrMaxFieldLength);
+ TPtr tsyPtr(mTsyName->Des());
+
+ CCommsDatabase* database = CCommsDatabase::NewL(EDatabaseTypeUnspecified);
+ CleanupStack::PushL(database);
+
+ database->GetGlobalSettingL(TPtrC(MODEM_PHONE_SERVICES_SMS), modemNo);
+
+ // Now read the TSY name from the modem table record
+ CCommsDbTableView* dbTable = database->OpenViewMatchingUintLC(TPtrC(MODEM),
+ TPtrC(COMMDB_ID), modemNo);
+
+ User::LeaveIfError(dbTable->GotoFirstRecord());
+ dbTable->ReadTextL(TPtrC(MODEM_TSY_NAME), tsyPtr);
+ CleanupStack::PopAndDestroy(dbTable);
+ CleanupStack::PopAndDestroy(database);
+
+
+ // Make a connection to RTelServer
+ User::LeaveIfError(mTelServer.Connect());
+ User::LeaveIfError(mTelServer.ShareAuto());
+
+ User::LeaveIfError(mTelServer.LoadPhoneModule(*mTsyName));
+
+ // Get the name of the first phone
+ TInt phones;
+ User::LeaveIfError(mTelServer.EnumeratePhones(phones));
+
+ // Find the one which has the cbs functionality
+
+ while (phones--)
+ {
+ TName tsyPhone;
+ User::LeaveIfError(mTelServer.GetTsyName(phones, tsyPhone));
+
+ if (tsyPhone.CompareF(*mTsyName) == KErrNone)
+ {
+ // Get the phone info
+ RTelServer::TPhoneInfo tPhone;
+ User::LeaveIfError(mTelServer.GetPhoneInfo(phones, tPhone));
+ User::LeaveIfError(mMobilePhone.Open(mTelServer, tPhone.iName));
+
+ // No need to look through any more of the available phones
+ break;
+ }
+ }
+ mCbsMessagePagesData = new(ELeave) CDesCArrayFlat(KDefaultArrayGranularity);
+ mOpenMonitor = Monitor::createMonitor();
+ int result = pthread_mutex_init(&mMutex, 0);
+ if (result == 0)
+ {
+ result = pthread_cond_init(&mCondVar, 0);
+ }
+ if (0 != result)
+ {
+ User::Leave(result);
+ }
+}
+
+void CbsServerConnection::open(ConnectionListener* aListener,
+ bool aIsAppLaunched)
+{
+ JELOG2(EWMA);
+ mIsAppLaunched = aIsAppLaunched;
+ CbsServerConnection::open(aListener);
+}
+
+OS_EXPORT void CbsServerConnection::open(ConnectionListener* aListener)
+{
+ JELOG2(EWMA);
+ int error = 0;
+ mListener = aListener;
+ //If it is push launched Message store will have received cbs messages
+ //notify the listener
+ if (mMessagesOnStore > 0)
+ {
+ mListener->msgArrived();
+ CbsServerConnectionFactory::getFactory().setPendingMsgFlag(mUri, false);
+ }
+ else if (!mIsListening)
+ {
+ TRAP(error, initializeL());
+ if (error != KErrNone)
+ {
+ ELOG1(EWMA, "CBS : Error while Initializing = %d", error);
+ std::string errTxt("ERROR!!! CBS : Error while Initializing");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
+ __FUNCTION__, __LINE__);
+ }
+ mInitialized = ETrue;
+ // Set up RBroadcastMessaging
+ error = mBroadcastMessage.Open(mMobilePhone);
+ if (error != KErrNone)
+ {
+ ELOG1(EWMA, "CBS : RBroadcastMessaging Open failed : %d", error);
+ std::string errTxt("ERROR!!! CBS :RBroadcastMessaging Open failed");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
+ __FUNCTION__, __LINE__);
+ }
+ // Get the phone capabilities to find out if it is a GSM or WCDMA
+ // based phone
+ error = mBroadcastMessage.GetCaps(mBroadcastPhoneCapsPckg);
+ if (error != KErrNone)
+ {
+ ELOG1(EWMA, "CBS : Get Capabilities failed : %d", error);
+ std::string errTxt("ERROR!!! CBS: Get Capabilities failed");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
+ __FUNCTION__, __LINE__);
+ }
+ // If the phone supports CDMA networks, then return KErrNotSupported
+ if ((mBroadcastPhoneCaps.iModeCaps
+ & RMobileBroadcastMessaging::KCapsCdmaTpduFormat)
+ == RMobileBroadcastMessaging::KCapsCdmaTpduFormat)
+ {
+ ELOG(EWMA, "CBS : CDMA networks - Not Supported");
+ std::string errTxt("ERROR!!!CBS : CDMA networks - Not Supported");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
+ __FUNCTION__, __LINE__);
+ }
+ // Create Message Store
+ const java::runtime::ApplicationInfo& appInf =
+ java::runtime::ApplicationInfo::getInstance();
+ const std::wstring& root = appInf.getRootPath();
+ error = createMessageStore(root + CBS_STORE_PATH);
+ if (error != KErrNone)
+ {
+ ELOG1(EWMA,"CBS : create message store failed : %d",error);
+ std::string errTxt("ERROR!!! CBS : create message store failed");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR,errTxt,__FILE__,
+ __FUNCTION__,__LINE__);
+ }
+ mState = ECbsOpen;
+ //Create the listening thread which listens for Cbs messages
+ error = pthread_create(&mThreadId, NULL,
+ CbsServerConnection::listenThread, this);
+
+ if (error != KErrNone)
+ {
+ ELOG1(EWMA,"CBS : listenThread creation failed : %d",error);
+ std::string errTxt("ERROR!!! CBS : listenThread creation failed");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR,errTxt,__FILE__,
+ __FUNCTION__,__LINE__);
+ }
+
+ mOpenMonitor->wait();
+ // If there are any messages already available in the message store
+ // notify the listener
+ if (mMessagesOnStore > 0)
+ {
+ mListener->msgArrived();
+ }
+ mIsListening = true;
+ }
+}
+
+
+void* CbsServerConnection::listenThread(void* aParams)
+{
+ JELOG2(EWMA);
+ CTrapCleanup* tc = CTrapCleanup::New();
+ CbsServerConnection* aCbsSrvConn =
+ reinterpret_cast<CbsServerConnection*>(aParams);
+ // As there is no possibility of active scheduler being installed to this
+ // thread prior to this , there is no need for any checks.
+ CActiveScheduler* activeScheduler = new CActiveScheduler();
+ CActiveScheduler::Install(activeScheduler);
+ CActiveScheduler::Add(aCbsSrvConn);
+ aCbsSrvConn->setFilterSettings();
+ aCbsSrvConn->SetActive();
+ (aCbsSrvConn->mOpenMonitor)->notify();
+ activeScheduler->Start();
+ delete activeScheduler;
+ delete tc;
+ return 0;
+}
+
+void CbsServerConnection::setFilterSettings()
+{
+ JELOG2(EWMA);
+ mBroadcastMessage.SetFilterSetting(iStatus,
+ RMobileBroadcastMessaging::EBroadcastAcceptAll);
+}
+
+
+void CbsServerConnection::startCBSListening()
+{
+ JELOG2(EWMA);
+ mState = ECbsReceivingActive;
+ mBroadcastMessage.ReceiveMessage(iStatus, mBroadcastPageData,
+ mBroadcastMsgAttributePackage);
+}
+
+void CbsServerConnection::DoCancel()
+{
+ JELOG2(EWMA);
+ // Only cancel the appropriate asynchronous request
+ switch (mState)
+ {
+ case ECbsOpen:
+ {
+ mBroadcastMessage.CancelAsyncRequest(
+ EMobileBroadcastMessagingSetFilterSetting);
+ break;
+ }
+ default:
+ {
+ mBroadcastMessage.CancelAsyncRequest(
+ EMobileBroadcastMessagingReceiveMessage);
+ break;
+ }
+ }
+}
+
+int CbsServerConnection::retrieveMessage(TJavaMessageParametersBuf& aCbsBuf)
+{
+ JELOG2(EWMA);
+ TCBSParametersBuf cbsParametersBuf;
+ std::wstring path;
+ path += mMessageStoreDirName;
+ try
+ {
+ path += JavaCommonUtils::intToWstring(mFirstMessageInStore);
+ char* messagePath = JavaCommonUtils::wstringToUtf8(path);
+ // Read the CBS file contents
+ readStream.exceptions(std::ifstream::failbit|std::ifstream::badbit);
+
+ readStream.open(messagePath, std::ios::in | std::ios::binary);
+ readStream.read((char*) cbsParametersBuf.Ptr(), cbsParametersBuf.Size());
+ readStream.read((char*)(aCbsBuf().mData).Ptr(),
+ cbsParametersBuf().mDataSize);
+ readStream.close();
+ (aCbsBuf().mData).SetLength((cbsParametersBuf().mDataSize)>>1);
+ LOG1(EWMA,EInfo,"WMA : CBS Message Data Length %d",
+ cbsParametersBuf().mDataSize);
+ aCbsBuf().mAddress = cbsParametersBuf().mAddress;
+ aCbsBuf().mPort = 0;
+ // Get encoding
+ aCbsBuf().mEncoding = cbsParametersBuf().mEncoding;
+ deleteMessage();
+ delete[] messagePath;
+ }
+ catch (std::ifstream::failure e)
+ {
+ ELOG(EWMA,"CBS : Exception while opening/reading file");
+ readStream.exceptions(std::ofstream::goodbit);
+ readStream.close();
+ return KErrGeneral;
+ }
+ catch (ExceptionBase ex)
+ {
+ return KErrGeneral;
+ }
+ return KErrNone;
+}
+
+
+void CbsServerConnection::close()
+{
+ JELOG2(EWMA);
+ // the close and RunL are synchronized to make it SMP safe.
+ if (mInitialized)
+ {
+ pthread_mutex_lock(&mMutex);
+ mMessagesOnStore = 0;
+ mInitialized = EFalse;
+ mIsListening = false;
+ mIsAppLaunched = false;
+ mCbsMessageReceived = EFalse;
+ mCbsPartiallyReceived = EFalse;
+ if (mState != ECbsReceivingDeactive)
+ {
+ // Cancel blocks, so it is not called. Instead we check for any
+ // outstanding request and call DoCancel().
+ if (IsActive())
+ {
+ DoCancel();
+ }
+ mState = ECbsReceivingDeactive;
+ if (mRunning)
+ {
+ pthread_cond_wait(&mCondVar, &mMutex);
+ }
+ mBroadcastMessage.Close();
+ mMobilePhone.Close();
+ mTelServer.Close();
+ mCbsMessagePagesRef.Reset();
+ delete mCbsMessagePagesData; // invokes Reset() if necessary
+ delete mOpenMonitor;
+ delete mTsyName;
+ }
+ pthread_mutex_unlock(&mMutex);
+ pthread_mutex_destroy(&mMutex);
+ pthread_cond_destroy(&mCondVar);
+ }
+}
+
+TInt CbsServerConnection::RunError(TInt aError)
+{
+ JELOG2(EWMA);
+ mListener->error(mUri, aError, "CBS :Error Receiving Broadcast Message");
+ mRunning = EFalse;
+ pthread_cond_signal(&mCondVar);
+ pthread_mutex_unlock(&mMutex);
+ CActiveScheduler::Stop();
+ return KErrNone;
+}
+
+void CbsServerConnection::RunL()
+{
+ JELOG2(EWMA);
+ pthread_mutex_lock(&mMutex);
+ if (iStatus.Int() < KErrNone && iStatus.Int() != KErrCancel
+ && mState != ECbsReceivingDeactive)
+ {
+ ELOG1(EWMA,"CBS : Error Receiving Broadcast Message:%d",iStatus.Int());
+ mListener->error(mUri, iStatus.Int(),
+ "CBS : Error Receiving Broadcast Message");
+ if (mIsAppLaunched)
+ {
+ startCBSListening();
+ SetActive();
+ }
+ else
+ {
+ mRunning = EFalse;
+ pthread_cond_signal(&mCondVar);
+ CActiveScheduler::Stop();
+ }
+ pthread_mutex_unlock(&mMutex);
+ return;
+ }
+ switch (mState)
+ {
+ case ECbsOpen:
+ {
+ mRunning = ETrue;
+ //start listening for cbs messages
+ startCBSListening();
+ SetActive();
+ break;
+ }
+ case ECbsReceivingActive:
+ {
+ TRAPD(error, readMessageFromStackL());
+ if (error != KErrNone)
+ {
+ // port number does not match
+ if (error != KErrDoesNotMatchMessageId)
+ {
+ // Otherwise report back to client as a system error occurred
+ mListener->error(mUri, error,
+ "CBS : Error Receiving Broadcast Message");
+ }
+ }
+ else
+ {
+ if (mCbsMessageReceived)
+ {
+ mCbsMessageReceived = EFalse;
+ // we have a complete message, so notify client
+ mMessagesOnStore++;
+ // If listening by push setPendingMsgFlag to true.
+ // This is required as per push framework , so that
+ // listConnections & other push calls works fine.
+ if (!mIsAppLaunched)
+ {
+ CbsServerConnectionFactory::getFactory().setPendingMsgFlag(
+ mUri, true);
+ }
+ mListener->msgArrived();
+ }
+ }
+ startCBSListening();
+ SetActive();
+ break;
+ }
+ case ECbsReceivingDeactive:
+ {
+ mRunning = EFalse;
+ pthread_cond_signal(&mCondVar);
+ CActiveScheduler::Stop();
+ break;
+ }
+ default:
+ {
+ //Nothing to do
+ }
+ }
+ pthread_mutex_unlock(&mMutex);
+}
+
+void CbsServerConnection::readMessageFromStackL()
+{
+ JELOG2(EWMA);
+ // Generate a message decoder
+ CJavaCbsDecoder* cbsDecoder = new CJavaCbsDecoder();
+ CleanupStack::PushL(cbsDecoder);
+
+ TCBSDataBuf messageData = decodeCbsMessageL(cbsDecoder , mBroadcastPageData);
+ // Filter the message based on the message Id
+ if (mCbsMessageId != mPort)
+ {
+ CleanupStack::PopAndDestroy(cbsDecoder);
+ User::LeaveIfError(KErrDoesNotMatchMessageId);
+ }
+
+ // Handle the possiblity of the message being a multipage message
+
+ if (mCbsTotalNumPages != 1)
+ {
+ // This is a part of a multipage message
+
+ // Get information about the message
+ TInt currentPage = mCbsPageNumber;
+ TUint messageCode = cbsDecoder->getMessageCode();
+
+ if (mCbsPartiallyReceived)
+ {
+ // check whether or not this is the same one of already received
+ // partial message.
+ if ((messageCode != mCbsMultipageMessageCode) ||(mCbsMessageId
+ != mCbsMultipageMessageId))
+ {
+ // This is a new message, so ignore the old one
+ // and setup for a new multipage message
+
+ mCbsMessagePagesData->Reset();
+ mCbsMessagePagesRef.Reset();
+ mPageCounter = 0;
+ mCbsPartiallyReceived = EFalse;
+ }
+ }
+ // Adding more data to a partially saved message
+
+ // For WCDMA messages, it is assumed that the pages will arrive
+ // in the correct order. mPageCounter is used to
+ // keep track of the current page number.
+ if (currentPage == KUnknownPageNumber)
+ {
+ currentPage = ++mPageCounter;
+ }
+ if (!mCbsPartiallyReceived)
+ {
+ // Start recording a new multipage message
+ mCbsReceivedPages = (1 << (currentPage - 1));
+ // Set some useful flags
+ mCbsMultipageMessageCode = messageCode;
+ mCbsMultipageMessageId = mCbsMessageId;
+ mCbsPartiallyReceived = ETrue;
+ }
+ // Store the received page number, such that the message can
+ // be reconstructed in the correct order later
+ mCbsMessagePagesRef.Append(currentPage);
+
+ // Store the actual content of the message
+ mCbsMessagePagesData->AppendL(messageData);
+
+ // Record which page has been received as a bitmask
+ mCbsReceivedPages |= (1 << (currentPage - 1));
+
+ // Check if all of the pages have been received
+ if (mCbsReceivedPages == ((static_cast<TUint>
+ (1 << mCbsTotalNumPages)) - 1))
+ {
+ // Have received all pages
+ mCbsMessageReceived = ETrue;
+ }
+ }
+ else
+ {
+ // This is a single-paged message
+
+ if (mCbsPartiallyReceived)
+ {
+ // Reset any existing partially stored multipage message
+ mCbsMessagePagesRef.Reset();
+ mCbsMessagePagesData->Reset();
+ mPageCounter = 0;
+ mCbsPartiallyReceived = EFalse;
+ }
+
+ mCbsMessageReceived = ETrue;
+ }
+ if (mCbsMessageReceived)
+ {
+ saveCbsMessageL(cbsDecoder->getEncoding(),messageData);
+ }
+ CleanupStack::PopAndDestroy(cbsDecoder);
+}
+
+TCBSDataBuf CbsServerConnection::decodeCbsMessageL(CJavaCbsDecoder* aDecoder,
+ const TDesC8& aData)
+{
+ JELOG2(EWMA);
+ TUint8 codingScheme =0;
+ TUint16 serialNum =0;
+ const TUint8* data = NULL;
+ //Check whether phone supports GSM/WCDMA
+ if (mBroadcastMsgAttributes.iFormat ==
+ RMobileBroadcastMessaging::EFormatGsmTpdu)
+ {
+ //Get the coding scheme as TUint8 from received cbs message
+ codingScheme = aData[KDataCodingSchemeIndex];
+ //Find the curent PageNumber & TotalNumPages from the message pageInfo.
+ aDecoder->findPageInfo(aData[KPageInfoIndex],mCbsPageNumber,
+ mCbsTotalNumPages);
+ serialNum = aData[KSerialNumberUpperpart] << 8;
+ serialNum = serialNum | aData[KSerialNumberLowerpart];
+ // Get the Message Identifier for GSM
+ mCbsMessageId = aData[KMessageIdUpperpart] << 8;
+ mCbsMessageId = mCbsMessageId | aData[KMessageIdLowerpart];
+ //Get the Message Data for decode without message Header
+ TInt len = aData.Length();
+ TPtrC8 cbsData = aData.Mid(KGsmHeaderSize, len - KGsmHeaderSize);
+ data = cbsData.Ptr();
+ }
+ else if (mBroadcastMsgAttributes.iFormat ==
+ RMobileBroadcastMessaging::EFormatWcdmaTpdu)
+ {
+ //Get the coding scheme as TUint8 from received cbs message
+ codingScheme = mBroadcastMsgAttributes.iDCS;
+ serialNum = mBroadcastMsgAttributes.iSerialNum;
+ // Get the Message Identifier for wcdma
+ mCbsMessageId = mBroadcastMsgAttributes.iMessageId;
+ //Find the curent PageNumber & TotalNumPages for the Cbs Message
+ mCbsTotalNumPages = mBroadcastMsgAttributes.iNumberOfPages;
+ mCbsPageNumber = KUnknownPageNumber;
+ data = aData.Ptr();
+ // Leave iff total number of messages is greater then Maximum number of
+ // pages supported .
+ if (mCbsTotalNumPages > KMaximumNumOfPages)
+ {
+ User::Leave(KErrGeneral);
+ }
+ }
+ else
+ {
+ //Others are not supported
+ User::Leave(KErrNotSupported);
+ }
+
+ //Find the message code of the cureent cbs message
+ aDecoder->findMessageCode(serialNum);
+
+ TCBSDataBuf cbsData;
+ //Decode the message
+ aDecoder->decodeMessageL((TPtrC8)data, cbsData,codingScheme,mFs);
+ return cbsData;
+}
+
+void CbsServerConnection::saveCbsMessageL(TSmsDataCodingScheme::TSmsAlphabet
+ aEncoding,TCBSDataBuf& aMessageData)
+{
+ JELOG2(EWMA);
+ TCBSParametersBuf cbsParams;
+
+ HBufC* multipageMessage = NULL;
+
+ if (!mCbsPartiallyReceived)
+ {
+ // Set the messageData size parameter
+ cbsParams().mDataSize = aMessageData.Size();
+
+ }
+ else
+ {
+ // The multipage cbs message may arrive in the incorrect order.
+ // Calculate the total length for reconstructed message
+ TInt totalLength = 0;
+ TUint index =1;
+ while (index <= mCbsTotalNumPages)
+ {
+ TInt pos = mCbsMessagePagesRef.FindL(index);
+ totalLength += (*mCbsMessagePagesData)[pos].Length();
+ index++;
+ }
+ // Create an buffer of sufficient size to hold the entire message
+ multipageMessage = HBufC::NewLC(totalLength);
+ TPtr multipagePtr = multipageMessage->Des();
+
+ // construct the multipage message
+ index =1;
+ while (index <= mCbsTotalNumPages)
+ {
+ TInt pos = mCbsMessagePagesRef.FindL(index);
+ multipagePtr.Append((*mCbsMessagePagesData)[pos]);
+ index++;
+ }
+ cbsParams().mDataSize = multipageMessage->Size();
+ }
+
+ // Set the message encoding scheme
+ cbsParams().mEncoding = aEncoding;
+
+ std::wstring path(mMessageStoreDirName);
+ char* messagePath = 0;
+ std::ofstream writeStream;
+ writeStream.exceptions(std::ofstream::failbit|std::ofstream::badbit);
+ try
+ {
+ path += JavaCommonUtils::intToWstring(mNextMessageInStore);
+ messagePath = JavaCommonUtils::wstringToUtf8(path);
+ writeStream.open(messagePath, std::ios::out | std::ios::binary);
+ writeStream.write((char*) cbsParams.Ptr(), cbsParams.Size());
+ if (mCbsPartiallyReceived)
+ {
+ // Write the generated message to the file
+ writeStream.write((char*) multipageMessage->Ptr(),
+ multipageMessage->Size());
+ }
+ else
+ {
+ // write the (single-paged) message
+ writeStream.write((char*) aMessageData.Ptr(), aMessageData.Size());
+ }
+ writeStream.close();
+ }
+ catch (std::ofstream::failure e)
+ {
+ ELOG(EWMA,"CBS : Exception while creating/writing file");
+ writeStream.exceptions(std::ofstream::goodbit);
+ writeStream.close();
+ User::Leave(KErrGeneral);
+ }
+ catch (ExceptionBase ex)
+ {
+ User::Leave(KErrGeneral);
+ }
+ delete[] messagePath;
+ if (mCbsPartiallyReceived)
+ {
+ // Cleanup the received multipage message
+ CleanupStack::PopAndDestroy(multipageMessage);
+ mCbsMessagePagesRef.Reset();
+ mCbsMessagePagesData->Reset();
+ mPageCounter = 0;
+ mCbsPartiallyReceived = EFalse;
+ }
+
+ if (mFirstMessageInStore == KErrNotFound)
+ {
+ mFirstMessageInStore = mNextMessageInStore;
+ }
+ mNextMessageInStore++;
+}
+
+} // end of namespace wma
+} // end of namespace java