package org.mobicents.servers.media.examples.simple.proxies.ann;
import java.text.ParseException;
import java.util.logging.Level;
import jain.protocol.ip.mgcp.JainMgcpCommandEvent;
import jain.protocol.ip.mgcp.JainMgcpEvent;
import jain.protocol.ip.mgcp.JainMgcpResponseEvent;
import jain.protocol.ip.mgcp.message.CreateConnection;
import jain.protocol.ip.mgcp.message.CreateConnectionResponse;
import jain.protocol.ip.mgcp.message.DeleteConnection;
import jain.protocol.ip.mgcp.message.DeleteConnectionResponse;
import jain.protocol.ip.mgcp.message.NotificationRequest;
import jain.protocol.ip.mgcp.message.NotificationRequestResponse;
import jain.protocol.ip.mgcp.message.Notify;
import jain.protocol.ip.mgcp.message.NotifyResponse;
import jain.protocol.ip.mgcp.message.parms.CallIdentifier;
import jain.protocol.ip.mgcp.message.parms.ConnectionDescriptor;
import jain.protocol.ip.mgcp.message.parms.ConnectionMode;
import jain.protocol.ip.mgcp.message.parms.EmbeddedRequest;
import jain.protocol.ip.mgcp.message.parms.EndpointIdentifier;
import jain.protocol.ip.mgcp.message.parms.EventName;
import jain.protocol.ip.mgcp.message.parms.NotifiedEntity;
import jain.protocol.ip.mgcp.message.parms.RequestIdentifier;
import jain.protocol.ip.mgcp.message.parms.RequestedAction;
import jain.protocol.ip.mgcp.message.parms.RequestedEvent;
import jain.protocol.ip.mgcp.message.parms.ReturnCode;
import jain.protocol.ip.mgcp.pkg.MgcpEvent;
import jain.protocol.ip.mgcp.pkg.PackageName;
import javax.management.Notification;
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.mobicents.servers.media.examples.simple.CallProxy;
import org.mobicents.servers.media.examples.simple.SimplExample;
import org.mobicents.servers.media.examples.simple.proxies.echo.EchoProxyState;
public class AnnProxy extends CallProxy {
private AnnProxyState state = AnnProxyState.INITIAL;
public static final String HELLO_WORLD = "";
public AnnProxy(SimplExample mainDish) {
super(mainDish);
super.callIdentifier = new CallIdentifier("" + this.hashCode());
super.endpointName = "media/test/trunk/Announcement/$";
}
public void processMgcpCommandEvent(JainMgcpCommandEvent mgcpCommand) {
switch (this.state) {
case SENT_INVITE_200:
if(mgcpCommand instanceof Notify)
{
//here we could do something, instead we respond with 200 and remove
Notify notify = (Notify) mgcpCommand;
super.mainDish.removeCallProxy(notify.getRequestIdentifier());
ReturnCode rc= ReturnCode.Transaction_Executed_Normally;
NotifyResponse notifyResponse = new NotifyResponse(this,rc);
notifyResponse.setTransactionHandle(notify.getTransactionHandle());
super.mgcpProvider.sendMgcpEvents(new JainMgcpEvent[]{notifyResponse});
}
break;
default:
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received message on wrong state: " + this.state + ", message: " + mgcpCommand);
}
}
}
public void processMgcpResponseEvent(JainMgcpResponseEvent mgcpResponse) {
int code = mgcpResponse.getReturnCode().getValue();
switch (this.state) {
case SENT_CRCX:
// here we wait for answer, we need to send 200 to invite
if (mgcpResponse instanceof CreateConnectionResponse) {
CreateConnectionResponse ccr = (CreateConnectionResponse) mgcpResponse;
if (99 < code && code < 200) {
// its provisional
} else if (199 < code && code < 300) {
// its success
this.endpointIndentifier = ccr.getSpecificEndpointIdentifier();
ConnectionDescriptor cd = ccr.getLocalConnectionDescriptor();
try {
Response inviteResponse = super.mainDish.getMessageFactory().createResponse(Response.OK, super.actingTransaction.getRequest());
ContentTypeHeader ctp = super.mainDish.getHeaderFactory().createContentTypeHeader("application", "sdp");
inviteResponse.setContent(cd.toString(), ctp);
ToHeader tHeader = (ToHeader) inviteResponse.getHeader(ToHeader.NAME);
tHeader.setTag(this.hashCode() + "");
SipURI contactURI = super.mainDish.getAddressFactory().createSipURI("SimpleUser", super.mainDish.getStackAddress() + ":" + super.mainDish.getPort());
ContactHeader ch = super.mainDish.getHeaderFactory().createContactHeader(super.mainDish.getAddressFactory().createAddress(contactURI));
inviteResponse.addHeader(ch);
super.actingTransaction.sendResponse(inviteResponse);
super.mainDish.removeCallProxy(mgcpResponse);
this.state = AnnProxyState.SENT_INVITE_200;
super.actingTransaction = null;
RequestIdentifier ri = new RequestIdentifier("" + (Math.random()));
NotificationRequest notificationRequest = new NotificationRequest(this, super.endpointIndentifier, ri);
EventName[] signalRequests = { new EventName(PackageName.Announcement, MgcpEvent.ann.withParm(HELLO_WORLD), ccr.getConnectionIdentifier()) };
notificationRequest.setSignalRequests(signalRequests);
RequestedAction[] actions = new RequestedAction[] { RequestedAction.NotifyImmediately };
RequestedEvent[] requestedEvents = { new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.oc, ccr.getConnectionIdentifier()), actions),
new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.of, ccr.getConnectionIdentifier()), actions) };
notificationRequest.setRequestedEvents(requestedEvents);
// notificationRequest.setTransactionHandle(mgcpProvider.getUniqueTransactionHandler());
NotifiedEntity notifiedEntity = new NotifiedEntity(super.mainDish.getMgcpClientAddress().getHostAddress(), super.mainDish.getMgcpClientAddress().getHostAddress(),
super.mainDish.getMgcpClientPort());
notificationRequest.setNotifiedEntity(notifiedEntity);
super.mainDish.addCallProxy(ri, this);
super.mainDish.addCallProxy(notificationRequest, this);
super.mgcpProvider.sendMgcpEvents(new JainMgcpCommandEvent[] { notificationRequest });
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
// its error always?
super.mainDish.removeCallProxy(mgcpResponse);
Response inviteResponse = super.mainDish.getMessageFactory().createResponse(Response.SERVER_INTERNAL_ERROR, super.actingTransaction.getRequest());
ContentTypeHeader ctp = super.mainDish.getHeaderFactory().createContentTypeHeader("text", "plain");
inviteResponse.setContent(mgcpResponse.toString(), ctp);
ToHeader tHeader = (ToHeader) inviteResponse.getHeader(ToHeader.NAME);
tHeader.setTag(this.hashCode() + "");
SipURI contactURI = super.mainDish.getAddressFactory().createSipURI("SimpleUser", super.mainDish.getStackAddress() + ":" + super.mainDish.getPort());
ContactHeader ch = super.mainDish.getHeaderFactory().createContactHeader(super.mainDish.getAddressFactory().createAddress(contactURI));
inviteResponse.addHeader(ch);
super.actingTransaction.sendResponse(inviteResponse);
super.mainDish.removeCallProxy(mgcpResponse);
this.state = AnnProxyState.TERMINATED;
super.actingTransaction = null;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received wrong message, it should be CRCX response, state: " + this.state + ", message: " + mgcpResponse);
}
}
break;
case SENT_DLCX:
if (mgcpResponse instanceof DeleteConnectionResponse) {
if (99 < code && code < 200) {
// its provisional
} else if (199 < code && code < 300) {
// its success
try {
Response byeResponse = this.mainDish.getMessageFactory().createResponse(Response.OK, super.actingTransaction.getRequest());
super.actingTransaction.sendResponse(byeResponse);
this.state = AnnProxyState.SENT_BYE_200;
} catch (Exception e) {
e.printStackTrace();
this.state = AnnProxyState.TERMINATED;
}
} else {
// its error always?
super.mainDish.removeCallProxy(mgcpResponse);
this.state = AnnProxyState.TERMINATED;
try {
Response byeResponse = this.mainDish.getMessageFactory().createResponse(Response.OK, super.actingTransaction.getRequest());
super.actingTransaction.sendResponse(byeResponse);
this.state = AnnProxyState.TERMINATED;
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received wrong message, it should be CRCX response, state: " + this.state + ", message: " + mgcpResponse);
}
}
break;
case SENT_INVITE_200:
if (mgcpResponse instanceof NotificationRequestResponse) {
// We do nothing, we just wait for notify on end
super.mainDish.removeCallProxy(mgcpResponse);
} else {
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received wrong message, it should be CRCX response, state: " + this.state + ", message: " + mgcpResponse);
}
}
break;
default:
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received message on wrong state: " + this.state + ", message: " + mgcpResponse);
}
}
}
public void processDialogTerminated(DialogTerminatedEvent dte) {
super.mainDish.removeCallProxy(dte.getDialog().getCallId());
}
public void processIOException(IOExceptionEvent io) {
// 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?
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("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);
EndpointIdentifier ei = new EndpointIdentifier(super.endpointName, this.mgcpServerAddress.getHostAddress() + ":" + this.mgcpServerPort);
CreateConnection crcx = new CreateConnection(this, this.callIdentifier, ei, ConnectionMode.SendRecv);
this.mgcpProvider.sendMgcpEvents(new JainMgcpEvent[] { crcx });
this.mainDish.addCallProxy(crcx, this);
this.state = AnnProxyState.SENT_CRCX;
} catch (Exception e) {
e.printStackTrace();
}
} else {
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("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 {
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received wrong message on state: " + this.state + ", message: " + requestEvent.getRequest());
}
}
break;
case SENT_BYE_200:
// here we await for ACK
if (method.compareTo(Request.ACK) == 0) {
// Its ok, we do nothing?
this.state = AnnProxyState.TERMINATED;
} else {
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received wrong message on state: " + this.state + ", message: " + requestEvent.getRequest());
}
}
break;
case RECEIVED_ACK:
try {
// here we wait for BYE
if (method.compareTo(Request.BYE) != 0) {
// FIXME: add more
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("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;
}
super.actingTransaction = requestEvent.getServerTransaction();
// This shoudl remove all connections (actually there is one :))
DeleteConnection dlcx = new DeleteConnection(this, this.callIdentifier, this.endpointIndentifier);
this.mgcpProvider.sendMgcpEvents(new JainMgcpEvent[] { dlcx });
this.mainDish.addCallProxy(dlcx, this);
this.state = AnnProxyState.SENT_DLCX;
} catch (Exception e) {
e.printStackTrace();
}
break;
case TERMINATED:
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received message on TERMINATED state, message: " + requestEvent.getRequest());
}
break;
default:
if (this.logger.isLoggable(Level.SEVERE)) {
logger.severe("Received wrong message on state: " + this.state + ", message: " + requestEvent.getRequest());
}
}
}
public void processResponse(ResponseEvent response) {
// TODO Auto-generated method stub
}
public void processTimeout(TimeoutEvent te) {
// TODO Auto-generated method stub
}
public void processTransactionTerminated(TransactionTerminatedEvent tte) {
// TODO Auto-generated method stub
}
public void transactionEnded(int arg0) {
// TODO Auto-generated method stub
}
public void transactionRxTimedOut(JainMgcpCommandEvent msg) {
try {
super.mainDish.removeCallProxy(msg);
super.mainDish.removeCallProxy(msg);
Response response = super.mainDish.getMessageFactory().createResponse(Response.SERVER_INTERNAL_ERROR, super.actingTransaction.getRequest());
ContentTypeHeader ctp = super.mainDish.getHeaderFactory().createContentTypeHeader("text", "plain");
response.setContent("TIMEDOUT\n" + msg.toString(), ctp);
ToHeader tHeader = (ToHeader) response.getHeader(ToHeader.NAME);
tHeader.setTag(this.hashCode() + "");
SipURI contactURI = super.mainDish.getAddressFactory().createSipURI("SimpleUser", super.mainDish.getStackAddress() + ":" + super.mainDish.getPort());
ContactHeader ch = super.mainDish.getHeaderFactory().createContactHeader(super.mainDish.getAddressFactory().createAddress(contactURI));
response.addHeader(ch);
super.actingTransaction.sendResponse(response);
super.mainDish.removeCallProxy(msg);
this.state = AnnProxyState.TERMINATED;
super.actingTransaction = null;
} catch (Exception e) {
e.printStackTrace();
}
}
public void transactionTxTimedOut(JainMgcpCommandEvent msg) {
try {
super.mainDish.removeCallProxy(msg);
Response response = super.mainDish.getMessageFactory().createResponse(Response.SERVER_INTERNAL_ERROR, super.actingTransaction.getRequest());
ContentTypeHeader ctp = super.mainDish.getHeaderFactory().createContentTypeHeader("text", "plain");
response.setContent("TIMEDOUT\n" + msg.toString(), ctp);
ToHeader tHeader = (ToHeader) response.getHeader(ToHeader.NAME);
tHeader.setTag(this.hashCode() + "");
SipURI contactURI = super.mainDish.getAddressFactory().createSipURI("SimpleUser", super.mainDish.getStackAddress() + ":" + super.mainDish.getPort());
ContactHeader ch = super.mainDish.getHeaderFactory().createContactHeader(super.mainDish.getAddressFactory().createAddress(contactURI));
response.addHeader(ch);
super.actingTransaction.sendResponse(response);
super.mainDish.removeCallProxy(msg);
this.state = AnnProxyState.TERMINATED;
super.actingTransaction = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}