This file defines the peripheral discovery API, which provides functions for your app to receive notifications about the insertion or removal of peripheral devices. This API also allows you to retrieve information about inserted peripherals. This API supports USB peripherals. Support for Bluetooth, DisplayPort, and HDMI peripherals may be added in future releases.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/siginfo.h>
#include <peripheral_discovery.h>
static void print_peripheral_properties( pd_peripheral_t *peripheral ) {
pd_peripheral_properties_t *properties;
pd_peripheral_property_t *property;
pd_property_type_t type;
const char *name;
const char *strvalue;
int intval;
if( (properties = pd_alloc_property_list()) == NULL ) {
printf( "Couldn't allocate properties\n" );
return;
}
if( pd_get_peripheral_properties( peripheral, properties ) == EOK ) {
while( pd_get_next_property( properties, &property ) == EOK ) {
type = pd_get_property_type( property );
switch( type ) {
case PD_STRING_TYPE:
pd_get_property_as_string( property, &name, &strvalue );
printf(" property: %s, value: %s\n", name, strvalue);
break;
case PD_INTEGER_TYPE:
pd_get_property_as_integer( property, &name, &intval );
printf(" property: %s, value: %d\n", name, intval);
break;
}
}
} else {
printf( "Couldn't get properties\n" );
}
pd_free_property_list( &properties );
}
#define MY_PD_PULSE_CODE 1
int main( int argc, char *argv[] ) {
bool usb_host_mode_supported;
bool serial_is_supported, vendor_defined_is_supported;
struct sigevent ev1, ev2;
pd_peripheral_t *peripheral;
int chid, coid;
if( pd_initialize( 0 ) )
{
printf( "Couldn't connect to peripheral discovery API\n" );
return 1;
}
if( pd_is_bus_supported( PD_BUS_USB_HOST_MODE,
&usb_host_mode_supported ) != EOK ) {
printf( "Error determining if usb host mode is supported\n" );
pd_uninitialize();
return 1;
}
if( pd_is_class_supported( PD_CLASS_SERIAL,
&serial_is_supported ) != EOK ) {
printf("Error determining if serial class is supported\n");
pd_uninitialize();
return 1;
}
if( pd_is_class_supported( PD_CLASS_VENDOR_DEFINED,
&vendor_defined_is_supported ) != EOK ) {
printf("Error determining if vendor defined class is supported\n");
pd_uninitialize();
return 1;
}
if( !usb_host_mode_supported ) {
printf( "USB host mode is not supported.\n
No sense trying to find peripherals\n" );
pd_uninitialize();
return 1;
}
if( !serial_is_supported && !vendor_defined_is_supported ) {
printf( "None of the classes I'm interested in is supported.\n");
printf( "No sense trying to find peripherals.\n" );
pd_uninitialize();
return 1;
}
chid = ChannelCreate( 0 );
coid = ConnectAttach( 0, 0, chid, 0, 0 );
// Initialize pulse sigevent.
// You can add the class id to help identify events later,
// if you're registering for multiple classes.
if( serial_is_supported ) {
SIGEV_PULSE_INIT( &ev1, coid,
SIGEV_PULSE_PRIO_INHERIT,
MY_PD_PULSE_CODE,
PD_CLASS_SERIAL );
}
if( vendor_defined_is_supported ) {
SIGEV_PULSE_INIT( &ev2, coid,
SIGEV_PULSE_PRIO_INHERIT,
MY_PD_PULSE_CODE,
PD_CLASS_VENDOR_DEFINED );
}
if( serial_is_supported ) {
pd_register_event( PD_CLASS_SERIAL, &ev1 );
}
if( vendor_defined_is_supported ) {
pd_register_event( PD_CLASS_VENDOR_DEFINED, &ev2 );
}
// You need to allocate a pd_peripheral_t to get events,
// but you only need to do it once.
peripheral = pd_alloc_peripheral();
// A message receive thread.
while (1) {
struct _pulse pulse;
pd_event_type_t type;
int peripheral_id;
pd_class_t event_class;
MsgReceive(chid, &pulse, sizeof(pulse), NULL);
if( pulse.code == MY_PD_PULSE_CODE ) {
// If you populated the sigevent value pointer,
// retrieve it now.
event_class = (pd_class_t) pulse.value.sival_ptr;
// Get the event that woke this thread up.
if( pd_get_event( &type, &peripheral_id, peripheral ) == EOK ) {
switch( type ) {
case PD_EVENT_INSERTION:
printf( "Peripheral Insertion. id=0x%X, class=%d\n",
peripheral_id, event_class );
print_peripheral_properties( peripheral );
break;
case PD_EVENT_REMOVAL:
printf( "Peripheral Removal. id=0x%X, class=%d\n",
peripheral_id, event_class );
break;
}
}
}
}
pd_free_peripheral( &peripheral );
pd_uninitialize();
return 0;
}
These properties are for every class of peripheral.
There may be properties that are specific to the bus that a peripheral is using. Currently, only USB host mode has such properties.
USB Host Mode
Not all devices support USB Host Mode; call pd_is_bus_supported() to determine if it's supported on the current device. Currently, only the BlackBerry Z30 supports USB Host Mode.
PD_BUS_USB_HOST_MODE
Simple peripherals
PD_CLASS_SERIAL
PD_CLASS_PRINTER
PD_CLASS_VENDOR_DEFINED
HID properties
PD_CLASS_HID
Networking properties
PD_CLASS_NETWORKING
USB ethernet dongles belong to the PD_CLASS_NETWORKING class.
Unknown peripherals
PD_CLASS_UNKNOWN
Any device that is seen by the USB stack, but for which a driver can't be found, falls under the PD_CLASS_UNKNOWN peripheral type. Only the USB bus information is available for such devices.