Asynchronous Communications with Java ME and SIP: Part 2

By Bruce Hopkins

As you may recall from Part 1 of this series, I showed you two example applications that used the Session Initiation Protocol (SIP) to send a simple message asynchronously from one application to the other. In this tech tip, we are going to explore why the REGISTER method type is important and learn how to use it.

The SIP protocol supports the following method types when SIP devices are communicating:

ACKMESSAGEREFER
BYENOTIFYREGISTER
CANCELOPTIONSSUBSCRIBE
INFOPRACKUPDATE
INVITEPUBLISH

In the previous example, you saw how easy it was for each user to communicate with each other using the MESSAGE method type. This was, of course, due to the fact that each user had a routable IP address, and there were no barriers in place (such as a firewall) to impede the communication between the devices. This gets a little tricky, however, when one or both of the users are located behind a firewall or NAT proxy as shown in Figure 1.

Incoming-Outgoing SIP Traffic

Figure 1. Incoming Requests to Devices Behind a Firewall Are Blocked

If you're lucky, you can always ask the network administrator at your organization to open a port on the firewall for your device. However, that solution is definitely not scalable -- what if other people in your company wanted a port open for their devices, too? Additionally, what would you need to do if the IP address of your mobile device changed? Your network administrator would have to reconfigure the firewall to point to your new address. Figure 2, below, shows the scalability problem if you open a port on the firewall for each SIP device.

Incoming SIP

Figure 2: Opening Individual Ports on the Firewall for Incoming SIP Requests Is Not a Scalable Solution

Obviously, there must be a scalable solution for multiple SIP devices to communicate if one or more of them are located behind a firewall. Fortunately, that's where the REGISTER method type comes into play. As you can see in Figures 3 and 4 below, the use of a SIP proxy and the REGISTER method type provide a simple, yet scalable solution. When a SIP device is behind a firewall, it needs to send a REGISTER method type to the external SIP proxy located outside the firewall. For the purposes of this tech tip, the external SIP proxy will also act as a registrar.

SIP Proxy

Figure 3. REGISTER Requests are Sent Directly to External SIP Proxy

Incoming SIP Routing

Figure 4. Incoming SIP Messages Are Now Routed to the Proper Devices

What happens when your SIP device get a new IP address? All it needs to do is send a new RIGISTER request to the SIP proxy with its new IP address – and that’s it! The SIP Proxy will route all messages to your device now that it knows how to contact you.

If you want to try this out yourself, all you need to do is to standup the embedded SIP Proxy/Registrar inside the Sun Java Wireless Toolkit 2.5.2 application. To start the SIP proxy, execute the “Utilities” application with the Wireless Toolkit program group. After the Utilities application starts, click on the “Start SIP Server” option. After the server starts, you can then now register yourself with the SIP Proxy by sending to it a REGISTER message. The code in Listing 1 provides a practical example on how it is done:

    public void register(final SipClientConnectionListener listener, final Thread waitFor){
        Thread t = new Thread() {
                public void run() {
                    runGauge();

                    try {
                        try {
                            if (waitFor != null) {
                                waitFor.join();
                            } else {
                            }
                        } catch (InterruptedException ie) {
                        }

                        scc = (SipClientConnection)Connector.open("sip:" + proxyAddress +
                                ":5060;transport=udp");
                        scc.setListener(listener);
                        scc.initRequest("REGISTER", scn);

                        String adr =
                            myDisplayName + " ";
                        scc.setHeader("To", adr);
                        scc.setHeader("From", adr);
                        scc.setHeader("Content-Length", "0");
                        scc.setHeader("Max-Forwards", "6");
                        uaStatus.setStatus(REGISTERING);
                        scc.send();
                        uaStatus.waitUntilChanged();
                        progressGaugeFinished = true;
                    } catch (Exception e) {
                        e.printStackTrace();
                        failMessage = e.getMessage();
                        commandAction(failedCmd, currentDisplay);

                        return;
                    }
                }
            };

        t.start();
    }

Listing 1. Using the JSR-180 API to Create and Send a Register Request

The following image shows the results of the REGISTER request that was sent to my SIP Proxy. As you can see, I am now registered with the proxy. Now anyone can send a message to me via the proxy. Be sure to note that the proxy also functions a handy debug tool, and it shows you the contents of the SIP messages that it proxies.

REGISTER Request

Figure 5. The Result of the REGISTER Request Sent to the SIP Proxy

Conclusion

