wireless
Search EarthWeb
CodeGuru | Gamelan | Jars | Wireless | Discussions
Navigate developer.com
Architecture & Design  
Database  
Java
Languages & Tools
Microsoft & .NET
Open Source  
Project Management  
Security  
Techniques  
Voice  
Web Services  
Wireless/Mobile
XML  
New
 
Technology Jobs  

   Developer.com Webcasts:
  The Impact of Coding Standards and Code Reviews

  Project Management for the Developer

  Defining Your Own Software Development Methodology

  more Webcasts...




Vote for the Developer.com Product of the Year Winners!




Developer Jobs

Be a Commerce Partner














 


Developer News -
Apple's iPhone SDK Off to The Races    March 12, 2008
Sales Data, New Challengers Don't Bode Well For Moto    February 28, 2008
iPhone Grabs Market Share, But Not Yet in The Enterprise    February 6, 2008
Open Wireless Network Looms on Horizon    February 1, 2008
Free Tech Newsletter -

BREW's Short Messaging Service Interfaces: Which to Use and Why
By Ray Rischpater

Go to page: 1  2  Next  

If you've downloaded the latest QUALCOMM BREW SDKs (see the resources section) and reviewed the documentation, you doubtless saw a bevy of new Short Messaging Service (SMS)-related interfaces including ISMS, ISMSMsg, ISMSNotifier, and ISMSStorage. If so, you're probably wondering: What do these classes offer that ITAPI doesn't, and why would you use them? You're not alone. In this article, I'll review how SMS sends and receives works in BREW, and explain why there are all of these new classes around the SMS protocol. Fortunately, as you will see, most applications can continue to use the existing ITAPI interfaces for managing SMS; the new interfaces are for a few very specific purposes.

The ITAPI Interface and SMS

For time immemorial (BREW time, anyway), the ITAPI interface has been your pathway to sending and receiving SMS. Sending is trivial, thanks to the ITAPI_SendSMS method, which takes the destination address, message, and an optional class ID to which the message should be delivered as well as a status callback, like this:

   ITAPI_SendSMS (pITapi, "8885551212", "Hello World",
                  0,MOSMSNotify, pThis );
void MOSMSNotify( void *p, int result )
{
   if ( result == AEEMOSMS_ERR_NO_ERR )
      DBGPRINTF("Success!");
 5  else
      DBGPRINTF("Failure &d", result );
}

It's up to your application logic to determine how best to handle errors; some error codes returned by the ITAPI interface are temporary in nature (such as the network being unavailable), while others are more grievous—such as the message not being accepted by the network at all, or an internal configuration error (likely from a handset that's not been provisioned).

While sending SMS messages is trivial—all it requires is the message text and a callback—receiving messages presents you with a number of choices in how you wish to receive a message. All handsets have always had the ability to receive BREW-directed SMS messages (also called BDSMS), those messages which begin with the string //BREW:classid: where classid is your application's class id. When the handset receives a BDSMS to your application, it posts the payload of the message to your application using the EVT_APP_MESSAGE event.

More recent versions of BREW let you receive all SMS text messages, although you need to take care when doing this that you don't inadvertently hijack the handset's text messaging application, keeping the handset user from receiving any text messages. To do this, you must only register for with the TAPI class using the NMASK_TAPI_SMS_TEXT mask in your application's Module Information File (MIF). When a message comes in, your application receives an EVT_NOTIFY, and can get the contents of the message as an AEESMSTextMsg structure like this:

// In your application's event handler
case EVT_NOTIFY:
{
   AEENotify *pNoti = (AEENotify *)dwParam;
   if ( pNoti->cls ==  AEECLSID_TAPI )
   {
      AEESMSMsg pMsg = (AEESMSTextMsg *)pNoti->pData;
      // Do something with the payload here.
   }
}

Text SMS messages are just one of a subset of messages deliverable via SMS; the SMS protocol provides for multiple addresses for SMS messages, called teleservice ids. These are analogous to the notion of a port number in the TCP/IP protocol; different teleservice ID's are used for different purposes, such as WAP push notifications or voicemail notifications. You can receive these messages with ITAPI, too, using a very similar mechanism; see the BREW documentation for details.

The ISMS Interface

New in the latest versions of BREW 3.1.2 is a suite of SMS interfaces, ISMS, ISMSNotifier, ISMSMsg, and ISMSStorage. These interfaces open up the entire suite of SMS on the phone, letting you:

  • Send SMS messages—text or binary—using ISMS and ISMSMsg
  • Receive SMS messages using ISMSNotifier, ISMS, and ISMSMsg
  • Insert and fetch messages from the handset's native message store

Looking at this list, you might surmise that these interfaces aren't for general consumption, and you'd be absolutely correct. These interfaces are provided largely for handset manufacturers, who now can write the handset's embedded messaging suite in BREW, something that couldn't easily be done before. Nonetheless, it's instructive to look at how these classes work, if only because they provide insight into how the handset's SMS functionality works under the hood.

Consider sending an SMS: Previously, as developers we've only been able to send SMS using ITAPI_SendSMS. By using ISMS and ISMSMsg, there's considerably more flexibility—at the cost of complexity, as you can imagine. Here's pseudocode to send a message:

