📄 smssendrecv.cpp
字号:
// SMSSendRecv.cpp
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#include "SMSSendRecv.h"
CSMSSender* CSMSSender::NewL()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
@returns a new CSMSSender instance.
*/
{
CSMSSender* self = NewLC();
CleanupStack::Pop();
return self;
}
CSMSSender* CSMSSender::NewLC()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves a CSMSSender instance on the CleanupStack.
@returns a new CSMSSender instance.
*/
{
CSMSSender* self = new(ELeave) CSMSSender;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CSMSSender::ConstructL()
/**
Second phase of construction, opens connections to the Socket Server and File server,
and opens an SMS socket.
*/
{
iSocketServer.Connect();
iFs.Connect();
User::LeaveIfError(iSocket.Open(iSocketServer, KSMSAddrFamily, KSockDatagram, KSMSDatagramProtocol));
}
CSMSSender::~CSMSSender()
/**
Close the connections to the Socket Server, Socket and File Server
*/
{
iSocket.Close();
iSocketServer.Close();
iFs.Close();
}
void CSMSSender::CreateSMSMessageL(const TDesC8& aText, const TDesC8& aAddress)
/**
Prepare SMS specific objects ready to send via ESOCK
@param aText buffer containing ascii contents of message to send
@param aAddress buffer with telephone number of SMS receiver
*/
{
TSmsAddr smsAddr;
smsAddr.SetSmsAddrFamily(ESmsAddrSendOnly);
iSocket.Bind(smsAddr);
CSmsBuffer* smsBuffer = CSmsBuffer::NewL();
//CleanupStack::PushL(smsBuffer) is NOT used because CSmsMessage takes ownership of our buffer :-)
CSmsMessage* smsMsg = CSmsMessage::NewL(iFs, CSmsPDU::ESmsSubmit, smsBuffer);
CleanupStack::PushL(smsMsg);
TSmsUserDataSettings smsSettings;
smsSettings.SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet7Bit);
smsSettings.SetTextCompressed(EFalse);
smsMsg->SetUserDataSettingsL(smsSettings);
TBuf<KMaxAddressSize> toAddress;
toAddress.Copy(aAddress);
smsMsg->SetToFromAddressL(toAddress);
smsMsg->SmsPDU().SetServiceCenterAddressL(smsMsg->ServiceCenterAddress());
//convert to wide
HBufC* payload = HBufC::NewL(aText.Length());
CleanupStack::PushL(payload);
TPtr pPayload=payload->Des();
pPayload.Copy(aText); //copy from narrow to wide and convert
smsBuffer->InsertL(0, pPayload); //copies payload
RSmsSocketWriteStream writeStream(iSocket);
writeStream << *smsMsg; // remember << operator _CAN_ leave
writeStream.CommitL();
CleanupStack::PopAndDestroy(2);//smsMsg, payload
}
void CSMSSender::SendSMSL(const TDesC8& aText, const TDesC8& aAddress, TRequestStatus& aStatus)
/**
Send an SMS message Asynchronously
@param aText buffer containing ascii contents of message to send
@param aAddress buffer with telephone number of SMS receiver
@param aStatus TRequestStatus which receives completion notification following a Send
*/
{
CreateSMSMessageL(aText, aAddress);
iSocket.Ioctl(KIoctlSendSmsMessage, aStatus, &iBuf, KSolSmsProv);
}
/*
CSMSReceiver
*/
// Construction functions
CSMSReceiver::CSMSReceiver() : CActive(EPriorityStandard)
/**
Standard priortiy active object.
*/
{
}
CSMSReceiver* CSMSReceiver::NewL()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
@returns a new CSMSSender instance.
*/
{
CSMSReceiver* self = NewLC();
CleanupStack::Pop();
return self;
}
CSMSReceiver* CSMSReceiver::NewLC()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves an instance of CSMSReceiver on the CleanupStack.
@returns a new CSMSSender instance.
*/
{
CSMSReceiver* self = new(ELeave) CSMSReceiver;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CSMSReceiver::ConstructL()
/**
Second phase of construction, opens connections to the Socket Server and File server,
and opens an SMS socket.
*/
{
iSocketServer.Connect();
iFs.Connect();
User::LeaveIfError(iSocket.Open(iSocketServer, KSMSAddrFamily, KSockDatagram, KSMSDatagramProtocol));
iReceiveStatus = EIdle;
CActiveScheduler::Add(this);
}
CSMSReceiver::~CSMSReceiver()
/**
Cancels any outstanding Receive, before closing sessions with the Socket and File Servers.
*/
{
Cancel(); //Cancel any outstanding Receiver
iSocket.Close();
iSocketServer.Close();
iFs.Close();
}
void CSMSReceiver::RunL()
/**
Handle asynchronous receive which is a two step process.
1. Accept and process an incoming SMS
2. Inform network that you received the message and not to try a resend.
Then we can complete the clients TRequestStatus we stored earlier
*/
{
switch (iReceiveStatus)
{
case EListening:
{
// Got an SMS, lets extract it
ExtractMessageL();
// And now let the network know that we received the message so that we
// do not receive another attempt
iSocket.Ioctl(KIoctlReadMessageSucceeded, iStatus, &iBuf, KSolSmsProv);
iReceiveStatus = EAcknowledging;
SetActive();
break;
}
case EAcknowledging:
// Finished Network acknowledgement. Client now needs to be informed
// of the outcome
User::RequestComplete(iClientStatus, iStatus.Int());
break;
default:
User::Panic(_L("Not Possible to be in RunL in Idle state"),KErrUnknown);
break;
}
}
void CSMSReceiver::DoCancel()
/**
Cancel any outstanding Ioctls.
*/
{
iSocket.CancelIoctl();
}
void CSMSReceiver::SetupSocketsL(const TDesC8& aPattern)
/**
Bind to socket and specify pattern match so that only incoming messages matching
the pattern are intercepted. Other messages will be caught by the messaging component.
@param aPattern buffer pattern match at beginning of incoming SMS message. Only SMS
messages containing this Pattern match will be intercepted.
*/
{
TSmsAddr smsAddr;
smsAddr.SetSmsAddrFamily(ESmsAddrMatchText);
smsAddr.SetTextMatch(aPattern);
User::LeaveIfError(iSocket.Bind(smsAddr));
}
void CSMSReceiver::ExtractMessageL()
/**
Following receive extract the contents of the message and store within CDatagram object.
*/
{
CSmsBuffer* buffer;
buffer=CSmsBuffer::NewL();
//CleanupStack::PushL(buffer) is NOT used because CSmsMessage takes ownership of our buffer :-)
iSmsMsg = CSmsMessage::NewL(iFs, CSmsPDU::ESmsSubmit, buffer);
RSmsSocketReadStream readstream(iSocket);
readstream >> *iSmsMsg;
HBufC* dgram = HBufC::NewLC(KMaxSMSSize);
TPtr ptr = dgram->Des();
buffer->Extract(ptr, 0, buffer->Length());
// Convert from unicode data
TBuf8<KMaxSMSSize> buf; // it is ok to do this on the stack because SMS size is small
buf.Copy(*dgram);
iDatagram->SetDataL(buf);
CleanupStack::PopAndDestroy(); //dgram
}
void CSMSReceiver::ListenForSMSL(const TDesC8& aPattern, CDatagram* aDatagram, TRequestStatus& aStatus)
/**
Receive an SMS message Asynchronously
@param aPattern buffer pattern match at beginning of incoming SMS message. Only SMS
messages containing this Pattern match will be intercepted. Example: //MYPATTERN
@param aDatagram CDatagram to be populated during receive.
@param aStatus will receive completion notification following receive
*/
{
aStatus = KRequestPending;
iDatagram = aDatagram;
iClientStatus = &aStatus;
SetupSocketsL(aPattern);
iBuf()=KSockSelectRead;
iSocket.Ioctl(KIOctlSelect, iStatus, &iBuf,KSOLSocket);
iReceiveStatus = EListening;
SetActive();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -