Sequence of Actions for Placing a Call

Updated 26 May 1999

http://www.cs.cornell.edu/cnrg/telephony/JavaDocs/EventSequence.html


This note describes the sequence of events for when an application places a call. Application 1, Desktop Signaling 1, etc. are running on the first computer and Application 2, etc. are running on the second computer. Application 2 might be the Gateway, if a telephone is being called.

APPLICATION 1:

Instantiate a DesktopSignaling object, which in turn  instantiates a DirectoryService object and authenticates the application with Directory Service by calling the declareIdentity() method. Invoke Dial(String) on your DesktopSignaling object. Example: SignalConnection co = sig.Dial("susie") Dial either returns, or throws an exception.  When Dial returns, if co is NULL, the invitation failed; otherwise the data connection is complete and ready to use. Invoke co.open(), if you want to use the data connection.  At some point the Signaling Observer's onStart() method will be invoked, which the application may  over-ride. For example, the application could play a recording now, or punch some DTMF tones.

APPLICATION 2:

Instantiate a DesktopSignaling object, which will sit and wait for incoming Invite Packets. Since application 2 is a SignalingObserver, its onInvite() method will be invoked when the invitation arrives.  It is passed an  InviteEvent object containing the properties of the data connection of the caller (e.g. abilities, port it will be sending data out on, port it will be taking data in on). onInvite() decides whether to accept or reject.  (Other possible outcomes are busy and incompatible.)   If accept, call the Invite Packet's Accept() method, and exit from the onInvite() method.

DESKTOP SIGNALING 1:

Its Dial() method has been invoked by the main application. An application-specific in channel and out channel may have been passed in with the Dial. Otherwise, default in and out channels are used.   First instantiate a Connection object with all the resources required in it. If you can't do this, thrown an exception. Otherwise extract the "properties" and put them into a serializable invite SignalPacket and pack it all up into a SignalConnection object to send to your peer signaling component.

Next we have to know where DESKTOP SIGNALING 2 is. Construct a UserID from the String parameter passed to Dial().  Use Directory Services to look up the list of "DesktopSignaling" peers (a LocationList) of all the places where the dialed destination might be reached.  Try each Location in turn until the call is accepted or the end of the list is reached.  If a Location is another entry in the directory, try its LocationList, but do this for only one level down.

Send the Invite packet to DESKTOP SIGNALING 2, which is currently waiting on its port. Wait for a packet to come back. If no packet comes back, execute a timeout procedure.

When the next packet comes in, see if it is for the same invite by matching up on sequence numbers.  See if it is an accept, busy, incompatible, or reject.

If it is an accept, send a "start" SignalPacket to DESKTOP SIGNALING 2. Then fill in your Connection object with the properties sent back in the accept packet. You now have a complete Connection object; return it to the application. If it is a BUSY, try the next location on the list.

DESKTOP SIGNALING 2:

At instantiation time, register yourself with Directory Services as UserID "signalingsrv" listening on port such-and-such at IP Address such and such on behalf of application such-and-such. This results in a new Location being added to the LoctionList that belongs to "signalingsrv".

When the invite SignalPacket comes in, unpack it. Observing that this is an invite, construct a new InviteEvent e and call your SignalObserver's onInvite() routine with that event. The event should contain the information that was included in the packet, such as the source's PropertiesCollection object.  Upon return from onInvite, check to see whether the invitation was rejected.  If so, send a reject SignalPacket back to DESKTOP SIGNALING 1.

If the InviteSignalPacket was accepted, this means that the application is accepting the call. Create a complete SignalConnection object, incorporating the properties sent by DESKTOP 1 and the final format decided on, and input/output data ports numbers for net connections.

Serialize the final properties object into an accept packet and send it back to DESKTOP SIGNALING 1.

Go back to waiting on your port. When a START SignalPacket arrives, retrieve the appropriate SignalConnection from the packet and call your Signaling Observer's onStartCall() method. If the START packet does not arrive within a certain time, call your Signaling Observer's onAbortCall() event handler.

Go back to waiting on your port.

DATA EXCHANGE 1:

Connection constructor is called by a DesktopSignaling object when its Dial() routine is invoked. Stick an input channel and output channel into the Connection object. The default constructor is mike->net, net->speaker.

DATA EXCHANGE 2:

Connection constructor is called by a DesktopSignaling object when its Accept() routine is invoked. See DATA EXCHANGE 1 for other constructor stuff.