Monitoring USB Peripheral Attachment and Detachment

The functionality described in this document is for On-The-Go (OTG) -enabled Symbian phones only.

Purpose

The USB control application (and/or other USB-aware applications) needs to know when a peripheral device has successfully attached to the USB host stack on the Symbian platform phone.

The control application also needs to know when the host stack has loaded the device drivers for the peripheral and when the peripheral has detached from the host.

This document tells you how to request notifications of these events.

Intended Audience

This document is for platform developers who are implementing USB services, including host and On-The-Go services, on a Symbian device.

Required Background

For details of, and links to, the USB and On-The-Go (OTG) specifications on the USB Implementers Forum website, see The USB Manager library.

Setup and Configuration Requirements

The Symbian USB client and USB host/OTG stacks need to be included in the ROM.

Requesting information about attaching or attached peripherals

Basic Procedure

  1. Make an asynchronous request for notification of USB host-related events.

  2. If necessary, cancel a pending request notification of USB host-related events.

Requesting notifications of USB host events

Making requests and using the TDeviceEventInformation structure

Use the RUsb::HostEventNotification() function to receive a notification when:

  • a peripheral device attaches to the phone,

  • a peripheral device detaches from the phone,

  • host-driver loading succeeds for a peripheral device.

For example:

TRequestStatus status;
TDeviceEventInformation deviceInfo;  //Create a member variable to store details of attaching peripheral 
RUsb::HostEventNotification(status, deviceInfo);
User::WaitForRequest(status);
if ( status != KErrNone )
  {
    //Handle error
  }
//deviceInfo is now populated with event information

The RUsb::HostEventNotification() function takes a parameter of type TDeviceEventInformation in addition to its TRequestStatus parameter.

Note: You can only have one call to this function pending at a time.

Note also that you will probably need to wrap your RUsb::HostEventNotification() request in an active object (see Active objects and Asynchronous programming).

If your application needs access to host events, it must register as soon as possible to ensure that it does not miss any, and it must continue to request them (repeating the call each time one call to RUsbHostNotification() returns) for as long as the application's session to the USB Manager remains open. If the application does not need host events, then it must never request them. The USB Manager queues up host events for each application that requests them. If a calling application does not remove them from the queue, then the queue will simply keep growing.

The TDeviceEventInformation structure that is updated by the RUsb::HostEventNotification() function contains various fields, including the remote USB peripheral's device Id (iDeviceId), vendor Id (iVid), and product Id (iPid). It also tells you:

  • Whether the peripheral is attached, whether an attempt has been made by the host software to load function drivers for it, and whether it has detached. The field that tells you this is the iEventType field, which is of type TUsbHostStackEventType. The Enum contains the values below. They each represent an event in the USB peripheral's lifecycle:

    • EDeviceAttachment = 0

    • EDriverLoad = 1

    • EDeviceDetachment = 2

    The events represented by this Enum can only happen in the order: attachment, driver load, detachment. Of course a peripheral can fail to attach, in which case the iError field of the TDeviceEventInformation structure will contain a value other than KErrNone. For example an error code of KErrBadPower signifies the wrong power requirement from the descriptor.

  • Whether the host software on the Symbian platform phone has successfully loaded function drivers for the peripheral device. The field that tells you this is the iDriverLoadStatus field. (This field only contains a value when the iEventType field is EDriverLoad.) The iDriverLoadStatus field is of type TDriverLoadStatus; this Enum contains the following values:

    • EDriverLoadSuccess = 0

    • EDriverLoadPartialSuccess = 1

    • EDriverLoadFailure = 2

Note: Host-driver loading for a peripheral is only a success (EDriverLoadSuccess) if function drivers for all of the peripheral's interfaces have loaded.

Note also that after a successful attachment there is guaranteed to be a detachment notification.

The TDeviceEventInformation structure is defined as follows in the file ... epoc32\include\usbhostdefs.h (this file also contains the definitions of TUsbHostStackEventType and TDriverLoadStatus):

NONSHARABLE_CLASS(TDeviceEventInformation)
    {
public:
    inline TDeviceEventInformation()
        // These initialisations are arbitrary
        :    iDeviceId(0),
            iEventType(EDeviceAttachment),
            iError(KErrNone),
            iDriverLoadStatus(EDriverLoadSuccess),
            iVid(0),
            iPid(0)
        {}

    // Always relevant- the ID of the device the event relates to.
    TUint iDeviceId;

    // Always relevant- the type of event that has occurred.
    TUsbHostStackEventType iEventType;

    // Relevant to attachment and driver load events.
    TInt iError;

    // Relevant to driver load events only.
    TDriverLoadStatus iDriverLoadStatus;

    // Relevant to attachments with iError KErrNone.
    TUint16 iVid;

    // Relevant to attachments with iError KErrNone.
    TUint16 iPid;
    };      

Cancelling a pending host event notification request

To cancel a pending RUsb::HostEventNotification() call, use the RUsb::HostEventNotificationCancel() function. For example:

usb.HostEventNotificationCancel();

You need to call this function from the active object's DoCancel() function.