SIP stack implementation in WTK2.5
Hello friends,
I want to implement the SIP communication in J2ME. I am using the wtk2.5 emulator where the SIP stack has been implemented. I followed the tutorial provided by sun and now position is as follows:
1. I can send SIP requests to a SIP server.
2. The SIP server is responding to the request BUT my J2ME application is not receiving it.
So I tried the example application SIPDemo provided with wtk2.5 toolkit. As far as I studied the program it is performing the following operations:
1. Receiver:
i. Opens a SIP server port at a particular port (say 5060)
ii. Waits for client.
iii. When client connects it receives message from the client.
iv. After receiving message from the client it sends a 200 OK response to the client.
2. Sender:
i. Sends a SIP message to a particular URI (say somebody@127.0.0.1:5060)
ii. Waits for the 200 OK response from the receiver.
iii. When it receives the response displays something meaningful.
The receiver is performing all the tasks, i.e. receiving msg from the Sender and sending the 200 OK response back to the Sender. BUT the Sender (i.e. the client) sends the msg to the receiver (which is perfectly received by the Receiver) but fails to receive the response from the receiver.
So anybody could please explain what is the exact problem as the Sender fails to receive the response from the Receiver.
Note: I am not testing my own code, I am testing the SIPDemo provide with the WTK2.5 simulator. I am also attaching the source code here:
/*
*
* Copyright ?2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.sip.*;
publicclass SIPDemoextends MIDletimplements CommandListener{
privatestaticfinal String appTitle ="SIP Demo";
private String sipAddress ="Somebody@127.0.0.1";
privateint portReceive = 5070;
privateint portSend = 5070;
private String message ="Some Message Body";
private String msgSubject ="Test Message";
private Display display;
private Form form =new Form(appTitle);
private List list;
private Command goCommand =new Command("Go", Command.ITEM, 1);
private Command exitCommand =new Command("Exit", Command.EXIT, 0);
private Command sendCommand =new Command("Send", Command.OK, 1);
private Command receiveCommand =new Command("Receive", Command.OK, 1);
private TextField tfAddress;
private TextField tfPort;
private TextField tfSubject;
private TextField tfMessage;
private SipClientConnection sc =null;
private SipConnectionNotifier scn =null;
private SipServerConnection ssc =null;
public SIPDemo(){
super();
display = Display.getDisplay(this);
initList();
display.setCurrent(list);
}
privatevoid initList(){
list =new List(appTitle, Choice.IMPLICIT);
list.append("Send Message",null);
list.append("Receive Message",null);
list.addCommand(exitCommand);
list.addCommand(goCommand);
list.setCommandListener(this);
}
privatevoid composeMessage(){
tfAddress =new TextField("Address ", sipAddress, 50, TextField.LAYOUT_LEFT);
tfPort =new TextField("Port ", String.valueOf(portSend), 6, TextField.LAYOUT_LEFT);
tfSubject =new TextField("Subject ", msgSubject, 50, TextField.LAYOUT_LEFT);
tfMessage =new TextField("Message Body ", message, 150, TextField.LAYOUT_LEFT);
form.append(tfAddress);
form.append(tfPort);
form.append(tfSubject);
form.append(tfMessage);
form.addCommand(sendCommand);
form.addCommand(exitCommand);
form.setCommandListener(this);
display.setCurrent(form);
}
publicvoid receiveMessage(){
tfPort =new TextField("Port ", String.valueOf(portReceive), 6, TextField.LAYOUT_LEFT);
form.append(tfPort);
form.addCommand(receiveCommand);
form.addCommand(exitCommand);
form.setCommandListener(this);
display.setCurrent(form);
}
publicvoid receiveTextMessage(){
Thread receiveThread =new ReceiveThread();
receiveThread.start();
}
publicvoid commandAction(Command c, Displayable s){
if (c == exitCommand){
destroyApp(true);
notifyDestroyed();
}elseif (((s == list) && (c == List.SELECT_COMMAND)) || (c == goCommand)){
int i = list.getSelectedIndex();
if (i == 0){// Send Msg
composeMessage();
}elseif (i == 1){// Receive Msg
receiveMessage();
}
}elseif (s == form){
if (c == sendCommand){
message = tfMessage.getString();
msgSubject = tfSubject.getString();
sipAddress = tfAddress.getString();
portSend = getPort(tfPort.getString());
if (portSend == -1){
return;
}
sendTextMessage(message);
}elseif (c == receiveCommand){
portReceive = getPort(tfPort.getString());
if (portReceive == -1){
return;
}
form.deleteAll();
form.removeCommand(receiveCommand);
receiveTextMessage();
}
}
}
/**
* Converts ASCII to int and ensures a positive number.
* -1 indicates an error.
*/
publicint getPort(String s){
int i = -1;
try{
i = Integer.valueOf(s).intValue();
}catch (NumberFormatException nfe){
// don't do anything, the number will be -1
}
if (i < 0){
Alert alert =new Alert("Error");
alert.setType(AlertType.ERROR);
alert.setTimeout(3000);// display the alert for 3 secs
alert.setString("The port is not a positive number.\n" +
"Please enter a valid port number.");
display.setCurrent(alert);
return -1;
}
return i;
}
publicvoid startApp(){
System.out.println("Starting SIP Demo...\n");
}
publicvoid sendTextMessage(String msg){
SendThread sendThread =new SendThread();
sendThread.start();
}
publicvoid destroyApp(boolean b){
System.out.println("Destroying app...\n");
try{
if (sc !=null){
System.out.println("Closing Client Connection...");
sc.close();
}
if (ssc !=null){
System.out.println("Closing Server Connection...");
ssc.close();
}
if (scn !=null){
System.out.println("Closing Notifier Connection...");
scn.close();
}
}catch (IOException e){
e.printStackTrace();
}finally{
notifyDestroyed();
}
}
publicvoid pauseApp(){
System.out.println("Paused...\n");
}
/** Send Message Thread */
class SendThreadextends Threadimplements SipClientConnectionListener{
privateint recTimeout = 0;// do not wait, just poll
publicvoid notifyResponse(SipClientConnection sc){
try{
sc.receive(recTimeout);
form.append("Response received: " + sc.getStatusCode() +" " +
sc.getReasonPhrase());
sc.close();
}catch (Exception ex){
form.append("MIDlet: exception " + ex.getMessage());
ex.printStackTrace();
}
}
publicvoid run(){
try{
sc = (SipClientConnection)Connector.open("sip:" + sipAddress +":" + portSend);
sc.setListener(this);
sc.initRequest("MESSAGE",null);
sc.setHeader("From","sip:" + sipAddress);
sc.setHeader("Subject", msgSubject);
sc.setHeader("Content-Type","text/plain");
sc.setHeader("Content-Length", Integer.toString(message.length()));
OutputStream os = sc.openContentOutputStream();
os.write(message.getBytes());
os.close();// close the stream and send the message
form.deleteAll();
form.removeCommand(sendCommand);
form.append("Message sent...\n");
}catch (IllegalArgumentException iae){
Alert alert =new Alert("Error");
alert.setType(AlertType.ERROR);
alert.setTimeout(3000);// display the alert for 3 secs
alert.setString("Some of the submitted data is invalid.\n" +
"Please enter valid information.");
display.setCurrent(alert);
}catch (Exception ex){
form.append("MIDlet: exception " + ex.getMessage());
ex.printStackTrace();
}
}
}
/** Receive Message Thread */
class ReceiveThreadextends Thread{
privatebyte[] buffer =newbyte[0xFF];
publicvoid run(){
try{
scn = (SipConnectionNotifier)Connector.open("sip:" + portReceive);
form.append("Listening at " + portReceive +"...");
// block and wait for incoming request.
// SipServerConnection is established and returned
// when a new request is received.
ssc = scn.acceptAndOpen();
if (ssc.getMethod().equals("MESSAGE")){
String contentType = ssc.getHeader("Content-Type");
if ((contentType !=null) && contentType.equals("text/plain")){
InputStream is = ssc.openContentInputStream();
int bytesRead;
String msg =new String("");
while ((bytesRead = is.read(buffer)) != -1){
msg +=new String(buffer, 0, bytesRead);
}
form.append("\n...Message Received\n");
form.append("Subject: \"" + ssc.getHeader("Subject") +"\"\n");
form.append("Body: \"" + msg +"\"\n\n");
}
// initialize SIP 200 OK and send it back
ssc.initResponse(200);
ssc.send();
form.append("Response sent...\n");
}
ssc.close();
}catch (Exception ex){
// IOException
// InterruptedIOException
// SecurityException
// SipException
form.append("MIDlet: exception " + ex.getMessage());
ex.printStackTrace();
}
}
}
}

