Quantcast

Extend J2ME to Wireless Messaging

Get the WebProNews Newsletter:
[ Technology]

The notion of wireless messaging provides a whole new vista to J2ME. J2ME applications powered by wireless messaging have a platform-independent access to wireless communication resources like Short Message Service (SMS) and Cell Broadcast Service (CBS) for Global System for Mobile Communication (GSM) Networks, a mobile telephony system permitting inter-country communication.

Before proceeding with the details on how J2ME Wireless Messaging works, I will discuss, in short, the SMS and CBS messaging systems in a GSM Network.

Before proceeding with the details on how J2ME Wireless Messaging works, I will discuss, in short, the SMS and CBS messaging systems in a GSM Network.

GSM Short Message Service (SMS)
SMS is the transmission of short text messages to and from a mobile phone, fax machine, and/or IP address in a GSM network. Messages must be no longer than 160 alphanumeric characters and contain no images or graphics. The main features of this service are speed, cheap rates, and the guarantee that the message will reach the target person, even if he is out of radio coverage or his phone is turned off.

Once a message is sent, it is received by a Short Message Service Center (SMSC), which must then get it to the appropriate mobile device. To do this, the SMSC sends a SMS request to the home location register (HLR) to find the roaming customer. Once the HLR receives the request, it will respond to the SMSC with the subscriber’s status, as in 1) inactive or active, and 2) roaming location.

If the response is inactive, then the SMSC will hold onto the message for a period of time. When the subscriber accesses his device, the HLR sends a SMS notification to the SMSC, and the SMSC attempts delivery.

The SMSC transfers the message to a GSM message delivery system in a Short Message Delivery Point-to-Point format. The system pages the device and, if it responds, delivers the message.

The SMSC receives verification that the message was received by the end user, and then categorizes the message as sent and will not attempt to send it again. The SMS delivery mechanism is illustrated in Figure 1.

Figure 1. SMS Delivery System
Figure 1. SMS Delivery System

GSM cell broadcast service
The GSM cell broadcast service allows messages to be sent to every Mobile Station (MS), such as a mobile phone, fax machine, and/or IP address currently in a particular cell. Cell broadcast messages are repeated at intervals over a period of time, which allows an MS to receive the message even if entering the cell after the first transmission. The data can be sent either as binary data or ASCII text up to 15 pages in length, with a page being up to 93 characters in length; the test set only provides support for ASCII messages. Cell broadcast messages are classified by topic and allocated a channel number, message code, update number, and language:

  • A Channel Number is a header number identifying the message topic (such as ‘Weather Report’ or ‘Traffic Information’).

  • A Message Code identifies a particular message, so that an MS receiving a message with the same code as a previously received message will recognize that it is a repeat, and may not display it to the user.
  • An Update Number is used to identify a particular version of a message. This is useful for reporting a dynamic situation, where a message may be reporting one event (such as road construction ahead), but the details of which change periodically (the length of the traffic jam, for example). An MS that remains in one cell for a length of time will receive messages with the same message code, but update numbers as updated versions of the same message are received; however, an MS that enters the cell will receive only the most recent version of the message, followed by any subsequent versions.
  • Language indicates in what language the message is. Changing this parameter does not translate the text of a message.

While SMS is a one-to-one and one-to-few messaging system, CBS provides one-to-many messaging within a certain geographical area.

The wireless messaging system
This system can be viewed as a 3-tiered architecture, consisting of the Interface Layer, Implementation Layer and Transport Layer.

The Interface Layer constitutes a generic set of messaging interfaces, independent of any messaging protocol. These interfaces provide the basic definition of a message, define the basic functionality of sending and receiving it, and provide a mechanism for the MIDlet application to be notified of the incoming message.

The Implementation Layer contains classes which implement each Interface Layer to access wireless messaging like SMS or CBS functionalities on a GSM mobile device. For instance, from the SMS point of view, this layer provides an implementation of the message connection for SMS messages as well as an implementation of a SMS message with text or binary attributes. The Implementation Layer also performs segmentation and concatenation of messages for the underlying protocol. The MIDlet can then specify the number of segments a message should be broken into in a MessageConnection.

