Real World Experiences with the WMA and the Push Registry

Real World Experiences with the WMA and the Push Registry


Introduction


This article will recount my experiences on a recent project that involved use of the Wireless Messaging API (WMA) and the Push Registry. The Push Registry is a feature new to the MIDP 2.0 spec, and the WMA, while not a MIDP 2.0 feature, is an optional feature that can be found on several MIDP 1.0 and 2.0 phones.


The functionality achievable with the Push Registry is summarized as follows: the device first receives a message, and if the message contains a header that defines a specific port, the device will pass the message to the application that has been registered for that port. For Java applications, though, the message first gets passed to the JAM (Java Application Manager), and it in turn will pass the message to the J2ME application that has registered the port number.


The WMA allows an application to send and receive SMS or CBS messages while the application is running. When the application is not running (which is probably most of the time), it cannot receive messages unless it is registered with the Push Registry. Controlled by the JAM, the Push Registry will launch the application which has previously registered the port to which the incoming message is destined. The Push Registry can also be set to launch an application at predefined time, but that function will not be discussed here (as it does not apply to using the WMA).



Handling incoming messages


The WMA JavaDocs (specifically, the javax.wireless.messaging.MessageListener page) has an excellent reference implementation for receiving messages. Essentially, the application’s main thread implements the MessageListener interface and performs the main application logic.When a message arrives, a separate object (possibly within another thread) is passed the message and handles it. This is the model I implemented in my several of my client’s projects (with some subtle transformations, of course), and it works well (see Code Sample 1).


This implementation applies to messages received not only while the application is running, but also when the application is started due to a Push Registry notification. When the application is launched in this later way, the Push Registry is queried to see if messages are waiting for this application and processes any that are there.


One issue you may want (or have) to consider at the client application level is how to deal with multiple messages arriving at the same time. To handle all of the messages, they will need to be handled serially, or else some of the messages will be dropped. The downside of this is that if for each message the implementation might display some type of alert message or invoke a function of the application. So sending multiple messages to a destination at once is not a good idea. As always, and especially with this type of messaging we must be vigilant about making the user experience as friendly and simple as possible.


 


Security considerations with messages


An issue to consider with incoming messages is the authenticity of the sender. Assuming the sender had the proper privileges to send an SMS message on the carrier’s network, and further assuming the sender knew the port number at which the Java application is registered in the JAM (via the Push Registry or a live J2ME application that has requested a port), you still may want to include some application-specific way of authenticating the message.


The MIDlet-Push- parameter in the JAD has three comma-delimited values, the last of which is . Defining this value, which is basically a URL, allows incoming messages to be received only from the stated address. While this may be good for friendly network communications, this cannot be relied upon to be completely secure. Thus, you may want to define your own mechanism for validating the incoming message. The message may have cleared the device and the JAM’s security restrictions, but that does not mean the message is safe or valid.


One technique is to embed a binary hash at the head of every message sent by your server. This hash will then be checked for validity by your application every time a new message is received. In this scenario, the message is still read by the application, but it can be verified before starting to perform application logic.


In the current mobile space, security concerns of this ilk might not be so vital, but it may be crucial for enterprise-type applications.


 


Provisioning the Application


There are some additional deployment issues to take into account when using WMA or Push Registry. Applications using the Push Registry must be provisioned OTA (Over The Air), as installing via USB/infrared is not guaranteed to work (or, at the least, will not be one hundred percent functional). Assuming your OTA server is properly configured (correct MIME types, host address, and so on), the first issue to work through is the Push Registry URL that must be declared in the JAD property MIDlet-Push-. The URL will look like “sms://:16885”. The most difficult and unpredictable part of this URL is the all Java applications on the device that use the Push Registry must have a unique port number. If an application is already registered on port 16885, and the user downloads a new application that also tries to use port 16885, the installation of the new application will fail. As there is no way to know beforehand what ports are in use by other Java application, its kind of a gamble as to which ports are unused. At this time (mid-2004), not many applications use the Push Registry functionality, so port number conflicts should not be too much of a concern. In my projects, however, I did have to handle it.


