⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdpsms.cpp

📁 Symbian C++ scmp.zip
💻 CPP
字号:
// gdpsms.cpp
//
// Copyright (c) 2002 Symbian Ltd.  All rights reserved.
//

#include "gdpsms.h"
#include <ImplementationProxy.h>
#include <ecom.h>

CGdpSmsComms::CGdpSmsComms()
	{
	}

CGdpSmsComms::~CGdpSmsComms()
	{
	REComSession::DestroyedImplementation(iDtor_ID_Key);
	delete iSender;
	delete iReceiver;
	delete iResMan;
	}

CGdpSession* CGdpSmsComms::NewL()
	{
	return new (ELeave) CGdpSmsComms();
	}

void CGdpSmsComms::OpenL(MGdpPacketHandler* aHandler)
	{
	RDebug::Print(_L("CGdpSmsComms::OpenL() Called"));
	iResMan = new(ELeave) CGdpSmsResourceManager();
	iResMan->OpenL();
	iSender = new(ELeave) CGdpSmsSender(*iResMan);
	iSender->OpenL(*aHandler);	// Inform handler of successful send
	iReceiver = new(ELeave) CGdpSmsReceiver(*iResMan);
	iReceiver->OpenL(*aHandler);	// route packets up to the handler passed to us
	}


void CGdpSmsComms::SendL(const TDesC8& aAddress, const TDesC8& aData)
	{
	RDebug::Print(_L("CGdpSmsComms::SendL() Called."));
	__ASSERT_ALWAYS(iSender != NULL, GdpUtil::Fault(GdpUtil::EProtocolNotOpen));
	iSender->SendL(aAddress, aData);
	}

TInt CGdpSmsComms::ReceiveAll()
	{
	RDebug::Print(_L("CGdpSmsComms::ReceiveAllL() Called"));
	__ASSERT_ALWAYS(iReceiver != NULL, GdpUtil::Fault(GdpUtil::EProtocolNotOpen));
	iReceiver->ReceiveAllL();
	return KErrNone;
	}

TInt CGdpSmsComms::GetMaxPacketLength() const
	{
	RDebug::Print(_L("CGdpSmsComms::GetMaxPacketLength() Called"));
	return KGdpSmsSduMaxSize;
	}

TBool CGdpSmsComms::IsNetworked() const
	{
	return ETrue;
	}


CGdpSmsStateMachine::CGdpSmsStateMachine(CGdpSmsResourceManager& aResMan)
: CGdpStateMachine(EPriorityStandard), iResMan(aResMan)
	{
	}

#pragma warning(disable:4355) // Disable "C4355: 'this' used in member initialization". 

CGdpSmsSender::CGdpSmsSender(CGdpSmsResourceManager& aResMan)
: CGdpSmsStateMachine(aResMan), 
  iSendMsgState(*this)
	{
	RDebug::Print(_L("CGdpSmsSender::CGdpSmsSender"));
	}
#pragma warning(default:4355) // Turn it back on.



CGdpSmsSender::~CGdpSmsSender()
	{
	Close();
	}
	
void CGdpSmsSender::OpenL(MGdpPacketHandler& aHandler)
	{
	iHandler = &aHandler;
	Reset();
	}
	
void CGdpSmsSender::Close()
	{
	Cancel();
	}
	
void CGdpSmsSender::SendL(const TDesC8& aAddress, const TDesC8& aData)
	{
	RDebug::Print(_L("CGdpSmsSender::SendL() Called."));
	if (IsActive())
		return;	// Don't leave -- just quietly drop the overflow packet

	// Create the SMS message
	CSmsBuffer* smsBuffer = CSmsBuffer::NewL();
	iSmsMsg = CSmsMessage::NewL(iResMan.iFs, CSmsPDU::ESmsSubmit, smsBuffer);

    TSmsUserDataSettings smsSettings;
	smsSettings.SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet8Bit);
	smsSettings.SetTextCompressed(EFalse);
	
	// Convert address to unicode string required by CSmsMessage
	__ASSERT_ALWAYS(aAddress.Length() <= KGdpMaxAddressLen, GdpUtil::Fault(GdpUtil::EBadSendAddress));

	TBuf<KGdpMaxAddressLen> bufAddress;
	bufAddress.Copy(aAddress);
	
	iSmsMsg->SetUserDataSettingsL(smsSettings);
	iSmsMsg->SetToFromAddressL(bufAddress);
	iSmsMsg->SmsPDU().SetServiceCenterAddressL(KServiceCenterNumber); 

	// Insert our SMS pattern header so that our receiver is able to detect
	// the incoming message, and then append the data.
	smsBuffer->InsertL(0, KGdpSmsHeaderTag);

	CSmsPDU& pdu = iSmsMsg->SmsPDU();
	CSmsUserData& userData = pdu.UserData();
	userData.AddInformationElementL(CSmsInformationElement::ESmsIEIReserved, aData);
	
	iRetries = KGdpSmsSendRetries;
	Reset();
	ReEnterCurrentState();	// Kick us off again.
	}
	
