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, Bluetooth, DisplayPort, and HDMI peripherals.

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 are 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

Last modified: 2013-12-21

comments powered by Disqus