Build Your Own UA App
Create a WAR (or SIP application) with SIP Servlet and javax/javaee dependencies.
Create a SIP Servlet Application
- Create a SIP Servlet application packaged as a WAR (or SIP application archive) and include the SIP Servlet API dependencies required by your project.
- Add
mediagateway-apiandags-implto your project dependencies. - Add
sip.xmland, if needed,web.xml. - If you do not want time-based session expiration, set session-timeout to 0.
<dependency>
<groupId>oracle.occas</groupId>
<artifactId>mediagateway-api</artifactId>
<version>8.3.0.0.0</version>
</dependency>
<dependency>
<groupId>oracle.occas</groupId>
<artifactId>ags-impl</artifactId>
<version>8.3.0.0.0</version>
</dependency>Obtain the API Instances
- In your SIP servlet (or a service class), obtain both factory instances and their API objects.
// Media Gateway MediaFactory mediaFactory = MediaFactory.getInstance(); MediaGatewayServiceApi mediaApi = mediaFactory.createMediaGatewayServiceApi(); // AI Gateway AIGatewayServiceFactory aiFactory = AIGatewayServiceFactory.getInstance(); AIGatewayService aiApi = aiFactory.createAIGatewayService(); - Optional: Create a small application wrapper (for example, a
MediaGatewayClientandAIUdpClientinterface and implementation) so the rest of the application does not depend directly on MGS or AGS API types.
Map INVITEs to CreateMediaRequest
- Extract the call ID, stream ID, media type, direction, source IP, source port, and codecs.
- Create the STT session first via AGS to obtain the egress destination IP and UDP port for audio routing.
- Use the
AIGatewayServiceFactorybuilders to construct theCreateAISessionRequestand callcreateSTTSession. Validate the response and readudpPortandincomingMediaIPfromAISessionDetails. - Use the egress IP and port from the AGS response as the egress destination in the
EgressMediaStream. - Use the
MediaFactorybuilders to construct the Identifiers,OfferedSDP,IngressMediaStream, andEgressMediaStream. - Build the
CreateMediaRequestwith one ingress and one egress stream.
You must set the call ID, stream ID, participant ID, session ID, and stream direction. This information is used to add metadata and headers for each egress UDP packet.
// Step 1 — Get WebSocket URL and create STT session
String wsUrl = aiApi.getWebSocketUrl(callId, participantId);
CreateAISessionRequest aiReq = aiFactory.createAISessionRequestBuilder()
.callId(callId)
.participantId(participantId)
.participantName(participantName)
.provider("oci")
.headerSize(appConfig.getHeaderSize())
.metaData(metaData)
.build();
if (wsUrl != null) {
aiReq.setExternalEndpoint(wsUrl);
}
AISessionResponse aiResp = aiApi.createSTTSession(aiReq);
// Step 2 — Validate AGS response
if (aiResp == null
|| aiResp.getSessionState() == null
|| "ERROR".equalsIgnoreCase(aiResp.getSessionState().name())
|| aiResp.getAiSessionDetails() == null
|| aiResp.getAiSessionDetails().getUdpPort() == null) {
// trigger cleanup and return error
return;
}
String egressIp = aiResp.getAiSessionDetails().getIncomingMediaIP();
Integer egressPort = aiResp.getAiSessionDetails().getUdpPort();
// Step 3 — Create media session using AGS egress IP and port
CreateMediaRequest mediaReq = mediaFactory.createCreateMediaRequestBuilder()
.callId(callId)
.mediaSessionPurpose(MediaSessionPurpose.EXTERNAL_STREAM)
.addIngressMediaStream(ingressStream)
.addEgressMediaStream(egressStream) // egressStream uses egressIp and egressPort from AGS
.build();
Response mediaResp = mediaApi.createMediaSession(mediaReq);Store session IDs and link to SIP dialog
- Store
mediaSessionIdandaiSessionIdin your application call state, keyed by Call-ID and stream/label. - If you use a
MediaSessionErrorListener, register a mapping frommediaSessionIdtoSipSession(or dialog ID). This enables your application to correlate Media Gateway errors to the correct SIP dialog and trigger cleanup (including deleting both the media session and the STT session) for errors.
A listener dependency example:
<dependency>
<groupId>oracle.occas</groupId>
<artifactId>wlssapi</artifactId>
<version>8.3.0.0.0</version>
</dependency>To register the listener:
<!-- WEB-INF/sip.xml -->
<listener>
<javaee:listener-class>
com.oracle.occas.app.listener.MediaSessionErrorListenerImpl
</javaee:listener-class>
</listener>Handle re-INVITEs
If the caller sends a re-INVITE with SDP changes, update both the media session and the STT session:
// Update STT session
ModifyAISessionRequest modAiReq = aiFactory.modifyAISessionRequestBuilder()
.metaData(metaDataUpdate)
.build();
modAiResp = aiApi.updateSTTSession(aiSessionId, modAiReq);
aiApi.updateSTTSession(aiSessionId, modAiReq);Use the responses to update your call state and build the 200 OK SDP.
Handle the BYE or CANEL
// Delete media session
MediaSessionActionRequest actionReq = mediaFactory.createMediaSessionActionRequestBuilder()
.reason("BYE")
.build();
mediaApi.deleteMediaSession(mediaSessionId, actionReq);
// Delete STT session
aiApi.deleteSTTSession(aiSessionId);For CANCEL, send 487 as appropriate and follow the same cleanup sequence. Deactivate
updateSTTSession.mediaApi.deactivateMediaSession(mediaSessionId, actionRequest);The actionRequest should carry the reason (for example, "call hold").
Deploy and Configure
Assuming you have set up and configured the Media Flow Engines, RTP Proxies, and IACs as documented in the Intelligent Media Connector Guide, the last step is to deploy your WAR or SIP application.