void CGdpSmsSender::Reset()
	{
	SetNextState(static_cast<TState*>(&iSendMsgState));
	}
	
CGdpStateMachine::TState* CGdpSmsSender::ErrorOnStateEntry(TInt /*aError*/)
	{
	return NULL;	// Give up!
	}
	
CGdpStateMachine::TState* CGdpSmsSender::ErrorOnStateExit(TInt /*aError*/)
	{
	Reset();
	if (--iRetries < 0)
		return NULL;
	return CurrentState(); // Force re-entry to initial state
	}

CGdpSmsSender::TSenderState::TSenderState(CGdpSmsSender& aSmsSender)
: iSender(aSmsSender)
	{
	}


CGdpSmsSender::TSendMsgState::TSendMsgState(CGdpSmsSender& aSmsSender)
: TSenderState(aSmsSender)
	{
	}


void CGdpSmsSender::TSendMsgState::EnterL()
	{
	// Close the socket as it may already be open.
	iSender.iSocket.Close();

	// Open a socket
	User::LeaveIfError(iSender.iSocket.Open(iSender.iResMan.iSocketServer, KSMSAddrFamily, KSockDatagram, KSMSDatagramProtocol));

	// Bind to SMS port
    TSmsAddr smsAddr;
    smsAddr.SetSmsAddrFamily(ESmsAddrSendOnly);
	iSender.iSocket.Bind(smsAddr);

	// Open a write stream on the socket and stream our message. 
	RSmsSocketWriteStream writeStream(iSender.iSocket);
	writeStream << *(iSender.iSmsMsg);

	// message has not been sent at this point
	writeStream.CommitL();

	// Send the message
	iSender.iSocket.Ioctl(KIoctlSendSmsMessage, iSender.iStatus, &iSender.iOctlResult, KSolSmsProv);
	iSender.SetActive();
	}

CGdpStateMachine::TState* CGdpSmsSender::TSendMsgState::CompleteL()
	{
	RDebug::Print(_L("Message sent!!"));
	iSender.iHandler->SendComplete(KErrNone);
	delete iSender.iSmsMsg;
	iSender.iSocket.Close();
	return NULL;	// Last state so return NULL
	}

CGdpStateMachine::TState* CGdpSmsSender::TSendMsgState::ErrorL(TInt aCode)
	{
	User::Leave(aCode);
	return NULL;
	}

void CGdpSmsSender::TSendMsgState::Cancel()
	{
	if (iSender.iSocket.SubSessionHandle())
		iSender.iSocket.CancelIoctl();
	}

/************** Receiver ***************/

#pragma warning(disable:4355) // Disable "C4355: 'this' used in member initialization". 

CGdpSmsReceiver::CGdpSmsReceiver(CGdpSmsResourceManager& aResMan)
: CGdpSmsStateMachine(aResMan),
  iWaitState(*this),
  iReadMsgState(*this)
	{
	}

#pragma warning(default:4355) // Turn it back on.


CGdpSmsReceiver::~CGdpSmsReceiver()
	{
	Close();
	}
	
void CGdpSmsReceiver::OpenL(MGdpPacketHandler& aHandler)
	{
	iHandler = &aHandler;
	Reset();
	}
	
void CGdpSmsReceiver::Close()
	{
	Cancel();
	}
	
void CGdpSmsReceiver::ReceiveAllL()
	{
	__ASSERT_ALWAYS(iHandler != NULL, GdpUtil::Fault(GdpUtil::EProtocolNotOpen));
	if (IsActive())
		return;
	iRetries = KGdpSmsReceiveRetries;
	ReEnterCurrentState();
	}

void CGdpSmsReceiver::Reset()
	{// Called on start-up and if an error occurs
	SetNextState(&iWaitState);
	}


CGdpStateMachine::TState* CGdpSmsReceiver::ErrorOnStateEntry(TInt /*aError*/)
	{
	return NULL;
	}

CGdpStateMachine::TState* CGdpSmsReceiver::ErrorOnStateExit(TInt /*aError*/)
	{
	Reset();
	if (--iRetries<0)
		return NULL;
	return CurrentState();
	}

CGdpSmsReceiver::TReceiverState::TReceiverState(CGdpSmsReceiver& aSmsReceiver)
: iReceiver(aSmsReceiver)
	{
	}

/* ---------- Receiver States ------------ */