// Make a new SMS message
   nResult = ISHELL_CreateInstance(pThis->sApplet.m_pIShell,
                                   AEECLSID_SMSMSG,
                                   (void**)&(pISMSMsg));
   if(nResult != SUCCESS )
   {
      DBGPRINTF("Failed to create ISMSMsg %s", nResult);
      goto fail;
   }
   // Make a new SMS service
   nResult = ISHELL_CreateInstance(pThis->sApplet.m_pIShell,
                                   AEECLSID_SMS,
                                   (void**)&(pThis->pISMS));
   if(nResult != SUCCESS )
   {
      DBGPRINTF("Failed to create ISMS %s", nResult);
      goto fail;
   }
   // Configure our options buffer. Options will be added
   // "one at a time"
   sOpts[1].nId = MSGOPT_END;
   sOpts[1].pVal = NULL;
   // We need to instruct the ISMSMessage to copy options that
   // are passed
   sOpts[0].nId = MSGOPT_COPYOPTS;
   sOpts[0].pVal = (void *)TRUE;
   ISMSMSG_AddOpt(pISMSMsg, (WebOpt *)&sOpts);
   // Set the destination address on our outbound sms message
   sOpts[0].nId = MSGOPT_TO_DEVICE_SZ;
   sOpts[0].pVal = (void *)"8885551212"
   ISMSMSG_AddOpt(pISMSMsg, (WebOpt *)&sOpts);
   // priority
   sOpts[0].nId = MSGOPT_PRIORITY;
   sOpts[0].pVal = (void *)AEESMS_PRIORITY_NORMAL;
   ISMSMSG_AddOpt(pISMSMsg, (WebOpt *)&sOpts);
   // sender address (from).  We get the sender's MDN from ITAPI
   nResult = ISHELL_CreateInstance(pThis->sApplet.m_pIShell,
                                   AEECLSID_TAPI,
                                   (void **)&pITapi);
   if(nResult != SUCCESS)
   {
      DBGPRINTF("Failed to create ITAPI instance %s", nResult);
      goto fail;
   }
   ITAPI_GetStatus(pITapi, &sStatus);
   ITAPI_Release(pITapi);
   sOpts[0].nId = MSGOPT_FROM_DEVICE_SZ;
   sOpts[0].pVal = (void *)&sStatus.szMobileID[5];
   ISMSMSG_AddOpt(pISMSMsg, (WebOpt *)&sOpts);
   sOpts[0].nId = MSGOPT_MOSMS_ENCODING;
   sOpts[0].pVal = (void *)AEESMS_ENC_ASCII;
   ISMSMSG_AddOpt(pISMSMsg, (WebOpt *)&sOpts);
   sOpts[0].nId = MSGOPT_PAYLOAD_SZ;
   sOpts[0].pVal = (void *)"Hello World";
   ISMSMSG_AddOpt(pISMSMsg, (WebOpt *)&sOpts);
   sOpts[0].nId = MSGOPT_PAYLOAD_ENCODING;
   sOpts[0].pVal = (void *)AEE_ENC_ISOLATIN1;
   ISMSMSG_AddOpt(pISMSMsg, (WebOpt *)&sOpts);
   // Prepare to send the message by init'ing callback and
   // setting status
   CALLBACK_Init(&pThis->m_sSendMessageCallback, SMSSendCB, pThis);
   ISMS_SendMsg(pThis->pISMS, pISMSMsg,
                &pThis->m_sSendMessageCallback, 
                &pThis->m_dwSMSSendResult);
// And our callback
static void SMSSendCB(CApp *pThis)
{
   int  nResult = EFAILED;
   uint32  dwErrorType = 0;
   uint32  dwErrorCode = EFAILED;
   dwErrorType = AEESMS_GETERRORTYPE(pThis->m_dwSMSSendResult);
   DBGPRINTF("etype: 0x%x", dwErrorType);
   dwErrorCode = AEESMS_GETERROR(pThis->m_dwSMSSendResult);
   DBGPRINTF("ecode: 0x%x", dwErrorCode);
   switch(dwErrorType)
   {
   case 0:
      // Should be a success!
      break;
   case 1:
      // SMSC Error type 1
      break;
   case 2:
      // SMSC Error type 2
      break;
   case 3:
      // SMSC Error type 3
      break;
   default:
      DBGPRINTF("invalid error type %d", dwErrorType);
      break;
  }
}

Wow. That's a lot of code just to send a message! After creating an empty SMS message and an instance of ISMS (which will actually perform the sending operation), most of the code consists of configuring the SMS message with the options for the message, such as its destination address, sender address, encoding (ASCII, as opposed to a binary SMS message), message payload (the ubiquitous "Hello World", and how the payload is encoded (ISO-Latin character set). For users of IWeb, this interface should look familiar—under the hood, an ISMSMessage is actually a collection of WebOpts.

Go to page: 1  2  Next  


Tools:
Add www.developer.com to your favorites
Add www.developer.com to your browser search box
IE 7 | Firefox 2.0 | Firefox 1.5.x
Receive news via our XML/RSS feed


BREW Archives






internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers