Peripheral Discovery Library

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.

Since:
BlackBerry 10.2.0
The following code sample shows how to use the peripheral discovery API to detect the insertion and removal of peripheral devices:
#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;
}

Common properties

These properties are for every class of peripheral.

  • "class"
    • The class of the peripheral
    • PD_INTEGER_TYPE, will be pd_class_t
  • "bus"
    • The bus that the peripheral is attached to.
    • PD_INTEGER_TYPE, will be pd_bus_t
  • "peripheral_id"
    • The unique peripheral id
    • PD_INTEGER_TYPE

Bus specific properties

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

  • "vendor_id"
    • USB vendor id
    • PD_INTEGER_TYPE
  • "product_id"
    • USB product id
    • PD_INTEGER_TYPE
  • "device_class"
    • USB device class
    • PD_INTEGER_TYPE
  • "device_subclass"
    • USB device subclass
    • PD_INTEGER_TYPE
  • "device_protocol"
    • USB device protocol
    • PD_INTEGER_TYPE

Class specific properties

Simple peripherals

PD_CLASS_SERIAL

PD_CLASS_PRINTER

PD_CLASS_VENDOR_DEFINED

  • "path"
    • The path to the peripheral. This peripheral can be opened and read/write operations can be performed on it.
    • PD_STRING_TYPE

HID properties

PD_CLASS_HID

  • "hid_devno"
    • The device number used with the HID API to connect to a device.
    • PD_INTEGER_TYPE

Networking properties

PD_CLASS_NETWORKING

USB ethernet dongles belong to the PD_CLASS_NETWORKING class.

  • "interface_name"
    • The interface name as shown by ifconfig.
    • PD_STRING_TYPE
  • "dhcp"
    • Whether DHCP is used to get an IP address. The default value is 1. This value is currently not user-configurable.
    • PD_INTEGER_TYPE
  • "link_up"
    • Whether the network link is currently up. This changes from 0 to 1 via a PD_EVENT_UPDATE event, which occurs when a network cable is plugged in.
    • PD_INTEGER_TYPE

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.

Last modified: 2014-06-24



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus