package org.mobicents.servers.media.examples.jsr309.proxies.ann;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import javax.media.mscontrol.JoinEvent;
import javax.media.mscontrol.MsControlException;
import javax.media.mscontrol.StatusEvent;
import javax.media.mscontrol.StatusEventListener;
import javax.media.mscontrol.Joinable.Direction;
import javax.media.mscontrol.mediagroup.MediaGroup;
import javax.media.mscontrol.mediagroup.Player;
import javax.media.mscontrol.networkconnection.NetworkConnection;
import javax.media.mscontrol.networkconnection.NetworkConnectionEvent;
import javax.media.mscontrol.resource.Error;
import javax.media.mscontrol.resource.MediaEventListener;
import javax.sip.DialogTerminatedEvent;
import javax.sip.IOExceptionEvent;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipException;
import javax.sip.TimeoutEvent;
import javax.sip.TransactionTerminatedEvent;
import javax.sip.address.SipURI;
import javax.sip.header.ContactHeader;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.ToHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;
import org.apache.log4j.Logger;
import org.mobicents.javax.media.mscontrol.MediaSessionImpl;
import org.mobicents.servers.media.examples.jsr309.CallProxy;
import org.mobicents.servers.media.examples.jsr309.Jsr309Example;
/**
*
* @author amit bhayani
*
*/
public class AnnProxy extends CallProxy {
private static Logger logger = Logger.getLogger(AnnProxy.class);
private AnnProxyState state = AnnProxyState.INITIAL;
// This file should be present on server on exact same address
public static final String HELLO_WORLD = "file://home/abhayani/workarea/mobicents/svn/trunk/servers/media/examples/jsr-309/audio/ann.wav";
NetworkConnection myNetworkConnection = null;
MediaGroup medGrp = null;
Player player = null;
public AnnProxy(Jsr309Example example) {
super(example);
}
public void processDialogTerminated(DialogTerminatedEvent dte) {
jsr309Example.removeCallProxy(dte.getDialog().getCallId());
}
public void processIOException(IOExceptionEvent arg0) {
// TODO Auto-generated method stub
}
public void processRequest(RequestEvent requestEvent) {
String method = requestEvent.getRequest().getMethod();
Request request = requestEvent.getRequest();
if (requestEvent.getServerTransaction() != null
&& !((method.compareTo(Request.ACK) == 0) || (method.compareTo(Request.BYE) == 0))) {
// its rtr?
logger.error("Received retransmission message, message: " + requestEvent.getRequest());
return;
}
switch (this.state) {
case INITIAL:
if (method.compareTo(Request.INVITE) == 0) {
try {
ServerTransaction st = super.sipProvider.getNewServerTransaction(request);
super.actingDialog = super.sipProvider.getNewDialog(st);
super.actingTransaction = st;
super.actingDialog.terminateOnBye(true);
super.mediaSession = this.msControlFactory.createMediaSession();
// TODO Using MediaSessionImpl till JSr 309 adds method
// createNetworkConnection()
myNetworkConnection = ((MediaSessionImpl) this.mediaSession).createNetworkConnection();
MediaEventListener<NetworkConnectionEvent> netConnList = new MediaEventListener<NetworkConnectionEvent>() {
public void onEvent(NetworkConnectionEvent anEvent) {
if (Error.e_OK.equals(anEvent.getError())) {
if (NetworkConnection.ev_Modify.equals(anEvent.getEventID())) {
if (logger.isDebugEnabled()) {
logger.debug("UA connected to PR endpoint " + anEvent.toString());
}
try {
final String localSdp = myNetworkConnection.getRawLocalSessionDescription();
StatusEventListener statusEvtList = new StatusEventListener() {
public void onEvent(StatusEvent event) {
if (event.getError().equals(Error.e_OK)) {
if (JoinEvent.ev_Joined.equals(event.getEventID())) {
if (logger.isDebugEnabled()) {
logger.debug("Join successful " + event);
}
try {
Response inviteResponse = jsr309Example.getMessageFactory()
.createResponse(Response.OK,
actingTransaction.getRequest());
ContentTypeHeader ctp = jsr309Example.getHeaderFactory()
.createContentTypeHeader("application", "sdp");
inviteResponse.setContent(localSdp, ctp);
ToHeader tHeader = (ToHeader) inviteResponse
.getHeader(ToHeader.NAME);
tHeader.setTag(this.hashCode() + "");
SipURI contactURI = jsr309Example.getAddressFactory()
.createSipURI(
"SimpleUser",
jsr309Example.getStackAddress() + ":"
+ jsr309Example.getPort());
ContactHeader ch = jsr309Example.getHeaderFactory()
.createContactHeader(
jsr309Example.getAddressFactory()
.createAddress(contactURI));
inviteResponse.addHeader(ch);
actingTransaction.sendResponse(inviteResponse);
state = AnnProxyState.SENT_INVITE_200;
} catch (ParseException e) {
logger.error(e);
} catch (SipException e) {
logger.error(e);
} catch (InvalidArgumentException e) {
logger.error(e);
}
try {
player = medGrp.getPlayer();
URI audioFile = new URI(HELLO_WORLD);
} catch (MsControlException e) {
logger.error(e);
} catch (URISyntaxException e) {
logger.error(e);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("UnJoin successful " + event);
}
}
} else {
logger.error("Join failed " + event);
}
}
};
myNetworkConnection.addListener(statusEvtList);
medGrp = ((MediaSessionImpl) mediaSession).createMediaGroup();
myNetworkConnection.join(Direction.DUPLEX, medGrp);
} catch (MsControlException msEx) {
logger.error(msEx);
}
}
} else {
}
}
};
byte[] sdp = request.getRawContent();
myNetworkConnection.addListener(netConnList);
myNetworkConnection.modify("$", new String(sdp));
} catch (Exception e) {
logger.error(e);
}
} else {
logger.error("Received wrong message, message: " + requestEvent.getRequest());
}
break;
case SENT_INVITE_200:
// here we await for ACK
if (method.compareTo(Request.ACK) == 0) {
// Its ok, we do nothing?
this.state = AnnProxyState.RECEIVED_ACK;
} else {
logger.error("Received wrong message on state: " + this.state + ", message: "
+ requestEvent.getRequest());
}
break;
case RECEIVED_ACK:
// here we wait for BYE
if (method.compareTo(Request.BYE) != 0) {
// FIXME: add more
logger.error("Received wrong message on state: " + this.state + ", message: "
+ requestEvent.getRequest());
return;
}
if (super.actingTransaction != null
&& super.actingTransaction.getRequest().getMethod().compareTo(Request.BYE) == 0) {
// rtr
return;
}
this.player.stop();
this.myNetworkConnection.release();
try {
Response byeResponse = jsr309Example.getMessageFactory().createResponse(Response.OK,
super.actingTransaction.getRequest());
super.actingTransaction.sendResponse(byeResponse);
this.state = AnnProxyState.SENT_BYE_200;
} catch (Exception e) {
logger.error(e);
this.state = AnnProxyState.TERMINATED;
}
break;
}
}
public void processResponse(ResponseEvent arg0) {
// TODO Auto-generated method stub
}
public void processTimeout(TimeoutEvent arg0) {
// TODO Auto-generated method stub
}
public void processTransactionTerminated(TransactionTerminatedEvent arg0) {
// TODO Auto-generated method stub
}
}