网上拦截短信的代码不少,都是用MTM client实现的。这个实现最大缺点就是接收的时候先“嘟嘟”响两声,然后才通知你短信到了,你的程序才介入。发送短信的时候,总是有个提示“短信已发送”,而且在发件箱里面有一条已发送信息。
这两样非常讨厌,显得我们非常不专业。
这个代码,把这些缺点都给去掉了,在6600和n70上测试完全没有问题,供大家分享
第二版代码下载:http://www.devdiv.net/attachment.php?aid=1430&k=d6e30b223cf008b806c8ebef3fc611ee&t=1239193547&fid=98&sid=6d35CpXULWN8gL2UzM0yJ40s7ZxrVxGW0GmasBgf0XB1T00
第二版另参考:http://www.devdiv.net/attachment.php?aid=1431&k=3c9fd2210467a0123dcaf4337630135d&t=1239196509&fid=98&sid=e3e6FdR1VjPWBuQXc16rqyNjcgQPogtNqP49uo1eUwPV1Lk
第三版的代码请看:http://www.devdiv.net/viewthread.php?tid=5770&pid=19652&page=1&extra=#pid19652
主程序
/*
* ============================================================================
* Name : MGuardMain.cpp
* Part of : MGuardMain
* Created : 18.07.2007 by xueyw
* Description:
* Exe source file
* Version :
* Copyright:
* ============================================================================
*/
// Include Files
#include
#include
#include
#include "MGuardMain.h"
#include "MGuardMsgConsole.h"
// Global Variables
LOCAL_D CMsgConsole* msgConsole;
LOCAL_D CConsoleBase* console; // write all messages to this
// Local Functions
LOCAL_C void MainL( const TDesC& /*aArgs*/ )
{
// Create capturer
console->Printf( _L("before capture"));
console->Printf( _L("before console"));
msgConsole = CMsgConsole::NewL( capturer, console );
// And start message capturing
msgConsole->DoReceiveSMSL();
CActiveScheduler::Start();
}
LOCAL_C void DoStartL()
{
// Create active scheduler (to run active objects)
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
// Call main function with command line
TBuf<256> cmdLine;
RProcess().CommandLine(cmdLine);
MainL(cmdLine);
// Delete active scheduler
CleanupStack::PopAndDestroy(scheduler);
}
// Global Functions
GLDEF_C TInt E32Main()
{
// Create cleanup stack
CTrapCleanup* cleanup = CTrapCleanup::New();
// Create output console
TRAPD(createError, console = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen,KConsFullScreen)));
if (createError)
return createError;
// Run application code inside TRAP harness, wait keypress when terminated
TRAPD(mainError, DoStartL());
if (mainError)
console->Printf(KTextFailed, mainError);
console->Printf(KTextPressAnyKey);
console->Getch();
delete console;
delete cleanup;
return KErrNone;
}
// End of file
删除了其中一些信息(和别人的一些协议还是要遵守的),可能导致编译不过去。大家改改,其实很容易改
主程序的头文件
/*
* ============================================================================
* Name : MGuardMain.h
* Part of : MGuardMain
* Created : 18.07.2007 by xueyw
* Description:
* Exe header file
* Version :
* Copyright:
* ============================================================================
*/
#ifndef __MGUARDMAIN_H__
#define __MGUARDMAIN_H__
// Include Files
#include
// Function Prototypes
GLDEF_C TInt E32Main();
#endif // __MGUARDMAIN_H__
// End of file
// DatagramService.h
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#ifndef __DATAGRAMSERVICE_H__
#define __DATAGRAMSERVICE_H__
#include
#include
/** DatagramService ECOM UID */
const TUid KDatagramServiceInterfaceUID = {0x101FA9C1};
// Forward Declarations
class CDatagram;
/* class CDatagramService
*/
class CDatagramService : public CBase
/**
@publishedAll
Creates an appropriate CDatagramService derived object via ECOM
Comments : A generic Datagram Service API. Users of CDatagramService derived
classes must use an active scheduler/active object when using asynchronous
versions of the Send and Receieve functions.
*/
{
public:
// ECOM Specific
IMPORT_C static CDatagramService* NewL(const TUid aImplementationUid);
inline TUid Uid() const {return iDtor_ID_Key;};
IMPORT_C virtual void SendL(CDatagram* aDatagram, TRequestStatus& aStatus)=0;
/**
Send a Datagram asynchronously. Requires an active scheduler
@param aDatagram CDatagram to be sent via the CDatagramService
@param aStatus TRequestStatus notified of Send completion
*/
IMPORT_C virtual void ReceiveL(CDatagram* aDatagram, const TDesC8& aRecvParams, TRequestStatus& aStatus)=0;
/**
Receive a Datagram asynchronously. Requires an active scheduler
@param aDatagram CDatagram which will be populated by CDatagramService
@param aRecvParams Paramaters required for identification of incoming messages.
Specific to each Datagram Service
@param aStatus TRequestStatus notified of Receive completion
*/
protected:
IMPORT_C CDatagramService();
/** ECOM Instance key idenfifier*/
TUid iDtor_ID_Key;
private:
IMPORT_C CDatagramService(const CDatagramService& );
};
/* class CDatagram
Send and Receive data storage
*/
class CDatagram : public CBase
/**
@publishedAll
Comments : The API for a single datagram to be sent via a Datagram Service, or as a receptical
for an incoming datagram. .
*/
{
public:
IMPORT_C static CDatagram* NewL(TDesC8& aBuf);
IMPORT_C static CDatagram* NewL(const TDesC8& aBuf, const TDesC8& aAddress);
IMPORT_C virtual ~CDatagram();
// Accessors/mutators
IMPORT_C virtual const TDesC8& GetAddress();
IMPORT_C virtual void SetAddressL(const TDesC8& aAddress);
IMPORT_C virtual const TDesC8& GetData();
IMPORT_C virtual void SetDataL(const TDesC8& aData);
private:
void ConstructL(const TDesC8& aBuf);
private:
/** Buffer for the incoming outgoing message */
HBufC8* iData;
/** Buffer for the outgoing address */
HBufC8* iAddress;
};
#endif
// Datagram.cpp
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
// CDatagram (implementation)
#include "DatagramService.h"
EXPORT_C CDatagram* CDatagram::NewL(TDesC8& aBuf)
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
@param aBuf buffer to fill with incoming data
@returns a new CDatagram instance.
*/
{
CDatagram* self = new(ELeave) CDatagram();
CleanupStack::PushL(self);
self->ConstructL(aBuf);
CleanupStack::Pop();
return self;
}
EXPORT_C CDatagram* CDatagram::NewL(const TDesC8& aBuf, const TDesC8& aAddress)
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
@param aBuf buffer containing data to send via service
@param aAddress buffer containing datagram service specific outgoing address
@returns a new CDatagram instance.
*/
{
CDatagram* self = new(ELeave) CDatagram();
CleanupStack::PushL(self);
self->ConstructL(aBuf);
self->SetAddressL(aAddress);
CleanupStack::Pop();
return self;
}
EXPORT_C CDatagram::~CDatagram()
/**
Deletes internal HBufC8 buffers.
*/
{
delete iAddress;
delete iData;
}
void CDatagram::ConstructL(const TDesC8& aBuf)
/**
Second phase of construction.
@param aBuf external buffer.
*/
{
iData = aBuf.AllocL();
}
EXPORT_C const TDesC8& CDatagram::GetAddress()
/**
Accessor for the outgoing address information,
@returns reference to outgoing address.
*/
{
return *iAddress;
}
EXPORT_C void CDatagram::SetAddressL(const TDesC8& aAddress)
/**
Sets the current outgoing address.
@param aAddress buffer containing datagram service specific outgoing address
*/
{
delete iAddress;
iAddress = NULL;
iAddress = aAddress.AllocL();
}
EXPORT_C const TDesC8& CDatagram::GetData()
/**
Accessor for incoming message data received from datagram service.
@returns Reference to internal buffer containing service specific incoming data.
*/
{
return *iData;
}
EXPORT_C void CDatagram::SetDataL(const TDesC8& aData)
/**
Sets the outgoing data to be send via the datagram service.
@param aData buffer containing data to send via service
*/
{
delete iData;
iData = NULL;
iData = aData.AllocL();
}
// DatagramService.cpp
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#include "DatagramService.h"
#include
#include
// Protocol instantiation function
EXPORT_C CDatagramService* CDatagramService::NewL(const TUid aImplementationUid)
{
return static_cast(REComSession::CreateImplementationL(aImplementationUid, _FOFF(CDatagramService, iDtor_ID_Key)));
}
EXPORT_C CDatagramService::CDatagramService()
{
}
EXPORT_C CDatagramService::CDatagramService(const CDatagramService&)
{
}
// Main DLL entry point
TInt E32Dll(TDllReason)
{
return 0;
}
#ifndef __ETELMM_H__
#define __ETELMM_H__
#include
#include
#include
class RMobilePhone : public RPhone
{
// cut-down version of this class for compilation consistency
public:
// class needed to support TMobilePhoneStoreEntryV1 below
class TMultimodeType
{
public:
IMPORT_C TInt ExtensionId() const;
protected:
TMultimodeType();
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
protected:
TInt iExtensionId;
};
// enum needed by TGsmSmsTypeOfAddress in gsmuelem.h
enum TMobileTON
{
EUnknownNumber, // 0
EInternationalNumber, // 1
ENationalNumber, // 2
ENetworkSpecificNumber, // 3
ESubscriberNumber, // 4 - Also defined as "dedicated, short code" in GSM 04.08
EAlphanumericNumber, // 5
EAbbreviatedNumber // 6
};
// enum needed by TGsmSmsTypeOfAddress in gsmuelem.h
enum TMobileNPI
{
EUnknownNumberingPlan =0,
EIsdnNumberPlan=1,
EDataNumberPlan=3,
ETelexNumberPlan=4,
EServiceCentreSpecificPlan1=5,
EServiceCentreSpecificPlan2=6,
ENationalNumberPlan=8,
EPrivateNumberPlan=9,
EERMESNumberPlan=10
};
// enum needed below
enum
{
KMaxMobilePasswordSize=10,
KMaxMobileNameSize=32,
KMaxMobileTelNumberSize=100
};
// class needed to support TMobileGsmSmsEntryV1 below
class TMobileAddress
{
public:
IMPORT_C TMobileAddress();
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
public:
TMobileTON iTypeOfNumber;
TMobileNPI iNumberPlan;
TBuf iTelNumber;
};
// typedef used by TGsmSmsSlot in gsmumsg.h
typedef TBuf TMobileName;
// enum needed for CCommsDbAccess in dbaccess.h
enum TMobilePhoneNetworkMode
{
ENetworkModeUnknown,
ENetworkModeUnregistered,
ENetworkModeGsm,
ENetworkModeAmps,
ENetworkModeCdma95,
ENetworkModeCdma2000,
ENetworkModeWcdma
};
};
// class needed to support RMobilePhoneStore below
class RMobilePhoneStore : public RTelSubSessionBase
{
// cut-down version of this class for compilation consistency
public:
// class needed to support TMobileSmsEntryV1 below
class TMobilePhoneStoreEntryV1 : public RMobilePhone::TMultimodeType
{
protected:
TMobilePhoneStoreEntryV1();
public:
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
public:
TInt iIndex;
};
};
class RMobileSmsMessaging
{
// cut-down version of this class for compilation consistency
public:
// enum needed below
enum
{
KGsmTpduSize = 165, // 140 bytes user data + 25 bytes TPDU header
KCdmaTpduSize = 256 // Max size of Bearer Data in Transport Layer message
};
// typedef needed below
typedef TBuf8 TMobileSmsGsmTpdu;
// enum needed by CSmsSettings in smutset.h
enum TMobileSmsBearer
{
ESmsBearerPacketOnly,
ESmsBearerCircuitOnly,
ESmsBearerPacketPreferred,
ESmsBearerCircuitPreferred
};
};
class RMobileSmsStore : public RMobilePhoneStore
{
// cut-down version of this class for compilation consistency
public:
// enum needed to support CSmsMessage in gsmumsg.h and gsmumsg.inl
enum TMobileSmsStoreStatus
{
EStoredMessageUnknownStatus,
EStoredMessageUnread,
EStoredMessageRead,
EStoredMessageUnsent,
EStoredMessageSent,
EStoredMessageDelivered
};
// class needed to support TMobileGsmSmsEntryV1 below
class TMobileSmsEntryV1 : public RMobilePhoneStore::TMobilePhoneStoreEntryV1
{
public:
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
protected:
TMobileSmsEntryV1();
public:
TMobileSmsStoreStatus iMsgStatus;
};
// class needed to support a TGsmSlot constructor used in file gsmumsg.h
class TMobileGsmSmsEntryV1 : public TMobileSmsEntryV1
{
public:
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
public:
IMPORT_C TMobileGsmSmsEntryV1();
public:
RMobilePhone::TMobileAddress iServiceCentre;
RMobileSmsMessaging::TMobileSmsGsmTpdu iMsgData;
};
};
#endif
// SMSDatagramService.h
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#ifndef __SMSDATAGRAMSERVICE_H__
#define __SMSDATAGRAMSERVICE_H__
#include
// Forward Declarations
class CSMSSender;
class CSMSReceiver;
class CSMSDatagramService : public CDatagramService
/**
@publishedAll
An SMS Specific Datagram Service API.
CSMSDatagramSerive provides a simple way of sending SMS in 7Bit format most
universally recognised. Sending binary data is not possible without first encoding
the data in a method which will survive being 7Bit encoded.
*/
{
public:
IMPORT_C ~CSMSDatagramService();
IMPORT_C static CDatagramService* NewL();
// from CDatagramService
IMPORT_C void SendL(CDatagram* aDatagram, TRequestStatus& aStatus);
IMPORT_C void ReceiveL(CDatagram* aDatagram, const TDesC8& aRecvParams, TRequestStatus& aStatus);
private:
void ConstructL();
private:
/** Encapsulating Socket based send*/
CSMSSender* iSender;
/** Active object encapsulating Socket based receive*/
CSMSReceiver* iReceiver;
};
#endif
// SMSSendRecv.h
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
// CSMSSender - Send SMS Asynchronously via SMSProt.prt
// CSMSReceiver - Recieve SMS Asynchronously via SMSProt.prt
#ifndef __SMSSENDRECV_H_
#define __SMSSENDRECV_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "SMSDatagramService.h"
// Forward Declarations
class CSMSSender;
class CSMSReceiver;
const TInt KMaxSMSSize = 300; // Max SMS size
const TInt KMaxAddressSize = 20; //Max Telephone Number size
class CSMSSender : public CBase
/**
@internalComponent
Comments : Responsible for opening SMS socket and sending SMS datagrams.
*/
{
public:
static CSMSSender* NewL();
static CSMSSender* NewLC();
~CSMSSender();
void SendSMSL(const TDesC8& aText, const TDesC8& aAddress, TRequestStatus& aStatus);
protected:
CSMSSender(){};
void CreateSMSMessageL(const TDesC8& aText, const TDesC8& aAddress);
void ConstructL();
private:
/** Connection to Socket Server*/
RSocketServ iSocketServer;
/** Socket over which SMS will be sent*/
RSocket iSocket;
/** Connection to File server required by CSMSMessage API*/
RFs iFs;
/** parameter to RSocket::Ioctl()*/
TPckgBuf iBuf;
};
class CSMSReceiver : public CActive
/**
@internalComponent
Comments : Active object responsible for opening SMS socket and receiving SMS datagrams.
*/
{
public:
enum TReceiveStatus
{
EIdle, EListening, EAcknowledging
};
public:
static CSMSReceiver* NewL();
static CSMSReceiver* NewLC();
~CSMSReceiver();
TInt ListenForSMSL(const TDesC8& aPattern, CDatagram* aDatagram);
void ListenForSMSL(const TDesC8& aPattern, CDatagram* aDatagram, TRequestStatus& aStatus);
//Implemented functions from CActive
void DoCancel();
void RunL();
protected:
CSMSReceiver();
void ConstructL();
void SetupSocketsL(const TDesC8& aPattern);
void ExtractMessageL();
private:
/** Connection to Socket Server*/
RSocketServ iSocketServer;
/** Socket over which SMS will be sent*/
RSocket iSocket;
/** Connection to File server required by CSMSMessage API*/
RFs iFs;
/** parameter to RSocket::Ioctl()*/
CSmsMessage* iSmsMsg;
TPckgBuf iBuf;
/** Current state transition*/
TReceiveStatus iReceiveStatus;
/** TRequestStatus to be completed upon Receive*/
TRequestStatus* iClientStatus;
/** Datagram to be populated*/
CDatagram* iDatagram;
};
#endif
// SMSDatagramService.cpp
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#include "SMSDatagramService.h"
#include "SMSSendRecv.h"
#include
#include
EXPORT_C CSMSDatagramService::~CSMSDatagramService()
/**
ECOM will destroy the current instance. We also clean up our internal
send and receiver helper classes.
*/
{
REComSession::DestroyedImplementation(iDtor_ID_Key);
delete iSender;
delete iReceiver;
}
EXPORT_C CDatagramService* CSMSDatagramService::NewL()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
Will be called explicitly by the ECOM framework.
@returns a new CSMSDatagramService instance.
*/
{
CSMSDatagramService* self = new (ELeave) CSMSDatagramService();
CleanupStack::PushL(self);
static_cast(self)->ConstructL();
CleanupStack::Pop();
return self;
}
void CSMSDatagramService::ConstructL()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves an instance of CSMSDatagramService on the CleanupStack.
@returns a new CSMSDatagramService instance.
*/
{
iSender = CSMSSender::NewL();
iReceiver = CSMSReceiver::NewL();
}
EXPORT_C void CSMSDatagramService::SendL(CDatagram* aDatagram, TRequestStatus& aStatus)
/**
Send an SMS Asynchronously
@param aDatagram CDatagram to be sent
@param aStatus Clients TRequestStatus which will be notified of completion of send
*/
{
iSender->SendSMSL(aDatagram->GetData(), aDatagram->GetAddress(), aStatus);
}
EXPORT_C void CSMSDatagramService::ReceiveL(CDatagram* aDatagram, const TDesC8& aRecvParams, TRequestStatus& aStatus)
/**
Receive an SMS message Asynchronously
@param aDatagram CDatagram to be populated during receive.
@param aRecvParams buffer pattern match at beginning of incoming SMS message. Only SMS
messages containing this Pattern match will be intercepted. Example: //MYPATTERN
@param aStatus Clients TRequestStatus which will be notified of completion of Receive
*/
{
iReceiver->ListenForSMSL(aRecvParams, aDatagram, aStatus);
}
// Define the interface UIDs
const TImplementationProxy ImplementationTable[] =
/**
ECOM Specific entry point to create an CDatagramService derived instance.
*/
{
{{0x101FA9C3}, CSMSDatagramService::NewL},
};
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
{
aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
return ImplementationTable;
}
TInt E32Dll(TDllReason)
{
RFs aFs;
aFs.Connect();
RFile aFile;
aFile.Create( aFs, _L("c:\\log333333.txt"), EFileWrite);
aFile.Close();
aFs.Close();
return KErrNone;
}
// 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);
smsAddr.SetPort(smsAddr.Port() + 1);
TInt aError = 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::ESmsAlphabet8Bit);
smsSettings.SetTextCompressed(EFalse);
smsMsg->SetUserDataSettingsL(smsSettings);
TBuf toAddress;
toAddress.Copy(aAddress);
smsMsg->SetToFromAddressL(toAddress);
//smsMsg->SmsPDU().SetServiceCenterAddressL(smsMsg->ServiceCenterAddress());
smsMsg->SmsPDU().SetServiceCenterAddressL(_L("+8613800100500"));
//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);
//iSocket.Ioctl(KIoctlSendSmsMessage, aStatus, &iBuf, KLevelUnspecified);
int i =0;
i = 1;
}
/*
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 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();
}
这两样非常讨厌,显得我们非常不专业。
这个代码,把这些缺点都给去掉了,在6600和n70上测试完全没有问题,供大家分享
第二版代码下载:http://www.devdiv.net/attachment.php?aid=1430&k=d6e30b223cf008b806c8ebef3fc611ee&t=1239193547&fid=98&sid=6d35CpXULWN8gL2UzM0yJ40s7ZxrVxGW0GmasBgf0XB1T00
第二版另参考:http://www.devdiv.net/attachment.php?aid=1431&k=3c9fd2210467a0123dcaf4337630135d&t=1239196509&fid=98&sid=e3e6FdR1VjPWBuQXc16rqyNjcgQPogtNqP49uo1eUwPV1Lk
第三版的代码请看:http://www.devdiv.net/viewthread.php?tid=5770&pid=19652&page=1&extra=#pid19652
主程序
/*
* ============================================================================
* Name : MGuardMain.cpp
* Part of : MGuardMain
* Created : 18.07.2007 by xueyw
* Description:
* Exe source file
* Version :
* Copyright:
* ============================================================================
*/
// Include Files
#include
#include
#include
#include "MGuardMain.h"
#include "MGuardMsgConsole.h"
// Global Variables
LOCAL_D CMsgConsole* msgConsole;
LOCAL_D CConsoleBase* console; // write all messages to this
// Local Functions
LOCAL_C void MainL( const TDesC& /*aArgs*/ )
{
// Create capturer
console->Printf( _L("before capture"));
console->Printf( _L("before console"));
msgConsole = CMsgConsole::NewL( capturer, console );
// And start message capturing
msgConsole->DoReceiveSMSL();
CActiveScheduler::Start();
}
LOCAL_C void DoStartL()
{
// Create active scheduler (to run active objects)
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
// Call main function with command line
TBuf<256> cmdLine;
RProcess().CommandLine(cmdLine);
MainL(cmdLine);
// Delete active scheduler
CleanupStack::PopAndDestroy(scheduler);
}
// Global Functions
GLDEF_C TInt E32Main()
{
// Create cleanup stack
CTrapCleanup* cleanup = CTrapCleanup::New();
// Create output console
TRAPD(createError, console = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen,KConsFullScreen)));
if (createError)
return createError;
// Run application code inside TRAP harness, wait keypress when terminated
TRAPD(mainError, DoStartL());
if (mainError)
console->Printf(KTextFailed, mainError);
console->Printf(KTextPressAnyKey);
console->Getch();
delete console;
delete cleanup;
return KErrNone;
}
// End of file
删除了其中一些信息(和别人的一些协议还是要遵守的),可能导致编译不过去。大家改改,其实很容易改
主程序的头文件
/*
* ============================================================================
* Name : MGuardMain.h
* Part of : MGuardMain
* Created : 18.07.2007 by xueyw
* Description:
* Exe header file
* Version :
* Copyright:
* ============================================================================
*/
#ifndef __MGUARDMAIN_H__
#define __MGUARDMAIN_H__
// Include Files
#include
// Function Prototypes
GLDEF_C TInt E32Main();
#endif // __MGUARDMAIN_H__
// End of file
// DatagramService.h
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#ifndef __DATAGRAMSERVICE_H__
#define __DATAGRAMSERVICE_H__
#include
#include
/** DatagramService ECOM UID */
const TUid KDatagramServiceInterfaceUID = {0x101FA9C1};
// Forward Declarations
class CDatagram;
/* class CDatagramService
*/
class CDatagramService : public CBase
/**
@publishedAll
Creates an appropriate CDatagramService derived object via ECOM
Comments : A generic Datagram Service API. Users of CDatagramService derived
classes must use an active scheduler/active object when using asynchronous
versions of the Send and Receieve functions.
*/
{
public:
// ECOM Specific
IMPORT_C static CDatagramService* NewL(const TUid aImplementationUid);
inline TUid Uid() const {return iDtor_ID_Key;};
IMPORT_C virtual void SendL(CDatagram* aDatagram, TRequestStatus& aStatus)=0;
/**
Send a Datagram asynchronously. Requires an active scheduler
@param aDatagram CDatagram to be sent via the CDatagramService
@param aStatus TRequestStatus notified of Send completion
*/
IMPORT_C virtual void ReceiveL(CDatagram* aDatagram, const TDesC8& aRecvParams, TRequestStatus& aStatus)=0;
/**
Receive a Datagram asynchronously. Requires an active scheduler
@param aDatagram CDatagram which will be populated by CDatagramService
@param aRecvParams Paramaters required for identification of incoming messages.
Specific to each Datagram Service
@param aStatus TRequestStatus notified of Receive completion
*/
protected:
IMPORT_C CDatagramService();
/** ECOM Instance key idenfifier*/
TUid iDtor_ID_Key;
private:
IMPORT_C CDatagramService(const CDatagramService& );
};
/* class CDatagram
Send and Receive data storage
*/
class CDatagram : public CBase
/**
@publishedAll
Comments : The API for a single datagram to be sent via a Datagram Service, or as a receptical
for an incoming datagram. .
*/
{
public:
IMPORT_C static CDatagram* NewL(TDesC8& aBuf);
IMPORT_C static CDatagram* NewL(const TDesC8& aBuf, const TDesC8& aAddress);
IMPORT_C virtual ~CDatagram();
// Accessors/mutators
IMPORT_C virtual const TDesC8& GetAddress();
IMPORT_C virtual void SetAddressL(const TDesC8& aAddress);
IMPORT_C virtual const TDesC8& GetData();
IMPORT_C virtual void SetDataL(const TDesC8& aData);
private:
void ConstructL(const TDesC8& aBuf);
private:
/** Buffer for the incoming outgoing message */
HBufC8* iData;
/** Buffer for the outgoing address */
HBufC8* iAddress;
};
#endif
// Datagram.cpp
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
// CDatagram (implementation)
#include "DatagramService.h"
EXPORT_C CDatagram* CDatagram::NewL(TDesC8& aBuf)
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
@param aBuf buffer to fill with incoming data
@returns a new CDatagram instance.
*/
{
CDatagram* self = new(ELeave) CDatagram();
CleanupStack::PushL(self);
self->ConstructL(aBuf);
CleanupStack::Pop();
return self;
}
EXPORT_C CDatagram* CDatagram::NewL(const TDesC8& aBuf, const TDesC8& aAddress)
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
@param aBuf buffer containing data to send via service
@param aAddress buffer containing datagram service specific outgoing address
@returns a new CDatagram instance.
*/
{
CDatagram* self = new(ELeave) CDatagram();
CleanupStack::PushL(self);
self->ConstructL(aBuf);
self->SetAddressL(aAddress);
CleanupStack::Pop();
return self;
}
EXPORT_C CDatagram::~CDatagram()
/**
Deletes internal HBufC8 buffers.
*/
{
delete iAddress;
delete iData;
}
void CDatagram::ConstructL(const TDesC8& aBuf)
/**
Second phase of construction.
@param aBuf external buffer.
*/
{
iData = aBuf.AllocL();
}
EXPORT_C const TDesC8& CDatagram::GetAddress()
/**
Accessor for the outgoing address information,
@returns reference to outgoing address.
*/
{
return *iAddress;
}
EXPORT_C void CDatagram::SetAddressL(const TDesC8& aAddress)
/**
Sets the current outgoing address.
@param aAddress buffer containing datagram service specific outgoing address
*/
{
delete iAddress;
iAddress = NULL;
iAddress = aAddress.AllocL();
}
EXPORT_C const TDesC8& CDatagram::GetData()
/**
Accessor for incoming message data received from datagram service.
@returns Reference to internal buffer containing service specific incoming data.
*/
{
return *iData;
}
EXPORT_C void CDatagram::SetDataL(const TDesC8& aData)
/**
Sets the outgoing data to be send via the datagram service.
@param aData buffer containing data to send via service
*/
{
delete iData;
iData = NULL;
iData = aData.AllocL();
}
// DatagramService.cpp
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#include "DatagramService.h"
#include
#include
// Protocol instantiation function
EXPORT_C CDatagramService* CDatagramService::NewL(const TUid aImplementationUid)
{
return static_cast(REComSession::CreateImplementationL(aImplementationUid, _FOFF(CDatagramService, iDtor_ID_Key)));
}
EXPORT_C CDatagramService::CDatagramService()
{
}
EXPORT_C CDatagramService::CDatagramService(const CDatagramService&)
{
}
// Main DLL entry point
TInt E32Dll(TDllReason)
{
return 0;
}
#ifndef __ETELMM_H__
#define __ETELMM_H__
#include
#include
#include
class RMobilePhone : public RPhone
{
// cut-down version of this class for compilation consistency
public:
// class needed to support TMobilePhoneStoreEntryV1 below
class TMultimodeType
{
public:
IMPORT_C TInt ExtensionId() const;
protected:
TMultimodeType();
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
protected:
TInt iExtensionId;
};
// enum needed by TGsmSmsTypeOfAddress in gsmuelem.h
enum TMobileTON
{
EUnknownNumber, // 0
EInternationalNumber, // 1
ENationalNumber, // 2
ENetworkSpecificNumber, // 3
ESubscriberNumber, // 4 - Also defined as "dedicated, short code" in GSM 04.08
EAlphanumericNumber, // 5
EAbbreviatedNumber // 6
};
// enum needed by TGsmSmsTypeOfAddress in gsmuelem.h
enum TMobileNPI
{
EUnknownNumberingPlan =0,
EIsdnNumberPlan=1,
EDataNumberPlan=3,
ETelexNumberPlan=4,
EServiceCentreSpecificPlan1=5,
EServiceCentreSpecificPlan2=6,
ENationalNumberPlan=8,
EPrivateNumberPlan=9,
EERMESNumberPlan=10
};
// enum needed below
enum
{
KMaxMobilePasswordSize=10,
KMaxMobileNameSize=32,
KMaxMobileTelNumberSize=100
};
// class needed to support TMobileGsmSmsEntryV1 below
class TMobileAddress
{
public:
IMPORT_C TMobileAddress();
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
public:
TMobileTON iTypeOfNumber;
TMobileNPI iNumberPlan;
TBuf iTelNumber;
};
// typedef used by TGsmSmsSlot in gsmumsg.h
typedef TBuf TMobileName;
// enum needed for CCommsDbAccess in dbaccess.h
enum TMobilePhoneNetworkMode
{
ENetworkModeUnknown,
ENetworkModeUnregistered,
ENetworkModeGsm,
ENetworkModeAmps,
ENetworkModeCdma95,
ENetworkModeCdma2000,
ENetworkModeWcdma
};
};
// class needed to support RMobilePhoneStore below
class RMobilePhoneStore : public RTelSubSessionBase
{
// cut-down version of this class for compilation consistency
public:
// class needed to support TMobileSmsEntryV1 below
class TMobilePhoneStoreEntryV1 : public RMobilePhone::TMultimodeType
{
protected:
TMobilePhoneStoreEntryV1();
public:
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
public:
TInt iIndex;
};
};
class RMobileSmsMessaging
{
// cut-down version of this class for compilation consistency
public:
// enum needed below
enum
{
KGsmTpduSize = 165, // 140 bytes user data + 25 bytes TPDU header
KCdmaTpduSize = 256 // Max size of Bearer Data in Transport Layer message
};
// typedef needed below
typedef TBuf8 TMobileSmsGsmTpdu;
// enum needed by CSmsSettings in smutset.h
enum TMobileSmsBearer
{
ESmsBearerPacketOnly,
ESmsBearerCircuitOnly,
ESmsBearerPacketPreferred,
ESmsBearerCircuitPreferred
};
};
class RMobileSmsStore : public RMobilePhoneStore
{
// cut-down version of this class for compilation consistency
public:
// enum needed to support CSmsMessage in gsmumsg.h and gsmumsg.inl
enum TMobileSmsStoreStatus
{
EStoredMessageUnknownStatus,
EStoredMessageUnread,
EStoredMessageRead,
EStoredMessageUnsent,
EStoredMessageSent,
EStoredMessageDelivered
};
// class needed to support TMobileGsmSmsEntryV1 below
class TMobileSmsEntryV1 : public RMobilePhoneStore::TMobilePhoneStoreEntryV1
{
public:
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
protected:
TMobileSmsEntryV1();
public:
TMobileSmsStoreStatus iMsgStatus;
};
// class needed to support a TGsmSlot constructor used in file gsmumsg.h
class TMobileGsmSmsEntryV1 : public TMobileSmsEntryV1
{
public:
void InternalizeL(RReadStream& aStream);
void ExternalizeL(RWriteStream& aStream) const;
public:
IMPORT_C TMobileGsmSmsEntryV1();
public:
RMobilePhone::TMobileAddress iServiceCentre;
RMobileSmsMessaging::TMobileSmsGsmTpdu iMsgData;
};
};
#endif
// SMSDatagramService.h
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#ifndef __SMSDATAGRAMSERVICE_H__
#define __SMSDATAGRAMSERVICE_H__
#include
// Forward Declarations
class CSMSSender;
class CSMSReceiver;
class CSMSDatagramService : public CDatagramService
/**
@publishedAll
An SMS Specific Datagram Service API.
CSMSDatagramSerive provides a simple way of sending SMS in 7Bit format most
universally recognised. Sending binary data is not possible without first encoding
the data in a method which will survive being 7Bit encoded.
*/
{
public:
IMPORT_C ~CSMSDatagramService();
IMPORT_C static CDatagramService* NewL();
// from CDatagramService
IMPORT_C void SendL(CDatagram* aDatagram, TRequestStatus& aStatus);
IMPORT_C void ReceiveL(CDatagram* aDatagram, const TDesC8& aRecvParams, TRequestStatus& aStatus);
private:
void ConstructL();
private:
/** Encapsulating Socket based send*/
CSMSSender* iSender;
/** Active object encapsulating Socket based receive*/
CSMSReceiver* iReceiver;
};
#endif
// SMSSendRecv.h
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
// CSMSSender - Send SMS Asynchronously via SMSProt.prt
// CSMSReceiver - Recieve SMS Asynchronously via SMSProt.prt
#ifndef __SMSSENDRECV_H_
#define __SMSSENDRECV_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "SMSDatagramService.h"
// Forward Declarations
class CSMSSender;
class CSMSReceiver;
const TInt KMaxSMSSize = 300; // Max SMS size
const TInt KMaxAddressSize = 20; //Max Telephone Number size
class CSMSSender : public CBase
/**
@internalComponent
Comments : Responsible for opening SMS socket and sending SMS datagrams.
*/
{
public:
static CSMSSender* NewL();
static CSMSSender* NewLC();
~CSMSSender();
void SendSMSL(const TDesC8& aText, const TDesC8& aAddress, TRequestStatus& aStatus);
protected:
CSMSSender(){};
void CreateSMSMessageL(const TDesC8& aText, const TDesC8& aAddress);
void ConstructL();
private:
/** Connection to Socket Server*/
RSocketServ iSocketServer;
/** Socket over which SMS will be sent*/
RSocket iSocket;
/** Connection to File server required by CSMSMessage API*/
RFs iFs;
/** parameter to RSocket::Ioctl()*/
TPckgBuf iBuf;
};
class CSMSReceiver : public CActive
/**
@internalComponent
Comments : Active object responsible for opening SMS socket and receiving SMS datagrams.
*/
{
public:
enum TReceiveStatus
{
EIdle, EListening, EAcknowledging
};
public:
static CSMSReceiver* NewL();
static CSMSReceiver* NewLC();
~CSMSReceiver();
TInt ListenForSMSL(const TDesC8& aPattern, CDatagram* aDatagram);
void ListenForSMSL(const TDesC8& aPattern, CDatagram* aDatagram, TRequestStatus& aStatus);
//Implemented functions from CActive
void DoCancel();
void RunL();
protected:
CSMSReceiver();
void ConstructL();
void SetupSocketsL(const TDesC8& aPattern);
void ExtractMessageL();
private:
/** Connection to Socket Server*/
RSocketServ iSocketServer;
/** Socket over which SMS will be sent*/
RSocket iSocket;
/** Connection to File server required by CSMSMessage API*/
RFs iFs;
/** parameter to RSocket::Ioctl()*/
CSmsMessage* iSmsMsg;
TPckgBuf iBuf;
/** Current state transition*/
TReceiveStatus iReceiveStatus;
/** TRequestStatus to be completed upon Receive*/
TRequestStatus* iClientStatus;
/** Datagram to be populated*/
CDatagram* iDatagram;
};
#endif
// SMSDatagramService.cpp
//
// Copyright (c) 2003 Symbian Ltd. All rights reserved.
//
#include "SMSDatagramService.h"
#include "SMSSendRecv.h"
#include
#include
EXPORT_C CSMSDatagramService::~CSMSDatagramService()
/**
ECOM will destroy the current instance. We also clean up our internal
send and receiver helper classes.
*/
{
REComSession::DestroyedImplementation(iDtor_ID_Key);
delete iSender;
delete iReceiver;
}
EXPORT_C CDatagramService* CSMSDatagramService::NewL()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves nothing on the CleanupStack.
Will be called explicitly by the ECOM framework.
@returns a new CSMSDatagramService instance.
*/
{
CSMSDatagramService* self = new (ELeave) CSMSDatagramService();
CleanupStack::PushL(self);
static_cast(self)->ConstructL();
CleanupStack::Pop();
return self;
}
void CSMSDatagramService::ConstructL()
/**
Intended Usage: Static factory constructor. Uses two phase
construction and leaves an instance of CSMSDatagramService on the CleanupStack.
@returns a new CSMSDatagramService instance.
*/
{
iSender = CSMSSender::NewL();
iReceiver = CSMSReceiver::NewL();
}
EXPORT_C void CSMSDatagramService::SendL(CDatagram* aDatagram, TRequestStatus& aStatus)
/**
Send an SMS Asynchronously
@param aDatagram CDatagram to be sent
@param aStatus Clients TRequestStatus which will be notified of completion of send
*/
{
iSender->SendSMSL(aDatagram->GetData(), aDatagram->GetAddress(), aStatus);
}
EXPORT_C void CSMSDatagramService::ReceiveL(CDatagram* aDatagram, const TDesC8& aRecvParams, TRequestStatus& aStatus)
/**
Receive an SMS message Asynchronously
@param aDatagram CDatagram to be populated during receive.
@param aRecvParams buffer pattern match at beginning of incoming SMS message. Only SMS
messages containing this Pattern match will be intercepted. Example: //MYPATTERN
@param aStatus Clients TRequestStatus which will be notified of completion of Receive
*/
{
iReceiver->ListenForSMSL(aRecvParams, aDatagram, aStatus);
}
// Define the interface UIDs
const TImplementationProxy ImplementationTable[] =
/**
ECOM Specific entry point to create an CDatagramService derived instance.
*/
{
{{0x101FA9C3}, CSMSDatagramService::NewL},
};
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
{
aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
return ImplementationTable;
}
TInt E32Dll(TDllReason)
{
RFs aFs;
aFs.Connect();
RFile aFile;
aFile.Create( aFs, _L("c:\\log333333.txt"), EFileWrite);
aFile.Close();
aFs.Close();
return KErrNone;
}
// 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);
smsAddr.SetPort(smsAddr.Port() + 1);
TInt aError = 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::ESmsAlphabet8Bit);
smsSettings.SetTextCompressed(EFalse);
smsMsg->SetUserDataSettingsL(smsSettings);
TBuf toAddress;
toAddress.Copy(aAddress);
smsMsg->SetToFromAddressL(toAddress);
//smsMsg->SmsPDU().SetServiceCenterAddressL(smsMsg->ServiceCenterAddress());
smsMsg->SmsPDU().SetServiceCenterAddressL(_L("+8613800100500"));
//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);
//iSocket.Ioctl(KIoctlSendSmsMessage, aStatus, &iBuf, KLevelUnspecified);
int i =0;
i = 1;
}
/*
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 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();
}
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9059159/viewspace-588937/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9059159/viewspace-588937/