📄 originatinginvite.java
字号:
/*
* ============================================================================
* Copyright (c) 2007 Nokia.
* This material, including documentation and any related computer programs,
* is protected by copyright controlled by Nokia. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of Nokia.
* This material also contains confidential information, which may not be
* disclosed to others without the prior written consent of Nokia.
* ============================================================================
*/
package examples;
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.sip.*;
public class OriginatingINVITE extends MIDlet implements CommandListener,
SipClientConnectionListener, SipServerConnectionListener {
private Display display;
private Form form;
private TextField address;
private Command startCmd;
private Command restartCmd;
private Command byeCmd;
private Command exitCmd;
private SipDialog dialog;
private StringItem str;
private final short S_OFFLINE = 0;
private final short S_CALLING = 1;
private final short S_RINGING = 2;
private short state = S_OFFLINE;
private SipClientConnection scc = null;
// using static SDP content as an example
private String sdp = "v=0\no=sippy 2890844730 2890844732 IN IP4 "
+ "host.example.com\ns=example code\nc=IN IP4 "
+ "host.example.com\nt=0 0\nm=message 54344 "
+ "SIP/TCP\na=user:sippy";
public OriginatingINVITE() {
// Initialize MIDlet display
display = Display.getDisplay(this);
// create a Form for progess info printings
form = new Form("Session example");
address = new TextField("INVITE:", "sip:user@172.21.38.219:5070", 40,
TextField.LAYOUT_LEFT);
form.append(address);
byeCmd = new Command("Hang-up", Command.CANCEL, 1);
restartCmd = new Command("Restart", Command.OK, 1);
startCmd = new Command("Call...", Command.OK, 1);
form.addCommand(startCmd);
exitCmd = new Command("Exit", Command.EXIT, 1);
form.addCommand(exitCmd);
form.setCommandListener(this);
}
public void commandAction(Command c, Displayable d) {
if (c == startCmd) {
form.deleteAll();
form.removeCommand(startCmd);
form.addCommand(byeCmd);
state = S_CALLING;
Thread t = new Thread() {
public void run() {
startSession();
}
};
t.start();
// startSession();
return;
} else if (c == exitCmd) {
destroyApp(true);
return;
} else if (c == byeCmd) {
if (state == S_RINGING) {
sendCANCEL();
} else {
sendBYE();
}
form.removeCommand(byeCmd);
form.addCommand(restartCmd);
return;
} else if (c == restartCmd) {
stopListener();
form.removeCommand(restartCmd);
form.addCommand(startCmd);
form.deleteAll();
form.append(address);
return;
}
}
public void startApp() {
display.setCurrent(form);
}
private void startSession() {
try {
state = S_CALLING;
// start a listener for incoming requests
startListener();
// open SIP connection with remote user
scc = (SipClientConnection) Connector.open(address.getString());
scc.setListener(this);
// initialize INVITE request
scc.initRequest("INVITE", null);
// We have dedicated SipConnectionNotifier so we, need
// to set the From and Contact headers
scc.setHeader("From", "sip:user@host.com");
scc.setHeader("Contact", "sip:user@" + scn.getLocalAddress() + ":"
+ scn.getLocalPort());
scc.setHeader("Content-Length", "" + sdp.length());
scc.setHeader("Content-Type", "application/sdp");
OutputStream os = scc.openContentOutputStream();
os.write(sdp.getBytes());
os.close(); // close and send
str = new StringItem("Inviting... ", scc.getHeader("To"));
form.append(str);
} catch (Exception ex) {
ex.printStackTrace();
// handle IOException
}
}
/**
* Handle incoming response here
*/
public void notifyResponse(SipClientConnection scc) {
int statusCode = 0;
try {
scc.receive(0); // fetch resent response
statusCode = scc.getStatusCode();
str = new StringItem("Response: ", statusCode + " "
+ scc.getReasonPhrase());
form.append(str);
if (statusCode < 200) {
if (statusCode == 180)
state = S_RINGING;
dialog = scc.getDialog();
form.append("Early-Dialog state: " + dialog.getState() + "\n");
form.append("RINGING...\n");
}
if (statusCode == 200) {
String contentType = scc.getHeader("Content-Type");
String contentLength = scc.getHeader("Content-Length");
int length = Integer.parseInt(contentLength);
if (contentType.equals("application/sdp")) {
//
// handle SDP here
//
}
dialog = scc.getDialog(); // save dialog info
form.append("Dialog state: " + dialog.getState());
scc.initAck(); // initialize and send ACK
scc.send();
str = new StringItem("Session established: ", scc
.getHeader("Call-ID"));
form.append(str);
scc.close();
state = S_OFFLINE;
} else if (statusCode >= 300) {
str = new StringItem("Session failed: ", scc
.getHeader("Call-ID"));
form.append(str);
form.removeCommand(byeCmd);
form.addCommand(restartCmd);
scc.close();
state = S_OFFLINE;
}
} catch (IOException ioe) {
// handle e.g. transaction timeout here
str = new StringItem("No answer: ", ioe.getMessage());
form.append(str);
form.removeCommand(byeCmd);
form.addCommand(restartCmd);
}
}
/**
* end session with BYE
*/
private void sendBYE() {
if (dialog != null) {
try {
SipClientConnection sc = dialog.getNewClientConnection("BYE");
sc.send();
str = new StringItem("user hang-up: ", "BYE sent...");
form.append(str);
boolean gotit = sc.receive(10000);
if (gotit) {
if (sc.getStatusCode() == 200) {
form.append("Session closed successfully...");
form.append("Dialog state: " + dialog.getState());
} else
form.append("Error: " + sc.getReasonPhrase());
}
sc.close();
state = S_OFFLINE;
} catch (IOException iox) {
form.append("Exception: " + iox.getMessage());
}
} else {
form.append("No dialog information!");
}
}
private void sendCANCEL() {
if (scc != null) {
try {
SipClientConnection cancel = scc.initCancel();
cancel.send();
if (cancel.receive(30000)) {
str = new StringItem("Session canceled: ", cancel
.getReasonPhrase());
form.append(str);
state = S_OFFLINE;
} else {
form.append("Error canceling the call...");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public void pauseApp() {
// pause
}
public void destroyApp(boolean b) {
notifyDestroyed();
}
public void shutdown() {
destroyApp(false);
}
private SipConnectionNotifier scn;
private SipServerConnection ssc = null;
public void notifyRequest(SipConnectionNotifier sn) {
try {
ssc = scn.acceptAndOpen(); // blocking
if (ssc.getMethod().equals("BYE")) {
// respond 200 OK to BYE
ssc.initResponse(200);
ssc.send();
str = new StringItem("Other side hang-up!", "");
form.append(str);
form.append("Closing notifier...");
form.removeCommand(byeCmd);
form.addCommand(restartCmd);
scn.close();
state = S_OFFLINE;
} else {
if (ssc.getMethod().equals("PRACK")) {
ssc.initResponse(200);
ssc.send();
} else {
// 405 Method Not Allowed
ssc.initResponse(405);
ssc.send();
}
}
} catch (IOException ex) {
// handle IOException
}
}
private void startListener() {
try {
if (scn != null)
scn.close();
// listen to requests on port 5060
scn = (SipConnectionNotifier) Connector.open("sip:5090");
scn.setListener(this);
} catch (IOException ex) {
// handle IOException
}
}
private void stopListener() {
try {
if (scn != null)
scn.close();
scn = null;
} catch (IOException ex) {
// handle IOException
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -