Wednesday, April 08, 2009

Plantronics Device Manager SDK for .NET


Plantronics upcoming Persono Suite product will introduce a new managed SDK for the Microsoft .NET platform that end user applications can use to communicate with the Plantronics USB Audio devices. This SDK will eventually replace the PersonoCall SDK 2.11.7.



Plantronics Device manager SDK will provide the host to device interface layer for all next generation Plantronics software products. The current implementation of the Plantronics device manager uses Microsoft .NET 2.0 and will be made available for .NET and un-managed COM applications


The Plantronics Device Manager SDK provides a generic application programming interface (API) for software applications while hiding the details of the of the interface implementation of a particular headset hardware model.
The device manager exposes few interfaces such as IDeviceManager for device enumeration and finding a specific device; IDevice for exposing common device behavior; IHostCommand; and IDeviceEvents for handling device specific behavior. IHostCommand abstracts all the commands a host can send to a device and IDeviceEvents abstracts all the events that a device can send to the host. As part of the device enumeration, the device manager will initialize the common device behavior and also the device specific behavior based on the device it enumerates.
The Plantronics Device Manager SDK includes managed assemblies and type libraries needed for developing applications that interfaces with Plantronics headsets. It also includes a merge module to allow for easy inclusion of all the needed redistributable files into any application’s installer.

Plantronics Device SDK Interface Specification


The Plantronics Device SDK is a managed API and is implemented using .NET 2.0 and is available for managed and unmanaged applications. The core interfaces that are part of the device SDK are IDeviceManager, IDeviceManagerEvents, IDevice, IHostCommand, and IDeviceEvents.
DeviceManager concrete class implements IDeviceManager and is the entry point for end user applications. After creating an instance of the DeviceManager application can request for a list of Plantronics devices connected to the USB or request for specific devices by specifying the Plantronics vendor ID (0x47F) or the product ID.

IDeviceManager Interface



public interface IDeviceManagerEvents
{
event DeviceStateEventHandler DeviceStateChanged;
event EventHandler Suspending;
event EventHandler Resuming;
event EventHandler QueryConfigChange;
}


public interface IDeviceManager : IDeviceManagerEvents, IDisposable
{
[ComVisible(false)]
Collection Devices { get;}
[ComVisible(false)]
Collection FindDevices(int vendorId);
[ComVisible(false)]
Collection FindDevices(int vendorId, int productId);

IEnumerator GetDeviceList();
IDevice FindDeviceForPath(String devicePath);
IDevice FindDeviceForProductID(int vendorId, int productId);
}


Property: Collection Devices { get;}
The Devices property returns a collection of supported Plantronics devices that are connected to the USB.

Method: Collection FindDevices (int vendorId)
Method: Collection FindDevices (int vendorId, int productId)
FindDevices() returns a collection of supported Plantronics devices that are connected to the USB

Method: IDevice FindDevice (String devicePath)
FindDevice() returns an Device object that matches the device path of supported Plantronics devices that are connected to the USB

Event: DeviceStateChanged
DeviceStateChanged event is triggered when a supported Plantronics device is removed or added to the USB port.

Event: Suspending
Suspending event is triggered when a the system starts to Standby or Hibernate. If a device is attached and listening for Input reports if the system enters Standby or Hibernate the device SDK automatically detaches from the device.

Event: Resuming
Resuming event is triggered when the system resumed from Standby or Hibernate.

Event: QueryConfigChange

QueryConfig event is triggered when the system is undocked. If a device is attached and listening for Input reports and an undock is requested, the device SDK will automatically detach from the device to allow a successful undock.

IDevice Interface

public interface IDevice : IDisposable
{
String DevicePath { get;}
int VendorId { get;}
int ProductId { get;}
int VersionNumber { get;}
String InternalName { get;}
String ProductName { get;}
String ManufacturerName { get;}
String SerialNumber { get;}
bool IsAttached { get;}
IDeviceAttribute Attribute { get;}

IDeviceEvents DeviceEvents { get; }
IHostCommand HostCommand { get;}

void Attach();
void Detach();
bool RegisterNotification();
bool UnRegisterNotification();
bool IsSupported(ushort usage);

event ReportDataEventHandler DataReceived;
event DeviceStateEventHandler DeviceStateChanged;
}

