?? messageprocessor.java
字號:
/*
* MessageProcessor.java
*
* Created on November 17, 2003, 5:52 PM
*/
package gov.nist.applet.phone.ua;
import java.text.ParseException;
import javax.sip.SipException;
import javax.sip.Transaction;
import javax.sip.SipFactory;
import javax.sip.ServerTransaction;
import javax.sip.ClientTransaction;
import javax.sip.message.Request;
import javax.sip.message.Response;
import javax.sip.message.MessageFactory;
import javax.sip.address.AddressFactory;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.address.URI;
import javax.sip.header.AcceptHeader;
import javax.sip.header.CallInfoHeader;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.FromHeader;
import javax.sip.header.ToHeader;
import javax.sip.header.ExpiresHeader;
import javax.sip.header.RouteHeader;
import javax.sip.header.RecordRouteHeader;
import javax.sip.header.ContactHeader;
import java.util.ListIterator;
import java.util.LinkedList;
import java.util.Iterator;
import gov.nist.applet.phone.media.MediaManager;
import gov.nist.applet.phone.media.messaging.VoicePlayer;
import gov.nist.applet.phone.media.messaging.VoiceRecorder;
import gov.nist.applet.phone.ua.call.*;
import gov.nist.applet.phone.ua.pidf.parser.PresenceTag;
import gov.nist.applet.phone.ua.pidf.parser.XMLpidfParser;
import gov.nist.applet.phone.ua.presence.*;
/**
* Handler of a major part of sip messages
*
* @author DERUELLE Jean
*/
public class MessageProcessor {
/**
* The SipFactory instance used to create the SipStack and the Address
* Message and Header Factories.
*/
SipFactory sipFactory;
/**
* The AddressFactory used to create URLs ans Address objects.
*/
AddressFactory addressFactory;
/**
* The HeaderFactory used to create SIP message headers.
*/
HeaderFactory headerFactory;
/**
* The Message Factory used to create SIP messages.
*/
MessageFactory messageFactory;
/**
* The MessageListener used to handle incoming messages
*/
MessageListener messageListener;
/**
* the configuration
*/
private Configuration configuration;
VoicePlayer voicePlayer = null;
/**
*
*/
MessengerManager messengerManager;
VoiceMessagingTask voiceMessagingTask;
CallManager callManager;
class VoiceMessagingTask implements Runnable {
Thread voiceMessagingThread = null;
String contactAddress = null;
protected static final String STARTED = "Started";
protected static final String STOPPED = "Stopped";
String state = STOPPED;
public VoiceMessagingTask(String contactAddress) {
this.contactAddress = contactAddress;
}
public synchronized void start() {
if (voiceMessagingThread == null) {
voiceMessagingThread = new Thread(this);
}
state = STARTED;
voiceMessagingThread.start();
}
public synchronized void stop() {
state = STOPPED;
}
public void run() {
while (state.equals(STARTED)) {
try {
byte[] buffer = VoiceRecorder.getInstance().getRecord();
if (buffer != null)
messengerManager.sendVoiceMessage(
contactAddress,
buffer);
voiceMessagingThread.sleep(
Configuration.latency4VoiceMessaging);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
/**
*
*/
protected void startVoiceMessagingSchedule(String callee) {
//schedule to send the voice messages every 2 sec.
VoiceRecorder.getInstance().initialize();
VoiceRecorder.getInstance().start();
voiceMessagingTask = new VoiceMessagingTask(callee);
voiceMessagingTask.start();
}
/**
*
*/
protected void stopVoiceMessagingSchedule() {
//Stop the voice messages schedule and the voiceRecorder
voiceMessagingTask.stop();
VoiceRecorder.getInstance().stop();
if (!VoiceRecorder.isClosed())
VoiceRecorder.getInstance().close();
}
/** Creates a new instance of MessageProcessor
* @param callListener - the sip Listener used to handle incoming messages
*/
public MessageProcessor(MessageListener messageListener) {
voicePlayer = new VoicePlayer();
this.messageListener = messageListener;
this.addressFactory = MessageListener.addressFactory;
this.sipFactory = MessageListener.sipFactory;
this.headerFactory = MessageListener.headerFactory;
this.messageFactory = MessageListener.messageFactory;
this.configuration = messageListener.getConfiguration();
this.messengerManager = messageListener.sipMeetingManager;
}
/**********************************************************************/
/* */
/* Handling request messages */
/* */
/**********************************************************************/
/**
* Process the INVITE received request
* @param serverTransaction - the server transaction associated with the request
* @param invite - the request
*/
public void processInvite(
ServerTransaction serverTransaction,
Request invite) {
//Strip out the callee
SipURI calleeURI =
(SipURI) ((FromHeader) invite.getHeader(FromHeader.NAME))
.getAddress()
.getURI();
String callee =
"sip:" + calleeURI.getUser() + "@" + calleeURI.getHost();
// Note that IM Calls are always accepted but VOICE calls may be rejected as there is
// only one Voice line.
try {
CallManager callManager =
messageListener.sipMeetingManager.getCallManager();
//The audio device cannot be shared so if the user is already
//in a call, a busy here is sent back
if (callManager.isAlreadyInAudioCall()) {
Response busyHere =
(Response) MessageListener.messageFactory.createResponse(
Response.BUSY_HERE,
invite);
//If the user has put an URL for the BUSY we add i in the CALL-Info
if(messageListener.getConfiguration().httpBusy!=null){
CallInfoHeader callInfoHeader=
MessageListener.headerFactory.createCallInfoHeader(
MessageListener.addressFactory.createURI(
messageListener.getConfiguration().httpBusy));
busyHere.addHeader(callInfoHeader);
}
System.out.println("send response : " + busyHere.toString());
serverTransaction.sendResponse(busyHere);
} else {
Response ringing =
(Response) MessageListener.messageFactory.createResponse(
Response.RINGING,
invite);
// System.out.println("send response : "+ringing.toString());
serverTransaction.sendResponse(ringing);
AudioCall audioCall = new AudioCall(messageListener);
audioCall.setCallee(callee);
audioCall.setDialog(serverTransaction.getDialog());
audioCall.setStatus(AudioCall.INCOMING_CALL);
System.out.println(
"Audio Call created : "
+ audioCall.getDialog().getDialogId());
callManager.addAudioCall(audioCall);
//Check if someone is inviting us to voice messaging
//or regular RTP media session
boolean voiceMessaging = false;
ContentTypeHeader contentTypeHeader =
(ContentTypeHeader) invite.getHeader(
ContentTypeHeader.NAME);
if (contentTypeHeader == null) {
ListIterator acceptHeaderList =
invite.getHeaders(AcceptHeader.NAME);
while (acceptHeaderList.hasNext() && !voiceMessaging) {
AcceptHeader acceptHeader =
(AcceptHeader) acceptHeaderList.next();
if (acceptHeader
.getContentSubType()
.equalsIgnoreCase("gsm")
|| acceptHeader.getContentSubType().equalsIgnoreCase(
"x-gsm"))
voiceMessaging = true;
}
}
audioCall.setVoiceMesaging(voiceMessaging);
// The SDP tool will be created when you send OK.
messageListener.sipMeetingManager.notifyObserversNewCallStatus(
audioCall);
}
} catch (SipException se) {
se.printStackTrace();
} catch (ParseException pe) {
pe.printStackTrace();
}
}
/**
* Process the BYE received request
* @param serverTransaction - the server transaction associated with the request
* @param bye - the bye request
*/
public void processBye(ServerTransaction serverTransaction, Request bye) {
CallManager callManager =
messageListener.sipMeetingManager.getCallManager();
//Find the matching call
Call call =
callManager.findCall(serverTransaction.getDialog().getDialogId());
if (call == null) return;
//Send OK
try {
Response ok =
(Response) MessageListener.messageFactory.createResponse(
Response.OK,
bye);
serverTransaction.sendResponse(ok);
if (call instanceof AudioCall) {
AudioCall audioCall = (AudioCall) call;
audioCall.setStatus(AudioCall.NOT_IN_A_CALL);
messageListener.sipMeetingManager.notifyObserversNewCallStatus(
audioCall);
if (audioCall.getVoiceMessaging()) {
stopVoiceMessagingSchedule();
} else {
audioCall.getMediaManager().stopMediaSession();
}
//Remove the call
System.out.println(
"Audio Call removed : " + call.getDialog().getDialogId());
callManager.removeAudioCall(audioCall);
} else {
IMCall imCall = (IMCall) call;
//Remove the call
System.out.println(
"IM Call removed : " + call.getDialog().getDialogId());
callManager.removeIMCall(imCall);
}
} catch (SipException se) {
se.printStackTrace();
} catch (ParseException pe) {
pe.printStackTrace();
}
}
/**
* Process the ACK received request
* @param serverTransaction - the server transaction associated with the request
* @param ack - the ack request
*/
public void processAck(ServerTransaction serverTransaction, Request ack) {
CallManager callManager =
messageListener.sipMeetingManager.getCallManager();
//Strip out the callee
SipURI calleeURI =
(SipURI) ((FromHeader) ack.getHeader(FromHeader.NAME))
.getAddress()
.getURI();
String callee =
"sip:" + calleeURI.getUser() + "@" + calleeURI.getHost();
//Find the Audio call
AudioCall call = callManager.findAudioCall(callee);
if (call != null) {
if (!call.getVoiceMessaging())
call.getMediaManager().startMediaSession(false);
else
startVoiceMessagingSchedule(callee);
call.setStatus(AudioCall.IN_A_CALL);
messageListener.sipMeetingManager.notifyObserversNewCallStatus(
call);
}
}
/**
* Process the CANCEL received request
* @param serverTransaction - the server transaction associated with the request
* @param cancel - the cancel request
*/
public void processCancel(
ServerTransaction serverTransaction,
Request cancel) {
CallManager callManager =
messageListener.sipMeetingManager.getCallManager();
//Strip out the callee
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -