--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/smsprotocols/smsstack/smsprot/Src/smsprov.cpp Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,1387 @@
+// Copyright (c) 2001-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:
+// Implements the CSmsProvider service access point (SAP) class.
+// Includes
+//
+//
+
+/**
+ @file
+*/
+
+#include "smsprot.h"
+
+#include <es_ver.h>
+#include <es_mbuf.h>
+
+#include "Gsmuelem.h"
+#include "gsmubuf.h"
+#include "Gsmumsg.h"
+
+#include "smsustrm.h"
+#include "smspmain.h"
+#include "smspfacadestor.h"
+
+// CSmsProvider policies
+//
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlDeleteSmsMessagePolicy,ECapabilityWriteUserData);
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlEnumerateSmsMessagesPolicy,ECapabilityReadUserData );
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlReadMessageSucceededPolicy,ECapabilityReadUserData );
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlReadMessageFailedPolicy,ECapabilityReadUserData );
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlSendSmsMessagePolicy,ECapabilityNetworkServices );
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlWriteSmsMessagePolicy,ECapabilityWriteUserData );
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlReadSmsParamsPolicy,ECapability_None );
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlCompleteReadSmsParamsPolicy,ECapability_None );
+static _LIT_SECURITY_POLICY_C1(smsProviderIoctlWriteSmsParamsPolicy,ECapabilityWriteDeviceData );
+
+// following not implemented as too paranoid
+//static _LIT_SECURITY_POLICY_C1(smsProviderIoctlSelectModemPresentPolicy,ECapabilityWriteDeviceData );
+//static _LIT_SECURITY_POLICY_C1(smsProviderIoctlSelectModemNotPresentPolicy,ECapabilityWriteDeviceData );
+static _LIT_SECURITY_POLICY_C1(smsProviderSetLocalNamePolicy,ECapabilityNetworkServices);
+static _LIT_SECURITY_POLICY_C1(smsProviderWritePolicy,ECapability_None);
+
+/**
+ * 2 Phase constructor.
+ *
+ * @param aProtocol a reference to the SMS protocol object.
+ * @leave Leaves if ContructL() leaves, or not enough memory is available.
+ * @return a new CSmsProvider object.
+ *
+ */
+CSmsProvider* CSmsProvider::NewL(CSmsProtocol& aProtocol)
+ {
+ LOGSMSPROT1("CSmsProvider::NewL");
+
+ CSmsProvider* self =new(ELeave) CSmsProvider(aProtocol);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+
+ LOGSMSPROT1("-> CSmsProvider::NewL - done");
+
+ return self;
+ }
+
+/**
+ * C'tor
+ *
+ * @param aProtocol a reference to the SMS protocol object.
+ */
+CSmsProvider::CSmsProvider(CSmsProtocol& aProtocol)
+: iProtocol(aProtocol),iEnumSocket(EFalse),iNumOfEnumeratedMessages(0)
+ {
+ }
+
+/**
+ * 2nd Phase of construction.
+ * Subscribes to the protocol as an observer, and creates our send and
+ * receive buffers.
+ *
+ */
+void CSmsProvider::ConstructL()
+ {
+ LOGSMSPROT1("CSmsProvider::ConstructL");
+
+ iProtocol.AddSmsMessageObserverL(*this);
+ SetObserverAddedToProtocol(ETrue);
+ iRecvBufSegArray=new(ELeave) CArrayPtrFlat<CBufSeg>(8);
+ iSendBufSeg = CBufSeg::NewL(KSmsMaxSegmentLength);
+
+ LOGSMSPROT1("-> CSmsProvider::ConstructL - done");
+ }
+
+/**
+ * D'tor
+ *
+ * Removes this SAP as an observer of the SMS protocol, and
+ * frees the send and receive buffers.
+ *
+ */
+CSmsProvider::~CSmsProvider()
+ {
+ if( ObserverAddedToProtocol() )
+ {
+ iProtocol.RemoveSmsMessageObserver(*this);
+ }
+ if( iRecvBufSegArray )
+ {
+ iRecvBufSegArray->ResetAndDestroy();
+ delete iRecvBufSegArray;
+ }
+ delete iSendBufSeg;
+ }
+
+/**
+ * Does nothing. Implementation of pure virtual CServProviderBase::Start().
+ *
+ */
+void CSmsProvider::Start()
+ {
+ LOGSMSPROT1("CSmsProvider::Start");
+ }
+
+/**
+ * Returns the local address of this SAP. Implementation of
+ * pure virtual CServProviderBase::LocalName().
+ *
+ */
+void CSmsProvider::LocalName(TSockAddr& aAddr) const
+ {
+ LOGSMSPROT1("CSmsProvider::LocalName");
+ aAddr = iLocalAddress;
+ }
+
+/**
+ * Sets the local address of this SAP by binding it to the protocol.
+ * The protocol ensures that there are no duplicate observers, and
+ * then calls back on the CSmsProvider::SetLocalAddress() method
+ * to set the address.
+ *
+ * Implementation of the pure virtual CServProviderBase::SetLocalName().
+ *
+ * @capability NetworkServices
+ */
+TInt CSmsProvider::SetLocalName(TSockAddr& aAddr)
+ {
+ LOGSMSPROT1("CSmsProvider::SetLocalName");
+
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderSetLocalNamePolicy,"CSmsProvider SetLocal Name policy check") != KErrNone) )
+ {
+ return KErrPermissionDenied;
+ }
+ TSmsAddr& smsAddr=static_cast<TSmsAddr&>(aAddr);
+ if( ( smsAddr.SmsAddrFamily() == ESmsAddrApplication8BitPort || smsAddr.SmsAddrFamily() == ESmsAddrApplication16BitPort ) && smsAddr.Port() == 0 )
+ {
+ if( !iProtocol.AllocateLocalAddress(smsAddr) )
+ {
+ return KErrInUse;
+ }
+ }
+ return iProtocol.BindSmsMessageObserver(*this,smsAddr);
+ }
+
+/**
+ * Called by the protocol to retrieve the remote name of the connection.
+ * This protocol is not connection oriented so this is not supported.
+ *
+ * Implementation of the pure virtual CServProviderBase::RemName().
+ *
+ */
+void CSmsProvider::RemName(TSockAddr& /*aAddr*/) const
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::RemName");
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called by the protocol to set the remote name of the connection.
+ * This protocol is not connection oriented so this is not supported.
+ *
+ * Implementation of the pure virtual CServProviderBase::SetRemName().
+ *
+ */
+TInt CSmsProvider::SetRemName(TSockAddr& /*aAddr*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::SetRemName");
+ return KErrNotSupported;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Returns the current value of an option setting for this SAP.
+ * No settings are currently defined.
+ * Implementation of pure virtual CServProviderBase::GetOption().
+ *
+ */
+TInt CSmsProvider::GetOption(TUint /*aLevel*/,TUint /*aName*/,TDes8& /*aOption*/) const
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::GetOption");
+ return 0;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called to perform specific IO control by the client. All of the SMS protocol
+ * services are provided through this interface.
+ *
+ * The local address of this SAP must already be bound, and only one ioctl request
+ * may be outstanding at any one time.
+ *
+ * A resulting socket error of KErrEof can result from a KErrNoMemory during a
+ * preceding write to the socket.
+ *
+ * Implementation of pure virtual CServProviderBase::Ioctl().
+ *
+ * @param aLevel the IOCTL level. Only KSolSmsProv is supported.
+ * @param aName the IOCTL name.
+ * @param aOption the IOCTL option.
+ *
+ */
+void CSmsProvider::Ioctl(TUint aLevel,TUint aName,TDes8* aOption)
+ {
+ LOGSMSPROT3("CSmsProvider::Ioctl [aLevel=%d, aName=%d]", aLevel, aName);
+ LOGSMSPROT2("CSmsProvider::Ioctl [provider=0x%08x]",this);
+
+ // Panic in debug mode if this call is invalid in this SAPs current state
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrUnbound,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ __ASSERT_DEBUG(!IoctlOutstanding(),SmspPanic(KSmspPanicIoctlAlreadyOutstanding));
+ // Gracefully handle invalid calls in release build
+ if( iLocalAddress.SmsAddrFamily()==ESmsAddrUnbound )
+ {
+ iSocket->Error(KErrNotReady,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ if( IoctlOutstanding() )
+ {
+ iSocket->Error(KErrInUse,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // General state is OK, now try to service the request
+ iName=aName;
+ switch( aLevel )
+ {
+ case KSolSmsProv:
+ {
+ switch( iName )
+ {
+ case KIoctlSupportOODClass0SmsMessages:
+ {
+ if( iProtocol.iReassemblyStore )
+ {
+ if( iProtocol.iReassemblyStore->IsSeparateClass0StoreSupported() )
+ {
+ iSocket->IoctlComplete(NULL);
+ }
+ else
+ {
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ }
+ }
+ else
+ {
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ }
+ } break;
+ case KIoctlSendSmsMessage:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlSendSmsMessagePolicy,"CSmsProvider Ioctl SendSmsMessage policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrLocalOperation,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ __ASSERT_DEBUG(aOption!=NULL,SmspPanic(KSmspPanicOptionBufferNull));
+ // Handle bad requests gracefully
+ if( iLocalAddress.SmsAddrFamily()==ESmsAddrLocalOperation )
+ {
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ if( aOption == NULL )
+ {
+ iSocket->Error(KErrArgument,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // Read message from socket
+ CSmsMessage* smsmessage=NULL;
+ TRAPD(ret,(smsmessage=InternalizeMessageL()));
+ if( ret!=KErrNone )
+ {
+ iSendBufSeg->Reset();
+ iSocket->Error(ret,MSocketNotify::EErrorIoctl);
+ }
+ else
+ {
+ // Pass the message to the protocol for sending
+ TPckgBuf<TUint> buf;
+ buf.Copy(*aOption);
+ SetIoctlOutstanding(ETrue);
+ iProtocol.SendSmsMessage(smsmessage,*this, buf());
+ }
+ } break;
+ case KIoctlEnumerateSmsMessages:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlEnumerateSmsMessagesPolicy, "CSmsProvider Ioctl EnumerateSmsMessages policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ // Handle bad requests gracefully
+ if( iLocalAddress.SmsAddrFamily()==ESmsAddrSendOnly )
+ {
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ return;
+ }
+
+ SetIoctlOutstanding(ETrue);
+ iProtocol.EnumeratePhone(*this);
+ } break;
+ case KIoctlWriteSmsMessage:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlWriteSmsMessagePolicy,"CSmsProvider IoctlWriteSmsMessage policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // Read message from the socket
+ CSmsMessage*smsmessage=NULL;
+ TRAPD(ret,(smsmessage=InternalizeMessageL()));
+ if( ret!=KErrNone )
+ {
+ iSendBufSeg->Reset();
+ iSocket->Error(ret,MSocketNotify::EErrorIoctl);
+ }
+ else
+ {
+ // Pass message to the protocol for writing
+ SetIoctlOutstanding(ETrue);
+ iProtocol.WriteSmsMessage(smsmessage,*this);
+ }
+ } break;
+ case KIoctlDeleteSmsMessage:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlDeleteSmsMessagePolicy,"CSmsProvider Ioctl DeleteSmsMessage policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ // Handle bad requests gracefully
+ if( iLocalAddress.SmsAddrFamily()==ESmsAddrSendOnly )
+ {
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // Read message from the socket
+ CSmsMessage*smsmessage=NULL;
+ TRAPD(ret,(smsmessage=InternalizeMessageL()));
+ if( ret!=KErrNone )
+ {
+ LOGSMSPROT2("-> CSmsProvider::Ioctl - CSmsProvider::InternalizeMessageL [ret=%d]", ret);
+ iSendBufSeg->Reset();
+ iSocket->Error(ret, MSocketNotify::EErrorIoctl);
+ }
+ else
+ {
+ // Pass request to protocol
+ SetIoctlOutstanding(ETrue);
+ iProtocol.DeleteSmsMessage(smsmessage,*this);
+ }
+ } break;
+ case KIoctlReadMessageSucceeded:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlReadMessageSucceededPolicy,"CSmsProvider Ioctl ReadMessageSucceeded policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ __ASSERT_DEBUG(NumSegments(iSegmentIndex==NumSegments(iRecvBufSegArray->At(0)->Size())),SmspPanic(KSmspPanicBadClientIoctlCall));
+ // TODO - flag
+ // i) delete entry from reassemblystore
+ // smsmsg = MyInternalize( iRecvBufSegArray );
+ // iReasStore->GetIndex( Index, smsmsg ); // iReasStore->DeleteSMS(smsmsg);
+ // iReasStore->DeleteEntry( Index );
+ // ii) looking for more sms left in the store
+ // iPotocol.ProcessCompleteSMSMessage();
+ // @note if this is only called from here the msg stay for a long time
+ // in the reassembly store if the processmessage fails
+ // i)
+ CSmsMessage*smsmessage=NULL;
+ TRAPD(ret,(smsmessage=InternalizeMessageL(iRecvBufSegArray->At(0))));
+ if( ret==KErrNone )
+ {
+ TRAP(ret,(iProtocol.DeleteSMSFromReaStoreL( *smsmessage )));
+ LOGSMSPROT2("-> CSmsProvider::Ioctl - CSmsProvider::DeleteSMSFromReaStoreL [ret=%d]", ret);
+ }
+ else
+ {
+ LOGSMSPROT2("-> CSmsProvider::Ioctl - CSmsProvider::InternalizeMessageL [ret=%d]", ret);
+ }
+ delete smsmessage;
+ // ii)
+ // this is now down after finishing the readprocess
+ // it has to be called here o in pdureadprocescompleted???
+ iProtocol.MessageReadedSuccessfully();
+ if( iEnumSocket )
+ {
+ --iNumOfEnumeratedMessages;
+ LOGSMSPROT2("-> CSmsProvider::Ioctl - [iNumOfEnumeratedMessages=%d]", iNumOfEnumeratedMessages);
+ if( iNumOfEnumeratedMessages <= 0 )
+ {
+ iProtocol.iPhoneEnumerationObserver=NULL;
+ iEnumSocket=EFalse;
+ iProtocol.MessageReadedSuccessfully();
+ LOGSMSPROT1("-> CSmsProvider::Ioctl - [iNumOfEnumeratedMessages=NULL]");
+ }
+ }
+ // Remove the message from the receive buffer & complete
+ delete iRecvBufSegArray->At(0);
+ iRecvBufSegArray->At(0) = NULL;
+ iRecvBufSegArray->Delete(0);
+
+ iSegmentIndex=0;
+ iSocket->IoctlComplete(NULL);
+ } break;
+ case KIoctlReadMessageFailed:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlReadMessageFailedPolicy,"CSmsProvider Ioctl ReadMessageFailed policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ __ASSERT_DEBUG(NumSegments(iSegmentIndex<=NumSegments(iRecvBufSegArray->At(0)->Size())),SmspPanic(KSmspPanicBadClientIoctlCall));
+ // Handle bad requests gracefully
+ if( iLocalAddress.SmsAddrFamily()==ESmsAddrSendOnly )
+ {
+ if( iEnumSocket )
+ {
+ --iNumOfEnumeratedMessages;
+ if( iNumOfEnumeratedMessages <= 0 )
+ {
+ iProtocol.iPhoneEnumerationObserver=NULL;
+ LOGSMSPROT1("-> CSmsProvider::Ioctl - fail [iNumOfEnumeratedMessages=NULL]");
+ iEnumSocket=EFalse;
+ iProtocol.MessageReadedSuccessfully();
+ }
+ }
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // Re-notify the socket that data is available, reset the segment
+ // index of the current message back to the start & complete
+ iSocket->NewData(iSegmentIndex);
+ iSegmentIndex=0;
+ iSocket->IoctlComplete(NULL);
+ } break;
+ case KIoctlReadSmsParams:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlReadSmsParamsPolicy,"CSmsProvider Ioctl ReadSmsParams policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // Handle bad requests gracefully
+ if( iLocalAddress.SmsAddrFamily()!=ESmsAddrLocalOperation )
+ {
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ return;
+ }
+
+ // Pass request on to the protocol
+ SetIoctlOutstanding(ETrue);
+ iProtocol.ReadSmsParameters(*this);
+ } break;
+ case KIoctlCompleteReadSmsParams:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlCompleteReadSmsParamsPolicy,"CSmsProvider Ioctl CompleteReadSmsParams policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ __ASSERT_DEBUG(NumSegments(iSegmentIndex==NumSegments(iRecvBufSegArray->At(0)->Size())),SmspPanic(KSmspPanicBadClientIoctlCall));
+ // Handle bad requests gracefully
+ if ( iLocalAddress.SmsAddrFamily()==ESmsAddrSendOnly )
+ {
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // Remove the parameter list from the receive buffer & complete
+ delete iRecvBufSegArray->At(0);
+ iRecvBufSegArray->At(0) = NULL;
+ iRecvBufSegArray->Delete(0);
+ iSegmentIndex=0;
+ iSocket->IoctlComplete(NULL);
+ } break;
+ case KIoctlWriteSmsParams:
+ {
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderIoctlWriteSmsParamsPolicy,"CSmsProvider Ioctl WriteSmsParams policy check") != KErrNone) )
+ {
+ iSocket->Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ // Read parameters from the socket
+ CMobilePhoneSmspList*mobilePhoneSmspList=NULL;
+ TRAPD(ret,(mobilePhoneSmspList=InternalizeParametersL()));
+ if( ret!=KErrNone )
+ {
+ iSendBufSeg->Reset();
+ iSocket->Error(ret,MSocketNotify::EErrorIoctl);
+ }
+ else
+ {
+ // Pass parameters to the protocol for writing.
+ // CSmsWriteParams takes ownership of mobilePhoneSmspList.
+ SetIoctlOutstanding(ETrue);
+ iProtocol.WriteSmsParameters(mobilePhoneSmspList, *this);
+ }
+ } break;
+ default:
+ {
+ // Panic in debug build
+ __ASSERT_DEBUG(EFalse,SmspPanic(KSmspUndefinedName));
+ // Error gracefully in release build
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ } break;
+ }
+ } break;
+ default:
+ {
+ // Unsupported ioctl level, panic in debug build
+ __ASSERT_DEBUG(EFalse,SmspPanic(KSmspUndefinedLevel));
+ // Gracefully error in release build
+ iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ } break;
+ }
+ }
+
+/**
+ * Cancels an outstanding ioctl.
+ * Since there can only be a single ioctl request outstanding, the parameters
+ * must match those of the original request.
+ * Implementation of the pure virtual CServProviderBase::CancelIoctl().
+ *
+ * @param aLevel the level of the ioctl request to cancel.
+ * @param aName the name of the ioctl request to cancel.
+ *
+ */
+void CSmsProvider::CancelIoctl(TUint aLevel, TUint aName)
+ {
+ LOGSMSPROT3("CSmsProvider::CancelIoctl [aLevel=%d, aName=%d]", aLevel, aName);
+
+ // Panic in debug mode if this call is invalid in this SAPs current state
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrUnbound,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ __ASSERT_DEBUG(iName==aName,SmspPanic(ESmspBadIoctlName));
+ if( iName != aName )
+ {
+ return;
+ }
+ switch( aLevel )
+ {
+ case KSolSmsProv:
+ {
+ // Request cancel via protocol
+ switch( iName )
+ {
+ case KIoctlSendSmsMessage:
+ {
+ iProtocol.CancelSendSmsMessage(*this);
+ } break;
+ case KIoctlEnumerateSmsMessages:
+ {
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ iProtocol.CancelEnumeratePhone(*this);
+ iEnumSocket=EFalse;
+ iProtocol.iPhoneEnumerationObserver=NULL;
+ LOGSMSPROT1("-> CSmsProvider::CancelIoctl - [iNumOfEnumeratedMessages=NULL]");
+ } break;
+ case KIoctlWriteSmsMessage:
+ {
+ iProtocol.CancelWriteSmsMessage(*this);
+ } break;
+ case KIoctlDeleteSmsMessage:
+ {
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ iProtocol.CancelDeleteSmsMessage(*this);
+ } break;
+ case KIoctlReadMessageSucceeded:
+ case KIoctlReadMessageFailed:
+ {
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+ } break;
+ case KIoctlReadSmsParams:
+ {
+ iProtocol.CancelReadSmsParams();
+ } break;
+ case KIoctlWriteSmsParams:
+ {
+ iProtocol.CancelWriteSmsParams();
+ } break;
+ default:
+ {
+ __ASSERT_DEBUG(EFalse,SmspPanic(KSmspUndefinedName));
+ } break;
+ }
+ } break;
+ default:
+ {
+ __ASSERT_DEBUG(EFalse,SmspPanic(KSmspUndefinedLevel));
+ } break;
+ }
+ }
+
+/**
+ * Sets an option on the SAP. No options are currently implemented.
+ *
+ * Implements the pure virtual CServProviderBase::SetOption().
+ *
+ */
+TInt CSmsProvider::SetOption(TUint /*aLevel*/,TUint /*aName*/,const TDesC8& /*aOption*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::SetOption()");
+ return 0;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called by the socket server to write data into the send queue.
+ * The data is a single segment of a serialized SMS message.
+ *
+ * A KErrNoMemory condition arising in this write will not be reported directly (due to
+ * the ESOCK design), instead it will be reflected in a KErrEof from the subsequent Ioctl()
+ * call.
+ *
+ * Implementation of the pure virtual CServProviderBase::Write().
+ *
+ * @param aBufChain the data to write into the send buffer.
+ * @param aOptions not used.
+ * @param aAddr not used.
+ * @return 1 (datagram written) on success, otherwise an error.
+ *
+ * @capability None
+ */
+TInt CSmsProvider::Write(RMBufChain& aBufChain, TUint /*aOptions*/, TSockAddr* /*aAddr*/)
+ {
+ LOGSMSPROT1("CSmsProvider::Write");
+
+ if( !iSecurityChecker || (iSecurityChecker->CheckPolicy(smsProviderWritePolicy,"CSmsProvider Write policy check") != KErrNone) )
+ {
+ return KErrPermissionDenied;
+ }
+ __ASSERT_DEBUG(iLocalAddress.SmsAddrFamily()!=ESmsAddrUnbound,SmspPanic(KSmspPanicWrongSmsAddressFamily));
+
+ /// @note: LOGIFH2A2 macro for logging esock write
+ LOGSMSPROT2("-> CSmsProvider::Write [%d bytes]", aBufChain.Length());
+#ifdef SMSLOGGERIF
+ HBufC8* debugBuf = HBufC8::New(aBufChain.Length());
+ if(debugBuf)
+ {
+ TPtr8 debugData = debugBuf->Des();
+ aBufChain.CopyOut(debugData);
+ LOGIF2(_L8("ESOCK WRITE: %S"),&debugData);
+ LOGIFH2A2(_L8("ESOCK WRITE: "),debugData);
+ delete debugBuf;
+ }
+#endif
+
+ TUint bytesCopied = 0;
+ // Append all of the mbufs to the send buffer
+ TInt ret = KErrNone;
+ TMBufIter iter(aBufChain);
+ while( iter.More() )
+ {
+ RMBuf* p = iter++;
+ TRAP(ret, iSendBufSeg->InsertL(iSendBufSeg->Size(), p->Ptr(), p->Length()));
+ if(ret != KErrNone)
+ break;
+ bytesCopied += p->Length();
+ }
+ if( ret != KErrNone )
+ {
+ iSendBufSeg->Reset(); // it has always done this, but won't innocent data get zapped?
+ }
+ else
+ {
+ aBufChain.Free(); // we accepted it all; flag these by consuming all buffers
+ }
+ return (ret == KErrNone)? 1: ret;
+ }
+
+/**
+ * Called by the socket server to retrieve data that this SAP has indicated
+ * is waiting in its buffers.
+ *
+ * Implentation of the pure virtual CServProviderBase::GetData().
+ *
+ * Once the provider has indicated new data is available using
+ * MSocketNotify::NewData(), the socket server will call on this method
+ * to retrieve the serialized SMS message in segments.
+ * Once the sockets client has streamed out the entire message, it
+ * will call on ioctl with KIoctlReadMessageSucceeded which resets the internal
+ * counters.
+ *
+ * @param aBufChain the buffer to insert the data.
+ * @param aLength not used.
+ * @param aOptions not used.
+ * @param aAddr not used.
+ * @return 1 (datagram read) on success, otherwise an error.
+ *
+ */
+TInt CSmsProvider::GetData(RMBufChain& aBufChain, TUint /*aLength*/, TUint /*aOptions*/, TSockAddr* /*aAddr*/)
+ {
+ __ASSERT_DEBUG((iLocalAddress.SmsAddrFamily()!=ESmsAddrUnbound) && (iLocalAddress.SmsAddrFamily()!=ESmsAddrSendOnly),SmspPanic(KSmspPanicWrongSmsAddressFamily));
+
+ LOGSMSPROT2("CSmsProvider::GetData [provider=0x%08x]", this);
+
+ // Get the segmented buffer of first message
+ CBufSeg* recvbufseg=iRecvBufSegArray->At(0);
+ TInt size=recvbufseg->Size();
+ __ASSERT_DEBUG(iSegmentIndex<NumSegments(size),SmspPanic(KSmspPanicBadClientMessageRead));
+
+ // Caculate the position of the next segment of the serialized message,
+ // insert into the buffer parameter and update our segment counter
+ TInt pos=iSegmentIndex*KSmsMaxSegmentLength;
+ TInt length = pos+KSmsMaxSegmentLength>size? size-pos: KSmsMaxSegmentLength;
+
+ TRAPD(err, aBufChain.AllocL(length));
+ if( err == KErrNone )
+ {
+ // For want of a segmented buffer copy for Mbufs we have a little loop. Because we're
+ // reading consecutive data out of the CBufSeg there shouldn't be a bad performance hit
+ // (see CBufSeg::Ptr() doco; CBufBase::Read() uses this)
+ TInt segPos = 0;
+ TMBufIter iter(aBufChain);
+ while( segPos < length )
+ {
+ RMBuf* p = iter++;
+ TInt readSize = Min(p->Size(), length - segPos);
+ recvbufseg->Read(pos + segPos, p->Buffer(), readSize);
+ segPos += readSize;
+ }
+ }
+ else if( err == KErrNoMBufs )
+ {
+ return KErrNoMBufs; // ask ESock to call us back when some buffers are free
+ }
+ else
+ {
+ iSocket->Error(err, MSocketNotify::EErrorRecv);
+ }
+ ++iSegmentIndex;
+ return 1; // datagrams are counted as atoms not bytes
+ }
+
+/**
+ * Called by the socket server to indicate the provider should connect to
+ * a peer. Not a connection oriented protocol so this is not implemented.
+ *
+ * Implementation of the pure virtual CServProviderBase::ActiveOpen().
+ *
+ */
+void CSmsProvider::ActiveOpen()
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::ActiveOpen [does nothing]");
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called by the socket server to indicate the provider should connect to
+ * a peer. Not a connection oriented protocol so this is not implemented.
+ *
+ * Implementation of the pure virtual CServProviderBase::ActiveOpen().
+ *
+ */
+void CSmsProvider::ActiveOpen(const TDesC8& /*aConnectionData*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::ActiveOpen [does nothing]");
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called by the socket server to indicate the provider should wait for an
+ * incoming client connection request. Not a connection oriented protocol
+ * so this is not implemented.
+ *
+ * Implementation of the pure virtual CServiceProviderBase::PassiveOpen().
+ *
+ */
+TInt CSmsProvider::PassiveOpen(TUint /*aQueSize*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::PassiveOpen [not supported]");
+ return KErrNotSupported;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called by the socket server to indicate the provider should wait for an
+ * incoming client connection request. Not a connection oriented protocol
+ * so this is not implemented.
+ *
+ * Implementation of the pure virtual CServiceProviderBase::PassiveOpen().
+ *
+ */
+TInt CSmsProvider::PassiveOpen(TUint /*aQueSize*/,const TDesC8& /*aConnectionData*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::PassiveOpen [not supported]");
+ return KErrNotSupported;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called by the socket server to shutdown a connection.
+ *
+ * Implementation of the pure virtual CServProviderBase::Shutdown().
+ *
+ */
+void CSmsProvider::Shutdown(TCloseType aOption)
+ {
+ LOGSMSPROT2("CSmsProvider::Shutdown [aOption=%d]", aOption);
+
+ TInt messagesInBuffer = iRecvBufSegArray->Count();
+ for( TInt index = 0; index < messagesInBuffer; ++index )
+ {
+ // Read message from the socket
+ CSmsMessage*smsmessage=NULL;
+ TRAPD(ret,(smsmessage=InternalizeMessageL(iRecvBufSegArray->At(index))));
+ if( ret == KErrNone )
+ {
+ TRAP(ret, (iProtocol.iReassemblyStore->SetMessagePassedToClientL(*smsmessage, EFalse)));
+ LOGSMSPROT2("-> CSmsProvider::Shutdown - SetMessagePassedToClientL [ret=%d]", ret);
+ }
+ else
+ {
+ LOGSMSPROT2("-> CSmsProvider::Shutdown - CSmsProvider::InternalizeMessageL leave [ret=%d]", ret);
+ }
+ delete smsmessage;
+ }
+
+ if( iEnumSocket && iProtocol.iPhoneEnumerationObserver == this )
+ {
+ iEnumSocket=EFalse;
+ iProtocol.iPhoneEnumerationObserver=NULL;
+ }
+ if( ObserverAddedToProtocol() )
+ {
+ iProtocol.CancelSendSmsMessage(*this);
+ }
+ if( aOption!=CServProviderBase::EImmediate )
+ {
+ iSocket->CanClose();
+ }
+ }
+
+/**
+ * Called by the socket server to shutdown a connection. Simply calls
+ * the single parameter version shutdown method.
+ *
+ * Implementation of the pure virtual CServProviderBase::Shutdown().
+ *
+ */
+void CSmsProvider::Shutdown(TCloseType aOption, const TDesC8& /*aDisconnectionData*/)
+ {
+ LOGSMSPROT1("CSmsProvider::Shutdown");
+ Shutdown(aOption);
+ }
+
+/**
+ * Called by the socket server to indicate the provider should choose
+ * a local address and bind to it. Not supported by this protocol.
+ *
+ * Implementation of the pure virtual CServProviderBase::AutoBind().
+ *
+ */
+void CSmsProvider::AutoBind()
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProvider::AutoBind [does nothing]");
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Called by the SMS protocol to obtain the local address of this SAP.
+ *
+ * @return the local address of this SAP.
+ *
+ */
+const TSmsAddr& CSmsProvider::GetLocalAddress() const
+ {
+ LOGSMSPROT1("CSmsProvider::GetLocalAddress");
+ return iLocalAddress;
+ }
+
+/**
+ * Called by the SMS protocol to bind a local address to this SAP.
+ *
+ */
+void CSmsProvider::SetLocalAddress(const TSmsAddr& aSmsAddr)
+ {
+ LOGSMSPROT1("CSmsProvider::SetLocalAddress");
+ iLocalAddress = aSmsAddr;
+ }
+
+/**
+ * Called by the protocol when the modem connection state has changed.
+ * Notifies any standard KIoctlSelect requests of this event.
+ *
+ * @param aStatus either KIoctlSelectModemPresent or KIoctlSelectModemNotPresent.
+ *
+ */
+void CSmsProvider::ModemNotificationCompleted(TInt aStatus)
+ {
+ LOGSMSPROT2("CSmsProvider::ModemNotificationCompleted [aStatus=%d]", aStatus);
+
+ if( !IoctlOutstanding() )
+ {
+ iSocket->Error(aStatus,MSocketNotify::EErrorIoctl);
+ }
+ }
+
+/**
+ * Called by the protocol when a message send request made by this
+ * SAP has completed.
+ *
+ * @param aStatus the result of the send.
+ *
+ */
+void CSmsProvider::MessageSendCompleted(TInt aStatus)
+ {
+ LOGSMSPROT2("CSmsProvider::MessageSendCompleted [aStatus=%d]", aStatus);
+
+ iSocket->Error(aStatus,MSocketNotify::EErrorIoctl);
+ SetIoctlOutstanding(EFalse);
+ }
+
+/**
+ * Called by the protocol when a message has been received for this SAP.
+ *
+ * @param aSmsMessage the received message.
+ * @return KErrNone if the message was serialized to the receive buffer successfully.
+ *
+ */
+TInt CSmsProvider::MessageReceived(const CSmsMessage& aSmsMessage,TDes& /*aDes*/)
+ {
+ LOGSMSPROT1("CSmsProvider::MessageReceived");
+
+ // Attempt to serial the message to the receive buffer & notify
+ // the socket of the new data
+ TInt numnewsegments=0;
+ TRAPD(ret,(numnewsegments=ExternalizeMessageL(aSmsMessage,ETrue)));
+ if( ret==KErrNone )
+ {
+ iSocket->NewData(numnewsegments);
+ }
+ return ret;
+ }
+
+/**
+ * Informs protocol whether client confirms received message
+ */
+TBool CSmsProvider::ClientConfirmsMessage() const
+ {
+ LOGSMSPROT1("CSmsProvider::ClientConfirmsMessage");
+
+ return ETrue;
+ }
+
+/**
+ * Informs protocol whether address is ued by the observer
+ */
+TInt CSmsProvider::SmsAddrIsDuplicate(const MSmsMessageObserver* aObserver, const TSmsAddr& aAddr) const
+ {
+ LOGSMSPROT1("CSmsProvider::SmsAddrIsDuplicate");
+
+ if( this == aObserver )
+ {
+ return EFalse;
+ }
+ return iLocalAddress==aAddr;
+ }
+
+/**
+ * Called by the protocol when an enumeration of the phone's message stores
+ * requested by this SAP has completed.
+ *
+ * @param aStatus the result of the enumeration.
+ *
+ */
+void CSmsProvider::EnumeratePhoneCompleted(TInt aStatus)
+ {
+ LOGSMSPROT2("CSmsProvider::EnumeratePhoneCompleted [aStatus=%d]", aStatus);
+
+ // Attempt to serialize all enumerated messages to the receive buffer
+ TInt numnewsegments=0;
+ TInt count=0;
+ if( aStatus==KErrNone )
+ {
+ // Save current message count in case we need to rollback on error
+ TInt nummessages=iRecvBufSegArray->Count();
+ TRAP(aStatus, (numnewsegments=ExternalizeEnumeratedMessagesL(count)));
+ if( aStatus==KErrNone )
+ {
+ // Success, obtain the message count and notify socket of the new data
+ if( numnewsegments>0 )
+ {
+ iSocket->NewData(numnewsegments);
+ }
+ }
+ else
+ {
+ // Error, rollback the messages we added
+ for( TInt i=(iRecvBufSegArray->Count()-nummessages)-1; i>=0; i-- )
+ {
+ delete iRecvBufSegArray->At(i);
+ iRecvBufSegArray->Delete(i);
+ }
+ }
+ }
+ // On success, complete with the count of messages enumerated
+ if( aStatus==KErrNone )
+ {
+ TPckgBuf<TInt> buf;
+ buf()=count;
+ if( count>0 )
+ {
+ iEnumSocket=ETrue;
+ }
+ else
+ {
+ iEnumSocket=EFalse;
+ iProtocol.iPhoneEnumerationObserver=NULL;
+ }
+ iNumOfEnumeratedMessages=count;
+ iSocket->IoctlComplete(&buf);
+ }
+ else
+ {
+ iEnumSocket=EFalse;
+ if( iProtocol.iPhoneEnumerationObserver == this)
+ {
+ iProtocol.iPhoneEnumerationObserver=NULL;
+ }
+ iSocket->Error(aStatus,MSocketNotify::EErrorIoctl);
+ }
+ SetIoctlOutstanding(EFalse);
+ }
+
+/**
+ * Called by the protocol when a request to write a message to
+ * a phone store by this SAP has completed.
+ * Implements the pure virtual MSmsMessageObserver::MessageWriteCompleted().
+ *
+ * @param aStatus the result of the write operation.
+ *
+ */
+void CSmsProvider::MessageWriteCompleted(TInt aStatus, const CSmsMessage* aSmsMessage)
+ {
+ LOGSMSPROT2("CSmsProvider::MessageWriteCompleted [aStatus=%d]", aStatus);
+
+ // If no errors at present populate the buffer
+ if( aStatus == KErrNone )
+ {
+ TRAP(aStatus, (PopulateBufferWithPDUSlotsL(*aSmsMessage)));
+ }
+ if( aStatus != KErrNone )
+ {
+ iSocket->Error(aStatus,MSocketNotify::EErrorIoctl);
+ }
+ SetIoctlOutstanding(EFalse);
+ } // CSmsProvider::MessageWriteCompleted
+
+
+/**
+ * Create and populate a buffer containing store type and PDU slot indexes
+ *
+ * @param aSmsMessage the message containing the slot information.
+ *
+ */
+void CSmsProvider::PopulateBufferWithPDUSlotsL(const CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CSmsProvider::PopulateBufferWithPDUSlotsL");
+
+ // Create buffer for store id and PDU slot indexes based on size of slot array
+
+ HBufC8* buf = HBufC8::NewL(aSmsMessage.iSlotArray.Count()+1 * sizeof(TUint));
+ buf->Des().Append(aSmsMessage.Storage());
+
+ TInt count = aSmsMessage.iSlotArray.Count();
+ for( TInt index=0; index<count; ++index )
+ {
+ buf->Des().Append(aSmsMessage.iSlotArray[index].iIndex);
+ }
+
+ TPtr8 textBufPtr(buf->Des());
+
+ iSocket->IoctlComplete(&textBufPtr);
+ delete buf;
+
+ LOGSMSPROT1("-> CSmsProvider::PopulateBufferWithPDUSlotsL - done");
+ }
+
+/**
+ * Called by the protocol when a request to delete a message from
+ * a phone store by this SAP has completed.
+ * Implements the pure virtual MSmsMessageObserver::MessageDeleteCompleted().
+ *
+ * @param aStatus the result of the deletion.
+ *
+ */
+void CSmsProvider::MessageDeleteCompleted(TInt aStatus)
+ {
+ LOGSMSPROT2("CSmsProvider::MessageDeleteCompleted [aStatus=%d]", aStatus);
+ iSocket->Error(aStatus,MSocketNotify::EErrorIoctl);
+ SetIoctlOutstanding(EFalse);
+ }
+
+/**
+ * Called by the CSmsReadParams object when a read all SMS parameter sets
+ * requested by this SAP has completed.
+ *
+ * @param aStatus the result of the read operation.
+ * @param aSmspList SMS parameter list
+ *
+ */
+void CSmsProvider::ReadSmsParamsCompleted(TInt aStatus, CMobilePhoneSmspList* aSmspList)
+ {
+ LOGSMSPROT2("CSmsProvider::ReadSmsParamsCompleted [aStatus=%d]", aStatus);
+
+ TInt numNewSegments=0;
+
+ if( aStatus == KErrNone )
+ {
+ // Attempt to serial the parameters to the receive buffer & notify
+ // the socket of the new data
+ __ASSERT_DEBUG(aSmspList != NULL,SmspPanic(KSmspPanicParameterBufferNull));
+ TRAP(aStatus,(numNewSegments=ExternalizeParametersL(*aSmspList)));
+ }
+ if( aStatus == KErrNone )
+ {
+ iSocket->NewData(numNewSegments);
+ TPckgBuf<TInt> buf;
+ buf()=1;
+ iSocket->IoctlComplete(&buf);
+ }
+ else
+ {
+ iSocket->Error(aStatus,MSocketNotify::EErrorIoctl);
+ }
+ SetIoctlOutstanding(EFalse);
+ }
+
+/**
+ * Called by the CSmsWriteParams object when a request to write SMS
+ * parameters to a phone store by this SAP has completed.
+ *
+ * @param aStatus the result of the write operation.
+ *
+ */
+void CSmsProvider::WriteSmsParamsCompleted(TInt aStatus)
+ {
+ LOGSMSPROT2("CSmsProvider::WriteSmsParamsCompleted [aStatus=%d]", aStatus);
+ iSocket->Error(aStatus,MSocketNotify::EErrorIoctl);
+ SetIoctlOutstanding(EFalse);
+ }
+
+/**
+ * Internal function called after a phone store enumeration request to
+ * serialize the messages to the receive buffer.
+ *
+ * @leave Leaves if any individual ExternalizeMessageL() call leaves.
+ * @return the total number of segments the messages were split into.
+ *
+ */
+TInt CSmsProvider::ExternalizeEnumeratedMessagesL(TInt& aCount)
+ {
+ LOGSMSPROT1("CSmsProvider::ExternalizeEnumeratedMessagesL");
+
+ TInt numnewsegments(0);
+ numnewsegments=iProtocol.ExternalizeEnumeratedMessagesL(*this,aCount);
+
+ LOGSMSPROT1("-> CSmsProvider::ExternalizeEnumeratedMessagesL - done");
+
+ return numnewsegments;
+ }
+
+/**
+ * Internal function used to serialize a message into the receive buffer.
+ * Each serialized message is split into smaller segments which form the
+ * basic unit of data passed back to the socket server in the GetData() method.
+ *
+ * @param aSmsMessage the message to serialize.
+ * @param aAppend specifies whether the message is inserted at the start or end of the buffer.
+ * @leave Leaves if the message could not be serialized or inserted into the buffer.
+ * @return the number of segments the message was split into.
+ *
+ */
+TInt CSmsProvider::ExternalizeMessageL(const CSmsMessage& aSmsMessage,TBool aAppend)
+ {
+ LOGSMSPROT1("CSmsProvider::ExternalizeMessageL()");
+
+ // Create a new segmented buffer for the serialization of this message
+ CBufSeg* recvbufseg = CBufSeg::NewL(KSmsMaxSegmentLength);
+ CleanupStack::PushL(recvbufseg);
+
+ // Attempt to serialize this message into the buffer
+ RBufWriteStream writestream(*recvbufseg);
+ writestream.Open(*recvbufseg);
+ CleanupClosePushL(writestream);
+ writestream << aSmsMessage;
+
+ // Append / insert this buffer at the end / start of the other serialized message buffers
+ if( aAppend )
+ {
+ iRecvBufSegArray->AppendL(recvbufseg);
+ }
+ else
+ {
+ iRecvBufSegArray->InsertL(0,recvbufseg);
+ }
+ CleanupStack::PopAndDestroy(); // writestream
+ CleanupStack::Pop(); // recvbufseg
+
+ LOGSMSPROT1("-> CSmsProvider::ExternalizeMessageL - done");
+
+ return NumSegments(recvbufseg->Size());
+ }
+
+/**
+ * Internal function to deserialize a message from the send buffer.
+ * Each serialized message is split into smaller segments which form the basic
+ * unit of data passed to this SAP from the socket server in the Write() method.
+ *
+ * @leave Leaves if the message could not be de-serialized.
+ * @return the de-serialized CSmsMessage object.
+ *
+ */
+CSmsMessage* CSmsProvider::InternalizeMessageL()
+ {
+ LOGSMSPROT1("CSmsProvider::InternalizeMessageL()");
+
+ // Initialize the read stream with the buffer
+ RBufReadStream readstream(*iSendBufSeg);
+ readstream.Open(*iSendBufSeg,0);
+ CleanupClosePushL(readstream);
+
+ // Create a buffer and message to store the result
+ CSmsBufferBase* buffer = CSmsBuffer::NewL();
+ CSmsMessage* smsmessage= CSmsMessage::NewL(iProtocol.FileSession(), CSmsPDU::ESmsDeliver,buffer);
+ CleanupStack::PushL(smsmessage);
+
+ // De-serialize the message from using the read stream
+ readstream >> *smsmessage;
+
+ CleanupStack::Pop(); // smsmessage
+ CleanupStack::PopAndDestroy(); // readstream
+ iSendBufSeg->Reset();
+
+ LOGSMSPROT1("-> CSmsProvider::InternalizeMessageL - done");
+
+ return smsmessage;
+ }
+
+/**
+ * Internal function used to serialize SMS parameters into the receive buffer.
+ * Each serialized parameter object is split into smaller segments which form the
+ * basic unit of data passed back to the socket server in the GetData() method.
+ *
+ * @param aMobilePhoneSmspList the parameters to serialize.
+ * @leave Leaves if the parameters could not be serialized or inserted into the buffer.
+ * @return the number of segments the parameters was split into.
+ *
+ */
+TInt CSmsProvider::ExternalizeParametersL(const CMobilePhoneSmspList& aMobilePhoneSmspList)
+ {
+ LOGSMSPROT1("CSmsProvider::ExternalizeParametersL");
+
+ // Create a new segmented buffer for the serialization of this message
+ CBufSeg* recvBufSeg = CBufSeg::NewL(KSmsMaxSegmentLength);
+ CleanupStack::PushL(recvBufSeg);
+
+ // Attempt to serialize this message into the buffer
+ RBufWriteStream writeStream(*recvBufSeg);
+ writeStream.Open(*recvBufSeg);
+ CleanupClosePushL(writeStream);
+ writeStream << aMobilePhoneSmspList;
+ writeStream.CommitL();
+
+ // Append start of the other serialized message buffers
+ CleanupStack::PopAndDestroy(); //writeStream
+ iRecvBufSegArray->InsertL(0,recvBufSeg);
+ CleanupStack::Pop(recvBufSeg);
+
+ LOGSMSPROT1("-> CSmsProvider::ExternalizeParametersL - done");
+
+ return NumSegments(recvBufSeg->Size());
+ }
+
+/**
+ * Internal function to retrieve a SMS parameters from the send buffer.
+ * Each serialized object is split into smaller segments which form the basic
+ * unit of data passed to this SAP from the socket server in the Write() method.
+ *
+ * @leave Leaves if the parameters could not retrieved.
+ * @return the retrieved CMobilePhoneSmspList object.
+ *
+ */
+CMobilePhoneSmspList* CSmsProvider::InternalizeParametersL()
+ {
+ LOGSMSPROT1("CSmsProvider::InternalizeParametersL");
+
+ // Initialize the read stream with the buffer
+ RBufReadStream readStream(*iSendBufSeg);
+ readStream.Open(*iSendBufSeg,0);
+ CleanupClosePushL(readStream);
+
+ // Create a parameter object to store the result
+ CMobilePhoneSmspList* mobilePhoneSmspList = CMobilePhoneSmspList::NewL();
+ CleanupStack::PushL(mobilePhoneSmspList);
+
+ // De-serialize the message from using the read stream
+ readStream >> *mobilePhoneSmspList;
+
+ CleanupStack::Pop(mobilePhoneSmspList);
+ CleanupStack::PopAndDestroy(); //readStream
+ iSendBufSeg->Reset();
+
+ LOGSMSPROT1("-> CSmsProvider::InternalizeParametersL - done");
+
+ return mobilePhoneSmspList;
+ }
+
+CSmsMessage* CSmsProvider::InternalizeMessageL( CBufSeg* aBufSeg)
+ {
+ LOGSMSPROT1("CSmsProvider::InternalizeMessageL");
+
+ RBufReadStream readstream(*aBufSeg);
+ readstream.Open(*aBufSeg,0);
+ CleanupClosePushL(readstream);
+ CSmsBufferBase* buffer = CSmsBuffer::NewL();
+ CSmsMessage* smsmessage= CSmsMessage::NewL(iProtocol.FileSession(),CSmsPDU::ESmsDeliver,buffer);
+
+ CleanupStack::PushL(smsmessage);
+ readstream >> *smsmessage;
+
+ CleanupStack::Pop(); // smsmessage
+ CleanupStack::PopAndDestroy(); // readsream
+
+ LOGSMSPROT1("-> CSmsProvider::InternalizeMessageL - done");
+
+ return smsmessage;
+ }
+
+TInt CSmsProvider::SecurityCheck(MProvdSecurityChecker* aSecurityChecker)
+ {
+ LOGSMSPROT1("CSmsProvider::SecurityCheck");
+ iSecurityChecker = aSecurityChecker;
+ return KErrNone;
+ }