Property: String DevicePath { get;}

The DevicePath property returns the HID path of the device. This is the path the device manager uses to read/write to the device.

Property: String InternalName { get;}

The InternalName property returns the internal device name.

Property: String ProductName { get;}

The ProductName property returns the name under which the device is ,marketed.

Property: String ManufacturerName { get;}

The ManufacturerName property returns the name of the device manufacturer, Plantronics Inc.

Property: Int VendorId { get;}

The VendorId property returns the USB Vendor ID for Plantronics Inc, which is 0x47F.

Property: Int ProductId { get;}

The ProductId property returns the USB Product ID assigned to the device by Plantronics Inc..

Property: bool IsAttached { get;}

The IsAttached property returns true if IDevice is currently attached to a device and false if there is no currently attached device.

Method: void Attach()

Attach connects to the device and starts listening for input report from the device

Method: void Detach()
Detach disconnects from the device and stops listening for input report from the device.

Method: void RegisterNotification()

After attaching to a device RegisterNotification can be used to register for Windows USB device attach and removal notifications.

Method: void UnRegisterNotification()

Before detaching from a device call UnRegisterNotification to unregister for Windows USB device attach and removal notifications.

Method: bool IsSupported(ushort Usage)
Given a HID Usage IsSupported() can be used to find if an attached device supports a specific usage or not

Event: DeviceStateChanged
DeviceStateChanged event is triggered when a device is removed or added to the USB port. For device state change events to be triggered applications should have called RegisterNotification on the device object.

Event: DataReceived
After attaching to a device applications can register for this event to process the raw input reports that are coming from the device. This is mainly useful for troubleshooting and to verify if the device is functioning correctly.

Property: IHostCommand HostCommand { get;}

The HostCommand property returns a IHostCommand interface. The IHostCommand provides methods and properties that can be used to send specific requests to the device from the host application.

IHostCommand Interface


public interface IHostCommand
{
void Ring(bool enable);
AudioType AudioState { get; set;}
bool Mute { get; }
bool Register(RegistrationType sign);
String GetVersion(VersionType version);
}


Method: void Ring(bool enable)

Ring method controls the headset ringer.
User applications should use the ringer property to indicate an incoming call. This should be done in addition to playing a ring-tone through the headset audio stream. This is done because wireless headsets may turn off the audio channel to conserve the battery power. If audio is disabled, no ring-tone will be heard until the radio link is established. Use of the Ring method allows a ring-tone to be signaled out-of-band, and thus allows the wearer to hear the ring even if the audio link is not established. Using the Ring method in addition to the audio-channel ring-tone will ensure that the ring is heard regardless of the audio link state.

Property: AudioType AudioState { get; set; }

This property enables or disables the audio stream to the device. For a wireless device this property also controls the RF link. The link is up when audio is enabled by setting the AudioState to AudioType.MonoOn and the link is down when the audio is disabled by setting the AudioState to AudioType.MonoOff. User applications should use this property to conserve battery power on wireless devices. (For example, a telephony application would keep the audio disabled while there are no active calls and then enable the audio when a call becomes active.)
The only supported values currently for AudioState are MonoOn and MonoOff. The other values are added for future devices that will support mono and stereo.

public enum AudioType
{
MonoOn = 1,
MonoOff = 2,
StereoOn = 3,
StereoOff = 4,
MonoOnWait = 5,
StereoOnWait = 6
}

Property: bool Mute { get; }
This property can be used to get the Mute state of the microphone in the headset.

Method: void Register(RegistrationType sign)
Host applications are required to SignIn and SignOut when they start and shutdown to notify the device that they are running and are interested in listening to device events. If the host applications didn’t register some device may not send input reports on a specific HID usage page.

public enum RegistrationType
{
SignIn = 1,
SignOut = 2,
Exclusive = 4
}

Method: void GetVersion(VersionType version)
GetVersion allows the host application to request for the USB version, the base version and the headset version of a particular Plantronics device.

public enum VersionType
{
USBFirmware =1,
BaseFirmware = 2,
RemoteFirmware = 3
}

Property: IDeviceEvents DeviceEvents { get;}

The DeviceEvents property returns an IDeviceEvents interface that can be used to register for device events like TalkPressed, ButtonPressed e.t.c. Some of these events are reported by the device based on user action such as a button press or when device state changes such as RFLink up or down.


IDeviceEvents Interface


public interface IDeviceEvents
{
event DeviceEventHandler TalkPressed;
event DeviceEventHandler ButtonPressed;
event DeviceEventHandler MuteStateChanged;
event DeviceEventHandler AudioStateChanged;
event DeviceEventHandler FlashPressed;
event DeviceEventHandler SmartPressed;
}

Event: TalkPressed

The TalkPressed event is triggered when an attached device’s “Talk” button is pressed.
A client application should subscribe to the TalkPressed event. If the application is not currently in an active call, the application should answer any incoming (“ringing”) call. If the application is already in an active call, the application should terminate the current call. If the application is neither in a call nor receiving an incoming call, the application should create a new call and put it into the “dialing” state (and send the dial tone into the headset).

Event : ButtonPressed

The ButtonPressed event is triggered when any of the buttons on the attached device is pressed.
The SDK provides client application two ways to handle button press events:
Via device-independent pre-translated events such as TalkPressed, FlashPressed and SmartPressed;
Via device-specific “raw” ButtonPressed events.
Different Plantronics headsets may map different set of buttons into TalkPressed, FlashPressed and SmartPressed events. Using these events instead of the “raw” ButtonPressed event is recommended because it makes the implementation device-independent and more likely to work with any future Plantronics products without any code changes.

Event: MuteStateChanged

The MuteStateChanged event is triggered when an attached device’s headset microphone mute is changed.

Event : AudioStateChanged
The AudioStateChanged event is triggered when an attached device’s AudioState changes. AudioState may change its state either in response to the client application modifying that property, or in response to the radio link being brought up or down by the device itself.
A client application should subscribe to the AudioStateChanged event and track the device’s status. If the radio link goes down, the application should probably drop the current call. If the radio link goes up, the application should probably pick up any incoming calls (if any) or create a new call and put it into the “dialing” state (and send the dial tone into the headset).
Because changing the AudioState property also causes the AudioStateChanged event to trigger, a client application should distinguish between the audio link state changes which occurred because of an application request, and the changes which were initiated by the device.

Event: FlashPressed

The FlashPressed event is triggered when one of the attached device’s “Flash” buttons is pressed. The nButton parameter indicates the flash button’s number
(For example, the CS50/60 headset interprets long volume up and volume down presses as flash buttons 0 and 1.)

A client application may use the flash buttons to put the current call on hold while simultaneously picking up a new incoming call or activate an existing call that is already on hold state. Distinguishing between the two different “flash” buttons may be used to cycle through the current call list in two different directions

Event: SmartPressed
The SmartPressed event is triggered when one of the attached device’s “Smart” buttons is pressed.
(For example, the CS50/60 headset interprets a long mute press as a “Smart” button press.)
A client application may associate application-specific logic with the “smart” button. Possible examples are launching another application or dialing a particular pre-configured phone number/extension.

Property: IDeviceAttribute Attribute { get;}

The Attribute property returns true a IDeviceAttribute interface that can be used to retrieve Device HID capabilities and details about Input, Output and feature report capabilities. A client application can use this information to know about the capabilities of the device.
IDeviceAttribute Interface

public interface IDeviceAttribute : IDisposable
{
DeviceCap DeviceCap { get;}
InputCaps Input { get;}
OutputCaps Output { get;}
FeatureCaps Feature { get;}

DeviceUsage GetDeviceUsage(ReportType reportType);
}

Property: DeviceCap DeviceCap { get;}
The DeviceCap property returns the top level device capabilities such as the Usage, Usage Page, Input report buffer length, Output report buffer length, Feature report buffer length e.t.c. from the USB device.

Property: InputCaps Input { get;}
The InputCaps property returns the HID Input capabilities from the USB Device.

Property: OutputCaps Output { get;}
The OutputCaps property returns the HID Output capabilities from the USB Device.

Property: FeatureCaps Feature { get;}
The FeatureCaps property returns the HID Feature capabilities from the USB Device.







Code Sample

//Instantiate DeviceManager and get a list of Plantronics devices
IDeviceManager m_deviceMgr = new DeviceManager();
Collection devices = m_deviceMgr.FindDevices(VendorID.Plantronics);
foreach (IDevice device in devices)
{
//Iterate through all the devices
}

//Register for the DeviceManager events

private void RegisterDevMgrNotification()
{

m_deviceMgr.DeviceStateChanged += new DeviceStateEventHandler(m_deviceMgr_DeviceStateChanged);
m_deviceMgr.Resuming += new EventHandler(m_deviceMgr_Resuming);
m_deviceMgr.Suspending += new EventHandler(m_deviceMgr_Suspending);
m_deviceMgr.QueryConfigChange += new EventHandler(m_deviceMgr_QueryConfigChange);

}

//UnRegister for the DeviceManager events
private void UnRegisterDevMgrNotification()
{
m_deviceMgr.DeviceStateChanged -= m_deviceMgr_DeviceStateChanged;
m_deviceMgr.Resuming -= m_deviceMgr_Resuming;
m_deviceMgr.Suspending -= m_deviceMgr_Suspending;
m_deviceMgr.QueryConfigChange -= m_deviceMgr_QueryConfigChange;
}

//On Attach Register for the events

public void Attach()
{
m_device.Attach();

if (m_device.IsAttached)
{
//Register for Device events
IDeviceEvents events = m_device.DeviceEvents;
events.TalkPressed += new DeviceEventHandler(events_TalkPressed);
events.AudioStateChanged += new DeviceEventHandler(events_AudioStateChanged);
events.MuteStateChanged += new DeviceEventHandler(events_MuteStateChanged);
events.ButtonPressed += new DeviceEventHandler(events_ButtonPressed);
}
}

//Event handlers for specific button presses

void events_TalkPressed(object sender, DeviceEventArgs e)
{
//Talk Pressed
}

void events_AudioStateChanged(object sender, DeviceEventArgs e)
{
//Audio state Changed
//e.AudioState will provide the current Audio State
}

void events_MuteStateChanged(object sender, DeviceEventArgs e)
{
//Mute state Changed
//e.Mute will be true or false
}

//Generic ButtonPressed event handler to handle
//all headset button presses

void events_ButtonPressed(object sender, DeviceEventArgs e)
{
switch (e.ButtonPressed)
{
case HeadsetButton.VolumeUp:
//Volume Up Pressed
break;

case HeadsetButton.VolumeDown:
//Volume Down Pressed
break;

case HeadsetButton.VolumeUpHeld:
//Long Volume Up Pressed
break;

case HeadsetButton.VolumeDownHeld:
//Long Volume Down Pressed
break;

case HeadsetButton.MuteHeld:
//Long Mute Pressed
break;

case HeadsetButton.Unknown:
//Unmapped event
break;
}
}


//On Detach Un-register the events

public void Detach()
{
IHostCommand command = m_device.HostCommand;
if (command != null)
{
command.Register(RegistrationType.SignOut);
}

//UnRegister Device events
IDeviceEvents events = m_device.DeviceEvents;
events.TalkPressed -= events_TalkPressed;
events.AudioStateChanged -= events_AudioStateChanged;
events.MuteStateChanged -= events_MuteStateChanged;
events.ButtonPressed -= events_ButtonPressed;

m_device.Detach();
}



If you are interested in developing using the Plantronics Device Manager SDK please email me Ramesh.Theivendran@Plantronics.com or our PM Naser.Sheikhzadegan@Plantronics.com.

0 Comments:

Post a Comment

<< Home