The Transport Layer contains classes that are the actual implementation of protocols that carry messages to the mobile device.

The 3-tiered mechanism is seen here in Figure 2.




Figure 2. Wireless Messaging system architecture


Figure 2. Wireless Messaging system architecture

The Generic Messaging API, javax.wireless.messaging
This API is defined by the package javax.wireless.messaging, which defines all the interfaces for sending and receiving wireless messages. Following is a list of interfaces:

Message. This provides the basic definition of a message, which acts as a container holding address, payload, and flags to send and block for a message. It is a superinterface to TextMessage, a message object with a text payload attribute, and a BinaryMessage, a message object with a binary payload attribute. The structure of a Message is shown in Figure 3.

Figure 3. Structure of a message

Figure 3. Structure of a message

MessageConnection. This provides the basic functionality of receiving and sending messages. It contains a method for sending and receiving messages, a factory method for creating new Message objects, and a method that calculates the number of segments of the underlying protocol that are needed to send a specified Message object.

This class is instantiated by a call to Connector.open().

In a client mode connection, messages can only be sent. A client mode connection is created by passing a string identifying a destination address to the Connector.open() method. This method returns a MessageConnection object.


clientConn = (MessageConnection)Connector.open("sms://
+18643630999:5000");

In a server mode connection, messages can be sent or received. A server mode connection is created by passing a string that identifies an end point (protocol dependent identifier, for example, a port number) on the local host to the Connector.open() method.


serverConn = (MessageConnection)Connector.open("sms://:5000");

MessageListener. This provides a basic mechanism to notify the MIDlet application of an incoming message. It allows a MIDlet to receive a callback when new messages are available to be read.

The Short Message Service API
The com.sun.midp.io.j2me.sms package provides an API for the Short Message Service Messaging system and allows MIDlet to access SMS functionality on a GSM mobile device.

The main components of the package — MessageObject and Protocol — support the sending and receiving of SMS messages.

MessageObject.MessageObject is the implementation of a SMS message. In the Implementation layer, the javax.wireless.messaging.Message interface is implemented as a buffer. The MessageObject handles the creation of message buffers and the input/output operations out of a buffer. Furthermore, it has two subclasses — TextObject and BinaryObject. These classes implement a SMS message with a payload, whether text or binary.

Protocol. This implements the message connection to a low-level Transport mechanism required to transmit a SMS message. In the process, it checks for all runtime configuration parameters and handles exceptions related to invalid URL syntax, security violations, I/O violations, and illegal arguments. Protocol also handles the sending and receiving of messages using a datagram or serial port connection.

The Cell Broadcast Messaging API
The com.sun.midp.io.j2me.cbs package provides an API for the Cell Broadcast Messaging system and allows MIDLlet to access CBS functionality on a GSM mobile device.

The main component of the package, com.sun.midp.io.j2me.cbs.Protocol, supports the receipt of a CBS Message.

The CBS differs from SMS in that:

  1. The URL Connection string does not support a designated host, and
  2. It is meant for an inbound-only protocol. A MIDlet having CBS capability can receive messages, but cannot send them.

A J2ME messaging application
In this section, I will show an example of a WMAServer that waits for incoming SMS messages and then displays them on a phone screen. The javax.microedition.lcdui package provides a set of features for implementation of user interfaces for the applications.

The WMAServer MIDlet creates a server mode connection by passing a string that identifies an end point (protocol-dependent identifier — like a port number, for example ) on the local host to the Connector.open() method.

In order to get notified of an incoming message, the MIDlet registers a MessageListener object at the MessageConnection instance, serverConn.


serverConn.setMessageListener(MessageListener ml);

It also implements notifyIncomingMessage() in the MessageListener interface. When an incoming message arrives at the MessageConnection, the notifyIncomingMessage() method is called. The application must retrieve the message using the receive() method of the MessageConnection.

The WMAServer application reads the payload data from the incoming message, whether text or binary, and stores it in a string object to be displayed later.


public void notifyIncomingMessage(MessageConnection conn) {
  
  		
        Message msg = null;
        //  Try reading (maybe block for) a message
        try {
            msg = conn.receive();
        }
        catch (Exception e) {
            // Handle reading errors
            System.out.println("processMessage.receive " + e);
        }
        // Process the received message
        if (msg instanceof TextMessage) {
            TextMessage tmsg = (TextMessage)msg;
    		msgReceived = tmsg.getPayloadText();
        }
        else 
		{
            // process received message
            if (msg instanceof BinaryMessage) {
                BinaryMessage bmsg = (BinaryMessage)msg;
                byte[] data = bmsg.getPayloadData();
                //  Handle the binary message...
				msgReceived = data.toString();
            
        }
	
}

The application provides a destroyApp() method when the connection resources and associated listener objects must be released.


  public void destroyApp(boolean unconditional) { 
  try {
    if (serverConn != null) {
        serverConn.setMessageListener(null);
        serverConn.close();
    }
}
catch (IOException e) {
    //  Handle the exception...
	e.printStacktrace();
}

Here is the complete application code:


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.wireless.messaging.*;
import java.io.*;
import java.lang.*;
import java.util.*;

//A first MIDlet with simple text and a few commands.
public class WMAExample extends MIDlet 
               implements CommandListener, MessageListener  {

  //The exit commands
  private Command exitCommand; 
  //Command to get Message 
  private Command getMsgCommand;
   
  //The display for this MIDlet
  private Display display;
  
  Form displayForm;
  String msgReceived;
  
  
  MessageConnection serverConn;
  
  
  
  public WMAExample() {
    display = Display.getDisplay(this);
    exitCommand = 
    new Command("Exit", Command.SCREEN, 1);
	getMsgCommand = 
    new Command("Get", Command.SCREEN, 1);
	
	
 }
 
 // Start the MIDlet by creating two command buttons
  public void startApp() {
  	 displayForm = new Form("Get Message");
	 
	 displayForm.addCommand(exitCommand);
     displayForm.addCommand(getMsgCommand);
 
     displayForm.setCommandListener(this);
	 displayForm.setItemStateListener(this);
	 display.setCurrent(displayForm);
	 
	 try
	 {
	 serverConn = (MessageConnection)Connector.open
	 ("sms://:5000");
	 // Register the listener for inbound messages.
     serverConn.setMessageListener(this);

	 }
	 catch (IOException ioExc)
	 {
	 System.out.println("Server connection could 
	 not be obtained");
	 ioExc.printStackTrace();
	 } 


  }
  
  public void notifyIncomingMessage(MessageConnection 
  conn) {
  
  		
        Message msg = null;
        //  Try reading (maybe block for) a message
        try {
            msg = conn.receive();
        }
        catch (Exception e) {
            // Handle reading errors
            System.out.println("processMessage.receive " 
            + e);
        }
        // Process the received message
        if (msg instanceof TextMessage) {
            TextMessage tmsg = (TextMessage)msg;
    		msgReceived = tmsg.getPayloadText();
        }
        else 
		{
            // process received message
            if (msg instanceof BinaryMessage) {
                BinaryMessage bmsg = (BinaryMessage)msg;
                byte[] data = bmsg.getPayloadData();
                //  Handle the binary message...
				msgReceived = data.toString();
            
        }
	
}
  // Pause is a no-op because there are no   background
  // activities 
  public void pauseApp() { }

  // Destroy must cleanup everything not handled 
  // by the garbage collector.
  
  public void destroyApp(boolean unconditional) { 
  try {
    if (serverConn != null) {
        serverConn.setMessageListener(null);
        serverConn.close();
    }
}
catch (IOException e) {
    //  Handle the exception...
	e.printStacktrace();
}

}

 // Respond to commands. 
  public void commandAction(
  Command c, Displayable s) {
    if (c == exitCommand) {
      	destroyApp(false);
      	notifyDestroyed();
    }
	
	if (c == getMsgCommand) {
		try
		{
			
			displayForm.append(msgReceived);
			display.setCurrent(displayForm);
			
		}
		catch (Exception exc)
		{
			exc.printStackTrace();
		}
		
	
	}
  }
  

 
 }

Next is an example of a WMA client that sends a SMS message to a GSM mobile phone. The WMA Client can only send messages. It creates a MessageConnection by passing a string identifying a destination address (which is a valid mobile number) to the Connector.open() method. Try:


	 {
	 clientConn = (MessageConnection)Connector.open("sms://
	 +18643630999:5000");
	 }
	 catch (IOException ioExc)
	 {
	 System.out.println("Client connection could not be obtained");
	 ioExc.printStackTrace();
	 } 

It then creates a valid TextMessage object by setting the payload and destination address and sends the message through the MessageConnection.


TextMessage tmsg =
            (TextMessage)clientConn.newMessage
              (MessageConnection.TEXT_MESSAGE);
        	tmsg.setAddress("sms://18643630999:5000");
        	tmsg.setPayloadText(msgToSend);
        	clientConn.send(tmsg);

Here is the complete application code for WMA Client:


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.wireless.messaging.*;
import java.io.*;
import java.lang.*;
import java.util.*;

//A first MIDlet with simple text and a few commands.
public class WMAClient extends MIDlet 
               implements CommandListener, MessageListener  {

  //The exit commands
  private Command exitCommand; 
  //Command to get Message 
  private Command sendMsgCommand;
   
  //The display for this MIDlet
  private Display display;
  
  Form displayForm;
  String msgToSend="Can you hear me?";
  
  MessageConnection clientConn;
  
  public WMAClient() {
    display = Display.getDisplay(this);
    exitCommand = 
    new Command("Exit", Command.SCREEN, 1);
	sendMsgCommand = 
    new Command("Send", Command.SCREEN, 1);
	
	
 }
 
public void notifyIncomingMessage(MessageConnection conn) 
 {
 
 }
 
 // Start the MIDlet by creating the TextBox and 
  // associating the exit command and listener.
  public void startApp() {
  	 displayForm = new Form("Send Message");
	 
	 displayForm.addCommand(exitCommand);
     displayForm.addCommand(sendMsgCommand);
 
     displayForm.setCommandListener(this);
	 displayForm.setItemStateListener(this);
	 display.setCurrent(displayForm);
	 
	 try
	 {
	 clientConn = (MessageConnection)Connector.open("sms://
	 +18643630999:5000");
	 }
	 catch (IOException ioExc)
	 {
	 System.out.println("Client connection could 
	 not be obtained");

	 ioExc.printStackTrace();
	 } 


  }
  
  // Pause is a no-op because there is no   background
  // activities or record stores to be closed.
  public void pauseApp() { }

  // Destroy must cleanup everything not handled 
  // by the garbage collector.
  public void destroyApp(boolean unconditional) { }

 // Respond to commands. 
  public void commandAction(
  Command c, Displayable s) {
    if (c == exitCommand) {
      	destroyApp(false);
      	notifyDestroyed();
    }
	
	if (c == sendMsgCommand) {
		try
		{
			TextMessage tmsg =
            (TextMessage)clientConn.newMessage
              (MessageConnection.TEXT_MESSAGE);
        	tmsg.setAddress("sms://18643630999:5000");
        	tmsg.setPayloadText(msgToSend);
        	clientConn.send(tmsg);

		}
		catch (Exception exc)
		{
			exc.printStackTrace();
		}
		
	
	}
  }
  

 
 }

Deploying wireless messaging
Always follow these three steps when deploying a MIDlet with wireless messaging capability:

  1. Download a Reference Implementation of WMA 1.0 from http://java.sun.com/products/wma. It is compatible with version 1.0.4 and higher of J2ME toolkit.

  2. Copy wma.jar, the WMA Reference Implementation from <WMA Root dir>/ wma1_0/lib to <J2ME Root dir>/lib.
  3. Update internal.config in the <J2ME Root dir>/lib directory with SMS and CBS specific entries.

In datagram-emulation mode, the WMA 1.0 RI emulates the transport by packing the SMS message into a Datagram and forming the actual client or server address based on the following entries:


# Default values for SMS internal implementation.
com.sun.midp.io.j2me.sms.Impl: com.sun.midp.io.j2me.sms.DatagramImpl
com.sun.midp.io.j2me.sms.DatagramHost: localhost
# Values will be same for a MIDLet which is both a Client and Server
com.sun.midp.io.j2me.sms.DatagramPortIn: 56789
com.sun.midp.io.j2me.sms.DatagramPortOut: 34567
#
# Permissions to use specific SMS features
com.sun.midp.io.j2me.sms.permission.receive: true
com.sun.midp.io.j2me.sms.permission.send: true
#
# Permissions to use specific CBS features
com.sun.midp.io.j2me.cbs.permission.receive: true
#
# Permissions to use connection handlers
javax.microedition.io.Connector.sms: true
javax.microedition.io.Connector.cbs: true
#
# Default SMS Service Center address
wireless.messaging.sms.smsc: +18643299089
############# WMA ##################

To build WMAClient and WMAServer classes into a runnable .jad file, create the following batch file:


@echo off
rem This batch file builds and preverifies the code for the demos.
rem it then packages them in a JAR file appropriately.
echo *** Creating directories ***
echo *** (this stage may produce already exist errors. Ignore them). ***
mkdir ..tmpclasses
mkdir ..classes
echo *** Compiling source files ***
javac -bootclasspath ......libmidpapi.zip -d ..tmpclasses -classpath 
..tmpclasses;f:wtk104libwma.jar ..src*.java
echo *** Preverifying class files ***
......binpreverify -classpath ......libmidpapi.zip;..tmpclasses;
f:wtk104libwma.jar -d ..classes ..tmpclasses
echo *** Jaring preverified class files ***
jar cmf MANIFEST.MF WMAClient.jar -C ..classes .
echo *** Jaring resource files ***
jar umf MANIFEST.MF WMAClient.jar -C ..res .

To run the result .jad file, create the following batch file:


@echo off
rem This file runs the WMAExample.jad/jar file in the emulator.
@echo on
cd ......bin
emulator -classpath ..appsWMAClientbinWMAClient.jar;f:wtk104lib
wma.jar  
-Xdescriptor:..appsWMAClientbinWMAClient.jad

The bottom line
For wireless messaging, the J2ME application opens up a full, new horizon — the GSM. Through MIDlet, it is now possible to communicate between GSM-compatible mobile phones in a system-independent and portable way.

Resources

A graduate in computer science and engineering, Soma Ghosh has developed a wide range of Java applications in the areas of e-commerce and networking over the past seven years. She believes that wireless commerce represents the near future of the industry and has recently been drawn to wireless initiatives of existing desktop components and models. Soma is currently an application developer with Entigo, a pioneer and industry leader in real e-business solutions and B2B sell- and service-side e-commerce products. She can be reached at sghosh@entigo.com.

Extend J2ME to Wireless Messaging
About Soma Ghosh
A graduate in computer science and engineering, Soma Ghosh has developed a wide range of Java applications in the areas of e-commerce and networking over the past seven years. She believes that wireless commerce represents the near future of the industry and has recently been drawn to wireless initiatives of existing desktop components and models. Soma is currently an application developer with Entigo, a pioneer and industry leader in real e-business solutions and B2B sell- and service-side e-commerce products. She can be reached at sghosh@entigo.com. WebProNews Writer
Top Rated White Papers and Resources
  • ahsan

    hi,
    I really appreciate your work.
    i am developing an app ,in which in need to send and receive SMSes.
    i am ok with sending but i am just wondering how my app will wait and always listen for incoming sms.
    suggestions plez

  • Guest

    Stop copying from http://www.ibm.com/developerworks/wireless/library/wi-extendj2me/

    give some pratical experiance idea if you have