It doesn’t take a lot of effort to use the JSR-180 API to register your device with a SIP Proxy/Registrar. If you’re looking for a fully functioning example, be sure to try out the GoSIP demo application in the Sun Java Wireless Toolkit 2.5.2\*. This application works out-of-the-box with the embedded SIP Proxy in the Wireless Toolkit, so that you can register multiple devices and to communicate via the proxy.

\*NOTE: The Sun Wireless Toolkit is called the Java ME SDK as of version 3.0.

Comments:

ME GUSTARIA ESTAR SATIS FECHO CON ESTE A

Posted by NESTOR on November 05, 2008 at 02:32 AM PST #

Hi,

How do you solve the NAT problem? The proxy doesn't know where 10.211.55.3 is.

/Håkan

Posted by Håkan Jonsson on November 09, 2008 at 04:36 PM PST #

Håkan,

If the proxy was deployed within a DMZ then you would potentially have a problem where the 10.x.x.x block is inaccessible to the Proxy. In this case, however, the proxy is physically located behind the firewall (therefore it has a 10.x.x.x address) and the 5060 port has been opened on the firewall for the SIP Proxy. So, all the ports on the firewall are blocked except for the 5060 port, which is forwarded to the SIP Proxy. This makes the SIP Proxy "appear" to be outside the firewall as in Figures 3 & 4.

Does that make sense?

Thanks,

Bruce

Posted by Bruce Hopkins on November 10, 2008 at 02:13 AM PST #

Thanks,

Yes that makes sense. The proxy in DMZ setup was not obvious from the figures and text, but now I get it.

/Håkan

Posted by Håkan Jonsson on November 10, 2008 at 04:23 PM PST #

Nice post: Do Sun Java Wireless Toolkit 2.5.2 support RTP? How actual media will be communicated?

Posted by Binod on November 13, 2008 at 11:53 PM PST #

Hi Bruce;
What is the goal of this article ?
The SIP-NAT/FW is a real problem solved ( partially ) by using all sort of
SIP solutions, some of them called Session Border Controllers, or
special kind of SIP proxies.

Your article describes a specific scenario where the proxy has a leg in the internal network and
so it can actually route messages to the private 10.x network.
But what happen when both clients wants to interchange some multimedia payload ( like voice or vide )?
The media doesnt go through the proxy, it goes peer-to-peer. And here you will have the same problem,
media packets will not make it to the other end ( from the public to the private network ) making the conversation
one way audio.

Again, I do not understand what are you trying to show in this article. Because REGISTER is a basic SIP message to bind AOR with IP addresses, it is not generally used to traverse firewalls, in its basic form.

Thanks

Posted by Inca on November 14, 2008 at 06:43 AM PST #

i want source code for Mobil to access wireless ofcource with java language i have project in my college about that put i now learning jse not jme if anybody can help me tell me in my e-mail tuothdoy1212@yahoo.com thanks for your time please help me

Posted by Ahmeed Hassan on November 14, 2008 at 12:37 PM PST #

Binod,

You wanted to know if the Sun Wireless Toolkit 2.5.2 supports RTP. No, the Wireless Toolkit does not provide any mechanism for you to use RTP or RTPS. However, the link below should help you to get up to speed on RTP and RTSP. Additionally, it provides some code on how to determine if your phone supports RTP and RTSP. For instance, some Motorola phones have a pure-Java ME implementation of RTP for developers to use.

http://www.agilejava.com/downloads/TS-5439.pdf

Thanks,

Bruce

Posted by Bruce Hopkins on November 17, 2008 at 05:24 AM PST #

Inca,

You asked about the goal of this article, and provided one of the major scenarios where SIP is used in the real word - voice and multimedia communication. As you already know, SIP is a very complicated protocol, and it encompasses multiple RFC specifications. The purpose of this two-part series was to get developers introduced to SIP with some basic functionality. In part 1, I talked about the basic code to send a MESSAGE. Here, I'm introducing developers to the REGISTER method type.

Since the Java ME MSA specification supports SIP, then this will allow developers to compile some code to get started quickly. So, in short, this is a "getting started" article on the protocol itself. I didn't mention anything about the actual media channels, since the SIP protocol allows you to use your own, and not all Java ME MSA devices support RTP and RTSP.

Thanks,

Bruce

Posted by Bruce Hopkins on November 17, 2008 at 05:43 AM PST #

Ahmeed,

The Java ME SDK provides tons of complete example code on how a mobile phone can access wireless services using Java. You can download it here:

http://java.sun.com/javame/downloads/sdk30ea.jsp

Thanks,

Bruce

Posted by Bruce Hopkins on November 17, 2008 at 05:51 AM PST #

Hi Bruce,
i read your both articles and they are really very easy to understand. Right now i am developing one j2me application where i have to send/receive some image files from one device to others. As i am a novice in J2ME, i wanna know if its possible to use SIP for transfering image files or not! could you please help me in this regard providing some code?
Again, in GoSIP demo application, if Sippy_A wants to send a message to Sippy_B, then is it enough to combine GoSIP and SIPDemo to do this?
Thanks.

Posted by lisa on December 18, 2008 at 07:57 PM PST #

Lisa,

Thanks for the compliments. Yes, you definitely can use SIP to transfer images. Actually, if you look at the code in the first article, instead of sending the text, just change the code to send the bytes for the image.

Problem solved!

Just to be safe, I'd change the code also so that the content type isn't "text/plain", but the MIME type for the image that you want to send.

Thanks,

Bruce

Posted by Bruce Hopkins on December 19, 2008 at 02:37 AM PST #

Hi Bruce,

Thnaks for the tips.

But i tried to send in that way but i failed. I actually tried to send a text file first. but i cant send the whole contents of the file if the file size is bigger than 1 KB. In sender size, it says that it sends the contents and also can write the whole text in console..but in receiver side, only first 1 KB of the file received!!! Here is the code that you uploaded in your first article, i changed in the following way. could you please tell me whats the solution if i want to send a file larger than 1KB??? or whats the problem in the following code?

In notifyRequest() method in SipReceiver file, i changed as below:
--------------------------------------------------------------------------
try {
ssc = scn.acceptAndOpen();
if(ssc.getMethod().equals("MESSAGE")) {
String contentType = ssc.getHeader("Content-Type");
String contentLength = ssc.getHeader("Content-Length");
int length = Integer.parseInt(contentLength);
if((contentType != null) && contentType.equals("text/plain"))
{
InputStream is = ssc.openContentInputStream();
//int i=0;
byte testBuffer[] = new byte[length];
String tmpMsg="";
while(is.read(testBuffer)!= -1)
{
String message = new String(testBuffer);
tmpMsg=tmpMsg+message;
}
System.out.println(tmpMsg);
}
ssc.initResponse(200);
ssc.send();
}
-----------------------------------------------------------------------------
and the rest are same as yours code.

In run() method in SipSender file, i changed as below:
-----------------------------------------------------------------------------
try {
FileConnection fc = (FileConnection)Connector.open("file:///root1/testFile.txt",Connector.READ_WRITE);
int a=(int)fc.fileSize();
sc = (SipClientConnection) Connector.open(addressTextField.getString());
sc.setListener(this);
sc.initRequest("MESSAGE", null);
sc.setHeader("From", addressTextField.getString());
sc.setHeader("Subject", subjectTextField.getString());
sc.setHeader("Content-Type", "text/plain");
sc.setHeader("Content-Length", "" + a);

int chunkSize = 512;
int index = 0;
int readLength = 0;

try {
InputStream is = fc.openInputStream();
OutputStream os = sc.openContentOutputStream();
String tmpMsg="";
int i=0;
byte[] data = null;
byte[] tmp = new byte[1];
while(is.read(tmp)!=-1)
{
os.write(tmp);
}
os.flush();
System.out.println(tmpMsg);
is.close();
os.close();
}
catch (IOException ie) {}
fc.close();
}
catch(Exception e) {
e.printStackTrace();
}
--------------------------------------------------------------------------------
and the rest are same, but i had to import this as i am using fileconnection api:

import javax.microedition.io.file.\*;

and i also put off the followings as i am not using them:

//private TextField messageTextField;
//messageTextField = new TextField("Message text", "", 30, TextField.LAYOUT_LEFT);
//form.append(messageTextField);

---------------------------------------------------------------------------------
Thnaks in advance,
and waiting for your reply...
Lisa.

Posted by Lisa on January 13, 2009 at 09:11 PM PST #

I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.

Ruth

ramupgrade.info

Posted by Ruth on March 18, 2009 at 06:17 PM PDT #

Thank you, Ruth. Please let us know if you have any suggestions.

Posted by Christine Dorffi on March 19, 2009 at 04:01 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Tips for developers who use Java technologies (Java SE, Java ME, JavaFX) for mobile and embedded devices.

Search

Categories
Archives
« July 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today