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:
- Use of the PBX is optional (-PBX on command line at launch includes PBX)
- The reason it is optional is that Gateway can now dial out calls
- Gateway can handle DTMF
- Name changes in Gateway
Changes since February 25:
- The application (via its
onStart()
routine) now invokes Connection.open()
;
before, DesktopSignaling did that.
- No more LocationList for "signalingsrv"; no more "signalingsrv".
DesktopSignaling's list of peers is "gatewaysrv"'s LocationList.
- The case of incoming calls to the Gateway was fleshed out a little bit.
- Gateway now uses an unmodified copy of DesktopSignaling and has SignalInterface
class mediate between the gateway application code and DesktopSignaling.
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.
- Application instantiates a DesktopSignaling, "sig", and invokes
sig.Dial(String). It now waits for the Dial to complete.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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? ]
- 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.
- 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.
- User calls one of the lines on the Gateway (4-5541 through 4-5544).
- 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.
- 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)? ]
- DesktopSignaling II runs pretty much like a generic DesktopSignaling from this point on.