One of the features in the Spokes SDK is a REST Service that exposes Plantronics device features and call control feature via a RESTful interface. The device features exposed by the Spokes REST service includes device command that the host can send to a device, device event (button presses and device state changes). The call control features include a way to notify about incoming /outgoing calls to Spokes, get call state change events and a way to make call via a default Soft phone.
Why REST?
REST (Representational State Transfer) is an architecture style for designing distributed applications. With REST, rather than using a distributed application framework such as CORBA, XML RPC or SOAP to build services, simple HTTP request is used to make calls between a client and a service. REST is a lightweight alternative to other mechanisms like RPC (Remote Procedure Calls) and Web Services (SOAP/ WSDL), as there are no client side proxies or stubs needed and the request response is handled via basic HTTP GET/POST/PUT or DELETE. RESTful applications identify resources with well define URIs and use simple HTTP request for all basic CRUD (Create (POST) / Retrieve (GET)/ Update (PUT) / Delete (DELETE)) operations. The "ST" in "REST" stands for "State Transfer", and in a good REST design operations are self-contained, and each client request carries with it (transfers) all the information (state) that the service needs in order to complete it.
Like Web Services, a REST service is platform-independent, the client and server can be running on different platforms/OS. It is standards-based, as it can run on top of HTTP/HTTPS and can easily be used in the presence of firewalls.
UnLike Web Services and WS-* standards, REST offers no built-in end to end message level security, encryption, session management, transaction and QoS guarantees, etc. In RESTful services, for security, username/password tokens are often used and for encryption REST services can use HTTPS.
The Spokes REST Service plug-in will act as a host for REST service instances. The REST service will expose device service and call service with well know URLs so clients can do simple HTTP POST, GET and get serviced in a RESTful way. The service instance will register for device events such as headset button presses, headset state changes, base/hub/handset button presses, base/hub/handset state changes and ATD state changes (Mobile and PSTN call indications). The service instance will also register for Spokes session level call events such as call state changes and call requested events.
This device service will expose device commands and device events and the call service will expose call commands and call events. Third party business applications, web (via JQuery Ajax post back) or thick client (via simple HTTPWebRequest
and HTTPWebResponse
) can interface out of process with the Spokes REST Service and communicate with the device and the Spokes runtime engine.
Device Service
The device service will expose URIs for getting a device list, getting metadata about a given device (such as PID, product name, version #, serial #, etc.), send a command to a given device and also query for events from a given device.
- Query Device List
http://localhost:port/Spokes/DeviceService/DeviceList
- Query Device PID, Name, Version, Serial etc.
http://localhost:port/Spokes/DeviceService/Device#1/Info
- Device Commands exposed in
IDeviceListener
http://localhost:port/Spokes/DeviceService/Device#1?Ring=true
http://localhost:port/Spokes/DeviceService/Device#1/Mute
http://localhost:port/Spokes/DeviceService/Device#1?Mute=true
http://localhost:port/Spokes/DeviceService/Device#1/AudioState
http://localhost:port/Spokes/DeviceService/Device#1?AudioState=MonoON
- Device Events exposed in
IDeviceListenerEvents
http://localhost:port/Spokes/DeviceService/Device#1/Events
http://localhost:port/Spokes/DeviceService/Device#1/Events/HeadsetEvents
http://localhost:port/Spokes/DeviceService/Device#1/Events/BaseEvents
http://localhost:port/Spokes/DeviceService/Device#1/Events/ATDEvents
Call Service
The call service will expose URIs to query active plugins, send call commands and query call states per registered client, query make call requests and query session manager level call states across plugins.
- Query Active plugins
http://localhost:port/Spokes/CallService/PluginList
- Call command exposed in
ICallCommand
http://localhost:port/Spokes/CallService/IncomingCall
http://localhost:port/Spokes/CallService/OutgoingCall
- Call events exposed in
ICallEvents
http://localhost:port/Spokes/CallService/Client#1/CallEvents
http://localhost:port/Spokes/CallService/Client#1/CallRequests
- SessionManager level events exposed in
ISessionManagerEvents
http://localhost:port/Spokes/CallService/Events
NOTE: The URI listed here may not match the ones in the released products so please refer to the Spokes SDK developer guide for more
details and there are sample code available in PDC as well.
Following is a simple code snippet to show available devices in a HTML web page
Sample 1: Getting Device List via JSON and updating a HTML div in the web page
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Device service test web site</title>
<script src="js/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
var Type;
var Url;
var Data;
var ContentType;
var DataType;
var ProcessData;
function CallService()
{
$.ajax({
type: Type,
url: Url,
data: Data,
contentType: ContentType,
dataType: DataType,
processdata: ProcessData,
success: function(msg) {
ServiceCallSucceeded(msg);
},
error: ServiceCallFailed
});
}
function ServiceFailed(result)
{
alert('Service call failed: ' + result.status + '' + result.statusText);
Type = null; Url = null; Data = null; ContentType = null; DataType = null; ProcessData = null;
}
function GetDeviceList()
{
Type = "GET";
Url = "http://localhost/Spokes/DeviceService/DeviceList";
ContentType = "application/json; charset=utf-8";
DataType = "json";
ProcessData = true;
CallService();
}
function ServiceCallSucceeded(result)
{
if (DataType == "json")
{
resultObject = result.GetUserResult;
if (result.length <= 0)
{
$("#result").fadeOut('fast', function() {
$("#result").html("NONE");
$("#result").fadeIn('fast');
});
return;
}
$('myDiv').load(result);
var output = "";
for (var i in result)
{
output += i +". "+ result[i] + "<BR>";
}
$("#result").fadeOut('fast', function() {
$("#result").html(output);
$("#result").fadeIn('fast');
});
}
}
function ServiceCallFailed(xhr)
{
alert("Service call failed");
}
$(document).ready(
function()
{
setInterval(GetDeviceList, 1000);
}
);
</script>
</head>
<body>
<form id="form1" runat="server">
<p>Devices Found </p>
<div id="result">
None
</div>
</form>
</body>
</html>
This article was contributed by Ramesh Theivendran. Ramesh has been a member of the Corporate Software development team at Plantronics since October 2007. Currently, he server as the software architect for Plantronics Spokes. Prior to joining Plantronics, Ramesh served as a Principal Architect at Borland International and as a Programmer at the Indian Institute of Technology, Bombay (IITB), INDIA. He has over 20 years of experience in building software tools & SDK for wide variety of distributed applications. Ramesh lives in Scotts Valley, California with his wife, Aruna, and their two daughters, Vineha and Vinusha.