Each session has a ‘status’, it can be ‘new’, ‘establishing’, ‘cancelling’, ‘established’, ‘tearingdown’ and ‘destroyed’.
When a new session is created, its status is ‘new’.
When an ‘INVITE’ is received, it sends out an ‘OK’ message and change its status to ‘establishing’.
After receiving an ‘ACK’ message the status will be changed to ‘established’.
Then begins the transferring of voice data using RTP.
When the sending finishes the status will become ‘tearingdown’.
A ‘BYE’ message is also sent to the client.
The status becomes ‘destroyed’ after getting ‘OK’ from the client.
When a ‘CANCEL’ message is received, the status becomes ‘cancelling’.
Then it sends back ‘OK’ and ‘Request Terminated’ messages.
After received an ‘ACK’, the status becomes ‘destroyed’.
The thread is as follows:
@Override
public void run() {
while (true) {
if (requests.size() == 0) {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
final DatagramPacket packet = requests.get(0);
final String request = new String(packet.getData());
System.err.println(request);
sipRequest = new SIPRequest(request);
if (request.toUpperCase().startsWith("INVITE")) {
System.out.println("Got INVITE");
if (!status.equals("new")) {
requests.remove(0);
continue;
}
String requestLine = request.substring(6).trim();
String uri = requestLine.substring(0, requestLine.indexOf(' '));
//System.out.println(uri);
String usr = "";
if (uri.toUpperCase().startsWith("SIP:")) {
usr = uri.substring(4, uri.indexOf('@'));
} else {
usr = uri.substring(0, uri.indexOf('@'));
}
if (!usr.equalsIgnoreCase(user)) {
sendUserNotFound(sipRequest);
status = "tearingdown";
System.out.println("Status: " + status);
continue;
}
sendTrying(sipRequest);
sendRinging(sipRequest);
final String rtpport = request.substring(request.indexOf("m=audio") + 8, request.indexOf("m=audio") + 13);
final String sdp = getSDP(request);
new Thread() {
@Override
public void run() {
File file = new File("wav/" + voiceFile);
if (file.exists()) {
locator = new MediaLocator("file:/" + file.getAbsolutePath());
} else {
System.out.println("Using default voice file!");
locator = new MediaLocator("file:/" + file.getAbsolutePath());
}
transmitter = new Transmitter(locator, packet.getAddress().toString().substring(1), rtpport);
transmitter.prepare();
}
}.start();
new Thread() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
}
if (status.equals("establishing")) {
sendOK(sipRequest, sdp, rtpport);
} else {
try {
transmitter.stop();
} catch (NullPointerException ex) {
Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Transmitter already stopped!");
}
}
}
}.start();
requests.remove(0);
status = "establishing";
System.out.println("Status: " + status);
} else if (request.toUpperCase().startsWith("ACK")) {
System.out.println("Got ACK");
//sendOK(sipRequest);
requests.remove(0);
if (status.equals("establishing")) {
status = "established";
System.out.println("Status: " + status);
new Thread() {
@Override
public void run() {
transmitter.start();
long duration = new VoiceInfo(locator).getDuration();
try {
Thread.sleep(duration);
} catch (InterruptedException ex) {
Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
}
try {
transmitter.stop();
} catch (NullPointerException ex) {
Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Transmitter already stopped!");
}
if (!status.equals("tearingdown") && !status.equals("destroyed")) {
sendBye(sipRequest);
status = "tearingdown";
System.out.println("Status: " + status);
}
}
}.start();
} else if (status.equals("tearingdown")) {
status = "destroyed";
System.out.println("Status: " + status);
break;
} else if (status.equals("cancelling")) {
status = "destroyed";
System.out.println("Status: " + status);
break;
}
} else if (request.toUpperCase().startsWith("BYE")) {
System.out.println("Got BYE");
sendOKWithoutSDP(sipRequest);
requests.remove(0);
try {
transmitter.stop();
} catch (NullPointerException ex) {
Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Transmitter already stopped!");
}
status = "destroyed";
System.out.println("Status: " + status);
break;
} else if (request.toUpperCase().startsWith("SIP/2.0 200")) {
requests.remove(0);
System.out.println("Got OK");
if (status.equals("tearingdown")) {
status = "destroyed";
System.out.println("Status: " + status);
break;
}
} else if (request.toUpperCase().startsWith("CANCEL")) {
requests.remove(0);
System.out.println("Got CANCEL");
status = "cancelling";
System.out.println("Status: " + status);
sendOKWithoutSDP(sipRequest);
sendTerminated(sipRequest);
} else {
requests.remove(0);
}
}
}
}