Provides the control layer for internet telephony.   Signaling hides all the complexity of finding the user (Directory Service), querying the user if he or she wants to talk to the caller and setting up a mutually acceptable channel to allow the call to take place (Data Exchange). The application can Dial a user by simply passing in a userid in String format or a telephone number to Dial.  If a telephone number is provided then Signaling forwards the request to the Gateway (as if it is a call to another PC) and returns a SignalConnection (once the Dial Sequence with Gateway is complete).

In order to use signaling capabilities, the application must implement the cnrg.itx.signal.SignalingObserver interface. For control over the dial sequence the application must in addition implement the cnrg.itx.signal.SignalConnectionObserver interface. These interfaces list possible events that require application feedback in order to be handled.

How applications can use the Non-blocking Dial

1) Implement all the methods in the cnrg.itx.signal.SignalConnectionObserver interface.   This allows the DialThread making the call to inform the application about the result(s) of the dial sequence.

2) Once these methods are implemented the application can do the following to use the non-blocking Dial():

	DesktopSignaling myDS; //handle to a instantiated DesktopSignaling
	String uid = "userIDorPhone";
	LocationList ll = myDS.getLocationList(uid);
	
	//The location list contains all the possible places for the given uid.  Any of these locations
	//may be used to get the desired location.  See cnrg.itx.ds.LocationList for more information.
	Location destLoc = ll.first();
	
	//The Dial function returns a SignalConnection immediately, which contains a DialThread object
	SignalConnection mySC = myDS.Dial(uid, destLoc, (SignalConnectionObserver) this);
	
	//This actually starts the DialThread and begins the Dial sequence.  The Dial thread will 
	//generate an event by using the appropriate method in SignalConnectionObserver.
	mySC.startCall();

The function can return after calling startCall(). Now, if the application wants to abort the call, it can simply say, mySC.abortCall(). If the call is still being made the thread stops mid-way and exits cleanly.

3) An example of what the DialThread does follows:

The DialThread will conduct a 3-way handshake with the peer application at the specified location (in destLoc from the above application). After the Dial Sequence the thread will call one of the following methods on the application:

onAccept(), onReject(), onBusy(), onInvalid(), onTimeout(), onIncompatible(), or onError()

These events describe what happened in the dial attempt and pass in a DialSignalEvent object to the application (or a DesktopSignalingException object in the case of onError()). The application should use the information contained in this extension of SignalEvent. For example, onAccept() & onReject() may be implemented as follows:

	public void onAccept(DialSignalEvent dse){
		SignalConnection sc = dse.getSignalConnection();
		sc.open();//open connection for data transfer
		//inform the user that he or she may start talking
	}

	public void onReject(DialSignalEvent dse){
		String reason = dse.getReason();
		//Tell the user why the call was rejected, in the status bar.
		//The SignalConnection is closed by Signaling before this method is called.
	}

Other Options for DesktopSignaling

The ITX Signaling component (this package) uses its own signaling protocol by default. However, we have begun to implement SIP. Use a special constructor to make your application "talk SIP":
   DesktopSignaling mySig = new DesktopSignaling (
      (SignalingObserver) so, (String) userid, (String)password,
      (String)configurationFileName, true);
The last parameter on that constructor is what tells DesktopSignaling to use SIP or not.

Omitting Directory Service

It is possible to setup DesktopSignaling without getting a Directory Service. In this case, applications must say what specific ports their signaling components are listening on. To leave out Directory Service altogether, use the following forms of the constructor:
   // DesktopSignaling picks what port to listen on
   DesktopSignaling mySig = new DesktopSignaling ( (SignalingObserver) so);
   // You tell DesktopSignaling what port to listen on
   DesktopSignaling mySig = new DesktopSignaling ( (SignalingObserver) so,
      (int)port );
When running without the directory service, you do not need to have the directory server running, nor do you need your application to have access to a resolv.conf file.

Further Reading

Further information on the ITX signaling component can be found in the source tree under "docs/signal".