The most flexible mechanism to handle this situation is to dynamically generate a port number for the application when the user chooses to download and install your application; in other words, a dynamically-created JAD file will be sent to the device (Note: this is not possible on some operators, particularly if the operator provisions the J2ME application themselves). As you will be tracking the user’s profile data anyway (in order to send SMS messages to the device in the first place), retaining a dynamically generated port number (versus a “one app-one port number” paradigm) is almost no extra work.


To create a dynamically generated port number, we chose to generate a random value between the port numbers 16000 and 16999 (*1). Beware that some OEMs/operators predefine some of these port numbers on their devices, so you may consider maintaining a list of “port numbers to avoid” which is incorporated into your random port number generator’s algorithm.


Now for the tough question: what happens when the user’s device already has an application installed which uses the SMS port number you have defined in your JAD? When this occurs, the JAM is required to halt the installation process and consider the process as failed.


There is a JAD attribute that can be set, MIDlet-Install-Notify, whose value is a URL to which the device can send a message to indicate the success or failure of the installation. According to the OTA provisioning spec (*2) (which is now part of the MIDP 2.0 spec, JSR-118 (*3)), the device will send a status report regarding the result of the install, to which the server can only reply with a HTTP 200. (The server can send more data, but, according the specs, the device must ignore it.) The possible response messages from the device are as follows (see the MIDP 2.0 spec for full details):


 


Status Code Status Message
900 Success
901 Insufficient Memory
902 User Canceled
903 Loss of Service
904 JAR size mismatch
905 Attribute mismatch
906 Invalid Descriptor
907 Invalid JAR
908 Incompatible Configuration or Profile
909 Application authentication failure
910 Application authorization failure
911 Push registration failure
912 Deletion notification
 


You can setup a server-side component to listen for incoming messages about install status reports. In addition to recording additional information about the deployment of your application, you can track and react to installation failures based on the status code returned. One possibility for recovering from a failed installation is to send a WAP Push message to the device with a URL for downloading the JAD and application again. If the user is reinstalling the application due to a port number conflict, the previous port number should be excluded from new port numbers that are generated. Admittedly, this WAP Push technique was not implemented in our projects due to the complex (and potentially confusing) nature of the user interaction.


 


Getting messages to the device


For various reasons, not just anybody is allowed to send SMS messages to devices. Thus, a mobile development company ends up with two options: forge a relationship with each individual carrier or partner with an SMS aggregator. As the former option is far from being a trivial task (the business needs alone are daunting), working with an SMS aggregator is a viable option as they have already created partnerships with many carriers and usually have a simple API that you can use (rather than writing your own SMPP code).


Two leading aggregators in the U.S. are MBlocks and SimpleWire. As my company had contacts there, we opted to use SimpleWire’s services. Typically, you have an account with the aggregator and pass your account information with every SMS message that you send. SimpleWire’s API is simple and does not take much time to integrate into your server-side components (my current implementation consists of about fifteen lines of simple code – see Code Sample 2).


One quasi-problem I ran into is that after my servlet transmitted a message there often was a delay before the device received it (3 to 10 seconds). For the vast majority of uses, though, the delay will be irrelevant, although it is something to be aware of.


Another issue to keep in mind is that messages are limited in the size of data they can hold. While this does vary from carrier to carrier, the maximum data size for some carriers is 160 characters (single-byte characters, that is) per message. While you may have more data space with some carriers, it is probably best to keep message length (either text or binary) to an absolute minimum. To make matters more difficult, the SMS port number must be embedded into the body of the message, and if you employ some type of message security (see the Security considerations with messages section), your data length will be even less. Still, with a delicate combination of live data from the incoming message and predefined application elements, you should be able to transmit a meaningful message to the user and invoke special application functions all within one message.


 


Emulators


In the J2ME/mobile Java space, working with the various emulators from the different OEMs, as well as Sun’s Wireless Toolkit (WTK), is typically a hit or miss situation. While an emulator may excel at one set of functions, it may completely crash or throw a litany of exceptions when asked to perform other functions. Thus, it’s always good to keep a handful of emulators around when debugging and testing.


For myself, I found the WTK to work well for testing the WMA and Push Registry functions. The WTK has a feature to send SMS and CBS messages to the emulator; the messages can either be text or binary. The project I was involved with involved one specific phone which handed only binary messages to the Java layer. That is, only instances of javax.wireless.messaging.BinaryMessage were passed to the application, and attempts to cast the incoming message to a javax.wireless.messaging.TextMessage threw a ClassCastException. Thus I needed to pass binary to the emulator, which it in turn passed to the application. The WTK only sends binaries via a file that is written on the hard disk, so to test the J2ME application, I wrote a small Java program to write binary data to a file on the hard disk. Of course, the format of the binary file matched the format that my a J2ME application was expecting. Then I used the WTK to send that binary to the emulator, at which point it could be read and parsed inside my application. This method proved to be a reliable test when compared to the operation of the device.


The Nokia emulators also support the WMA, and others may as well, so instead of using the “Default Color Phone” emulator with the WTK, you can setup the WTK to use the Nokia (or other OEM) emulators. Admittedly, I found the interaction between the WTK and non-WTK emulators a little lacking when using advanced functionality, so I decided to stick with the WTK’s “Default Color Phone” emulator most of the time. Furthermore, the skin for the “Default Color Phone” emulator of the WTK 2.1 seems to impress non-technical types, so you may get extra “ooos” and “ahhs” from the bosses above.


To use the WTK for WMA/Push Registry testing, though, you must “install” the application via OTA to emulator, instead of just clicking “Run”. To install via OTA, select “Run via OTA” from the Project menu. The process is simple; just follow the screens in the emulator. When you are done, the application will appear to the emulator as if it had been installed OTA, and you can use functions like the WMA and Push Registry easily. Both functions can be invoked from the WTK’s WMA console (File – > Utilities, click “Open Console” in the WMA section of the window). Text messages are easy to push to the emulator, but if your real world device only allows you BinaryMessage instances, pass the emulator a file containing the binary payload data you want to send.


 


Conclusion


The issues involved with getting a WMA/Push Registry-enabled application to market can seem daunting, but the benefits are clearly worthwhile. Through these mechanisms you can have a much more dynamic interaction with your users to aide in customer retention and brand loyalty. The one truly important caveat is the varying costs of SMS traffic. Thus, the message must be completely relevant to user and their interaction with the application. Also, the user must have a way to opt-in and opt-out of messages they may receive from your company. With a well-conceived business model, users may consider it essential to receive messages on their device about your application or services.


 


 


Code Sample 1 – A simplified version of the message handling classes


 


class MessageListenerImpl implements MessageListener


{


public void notifyIncomingMessage(MessageConnection mCon)


{ messageReader.handleMessage(); }


}


 


class WirelessMessageReader implements Runnable


{


private boolean readMessages = true;


private int pendingMessages;


private MessageConnection msgConn = null;


 


public void run()


{


while(readMessages)


{


synchronized(this)


{


if(pendingMessages == 0)


{


try { wait(); }


catch(InterruptedException ie) {}


}



pendingMessages–;


}



Message message = null;



try


{


Message message = msgConn.receive();


/* parse payload */


}


catch(IOException ioe) {}


}


}



synchronized void handleMessage()


{


pendingMessages++;


notify();


}


}


 


Code Sample 2 – integration with the SimpleWire API.


 


import com.simplewire.sms.*;


 


public void sendSmsMessage(String msisdn, short msgPort)


{


SMS smsMessage = new SMS();


smsMessage.setSubscriberID(YOUR_SUBSCRIBER_ID);


smsMessage.setSubscriberPassword(YOUR_PASSWORD);


smsMessage.setMsgPin(“+1” + msisdn);


smsMessage.setDestPort(msgPort);


smsMessage.setMsgText(“Your msg here”);


smsMessage.msgSend();


}


 


 


 


——————————————————————————–


1.  Sony Ericsson, “Advanced Message Coding using JSR 120”, section 3.4.


2. Sun Microsystems, “Over The Air Initiated Provisioning Recommended Practice for the .Mobile Device Profile”


3. Sun Microsystems, Mobile Information Device Profile, v2.0 (JSR-118)