Understanding CSTA - Part 2

When an application successfully established an ApplicationSession with a Switching Function there will mostly be silence on the wire, except for your regular ResetApplicationTimer request to keep the session alive. The first thing a Computing Function might want to do is discover what devices are available on the target system. Some applications implement a scraping function that requests device details for every possible identifier they can come up with (or the administrator specified), others implement the GetSwitchingFunctionDevices request. In the latter case, the Switching Function will answer with a GetSwitchingFunctionDevicesResponse, containing a list of available extensions. The Computing Function may then use this list to query the Switching Function for details.

To gather information on a Phone, the Computing Function will issue a GetPhysicalDeviceInformation request for the devices ID (its extension, or any other identifier obtained in the previous step). The Switching Function will reply with a GetPhysicalDeviceInformationResponse, containing details information on the device. In this example, the Computing Function queries the Switching Function for information on device 212700. The typeOfNumber="dialingNumber" indicates a number representation “as dialed from an extension”, the Switching Function is now able to retrieve the information and reply.

<?xml version="1.0" encoding="UTF-8"?>
<GetPhysicalDeviceInformation>
	<device typeOfNumber="dialingNumber">212700</device>
</GetPhysicalDeviceInformation>

<?xml version="1.0" encoding="UTF-8"?>
<GetPhysicalDeviceInformationResponse>
	<deviceCategory>station</deviceCategory>
	<hasLogicalElement>true</hasLogicalElement>
</GetPhysicalDeviceInformationResponse>

The Switching Function indicates the device is of the station type the identifier references a logical element. A logical element may be representing several physical elements, in case of a station, the user might have a desktop phone and a cordless phone, both reachable by the same number (for example a multi line appearance configuration).

The Computing Function might be interested in events related to the device to represent the current state in a CTI application. To receive events for a specified device, the Computing Function has to setup a Monitor Point. Monitor Points represent a subscription to events regarding a specific device and are identified by their Cross Reference ID. To create a Monitor Point, the Computing Function sends a MonitorStart request to the Switching Function. The monitorObject specifies the device to monitor for events. The Switching Function will then assign a cross reference ID.

<?xml version="1.0" encoding="UTF-8"?>
<MonitorStart>
	<monitorObject>
		<deviceObject typeOfNumber="dialingNumber">212700</deviceObject>
	</monitorObject>
	<monitorType>device</monitorType>
</MonitorStart>

<?xml version="1.0" encoding="UTF-8"?>
<MonitorStartResponse>
	<monitorCrossRefID>0</monitorCrossRefID>
</MonitorStartResponse>

Every event happening at the monitored station will be tagged with the supplied cross reference ID. The cross reference ID is unique for this session and might be reused by the Switching Function for other clients as well. To get the devices current state (the user might already be on the phone while the application is connecting) the Computing Function may issue a SnapshotDevice request. The Switching Function will provide the Computing Function with a complete dump of the devices current state (if any), for an idle, monitored device the response will include the cross reference ID only.

<?xml version="1.0" encoding="UTF-8"?>
<SnapshotDevice>
	<snapshotObject typeOfNumber="dialingNumber">212700</snapshotObject>
</SnapshotDevice>

<?xml version="1.0" encoding="UTF-8"?>
<SnapshotDeviceResponse>
	<serviceCrossRefID>0</serviceCrossRefID>
</SnapshotDeviceResponse>

For every event at the monitored device, the Switching Function will send an event message to the Computing Function. The Switching Function decides which events are generated, for some scenarios it might not be possible to send all events for example the hook switch of a SIP phone is (for most phone types) not monitored by the Switching Function as opposed to an analog phone. There will be no HookSwitchEvent when the user picks up the phones handset, the Switching Function will send an EstablishedEvent only. For some proprietary devices, the Switching Function is able to generate events for everything including individual key presses. These proprietary phones often can be controlled and monitored by Computing Functions in much greater detail.

This is an example event flow for an outgoing call to another extension from dialing to pickup:

<?xml version="1.0" encoding="UTF-8"?>
<OriginatedEvent>
	<monitorCrossRefID>0</monitorCrossRefID>
	<originatedConnection>
		<callID>169</callID>
		<deviceID>
			<deviceIdentifier typeOfNumber="dialingNumber">212700</deviceIdentifier>
		</deviceID>
	</originatedConnection>
	<callingDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">212700</deviceIdentifier>
	</callingDevice>
	<calledDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">211300</deviceIdentifier>
	</calledDevice>
	<localConnectionInfo>connected</localConnectionInfo>
	<cause>newCall</cause>
</OriginatedEvent>

<?xml version="1.0" encoding="UTF-8"?>
<DeliveredEvent>
	<monitorCrossRefID>0</monitorCrossRefID>
	<connection>
		<callID>169</callID>
		<deviceID>
			<deviceIdentifier typeOfNumber="dialingNumber">212700</deviceIdentifier>
		</deviceID>
	</connection>
	<alertingDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">211300</deviceIdentifier>
	</alertingDevice>
	<callingDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">212700</deviceIdentifier>
	</callingDevice>
	<calledDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">211300</deviceIdentifier>
	</calledDevice>
	<lastRedirectionDevice>
		<notRequired/>
	</lastRedirectionDevice>
	<localConnectionInfo>connected</localConnectionInfo>
	<cause>newCall</cause>
</DeliveredEvent>

<?xml version="1.0" encoding="UTF-8"?>
<EstablishedEvent>
	<monitorCrossRefID>0</monitorCrossRefID>
	<establishedConnection>
		<callID>169</callID>
		<deviceID>
			<deviceIdentifier typeOfNumber="dialingNumber">212700</deviceIdentifier>
		</deviceID>
	</establishedConnection>
	<answeringDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">211300</deviceIdentifier>
	</answeringDevice>
	<callingDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">212700</deviceIdentifier>
	</callingDevice>
	<calledDevice>
		<deviceIdentifier typeOfNumber="dialingNumber">211300</deviceIdentifier>
	</calledDevice>
	<lastRedirectionDevice>
		<notRequired/>
	</lastRedirectionDevice>
	<localConnectionInfo>connected</localConnectionInfo>
	<cause>newCall</cause>
</EstablishedEvent>

The OriginatedEvent represents the start of the callers part of the call, the user dialed “211300”. When the call is delivered to its destination, the Switching Function issues a DeliveredEvent. The delivered event may show an alternative alerting device in case the called extension has forwarded the call, the originally called device will be noted as the lastRedirectionDevice in this case. When the called party picks up the phone, the EstablishedEvent marks the start of the conversation. Again, the answering device might not be equal to the called device, a pickup may have occurred.

The call ID is chosen by the Switching Function. Every following request to control the call will have to provide this call ID for reference, every following event in relation to this call will be given the same call ID. Note the monitorCrossReferenceID too, the events have all been generated because of the cross reference created with MonitorStart at the beginning of the communication.

Part 3 will cover call control functions like MakeCall and ClearConnection as well as user agent control using uaCSTA.