JBoss.orgCommunity Documentation
MGCP Resource Adaptor Type is defined by Mobicents team as part of effort to standardize RA Types.
An MGCP activity object represents a set of related events in an MGCP resource. This Ra Type defines the following Activity objects:
The set of MGCP events regarding the managing (creation,
modification, destruction and state audit) of a MGCP
connection is represented by this activity object. This
activity ends implicitly when a DeleteConnection (MGCP
server role) or DeleteConnectionResponse (MGCP Call
Agent role) event is received. MGCP events related to
Signal generation or Event detection request for
specific connection are also represented by this
Activity. Class name is
net.java.slee.resource.mgcp.MgcpConnectionActivity
New
MgcpConnectionActivity
Activity objects are created by calling
JainMgcpProvider.getConnectionActivity(int
transactionHandle, EndpointIdentifier
endpointIdentifier)
or
JainMgcpProvider.getConnectionActivity(ConnectionIdentifier
connectionIdentifier, EndpointIdentifier
endpointIdentifier)
JainMgcpProvider.getConnectionActivity(int
transactionHandle, EndpointIdentifier
endpointIdentifier)
is mostly used by Application behaving as Media Gateway
Controller or MGCP call Agent Role. The above method is
called to create a new
MgcpConnectionActivity
for unknown
ConnectionIdentifier
, to be used when sending
CreateConnection
events and receive further related messages from a MGCP
Server.
MgcpConnectionActivity
Activity objects are created automatically when the
resource adaptor receives an incoming MGCP request (MGCP
server role).
The set of MGCP events regarding a MGCP endpoint, such
as event detecting/signal generation or
configuration/state audit, is represented by this
activity object. Since a MGCP endpoint doesn't have a
lifecyle this activity does not end implicitly on MGCP
events. Class name is
net.java.slee.resource.mgcp.MgcpConnectionActivity
New
MgcpEndpointActivity
Activity objects is created by calling
JainMgcpProvider.public MgcpEndpointActivity
getEndpointActivity(EndpointIdentifier
endpointIdentifier);
MgcpEndpointActivity
Activity objects are created automatically when the
resource adaptor receives an incoming MGCP request on an
Endpoint (MGCP server role).
Events represent MGCP Requests or Responses received by the MGCP
stack (incoming requests and responses) and Timer expiry. Each
MGCP Requests is fired as different event types. Each MGCP
Response is fired as different event types. Events are fired on
MgcpConnectionActivity
or
MgcpEndpointActivity
activities. There are several event types defined. Following is
the table that describes event-type (name, vendor and version),
event-class and whether its fired on MgcpConnectionActivity or
MgcpEndpointActivity or both.
Spaces where introduced in Name
and
Event Class
column values, to correctly render the
table. Please remove them when using copy/paste.
For proper render of this table prefixes, for entries on some columns are ommited. For prefix values, for each column, please see list below:
net.java.slee.resource.mgcp.
jain.protocol.ip.mgcp.message.
Version for all defined events is 1.0.
Vendor for all defined events is net.java.
Table 2.1. Events fired by MGCP
Name | Event Class | Conn | Enp | Comments |
---|---|---|---|---|
CREATE_ CONNECTION | Create Connection | Yes | No | Received by application acting as MGCP Server. |
CREATE_ CONNECTION_ RESPONSE | Create Connection Respone | Yes | No | Received by application acting as MGCP Call Agent |
MODIFY_ CONNECTION | Modify Connection | Yes | No | Received by application acting as MGCP Server |
MODIFY_ CONNECTION_ RESPONSE | Modify Connection Response | Yes | No | Received by application acting as MGCP Call Agent |
DELETE_ CONNECTION | Delete Connection | Yes | Yes | Received by application acting as MGCP Server |
DELETE_ CONNECTION_ RESPONSE | Delete Connection Response | Yes | Yes | Received by application acting as MGCP Call Agent |
AUDIT_ CONNECTION | Audit Connection | Yes | No | Received by application acting as MGCP Server |
AUDIT_ CONNECTION_ RESPONSE | Audit Connection Response | Yes | No | Received by application acting as MGCP Call Agent |
NOTIFICATION_ REQUEST | Notification Request | Yes | Yes | Received by application acting as MGCP Server. Whether this event will be fired on MgcpConnectionActivity or MgcpEndpointActivity Activity is decided by RA depending on if EventName (Request/Signal) has ConnectionIdentifier included or not. If Request/Signal has list of EventName's with few having ConnectionIdentifier set and few without ConnectionIdentifier, then this event will be fired on both the Activities. However please note that new Activity Object/s will not be created unless initial-event="True" is specified in sbb-jar.xml for this event-type. |
NOTIFICATION_ REQUEST_ RESPONSE | Notification Request Response | Yes | Yes | Received by application acting as MGCP Call Agent. If EventName (Signal/Request) in original NotificationRequest fired by this Application had ConnectionIdentifier set, then this event will be fired on MgcpConnectionActivity. If Request/Signal has list of EventName's with few having ConnectionIdentifier set and few without ConnectionIdentifier, then this event will be fired on both the Activities. However please note that event's will be fired only on existing Activty Object and no new Activity Object will be created unless initial-event="True" is specified in sbb-jar.xml. |
NOTIFY | Notify | Yes | Yes | Received by application acting as MGCP Call Agent. Whether this event will be fired on MgcpConnectionActivity or MgcpEndpointActivity Activity is decided by RA depending on if event is detected on connection or endpoint (ConnectionIdentifier included or not) |
NOTIFY_ RESPONSE | Notify Response | Yes | Yes | Received by application acting as MGCP Server. Whether this event will be fired on MgcpConnectionActivity or MgcpEndpointActivity Activity is decided by RA depending on if original Notify event is detected on connection or endpoint (ConnectionIdentifier included or not) |
TRANSACTION_ TIMEOUT | event. Transaction Timeout | Yes | Yes | Received by application acting as MGCP Server or MGCP Call Agent. Basically this is fired when Application sends the MGCP Request but there is no response. The activity ends automatically. |
AUDIT_ ENDPOINT | Audit Endpoint | No | Yes | Received by application acting as MGCP Server. |
AUDIT_ ENDPOINT_ RESPONSE | Audit Endpoint Response | No | Yes | Received by application acting as MGCP Call Agent. |
ENDPOINT_ CONFIGURATION | Endpoint Configuration | No | Yes | Received by application acting as MGCP Server. |
ENDPOINT_ CONFIGURATION_ RESPONSE | Endpoint Configuration Response | No | Yes | Received by application acting as MGCP Call Agent. |
RESTART_ IN_ PROGRESS | Restart In Progress | No | Yes | Received by application acting as MGCP Call Agent. |
RESTART_ IN_ PROGRESS_ RESPONSE | Restart In Progress Response | No | Yes | Received by application acting as MGCP Server. |
The interface of the JAIN MGCP resource adaptor type specific Activity Context Interface Factory is defined as follows:
package net.java.slee.resource.mgcp; import javax.slee.ActivityContextInterface; import javax.slee.FactoryException; import javax.slee.UnrecognizedActivityException; public interface MgcpActivityContextInterfaceFactory { public ActivityContextInterface getActivityContextInterface(MgcpEndpointActivity activity) throws NullPointerException, UnrecognizedActivityException, FactoryException; public ActivityContextInterface getActivityContextInterface(MgcpConnectionActivity activity) throws NullPointerException, UnrecognizedActivityException, FactoryException; }
The JAIN MGCP Resource Adaptor SBB Interface provides SBBs with access to the JAIN MGCP objects required for creating and sending Request/Response. It is defined as follows:
package net.java.slee.resource.mgcp; import jain.protocol.ip.mgcp.message.CreateConnection; import jain.protocol.ip.mgcp.message.NotificationRequest; import jain.protocol.ip.mgcp.message.parms.CallIdentifier; import jain.protocol.ip.mgcp.message.parms.ConnectionIdentifier; import jain.protocol.ip.mgcp.message.parms.EndpointIdentifier; import jain.protocol.ip.mgcp.message.parms.RequestIdentifier; import java.util.List; public interface JainMgcpProvider extends jain.protocol.ip.mgcp.JainMgcpProvider { public MgcpConnectionActivity getConnectionActivity(ConnectionIdentifier connectionIdentifier, EndpointIdentifier endpointIdentifier); public MgcpConnectionActivity getConnectionActivity(int transactionHandle, EndpointIdentifier endpointIdentifier); public List MgcpConnectionActivity getConnectionActivities(EndpointIdentifier endpointIdentifier); public MgcpEndpointActivity getEndpointActivity(EndpointIdentifier endpointIdentifier); public int getUniqueTransactionHandler(); public CallIdentifier getUniqueCallIdentifier(); public RequestIdentifier getUniqueRequestIdentifier(); }
The resource adaptor implementation should prevent SBBs from adding themselves as MGCP listeners, or changing the MGCP network configuration. Any attempt to do so should be rejected by throwing a SecurityException.
The following code shows how MGCP Call Agent can send CreateConnection request to MGCP Server
public abstract class IVRSbb implements Sbb { public final static String ENDPOINT_NAME = "/mobicents/media/IVR/$"; //SIP Invite received. Send CRCX to MGCP Server public void onCallCreated(RequestEvent evt, ActivityContextInterface aci) { Request request = evt.getRequest(); FromHeader from = (FromHeader) request.getHeader(FromHeader.NAME); ToHeader to = (ToHeader) request.getHeader(ToHeader.NAME); ActivityContextInterface daci = null; try { Dialog dialog = provider.getNewDialog(evt.getServerTransaction()); dialog.terminateOnBye(true); daci = acif.getActivityContextInterface((DialogActivity) dialog); daci.attach(sbbContext.getSbbLocalObject()); } catch (Exception e) { logger.severe("Error during dialog creation", e); respond(evt, Response.SERVER_INTERNAL_ERROR); return; } CallIdentifier callID = mgcpProvider.getUniqueCallIdentifier(); this.setCallIdentifier(callID.toString()); EndpointIdentifier endpointID = new EndpointIdentifier(ENDPOINT_NAME, JBOSS_BIND_ADDRESS + ":" + MGCP_PEER_PORT); CreateConnection createConnection = new CreateConnection(this, callID, endpointID, ConnectionMode.SendRecv); try { String sdp = new String(evt.getRequest().getRawContent()); createConnection.setRemoteConnectionDescriptor(new ConnectionDescriptor(sdp)); } catch (ConflictingParameterException e) { // should never happen } int txID = mgcpProvider.getUniqueTransactionHandler(); createConnection.setTransactionHandle(txID); MgcpConnectionActivity connectionActivity = null; try { connectionActivity = mgcpProvider.getConnectionActivity(txID, endpointID); ActivityContextInterface epnAci = mgcpAcif.getActivityContextInterface(connectionActivity); epnAci.attach(sbbContext.getSbbLocalObject()); } catch (FactoryException ex) { ex.printStackTrace(); } catch (NullPointerException ex) { ex.printStackTrace(); } catch (UnrecognizedActivityException ex) { ex.printStackTrace(); } mgcpProvider.sendMgcpEvents(new JainMgcpEvent[] { createConnection }); } //Received CRCX Response. Now Send RQNT for playing media file public void onCreateConnectionResponse(CreateConnectionResponse event, ActivityContextInterface aci) { ServerTransaction txn = getServerTransaction(); Request request = txn.getRequest(); ReturnCode status = event.getReturnCode(); switch (status.getValue()) { case ReturnCode.TRANSACTION_EXECUTED_NORMALLY: this.setEndpointName(event.getSpecificEndpointIdentifier().getLocalEndpointName()); ConnectionIdentifier connectionIdentifier = event.getConnectionIdentifier(); this.setConnectionIdentifier(connectionIdentifier.toString()); String sdp = event.getLocalConnectionDescriptor().toString(); ContentTypeHeader contentType = null; try { contentType = headerFactory.createContentTypeHeader("application", "sdp"); } catch (ParseException ex) { } String localAddress = provider.getListeningPoints()[0].getIPAddress(); int localPort = provider.getListeningPoints()[0].getPort(); Address contactAddress = null; try { contactAddress = addressFactory.createAddress("sip:" + localAddress + ":" + localPort); } catch (ParseException ex) { } ContactHeader contact = headerFactory.createContactHeader(contactAddress); sendRQNT(WELCOME, true); Response response = null; try { response = messageFactory.createResponse(Response.OK, request, contentType, sdp.getBytes()); } catch (ParseException ex) { logger.severe("ParseException while trying to create OK Response", ex); } response.setHeader(contact); try { txn.sendResponse(response); } catch (InvalidArgumentException ex) { logger.severe("InvalidArgumentException while trying to send OK Response", ex); } catch (SipException ex) { logger.severe("SipException while trying to send OK Response", ex); } break; default: try { response = messageFactory.createResponse(Response.SERVER_INTERNAL_ERROR, request); txn.sendResponse(response); } catch (Exception ex) { logger.severe("Exception while trying to send SERVER_INTERNAL_ERROR Response", ex); } } } private void sendRQNT(String mediaPath, boolean createActivity) { EndpointIdentifier endpointID = new EndpointIdentifier(this.getEndpointName(), JBOSS_BIND_ADDRESS + ":" + MGCP_PEER_PORT); NotificationRequest notificationRequest = new NotificationRequest(this, endpointID, mgcpProvider .getUniqueRequestIdentifier()); ConnectionIdentifier connectionIdentifier = new ConnectionIdentifier(this.getConnectionIdentifier()); EventName[] signalRequests = { new EventName(PackageName.Announcement, MgcpEvent.ann.withParm(mediaPath), connectionIdentifier) }; notificationRequest.setSignalRequests(signalRequests); RequestedAction[] actions = new RequestedAction[] { RequestedAction.NotifyImmediately }; RequestedEvent[] requestedEvents = { new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.oc, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.of, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf0, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf1, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf2, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf3, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf4, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf5, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf6, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf7, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf8, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmf9, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmfA, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmfB, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmfC, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmfD, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmfStar, connectionIdentifier), actions), new RequestedEvent(new EventName(PackageName.Dtmf, MgcpEvent.dtmfHash, connectionIdentifier), actions) }; notificationRequest.setRequestedEvents(requestedEvents); notificationRequest.setTransactionHandle(mgcpProvider.getUniqueTransactionHandler()); NotifiedEntity notifiedEntity = new NotifiedEntity(JBOSS_BIND_ADDRESS, JBOSS_BIND_ADDRESS, MGCP_PORT); notificationRequest.setNotifiedEntity(notifiedEntity); if (createActivity) { MgcpEndpointActivity endpointActivity = null; try { endpointActivity = mgcpProvider.getEndpointActivity(endpointID); ActivityContextInterface epnAci = mgcpAcif.getActivityContextInterface(endpointActivity); epnAci.attach(sbbContext.getSbbLocalObject()); } catch (FactoryException ex) { ex.printStackTrace(); } catch (NullPointerException ex) { ex.printStackTrace(); } catch (UnrecognizedActivityException ex) { ex.printStackTrace(); } } // if (createActivity) mgcpProvider.sendMgcpEvents(new JainMgcpEvent[] { notificationRequest }); logger.info(" NotificationRequest sent"); } public void onNotificationRequestResponse(NotificationRequestResponse event, ActivityContextInterface aci) { logger.info("onNotificationRequestResponse"); ReturnCode status = event.getReturnCode(); switch (status.getValue()) { case ReturnCode.TRANSACTION_EXECUTED_NORMALLY: logger.info("The Announcement should have been started"); break; default: ReturnCode rc = event.getReturnCode(); logger.severe("RQNT failed. Value = " + rc.getValue() + " Comment = " + rc.getComment()); break; } } public void onNotifyRequest(Notify event, ActivityContextInterface aci) { logger.info("onNotifyRequest"); NotificationRequestResponse response = new NotificationRequestResponse(event.getSource(), ReturnCode.Transaction_Executed_Normally); response.setTransactionHandle(event.getTransactionHandle()); mgcpProvider.sendMgcpEvents(new JainMgcpEvent[] { response }); EventName[] observedEvents = event.getObservedEvents(); for (EventName observedEvent : observedEvents) { switch (observedEvent.getEventIdentifier().intValue()) { case MgcpEvent.REPORT_ON_COMPLETION: logger.info("Announcemnet Completed NTFY received"); break; case MgcpEvent.REPORT_FAILURE: logger.info("Announcemnet Failed received"); break; case MgcpEvent.DTMF_0: logger.info("You have pressed 0"); sendRQNT(DTMF_0, false); break; case MgcpEvent.DTMF_1: logger.info("You have pressed 1"); sendRQNT(DTMF_1, false); break; case MgcpEvent.DTMF_2: logger.info("You have pressed 2"); sendRQNT(DTMF_2, false); break; case MgcpEvent.DTMF_3: logger.info("You have pressed 3"); sendRQNT(DTMF_3, false); break; case MgcpEvent.DTMF_4: logger.info("You have pressed 4"); sendRQNT(DTMF_4, false); break; case MgcpEvent.DTMF_5: logger.info("You have pressed 5"); sendRQNT(DTMF_5, false); break; case MgcpEvent.DTMF_6: logger.info("You have pressed 6"); sendRQNT(DTMF_6, false); break; case MgcpEvent.DTMF_7: logger.info("You have pressed 7"); sendRQNT(DTMF_7, false); break; case MgcpEvent.DTMF_8: logger.info("You have pressed 8"); sendRQNT(DTMF_8, false); break; case MgcpEvent.DTMF_9: logger.info("You have pressed 9"); sendRQNT(DTMF_9, false); break; case MgcpEvent.DTMF_A: logger.info("You have pressed A"); sendRQNT(A, false); break; case MgcpEvent.DTMF_B: logger.info("You have pressed B"); sendRQNT(B, false); break; case MgcpEvent.DTMF_C: logger.info("You have pressed C"); sendRQNT(C, false); break; case MgcpEvent.DTMF_D: logger.info("You have pressed D"); sendRQNT(D, false); break; case MgcpEvent.DTMF_STAR: logger.info("You have pressed *"); sendRQNT(STAR, false); break; case MgcpEvent.DTMF_HASH: logger.info("You have pressed C"); sendRQNT(POUND, false); break; } } } public void onCallTerminated(RequestEvent evt, ActivityContextInterface aci) { EndpointIdentifier endpointID = new EndpointIdentifier(this.getEndpointName(), JBOSS_BIND_ADDRESS + ":" + MGCP_PEER_PORT); DeleteConnection deleteConnection = new DeleteConnection(this, endpointID); deleteConnection.setTransactionHandle(mgcpProvider.getUniqueTransactionHandler()); mgcpProvider.sendMgcpEvents(new JainMgcpEvent[] { deleteConnection }); ServerTransaction tx = evt.getServerTransaction(); Request request = evt.getRequest(); try { Response response = messageFactory.createResponse(Response.OK, request); tx.sendResponse(response); } catch (Exception e) { logger.severe("Error while sending DLCX ", e); } } }