PBX and Gateway Notes Original version: 25 February 1999 (Updated 3 March and 27 May 1999)

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


Changes since March 3:

Changes since February 25:


In the following, the application runs on Computer A and has a DesktopSignaling component, DesktopSignaling I. The Gateway runs on Computer B (vada) and has a standard DesktopSignaling component, DesktopSignaling II. The PBXSignalingServer runs on Computer C. Here are some scenarios.

Application calling a real telephone: [ All that's needed for PanicButton ]

Initial state: Directory Service Server is running, waiting for queries. PBXSignalingServer is running waiting for packets on its input port. The Gateway server is running, with its DesktopSignaling waiting for incoming packets on its control port. PBXSignalingServer has registered in Directory Services as userid "PBXsrv"; that is, its host address and port have been added to the LocationList for userid "PBXsrv". Likewise, "gatewaysrv" has a list of current Locations on which a Gateway's DesktopSignaling is listening.

  1. Application instantiates a DesktopSignaling, "sig", and invokes sig.Dial(String). It now waits for the Dial to complete.
  2. DesktopSignaling I uses DirectoryService to look up the String argument, which is a telephone number, and gets back a LocationList of all the "gatewaysrv"s that are running.
  3. DesktopSignaling I constructs a SignalConnection object with our application's properties (in and out Channels may or may not have been specified in the Dial call). The default is microphone as the in channel, and speaker as the out channel.
  4. DesktopSignaling I sends an INVITE packet to DesktopSignaling II, and waits for an ACCEPT, BUSY,  REJECT, or INCOMPATIBLE.

    If DesktopSignaling I times out while waiting, treat this as a BUSY.  We'll try the next gateway on the list.

  5. DesktopSignaling II gets the INVITE packet, and calls Gateway's onInvite() handler. This handler checks to see if any lines are available. If there are no lines, the handler invokes busy() on the invitation, which in turn causes DesktopSignaling to send a BUSY packet back to Desktop Signaling I, and goes back to waiting for signaling packets.

    If there are lines, the handler calls GatewayDesktopSignaling's DIAL routine, giving it a Line object. This sends a DIAL packet to the PBXSignalingServer. This DIAL packet is different from others: it contains not only the INVITE information, but also the Line object.

  6. PBXSignalingServer has been sitting on its connection to the Gateway waiting for the next packet to come in from the Gateway. If it is a DIAL packet, extract its Line object and the remote telephone # and place the call. If the line is busy, send a BUSY back to the Gateway. If it is picked up, send an ACCEPT back to the gateway. The PBX won't time out on the call - it will hangup when told to do so by DesktopSignaling II.

    That is, suppose the PBX has dialed the remote telephone, but nobody picks up. The PBX does not time out. Instead, DesktopSignaling II times out if no ACCEPT or BUSY packet comes back in time and sends a HANGUP packet to PBXSignalingServer. (This is an extension of any DesktopSignaling's timeout between INVITE and ACCEPT..) Desktop Signaling II will time out in about 30 seconds.

  7. If DesktopSignaling II gets an ACCEPT packet from PBXSignaling, this means that somebody has picked up the telephone, or at least, that the phone is ringing.   DesktopSignaling II instantiates a complete Connection object, modifies the PropertiesCollection appropriately, and sends an ACCEPT packet back to DesktopSignaling I.
  8. If DesktopSignaling I gets an ACCEPT packet from DesktopSignaling II, it sends a CONFIRM packet to DesktopSignaling II, takes the Properties returned in the ACCEPT packet to build a complete SignalConnection object, and returns the SignalConnection to the application.

    If DesktopSignaling I gets a BUSY packet, it goes to the next Location on the LocationList and returns to step 2. If there is no next Location, treat this as a REJECT.

    If DesktopSignaling I gets a REJECT packet or if it runs out of Locations to invite, it tears down its SigConnection object, and returns null to the application. [ call SignalingObserver.Hangup() instead? in addition? ]

  9. The Dial() call made by the Application has completed, either returning a null SigConnection or a SigConnection that contains a complete data Connection object, which means that the call has been picked up. Now would be the time to play a menu message or whatever, after invoking the Connection's open() method.
  10. DesktopSignaling II, on getting a CONFIRM packet from DesktopSignaling I, calls the Gateway Driver's onStart() handler. This handler should invoke Connection.open() to let the data flow.

    If DesktopSignaling II never gets the CONFIRM packet, it calls the GatewayDriver's onAbort() method, so that the proposed line can be freed up.


Real telephone calling an application

Directory Service and Gateway are up. PBXSignling is not involved at all with Incoming Calls.

  1. User calls one of the lines on the Gateway (4-5541 through 4-5544).
  2. Gateway takes the incoming call, and plays a message instructing the caller to punch in the extension of a user or application, or even another phone number (which would be most bizarre). Or it could present a menu.
  3. GatewayDriver captures the resulting DTMF tones, and calls its DesktopSignaling's Dial() method, with the userid of the destination application/user/server. [ Does the GatewayDriver need to do a directory lookup in order to get the user string associated with the extension, so that it can call Dial(String)? ]
  4. DesktopSignaling II runs pretty much like a generic DesktopSignaling from this point on.