CGdpSmsReceiver::TWaitState::TWaitState(CGdpSmsReceiver& aSmsReceiver)
: TReceiverState(aSmsReceiver)
	{
	}

CGdpSmsReceiver::TReadMsgState::TReadMsgState(CGdpSmsReceiver& aSmsReceiver)
: TReceiverState(aSmsReceiver)
	{
	}


void CGdpSmsReceiver::TWaitState::EnterL()
	{
	// Close the socket as it may already be open.
	iReceiver.iSocket.Close();

	// Open a socket
	User::LeaveIfError(iReceiver.iSocket.Open(iReceiver.iResMan.iSocketServer, KSMSAddrFamily, KSockDatagram, KSMSDatagramProtocol));

	// Set the pattern to search for in incoming SMS messages. Messages which do not have our
	// signature will be consumed by the Messaging Application.
    TSmsAddr smsAddr;
	smsAddr.SetSmsAddrFamily(ESmsAddrMatchText);
	smsAddr.SetTextMatch(KGdpSmsHeaderTag8());
	
	User::LeaveIfError(iReceiver.iSocket.Bind(smsAddr));

	// Wait for incoming messages	
    iReceiver.iOctlResult()= KSockSelectRead;
    iReceiver.iSocket.Ioctl(KIOctlSelect, iReceiver.iStatus, &(iReceiver.iOctlResult), KSOLSocket);
	iReceiver.SetActive();
	}

CGdpStateMachine::TState* CGdpSmsReceiver::TWaitState::CompleteL()
	{
	// Received a message so move to read state.
	return static_cast<TState*> (&iReceiver.iReadMsgState);
	}

CGdpStateMachine::TState* CGdpSmsReceiver::TWaitState::ErrorL(TInt aCode)
	{
	User::Leave(aCode);
	return NULL;
	}

void CGdpSmsReceiver::TWaitState::Cancel()
	{
	iReceiver.iSocket.CancelIoctl();
	}


void CGdpSmsReceiver::TReadMsgState::EnterL()
	{
	// Create an empty message and buffer for our incoming message.
	CSmsBuffer* buffer=NULL;
	buffer=CSmsBuffer::NewL();
	iReceiver.iSmsMsg = CSmsMessage::NewL(iReceiver.iResMan.iFs, CSmsPDU::ESmsSubmit, buffer);

	// Read the message.
	RSmsSocketReadStream readstream(iReceiver.iSocket);
	readstream >> *(iReceiver.iSmsMsg);

	// Let the socket know that we have read the message and it can be removed from the message
	// store.
	iReceiver.iSocket.Ioctl(KIoctlReadMessageSucceeded, iReceiver.iStatus, NULL, KSolSmsProv);
	iReceiver.SetActive();
	}

CGdpStateMachine::TState* CGdpSmsReceiver::TReadMsgState::CompleteL()
	{
	// Extract the message contents
	CSmsPDU& pdu = iReceiver.iSmsMsg->SmsPDU();
	CSmsUserData& userData = pdu.UserData();
	CSmsInformationElement& recvElement = userData.InformationElement(0);

	// Convert from address from uncode and send to handler
	TPtrC ptrFrom = iReceiver.iSmsMsg->ToFromAddress();
	HBufC8* hFromAddress = HBufC8::NewLC(ptrFrom.Length());
	TPtr8 p = hFromAddress->Des();
	p.Copy(ptrFrom);

	iReceiver.iHandler->GdpHandleL(*hFromAddress, recvElement.Data());
	
	// Cleanup
	CleanupStack::PopAndDestroy(); // hbuf, hFromAddress;
	delete iReceiver.iSmsMsg;
	iReceiver.iSocket.Close();
	
	// Return to wait state for next message.
	return static_cast<TState*> (&iReceiver.iWaitState);
	}

CGdpStateMachine::TState* CGdpSmsReceiver::TReadMsgState::ErrorL(TInt aCode)
	{
	User::Leave(aCode);
	return NULL;
	}

void CGdpSmsReceiver::TReadMsgState::Cancel()
	{
	iReceiver.iSocket.CancelIoctl();
	}


CGdpSmsResourceManager::~CGdpSmsResourceManager()
	{
	Close();
	}

void CGdpSmsResourceManager::OpenL()
	{
	User::LeaveIfError(iSocketServer.Connect());
	User::LeaveIfError(iFs.Connect());
	}

void CGdpSmsResourceManager::Close()
	{
	iFs.Close();
	iSocketServer.Close();
	}


// Define the interface UIDs
const TImplementationProxy ImplementationTable[] =
    {
    {{0x101f8b5e}, CGdpSmsComms::NewL},
    };


EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
    {
    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);

    return ImplementationTable;
    }

TInt E32Dll(TDllReason)
	{
	return KErrNone;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -