×

Discussion Board

Page 1 of 2 12 LastLast
Results 1 to 15 of 30
  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    13

    Sending and Receiving SMS Series 60 C++

    All,

    This does not seem like a strange need, but I cannot find a cogent example on symbiandevnet or on this forum....

    What I would like (need at this point) is a simple, cogent example that demonstrates an application sending an SMS from a Series 60 device (in C++) and receiving an SMS from another terminal.

    That's it. Simple. When I look thru the (very confusing) documentation, I see references to CSendAs, MTMs, BIO messasing, etc. I am very confused ---

    I cannot find one simple example that says "Here's how to send an SMS from your Series 60 program using C++" or "Here's how to receive an SMS using your custom application."

    There are "teaser" examples on the Symbian Web site, but I am not sure that they will work on the Series 60 devices, which I understand Nokia is supposed to support.

    Nokia, expert developer, anyone know how to do what I'm looking for on a Series 60 device using C++? Can you point me to sample code that works?

    Many thanks,
    John

  2. #2
    Registered User
    Join Date
    Mar 2003
    Posts
    36

    works on emulator and nokia 3650 device

    i had the same problem as you, i found a solution after looking at several forums, i'll post all my code. i got this info from symbianyucca and others.

    i'm using the series 60 skd v1.0.

    1 - get the following missing .h files from the nokia communicator 9200 sdk and put them in your '\epoc32\include\' directory:

    etelbgsm.h
    comabs.h
    smsetdlg.h
    etelgprs.h
    smsu.h

    2 - cut and paste the following code and build (this is just the nokia 9200 'send sms' example code slightly modified because the example code has a telephone number dialog not supported in the series 60 sdk). make sure you change the .pkg file to reflect the appropriate paths. when executing program, don't hit the pencil button when entering the sms number, it will crash the program. it's easy to fix, i didn't fix it because i didn't need the dialog.

    /*

    GDSMS.H - header file for GDSMS application


    */

    #ifndef __GDSMS_H__
    #define __GDSMS_H__

    #if !defined(__EIKAPP_H__)
    #include <eikapp.h> // for CEikApplication
    #endif

    #if !defined(__EIKDOC_H__)
    #include <eikdoc.h> // for CEikDocument
    #endif

    #if !defined(__EIKAPPUI_H__)
    #include <eikappui.h> // for CEikAppUi
    #endif

    #if !defined(__EIKDIALG_H__)
    #include <eikdialg.h> // for CEikDialog, CCoeControl
    #endif

    #if !defined(__MSVAPI_H__)
    #include <msvapi.h> // for MMsvSessionObserver
    #endif

    // Forward declarations
    class CClientMtmRegistry;
    class CMsvSession;
    class CBaseMtm;




    //
    // Application View class
    //
    class CGDSMSAppView : public CCoeControl
    {
    public:
    static CGDSMSAppView* NewL(const TRect& aRect);
    static CGDSMSAppView* NewLC(const TRect& aRect);
    protected:
    private:
    CGDSMSAppView();
    void ConstructL(const TRect& aRect);
    void Draw(const TRect& aRect) const;
    };


    //
    // Application Ui class, this contains all application functionality
    //
    class CGDSMSAppUi : public CEikAppUi, public MMsvSessionObserver
    {
    public:
    void ConstructL();
    ~CGDSMSAppUi();
    TBool MessageReceivedL(TMsvId aEntryId);
    void HandleCommandL(TInt aCommand);

    protected:

    private:
    void CompleteConstructL();
    void CmdSendL();
    void CmdExitL();
    TBool InitializeCommunicationsL();
    TMsvId CreateNewMessageL();
    TBool SendMessageL();
    void SetEntryL(TMsvId aEntryId);
    TMsvId MoveMessageEntryL(TMsvId aTarget);
    void SetScheduledSendingStateL(CMsvEntrySelection* aSelection);
    TBool DeleteSentEntry(TMsvId aEntryId);
    void DeleteMessagesFromInboxL();

    private: // from MMsvSessionObserver
    void HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);

    private:
    CGDSMSAppView* iAppView;
    HBufC* iRecipient; // recipients gsm number

    TMsvId iMsvId; // message server entry id
    CMsvSession* iSession; // Client session on the message server
    CBaseMtm* iMtm; // Message Type Module (sms)
    CClientMtmRegistry* iMtmReg; // Mtm client registry for creating new mtms
    };


    //
    // Application document class
    //
    class CGDSMSDocument : public CEikDocument
    {
    public:
    static CGDSMSDocument* NewL(CEikApplication& aApp);
    CEikAppUi* CreateAppUiL();
    protected:
    private:
    CGDSMSDocument(CEikApplication& aApp);
    void ConstructL();
    };


    //
    // Application class
    //
    class CGDSMSApplication : public CEikApplication
    {
    public:
    TUid AppDllUid() const;
    private:
    CApaDocument* CreateDocumentL();
    };


    #endif // __GDSMS_H__

  3. #3
    Registered User
    Join Date
    Mar 2003
    Posts
    36
    /*

    GDSMS.CPP - source file for GDSMS application


    */


    #include <txtrich.h> // for CRichText
    #include <smscmds.h> // for TSmsMtmCommand (asynchronous sms commands)
    #include <eikenv.h> // for CEikonEnv
    #include <smuthdr.h> // for CSmsHeader
    #include <smsetdlg.h> // for CSmsAddServiceCentreDialog
    #include <comabs.h> // for CCommandAbsorbingControl
    #include <mtclreg.h> // for CClientMtmRegistry
    #include <smutset.h> // for CSmsMessageSettings

    #include "gdsms.h" // own definitions
    #include "gdsms.hrh" // own resource header
    #include <gdsms.rsg>

    #include <AknQueryDialog.h> // for CAknTextQueryDialog


    // this is the content of the message
    _LIT(KGDSMSTag, "GDSM");



    // Own constants
    const TUid KUidGDSMS = { 0x101F3CD9 }; // GDSMS application UID
    const TInt KTagLength = 4; // length of our message tag
    const TInt KMaxTelephoneNumberLength = 30; // maximum length for a gsm number


    //
    // CGDSMSAppView
    //

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppView::NewL()

    2nd phase construction.

    Return values: CGDSMSAppView*

    -----------------------------------------------------------------------------
    */
    CGDSMSAppView* CGDSMSAppView::NewL(const TRect& aRect)
    {
    CGDSMSAppView* self=NewLC(aRect);
    CleanupStack::Pop(); // self
    return self;
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppView::NewLC()

    2nd phase construction. Created object is put into CleanupStack
    before calling ConstructL().

    Return values: CGDSMSAppView*

    -----------------------------------------------------------------------------
    */
    CGDSMSAppView* CGDSMSAppView::NewLC(const TRect& aRect)
    {
    CGDSMSAppView* self = new(ELeave) CGDSMSAppView();
    CleanupStack::PushL(self);
    self->ConstructL(aRect);
    return self;
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppView::CGDSMSAppView()

    C++ constructor

    -----------------------------------------------------------------------------
    */
    CGDSMSAppView::CGDSMSAppView()
    {
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppView::ConstructL()

    2nd phase constructor.

    Return values: CGDSMSAppView*

    -----------------------------------------------------------------------------
    */
    void CGDSMSAppView::ConstructL(const TRect& aRect)
    {
    CreateWindowL();
    SetRect(aRect);
    ActivateL();
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppView:raw()

    Simple Draw method (only clears the application area).

    -----------------------------------------------------------------------------
    */
    void CGDSMSAppView:raw(const TRect& /*aRect*/) const
    {
    CWindowGc& gc = SystemGc();
    gc.Clear();
    }


    //
    // CGDSMSAppUi
    //

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::ConstructL()

    2nd phase constructor

    -----------------------------------------------------------------------------
    */
    void CGDSMSAppUi::ConstructL()
    {

    BaseConstructL(); // init this AppUi with standard values
    iAppView=CGDSMSAppView::NewL(ClientRect());

    iRecipient=HBufC::NewL(KMaxTelephoneNumberLength); // for recipient sms number
    iMsvId = NULL; // MsvId for keeping track of the message server entries.

    // Create CMsvSession
    iSession = CMsvSession::OpenAsyncL(*this); // new session is opened asynchronously
    // CompleteConstructL() is called when async finishes

    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::~CGDSMSAppUi()

    Destructor.

    -----------------------------------------------------------------------------
    */
    CGDSMSAppUi::~CGDSMSAppUi()
    {
    delete iAppView;

    delete iRecipient;

    delete iMtm;
    delete iMtmReg;

    iMsvId = NULL;

    delete iSession; // session must be deleted last (and constructed first)
    }




    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::CompleteConstructL()

    Creates client MTM registry when session is ready for use.
    This completes model construction and is called after 'server
    ready' event is received after async opening of CMsvSession.

    -----------------------------------------------------------------------------
    */

    void CGDSMSAppUi::CompleteConstructL()
    {
    // We get a MtmClientRegistry from our session
    // this registry is used to instantiate new mtms.
    iMtmReg = CClientMtmRegistry::NewL(*iSession);

    // notify the user with a InfoWin
    iEikonEnv->InfoWinL(_L("Construction"),_L("Server session opened."));
    }

  4. #4
    Registered User
    Join Date
    Mar 2003
    Posts
    36
    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::HandleSessionEventL()

    Handles session event observer and calls event handling functions in
    observer. Note that if additional session event handlers are defined in
    the session, they are called before this function (as this is the
    main session observer).

    The type of event is indicated by the value of aEvent. The
    interpretation of the TAny arguments depends on this type. For most
    event types, the action that is taken, for example, updating the
    display, is client-specific. All clients though should respond to
    EMsvCloseSession and EMsvServerTerminated events.

    -----------------------------------------------------------------------------
    */
    void CGDSMSAppUi::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/)
    {
    switch (aEvent)
    {

    case EMsvEntriesCreated: // A new entry has been created in the message server
    // We are interested in messages that are created in Inbox
    TMsvId* entryId;
    entryId = static_cast<TMsvId*>(aArg2); // entry id from the session event

    if ( *entryId == KMsvGlobalInBoxIndexEntryId ) // new entry has been created in Inbox folder
    {
    // We take the created entries into a selection
    CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);

    // entry pointer for making changes in the actual message contexts
    CMsvEntry* entry;

    //Process each created entry, one at a time.
    for(TInt i = 0; i < entries->Count(); i++)
    {
    // Setting all messages in the selection as invisible
    entry = iSession->GetEntryL( entries->At(i) ); // this reserves memory for a new CMsvEntry
    TMsvEntry msvEntry(entry->Entry());
    msvEntry.SetVisible(EFalse); // set as invisible

    if( MessageReceivedL(entries->At(i)) ) // this checks the entry and handles it if it is targeted to GDSMS app
    {
    // this is our message, set also as read
    msvEntry.SetUnread(EFalse);
    msvEntry.iMtmData3 = KUidGDSMS.iUid; // use our app uid as an identifier
    }
    else
    {
    // message was not for us, settin it as visible again
    msvEntry.SetVisible(ETrue);
    }

    entry->ChangeL( msvEntry ); // commit changes
    delete entry;
    }
    }
    break;

    case EMsvEntriesMoved: // this event is given when message entries are moved
    {
    // An entry has been moved to another parent
    // We are interested messages that have been moved to Sent folder
    TMsvId* entryId;
    entryId = static_cast<TMsvId*>(aArg2);

    if ( *entryId == KMsvSentEntryId ) // the entry has been moved into Sent folder
    {
    // We take the moved entries into a selection
    CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);

    //Process each created entry, one at a time.
    for(TInt i = 0; i < entries->Count(); i++)
    {
    DeleteSentEntry(entries->At(i)); // this checks the entry and deletes if it is created by GDSMS app
    }
    }
    }
    break;

    // This event tells us that the session has been opened
    case EMsvServerReady:
    CompleteConstructL(); // Construct the mtm registry & sms mtm
    break;

    default:
    // All other events are ignored
    break;
    }

    }



    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::HandleCommandL(TInt aCommand)

    Handle the commands from CBA and menu items

    -----------------------------------------------------------------------------
    */
    void CGDSMSAppUi::HandleCommandL(TInt aCommand)
    {
    switch (aCommand)
    {
    case EGDSMSCmdSend:
    CmdSendL();
    break;
    case EEikCmdExit:
    CmdExitL();
    break;
    default:
    break;
    }
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::CmdSendL()

    Handle send command

    -----------------------------------------------------------------------------
    */
    void CGDSMSAppUi::CmdSendL()
    {
    if (!InitializeCommunicationsL())
    {
    iEikonEnv->InfoWinL(_L("Error"),_L("Problems in initializing\ncommunications."));
    return;
    }
    if (!SendMessageL())
    {
    iEikonEnv->InfoWinL(_L("Error"),_L("Problems in sending\nmessage."));
    return;
    }
    }


    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::CmdExitL()

    Exit application

    -----------------------------------------------------------------------------
    */

    void CGDSMSAppUi::CmdExitL()
    {
    DeleteMessagesFromInboxL();
    Exit();
    }



    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::InitializeCommunicationsL()

    Initialize a new message and ask the user for a recipient gsm number.

    Return values: ETrue or EFalse

    -----------------------------------------------------------------------------
    */
    TBool CGDSMSAppUi::InitializeCommunicationsL()
    {
    // first the tel number
    // we get it from our telNumDialog
    // CGDSMSTelNumDialog* telNumDialog=new(ELeave)CGDSMSTelNumDialog(*iRecipient);

    // if (!telNumDialog->ExecuteLD(R_GDSMS_TEL_NUMBER_DIALOG))
    // return EFalse;

    TBuf<20> addr = iRecipient->Des();
    CAknTextQueryDialog* telNumDialog = CAknTextQueryDialog::NewL(addr, CAknQueryDialog::ENoTone);

    if (!telNumDialog->ExecuteLD(R_GDSMS_TEL_NUMBER_DIALOG))
    return EFalse;

    iRecipient->Des() = addr;

    // set up a new message
    iMsvId = CreateNewMessageL();
    // Set the new message to be the current entry
    SetEntryL(iMsvId);

    return ETrue;
    }



    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::CreateNewMessageL()

    Creates a new message server entry and set up default values.

    Return values: TMsvId (the id of created entry)

    -----------------------------------------------------------------------------
    */
    TMsvId CGDSMSAppUi::CreateNewMessageL()
    {
    TMsvEntry newEntry; // This represents an entry in the Message Server index
    newEntry.iMtm = KUidMsgTypeSMS; // message type is SMS
    newEntry.iType = KUidMsvMessageEntry; // this defines the type of the entry: message
    newEntry.iServiceId = KMsvLocalServiceIndexEntryId; // ID of local service (containing the standard folders)
    newEntry.iDate.HomeTime(); // set the date of the entry to home time
    newEntry.SetInPreparation(ETrue); // a flag that this message is in preparation

    //----
    //newEntry.iBioType = 0x1000ffff; // define a bio UID if sending a bio message over SMS bearer
    //----

    // - CMsvEntry accesses and acts upon a particular Message Server entry.
    // - NewL() does not create a new entry, but simply a new object to access an existing entry.
    // - It takes in as parameters the client's message server session,
    // ID of the entry to access and initial sorting order of the children of the entry.
    //
    CMsvEntry* entry = CMsvEntry::NewL(*iSession, KMsvDraftEntryIdValue ,TMsvSelectionOrdering());
    CleanupStack::PushL(entry);
    // CCommandAbsorbingControl::NewLC();
    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
    wait->Start();
    // We create a new entry asynchronously...
    CMsvOperation* oper = entry->CreateL(newEntry,wait->iStatus);
    CleanupStack::PushL(oper);
    CActiveScheduler::Start();

    // ...and keep track of the progress of the create operation.
    TMsvLocalOperationProgress progress = McliUtils::GetLocalProgressL(*oper);
    User::LeaveIfError(progress.iError);

    // Set our entry context to the created one
    entry->SetEntryL(progress.iId); // operation progress contains the ID of the ceated entry

    CleanupStack::PopAndDestroy(3); // entry,oper,wait, CCommandAbsorbingControl

    return progress.iId;
    }

  5. #5
    Registered User
    Join Date
    Mar 2003
    Posts
    36
    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::SetEntryL(TMsvId aEntryId)

    Set up current message entry.

    Note: It can be useful to remember the original entry id for
    error handling.

    -----------------------------------------------------------------------------
    */

    void CGDSMSAppUi::SetEntryL(TMsvId aEntryId)
    {
    // Get the server entry from our session
    CMsvEntry* entry = iSession->GetEntryL(aEntryId);
    CleanupStack::PushL(entry);

    // Check if our mtm is different from the mtm set to our entry
    if (iMtm == NULL || entry->Entry().iMtm != (iMtm->Entry()).Entry().iMtm)
    {
    // If so, we delete the old...
    delete iMtm;
    iMtm = NULL;

    // ...and get a new one from the MtmRegistry
    iMtm = iMtmReg->NewMtmL(entry->Entry().iMtm);
    iMtm->SetCurrentEntryL(entry);
    }
    else
    {
    // if there is no need to change our mtm,
    // we only set our entry as current.
    iMtm->SetCurrentEntryL(entry);
    }

    CleanupStack::Pop(); //entry
    entry = NULL;
    }



    /*
    -----------------------------------------------------------------------------
    CGDSMSAppUi::SendMessageL()

    Prepares the message body and sends the message.

    Return values: ETrue or EFalse

    -----------------------------------------------------------------------------
    */
    TBool CGDSMSAppUi::SendMessageL()
    {

    TMsvEntry msvEntry = iMtm->Entry().Entry();

    // We get the message body from Mtm and insert a bodytext
    CRichText& mtmBody = iMtm->Body();
    mtmBody.Reset();
    mtmBody.InsertL(0, KGDSMSTag); // insert our msg tag as the body text

    // set iRecipient into the Details of the entry
    msvEntry.iDetails.Set(iRecipient->Des()); // set recipient info in details
    msvEntry.SetInPreparation(EFalse); // set inPreparation to false

    msvEntry.SetSendingState(KMsvSendStateWaiting); // set the sending state (immediately)
    msvEntry.iDate.HomeTime(); // set time to Home Time


    // To handle the sms specifics we start using SmsMtm
    CSmsClientMtm* smsMtm = STATIC_CAST(CSmsClientMtm*, iMtm);


    //
    smsMtm->RestoreServiceAndSettingsL();

    // CSmsHeader encapsulates data specific for sms messages,
    // like service center number and options for sending.
    CSmsHeader& header = smsMtm->SmsHeader();
    CSmsSettings* sendOptions = CSmsSettings::NewL();
    CleanupStack::PushL(sendOptions);
    sendOptions->CopyL(smsMtm->ServiceSettings()); // restore existing settings

    // set send options
    sendOptions->SetDelivery(ESmsDeliveryImmediately); // set to be delivered immediately
    header.SetSmsSettingsL(*sendOptions);

    // let's check if there's sc address
    if (header.Message().ServiceCenterAddress().Length() == 0)
    {
    // no, there isn't. We assume there is at least one sc number set and use
    // the default SC number.
    CSmsSettings* serviceSettings = &(smsMtm->ServiceSettings());

    // if number of scaddresses in the list is null
    if (!serviceSettings->NumSCAddresses())
    {
    // here there should be a dialog in which user can add sc number
    iEikonEnv->InfoWinL(_L("No service center number"),_L("cannot send this one."));
    }
    else
    {
    // set sc address to default.
    CSmsNumber* sc = 0;
    sc = &(serviceSettings->SCAddress(serviceSettings->DefaultSC()));
    header.Message().SetServiceCenterAddressL(sc->Address());
    }
    }
    CleanupStack::PopAndDestroy(); // send options

    // Add our recipient to the list, takes in two TDesCs, first is real address and second is an alias
    // works also without the alias parameter.
    smsMtm->AddAddresseeL(iRecipient->Des(),msvEntry.iDetails);

    // Next we mark our message so later on we know which
    // message to delete from the Sent folder
    msvEntry.iMtmData3 = KUidGDSMS.iUid; // use our app uid as an identifier

    // save message
    CMsvEntry& entry = iMtm->Entry();
    entry.ChangeL(msvEntry); // make sure that we are handling the right entry
    smsMtm->SaveMessageL(); // closes the message

    // This moves the message entry to outbox, we'll schedule it for sending after this.
    TMsvId movedId = MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId ); // move message to outbox


    // We must create an entry selection for message copies (although now we only have one message in selection)
    CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
    CleanupStack::PushL(selection);

    selection->AppendL(movedId); // add our message to the selection
    SetScheduledSendingStateL(selection); // schedule the sending with the active scheduler

    CleanupStack::PopAndDestroy(); // selection

    return ETrue; // at this point the message has been sent

    }

    /*
    -----------------------------------------------------------------------------
    CGDSMSAppUi::MoveMessageEntryL(TMsvId aTarget) const

    Moves an entry to another parent.

    Return values: TMsvId of the moved message

    -----------------------------------------------------------------------------
    */
    TMsvId CGDSMSAppUi::MoveMessageEntryL( TMsvId aTarget )
    {
    TMsvEntry msvEntry( (iMtm->Entry()).Entry() );
    TMsvId id = msvEntry.Id();

    if (msvEntry.Parent() != aTarget)
    {
    TMsvSelectionOrdering sort;
    sort.SetShowInvisibleEntries(ETrue); // we want to handle also the invisible entries
    // Take a handle to the parent entry
    CMsvEntry* parentEntry = CMsvEntry::NewL(iMtm->Session(), msvEntry.Parent(), sort);
    CleanupStack::PushL(parentEntry);

    // Move original from the parent to the new location
    // CCommandAbsorbingControl::NewLC();
    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
    wait->Start();

    CMsvOperation* op = parentEntry->MoveL(msvEntry.Id(), aTarget, wait->iStatus);

    CleanupStack::PushL(op);
    CActiveScheduler::Start();
    TMsvLocalOperationProgress prog=McliUtils::GetLocalProgressL(*op);
    User::LeaveIfError(prog.iError);

    id = prog.iId; // id of the moved entry

    CleanupStack::PopAndDestroy(3);// op, wait, parentEntry, CCommandAbsorbingControl
    }
    return id;
    }

    /*
    -----------------------------------------------------------------------------

    void CGDSMSAppUi::SetScheduledSendingStateL

    Schedules the message to be sent through the etel server.

    Return values: none

    -----------------------------------------------------------------------------
    */

    void CGDSMSAppUi::SetScheduledSendingStateL(CMsvEntrySelection* aSelection)
    {

    CBaseMtm* smsMtm = iMtm;

    // Add entry to task scheduler
    TBuf8<1> dummyParams;
    // CCommandAbsorbingControl::NewLC();
    CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
    waiter->Start();
    // invoking async schedule copy command on our mtm
    CMsvOperation* op= smsMtm->InvokeAsyncFunctionL(
    ESmsMtmCommandScheduleCopy,
    *aSelection,
    dummyParams,
    waiter->iStatus);
    CleanupStack::PushL(op);
    CActiveScheduler::Start();
    CleanupStack::PopAndDestroy(2); // waiter, op, CCommandAbsorbingControl

    }

  6. #6
    Registered User
    Join Date
    Mar 2003
    Posts
    36
    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi:eleteSentEntry()

    Delete our message from the Sent folder. We are double checking that
    the entry we are handling is indeed in the Sent folder - AND that it
    is the same message entry that wsa sent by this application.

    If so, the message will be deleted from the Sent folder.

    Return values: ETrue or EFalse

    -----------------------------------------------------------------------------
    */
    TBool CGDSMSAppUi:eleteSentEntry(TMsvId aEntryId)
    {
    // Load this entry to our mtm
    SetEntryL( aEntryId );

    TMsvEntry msvEntry( (iMtm->Entry()).Entry() );


    if (msvEntry.Parent() == KMsvSentEntryId) // check again that our entry is in sent
    {

    if (msvEntry.iMtmData3 == KUidGDSMS.iUid) // this entry has been created by our app
    {
    // Taking a handle to the Sent folder...
    TMsvSelectionOrdering sort;
    sort.SetShowInvisibleEntries(ETrue); // we want to handle also the invisible entries
    // Take a handle to the parent entry
    CMsvEntry* parentEntry = CMsvEntry::NewL(iMtm->Session(), msvEntry.Parent(), sort);
    CleanupStack::PushL(parentEntry);

    // here parentEntry is the Sent folder (must be so that we can call DeleteL)
    parentEntry->DeleteL(msvEntry.Id());

    CleanupStack::PopAndDestroy(parentEntry);

    // information to the user
    iEikonEnv->InfoMsg(_L("Message deleted in SENT folder."));

    return ETrue; // entry was deleted
    }
    }

    return EFalse; // no entries deleted
    }


    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi::MessageReceivedL()

    Handle a new message entry that has been created on the messaging
    server. This method checks if the message was targeted for this
    application and then removes it from the server.

    -----------------------------------------------------------------------------
    */
    TBool CGDSMSAppUi::MessageReceivedL(TMsvId aEntryId)
    {
    TBool returnVal = EFalse;

    CMsvEntry* entry = iSession->GetEntryL(aEntryId);
    CleanupStack::PushL(entry);

    TMsvEntry msvEntry = entry->Entry();

    // first we create a new mtm to handle this message (in case our own mtm is in use)
    CBaseMtm* smsMtm = iMtmReg->NewMtmL(msvEntry.iMtm);
    smsMtm->SwitchCurrentEntryL(aEntryId);

    smsMtm->LoadMessageL(); // load the message

    if (smsMtm->Body().Read(0,4).Compare(KGDSMSTag)==0) // message is targeted to us
    {
    // Now we process the message
    iEikonEnv->InfoMsg(smsMtm->Body().Read(0,4)); // this will flash our message text in the upper right corner of the screen

    returnVal = ETrue;

    /* As a change to the previous version of GDSMS, the message will not be deleted right
    after reading it. Instead all messages that have been read by this app will be deleted
    from the Inbox when this app is closed. See DeleteMessagesFromInboxL().

    */
    }

    // release allocated memory
    delete smsMtm;

    CleanupStack::Pop(); // entry
    delete entry;

    return returnVal;
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSAppUi:eleteMessagesFromInboxL()

    This method reads the Inbox and deletes all GDSM messages that are
    invisible.

    -----------------------------------------------------------------------------
    */
    void CGDSMSAppUi:eleteMessagesFromInboxL()
    {
    // information to the user
    iEikonEnv->InfoMsg(_L("Deleting messages from Inbox."));

    // then delete message from inbox, first take a handle to Inbox...
    TMsvSelectionOrdering sort;
    sort.SetShowInvisibleEntries(ETrue); // we want to handle also the invisible entries
    // Take a handle to the Inbox entry
    CMsvEntry* parentEntry = CMsvEntry::NewL(*iSession, KMsvGlobalInBoxIndexEntryId, sort);
    CleanupStack::PushL(parentEntry);

    CMsvEntrySelection* entries = parentEntry->ChildrenL(); // A selection of all the entries of the Inbox
    CleanupStack::PushL(entries);

    // go through all entries in the Inbox
    for(TInt i = 0; i < entries->Count(); i++)
    {
    if( parentEntry->ChildDataL(entries->At(i)).iMtmData3 == KUidGDSMS.iUid ) // check that message is for GDSMS
    {
    // delete the current entry (message)
    parentEntry->DeleteL(entries->At(i));
    }
    }


    // information to the user
    iEikonEnv->InfoMsg(_L("Done."));

    CleanupStack::PopAndDestroy(2); // entries, parentEntry
    }


    //
    // CGDSMSDocument
    //

    /*
    -----------------------------------------------------------------------------

    CGDSMSDocument::NewL(

    2nd phase construction.

    -----------------------------------------------------------------------------
    */
    CGDSMSDocument* CGDSMSDocument::NewL(CEikApplication& aApp)
    {
    CGDSMSDocument* self = new(ELeave) CGDSMSDocument(aApp);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(); //self.
    return self;
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSDocument::CGDSMSDocument()

    C++ constructor

    -----------------------------------------------------------------------------
    */
    CGDSMSDocument::CGDSMSDocument(CEikApplication& aApp)
    : CEikDocument(aApp)
    {
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSDocument::ConstructL()

    2nd phase constructor.

    -----------------------------------------------------------------------------
    */
    void CGDSMSDocument::ConstructL()
    {
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSDocument::CreateAppUiL()

    Create new CGDSMSAppUi object

    Return values: CEikAppUi*

    -----------------------------------------------------------------------------
    */
    CEikAppUi* CGDSMSDocument::CreateAppUiL()
    {
    return (new(ELeave) CGDSMSAppUi);
    }


    //
    // CGDSMSApplication
    //

    /*
    -----------------------------------------------------------------------------

    CGDSMSApplication::AppDllUid()

    Returns application UID of GDSMS application

    -----------------------------------------------------------------------------
    */
    TUid CGDSMSApplication::AppDllUid() const
    {
    return KUidGDSMS;
    }

    /*
    -----------------------------------------------------------------------------

    CGDSMSApplication::CreateDocumentL()

    Create new application document

    Return values: CApaDocument*

    -----------------------------------------------------------------------------
    */
    CApaDocument* CGDSMSApplication::CreateDocumentL()
    {
    return (CGDSMSDocument::NewL(*this));
    }



    //
    // Functions for Application Architecture
    //

    EXPORT_C CApaApplication* NewApplication()
    {
    return (new CGDSMSApplication);
    }


    //
    // DLL entry point
    //

    GLDEF_C TInt E32Dll(TDllReason)
    {
    return KErrNone;
    }

  7. #7
    Registered User
    Join Date
    Mar 2003
    Posts
    36
    /*

    GDSMS.MMP - make file for GDSMS application


    */

    TARGET GDSMS.APP
    TARGETTYPE APP
    targetpath \SYSTEM\APPS\GDSMS

    UID 0X100039CE 0x101F3CD9

    SOURCEPATH ..\src
    SOURCE gdsms.cpp
    RESOURCE gdsms.rss

    USERINCLUDE ..\inc
    SYSTEMINCLUDE \epoc32\include

    LIBRARY euser.lib // for CBase, CSession, CActiveScheduler, ...
    LIBRARY msgs.lib // for MMsvSessionObserver
    LIBRARY apparc.lib // for CApaDocument
    LIBRARY cone.lib // for CCoeControl
    LIBRARY eikcore.lib // for CEikApplication, CEikDocument, CEikAppUi
    //LIBRARY eikctl.lib // for CEikTelephoneNumberEditor
    //LIBRARY eikcoctl.lib // for CEikBorderedControl
    //LIBRARY eikdlg.lib // for CEikDialog
    //LIBRARY muiu.lib // for CommandAbsorbingControl
    LIBRARY smcm.lib // for TSmsMtmCommand
    LIBRARY gsmu.lib // for Service Center address
    LIBRARY avkon.lib // for CAknTextQueryDialog


    /*

    GDSMS.CPP - resource file for GDSMS application


    */

    NAME GDSM


    #include <eikon.rh>
    #include <eikon.rsg>
    #include "gdsms.hrh"

    #include <avkon.rh>
    #include <avkon.rsg>


    RESOURCE RSS_SIGNATURE {}


    RESOURCE TBUF {buf="";}


    RESOURCE EIK_APP_INFO
    {
    menubar=r_gdsms_menubar;
    hotkeys=r_gdsms_hotkeys;
    cba=r_gdsms_cba;
    }


    RESOURCE MENU_BAR r_gdsms_menubar
    {
    titles =
    {
    MENU_TITLE { menu_pane = r_gdsms_file_menu; txt = "File";},
    MENU_TITLE { menu_pane = r_gdsms_messaging_menu; txt = "Messaging";}
    };
    }


    RESOURCE MENU_PANE r_gdsms_file_menu
    {
    items =
    {
    MENU_ITEM { command = EEikCmdExit; txt = "Close"; }
    };
    }


    RESOURCE MENU_PANE r_gdsms_messaging_menu
    {
    items =
    {
    MENU_ITEM { command = EGDSMSCmdSend; txt = "Send message"; }
    };
    }


    RESOURCE HOTKEYS r_gdsms_hotkeys
    {
    control =
    {
    HOTKEY {command = EEikCmdExit; key = 'e'; }
    };
    plain =
    {
    HOTKEY {command = EGDSMSCmdSend; key = 's'; }
    };
    }


    RESOURCE CBA r_gdsms_cba
    {
    breadth=80;
    buttons=
    {
    CBA_BUTTON
    {
    id = EGDSMSCmdSend;
    txt = "Send";
    },
    CBA_BUTTON
    {
    id = EEikBidBlank;
    txt = "";
    },
    CBA_BUTTON
    {
    id = EEikBidBlank;
    txt = "";
    },
    CBA_BUTTON
    {
    id = EEikCmdExit;
    txt = "Close";
    }
    };
    }

    /*
    RESOURCE DIALOG r_gdsms_tel_number_dialog
    {
    title = "Telephone Number";
    buttons = R_EIK_BUTTONS_CANCEL_OK;
    flags = EEikDialogFlagWait;
    items =
    {
    DLG_LINE
    {
    type = EEikCtTelephoneNumberEditor;
    prompt = "Recipient";
    id = EGDSMSTelNumEditor;
    label = "";
    control = TELNUMBER
    {
    country_prompt = "[country]";
    area_prompt = "[area]";
    number_prompt = "[number]";
    widthinpixels = 200;
    };
    }
    };
    }
    */

    RESOURCE DIALOG r_gdsms_tel_number_dialog
    {
    flags = EGeneralQueryFlags;
    buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
    items=
    {
    DLG_LINE
    {
    type = EAknCtQuery;
    id = EGeneralQuery;
    control= AVKON_DATA_QUERY
    {
    layout = EDataLayout;
    label = "Recipient";
    control = EDWIN
    {
    flags= EEikEdwinNoHorizScrolling | EEikEdwinResizable;
    maxlength = 100;
    width = 5;
    lines = 1;
    default_input_mode = EAknEditorNumericInputMode;
    allowed_input_modes = EAknEditorNumericInputMode;
    };
    };
    }
    };
    }


    /*

    GDSMS.HRH - resource header file for GDSMS application


    */

    #ifndef __GDSMS_HRH__
    #define __GDSMS_HRH__


    enum
    {
    EGDSMSCmdSend=100
    };

    enum
    {
    EGDSMSTelNumEditor
    };


    #endif //__GDSMS_HRH__

    /*

    GDSMS.HRH - resource header file for GDSMS application


    */

    #ifndef __GDSMS_HRH__
    #define __GDSMS_HRH__


    enum
    {
    EGDSMSCmdSend=100
    };

    enum
    {
    EGDSMSTelNumEditor
    };


    #endif //__GDSMS_HRH__









    gdsms.pkg


    ;
    ; Install file for GDSMS
    ;

    ; Languages -
    &EN

    ; Installation header
    ; Application UID
    #{"GDSMS"},(0x101F3CD9),1,40,0
    (0x101F6F88), 0, 0, 0, {"Series60ProductID"}
    ; Three files to install for GDSMS
    "\Symbian\6.1\Series60\Epoc32\release\thumb\urel\gdsms.app"-"!:\system\apps\GDSM
    S\gdsms.app"
    "\Symbian\6.1\Series60\Epoc32\release\thumb\urel\gdsms.rsc"-"!:\system\apps\GDSM
    S\gdsms.rsc"
    "gdsms.aif" - "!:\system\apps\GDSMS\gdsms.aif"

    ; Required files
    ; None

    ; Component .sis files
    ; None

  8. #8
    Registered User
    Join Date
    Oct 2003
    Posts
    28
    I'm having the same problem with MMS. Not a single working example!

    I managed to create an MMS in the outbox, but it's not being sent out. Seems like the access point is wrong, but I have no idea on how to add one.

  9. #9
    Registered User
    Join Date
    Mar 2003
    Posts
    13
    THANK YOU KIND SOUL!
    John

  10. #10
    Registered User
    Join Date
    Dec 2003
    Posts
    3

    Suggestions for MMS

    ajaykapur, would you have any suggestions for MMS? Is it at all related to the missing .h files required for SMS? I am having the same problem as sharibanis with a 3650 emulator (SDK 1.2). I get a System Error when trying to send a MMS (using vanilla Emulator Messaging). If anybody could tell me that they can in fact send a MMS message, then I would feel better and perhaps focus more on my Access Point configuration.

  11. #11
    Regular Contributor
    Join Date
    Feb 2004
    Posts
    51

    ESmsMtmCommandScheduleCopy - undeclared identifier

    hi.

    i am trying to use the posted gdsms code and i am encountering this error. i tried looking for ESmsMtmCommandScheduleCopy from the header files in the \eopc32\include\ folder but i can't find the header file i need to include.

    could someone help me? thanks!

    yen

  12. #12
    Registered User
    Join Date
    Mar 2003
    Posts
    36

    Re: ESmsMtmCommandScheduleCopy - undeclared identifier

    it is defined in the file smscmds.h. also, to the above question about MMS, i do know anything about sending those.

    here is the body of smscmds.h:

    //////////////////////////////////////////////////////////////////////////
    //
    // SmsCmds.H
    //
    // Copyright (c) 1999 Symbian Ltd. All rights reserved.
    //
    //////////////////////////////////////////////////////////////////////////

    #ifndef SMS_CMDS_H_
    #define SMS_CMDS_H_

    const TInt KMinCommandExpected = 10000;

    enum TSmsMtmCommand
    {
    // Asynchronous commands
    ESmsMtmCommandReadServiceCenter = KMinCommandExpected,
    ESmsMtmCommandWriteServiceCenter,
    ESmsMtmCommandScheduleCopy,
    ESmsMtmCommandScheduleMove,
    ESmsMtmCommandDeleteSchedule,
    ESmsMtmCommandCheckSchedule,
    ESmsMtmCommandSendScheduledCopy,
    ESmsMtmCommandSendScheduledMove,
    ESmsMtmCommandEnumerateSim,
    ESmsMtmCommandCopyFromSim,
    ESmsMtmCommandMoveFromSim,
    ESmsMtmCommandDeleteFromSim,
    ESmsMtmCommandReadSimParams,
    ESmsMtmCommandCopyToSim
    };

    #endif

  13. #13
    Regular Contributor
    Join Date
    Feb 2004
    Posts
    51

    thanks!

    thanks ajaykapur!

  14. #14
    Regular Contributor
    Join Date
    Sep 2003
    Posts
    195

    aarrrgghhh

    Hi,
    Did anyone get a sample project of this working that they
    could email me? (just the bare bones compiling project would do fine) I'm getting about a million errors in mine and it's driving me crazy.

    Thanks for any help.

    Paris.

  15. #15
    Regular Contributor
    Join Date
    Sep 2003
    Posts
    195
    Could somebody please post the files:
    etelbgsm.h
    comabs.h
    smsetdlg.h
    etelgprs.h
    smsu.h

    I downloaded the 9200 SDK purely to get these as instructed
    but the installer doesn't even work! I can't even extract
    the headers from the .cab files.

    Thanks for any assistance.

    Paris.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •