ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 代码共享:拦截短消息,发送短信代码。接收没有提示音,发送也不提示用户

代码共享:拦截短消息,发送短信代码。接收没有提示音,发送也不提示用户

原创 Linux操作系统 作者:c00lsun 时间:2009-04-14 10:21:02 0 删除 编辑
    网上拦截短信的代码不少,都是用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();
        }


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9059159/viewspace-588937/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-03-23

  • 博文量
    31
  • 访问量
    46916