I'm working on a project, where we have CUCM configured with CTI Route Points and CTI ports. Our backend server does the routing using JTAPI RouteCallback interface to 3rd party SIP phones. This part is mostly working correctly. In the case when no SIP phones are available, due to all of them servicing a call, our routing logic sends the incoming call to a CTI port, which should play some recording to the caller. The CTI port is configured for auto accept through JTAPI. After a SIP phone becomes available, I would like to transfer the call from the CTI Port to the newly available phone (Availability logic is handled by our server).
My questions are as follows:
1. what steps do I need to take to answer/accept(?) the call on the CTI port and transfer it to the 3rd party SIP client? Currently I'm trying to accept the call after an CallCtlConnOfferedEv, but I'm getting InvalidStateException with the message "Did not meet pre-conditions". What pre-conditions is the message referring to?
2. How do I do the actual transfer? (I know this is kinda broad, but I haven't gotten this far yet so I have very little understanding what does the transfer entail)
I managed to answer the call on the CTI Port but after about 10-15 seconds, CUCM disconnects the call between it and SIP Trunk for some reason.
If the CTIPort is dynamically registered, you should see a CiscoMediaOpenLogicalEvent. Upon receiving this event, applications must invoke setRTPParams on CiscoMediaTerminal or CiscoRouteTerminal and pass in the IP address and port number where they want to terminate the media, along with the rtpHandle that this event delivers.
If RTP is not setup call will be dropped after timeout.
Check if you running into this.
You can use redirect() or transfer() API to transfer the call to phone. Cisco JTAPI Javadocs or developer guide has the details.
indeed RTP was not setup correctly and using your advice I managed to get things working.
I do have a follow-up question. Our CTIPort configuration is static at the moment, and I would prefer it to be dynamic. What JTAPIinterfaces should I be looking at, if I want to create the CTIPorts dynamically?
You can use register(CiscoMediaCapability capabilities, int algorithmIDs) or register(CiscoMediaCapability) API to register CTIPort in dynamic mode. When CTIPort is dynamically registered, after answering the call applications should look for CiscoMediaOpenLogicalEvent and use setRTPParams API to set the IP address and port. This needs to be done whenever media is to established (hold/resume for example).
I got confused when talking about dynamically registering the CiscoMediaTerminal.
What I meant to ask was how would one dynamically create a CTIPort into CUCM? Is there a way using JTAPI or would I have to use a different API?
CTIPort is created like any other device in CUCM Admin and assigned to the user. After creating a CTIPort it will be in un-registered state until an application registers the CTIPort using one of the API mentioned above. There are 2 types of registration: 1) Static - where application specifies the IP address and Port number in register() API and CUCM will use it media setup. 2) Dynamic registration - where application specifies the capabilities of CTIPort but not the IPaddress and Port number. Whenever media is setup CUCM sends the CiscoMediaOpenLogicalEvent and application can specify the IPaddress and port number.
Cisco JTAPI currently doesn't come with any media drivers. So application using CTIPorts should use their own media drivers to terminate/transmit audio.
In any case application needs to register the CTIPort before it can start using it.