|
|
Contents: |
|
|
|
Related content: |
|
|
|
Subscriptions: |
|
|
| Making signals go the extra mile -- literally
Soma
Ghosh (mailto:sghosh@entigo.com%20?cc=&subject=Extend
J2ME to Wireless Messaging) Application developer, Entigo 4
February 2003
The objective of wireless messaging is to
extend the networking and I/O capabilities of J2ME applications to send
and receive messages using the messaging services on GSM networks, like
Short Message Wevice (SMS) and Cell Broadcast Service (CBS).
The Wireless Messaging System -- an
overview 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.
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
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
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
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:
- The URL Connection string does not support a designated host, and
- 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:
- Download a Reference Implementation of WMA 1.0 from http://java.sun.com/products/j2mewtoolkit. It is
compatible with version 1.0.4 and higher of J2ME toolkit.
- Copy wma.jar, the WMA Reference Implementation from <WMA Root
dir>/ wma1_0/lib to <J2ME Root dir>/lib.
- 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 ..\..\..\lib\midpapi.zip -d ..\tmpclasses -classpath
..\tmpclasses;f:\wtk104\lib\wma.jar ..\src\*.java
echo *** Preverifying class files ***
..\..\..\bin\preverify -classpath ..\..\..\lib\midpapi.zip;..\tmpclasses;
f:\wtk104\lib\wma.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 ..\apps\WMAClient\bin\WMAClient.jar;f:\wtk104\lib
\wma.jar
-Xdescriptor:..\apps\WMAClient\bin\WMAClient.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
- Download the J2ME Toolkit,
v1.0.4 and up, to run and test your WMA applications.
- Check out this site, which offers a robust list of articles focused on
MIDP.
- Webopedia is an online
dictionary and search engine for the terms used in this article, along
with all other computer and tech talk. Read more on MIDlets in the
article The
MIDlets class. (developerWorks, March 2002) Check out more on
networked J2ME applications in the article Mobile
device optimization. (developerWorks, January 2003)
- Stay connected to the wireless world with the developerWorks Wireless zone.
- The developerWorks Java technology
zone keeps you up to date on J2ME, MIDlet, and other events in the
Java arena.
- Find the latest developments on wireless, mobile, and voice
computing on IBM's Pervasive
Computing site.
- Build Java apps with IBM's VisualAge
for Java.
About the
author 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. |
|