Discovering details of USB personalities

This document explains how to use the USB Manager library's functions to discover information about the USB personalities currently available on the Symbian platform phone.

Purpose

A USB personality is a data structure whose purpose is to provide the configuration for USB peripheral services on a Symbian platform phone. In particular, it determines the class or classes of peripheral device that the Symbian platform phone can present itself as to a USB host.

For information about how to create a USB personality, see Using USB personalities.

Intended Audience

This document is for Symbian licensees who are implementing USB peripheral services on a Symbian platform phone.

Required Background

To follow this tutorial, you will find it helpful to have a general understanding of the USB 2.0 specification and a particular understanding of Chapter 9 of that specification (which concerns the USB device framework).

The USB 2.0 specification is available from the following location on the website of the USB Implementers Forum:

http://www.usb.org/developers/docs/

Information about USB classes is available from the following location on the same website:

http://www.usb.org/developers/devclass_docs#approved

Setup and Configuration Requirements

The Symbian platform phone you are writing code for needs to have Symbian's USB peripheral stack included in the ROM. It also needs to have a personality configured for it in which all the USB device classes it supports are specified. Note that the USB personality specifies the classes of device that the Symbian platform phone can present itself as to USB hosts; it does not provide any host configuration information in a Symbian platform phone that supports On-The-Go (OTG) role-swapping.

Using the USB Manager to find out about USB personalities

Basic Procedure

The high-level steps involved in finding out about USB personalities are shown here:

  1. Create an instance of RUsb and create an RUsb session.

  2. Get the ID of the USB personality that is currently loaded.

  3. Get a list of all available personalities.

  4. Get a description of a personality.

  5. Get a list of the device classes that a personality supports.

  6. Find out whether a personality enables the USB peripheral stack to support a particular class.

Sample .rss personality file

This section shows two PERSONALITY structs from a sample .rss personality file. They show the fields containing the information that you can retrieve about personalities by using the functionality described in this document.

For full information about using USB personalities, see Using USB personalities.

RESOURCE PERSONALITY_ARRAY device_personalities
   {
    personalities = 
    {
      PERSONALITY
        {
         bDeviceClass = 02;
         bDeviceSubClass = 0;
         protocol = 0;
         numConfigurations = 1;
         vendorId = 0x0e22;
         productId = 0x000b;
         bcdDevice = 0x0200;
         manufacturer = "ACME";
         product = "Widget";
         id = 1;                    
         class_uids = "101FBF22, 101fbf24"; \\ACM and WCM class_uids               
         description = "Modem"; 
         }
       PERSONALITY
        {
         bDeviceClass = 0;
         bDeviceSubClass = 0;
         protocol = 0;
         numConfigurations = 1;
         vendorId = 0x0e22;
         productId = 0x000b;
         bcdDevice = 0x0200;
         manufacturer = "ACME";
         product = "Widget2";
         id = 2;                    
         class_uids = "10204bbc";  \\Mass Storage class_uid              
         description = "File Transfer";
         }
    };
   }

Getting the ID of the current personality

To find out the ID of the personality that is currently running on the Symbian platform phone, create an instance of RUsb, create a session between the USB Manager client and server (by calling RUsb::Connect()), then call the function RUsb::GetCurrentPersonalityId(). For example:

RUsb usb;
usb.Connect();
TUint personalityId;            //Create a variable to pass to the GetCurrentPersonality() function
TInt err = usb.GetCurrentPersonalityId(personalityId); //Request the ID of the current personality
if (err != KErrNone)
 {
  //Handle error
 }

Getting a list of all available USB personalities

To retrieve a list of all the USB personalities available on the Symbian platform phone, call the function RUsb::GetPersonalityIds(). The personalities available are those specified in the list of PERSONALITY structs defined in the personalities resource file (see Using USB Personalities).

The following code illustrates how to call the function:

//Get personality IDs from the USB Manager
RUsb usb;
usb.Connect();

RArray<TInt> idArray;
TInt err = usb.GetPersonalityIds(idArray);    //Get a list of the available personalities on the phone
if (err != KErrNone)
 {
  //Handle error
 }

The RUsb::GetPersonalityIds() function writes the id field for each personality in your resource file into the array that you pass to it.

Getting a description of a particular personality

To retrieve the contents of a specified personality's description field, for example, to compare it with another personality's description field or with a particular text string, call the RUsb::GetDescription() function. For example:

RUsb usb;
usb.Connect();
    
HBufC* description;                       //Create a data structure to store the description in
TInt personalityID;
personalityID = 4;                        //Specify the personality you are interested in
                                          
TInt err = usb.GetDescription(personalityId, description) //Get the description of the personality
if ( err != KErrNone)  
 {
   //Handle error
 }

Note: After calling RUsb::GetDescription(), you must take responsibility for de-allocating any memory that the function has allocated for the HBufC* data structure you passed to it.

Getting a list of device classes that a personality supports

To get a list of the device classes that a particular personality supports (in other words, a list of the peripheral devices that the phone can present itself as to a USB host when it uses the personality specified), you need to use the RUsb::GetSupportedClasses() function. For example:

RUsb usb;
usb.Connect();

TInt personalityID;                              
RArray<TUid> uidArray;                  //Create an array to store the personality's list of class UIDs
TInt err = usb.GetSupportedClasses(personalityID,uidArray)) //Retrieve its list of class UIDs
 if ( err != KErrNone)  
 {
   //Handle error
 }
uidArray.Close();

When you call this function you need to pass it the ID of the personality you are concerned with, and you need to pass it an array (of UIDs) to store the personality's class UIDs in. (The field of the PERSONALITY struct that it retrieves the UIDs from from is the class_uids field.)

Finding out if the personality supports a particular device class

To find out whether a personality enables the phone's USB peripheral stack to support a particular device class, use the RUsb::ClassSupported() function.

RUsb usb;
usb.Connect();

TUid classUid ={0x10204BBC};        //The class UID for Mass Storage peripherals 
              
                                     //Alternatively, you can use the constant KUsbMsClassControllerUID,
                                     //which is defined in the file ...epoc32/include/usbmsshared.h.
TBool isClassSupported;              //A Boolean variable for the function to set if the specified 
                                     //personality has the Mass Storage UID in its class_UIDs field
TInt personalityID;
personalityID = 4; 
                                     //Find out if the personality includes Mass Storage support
TInt err = usb.ClassSupported(personalityID,classUid,isClassSupported) 
 
if ( err != KErrNone)
 {
   //Handle error
 }

if (isClassSupported)
 {
   //Decide what to do - for example, you might want to load the personality if it supports the 
   //required class
 }

The above sample code queries the personality with an id of 4 to see if it contains the Mass Storage class UID (which is 10204bbc) in its class_uids field. This class UID is in fact defined as a constant KUsbMsClassControllerUID, so you can use the constant instead if you prefer. It is defined in the file ...epoc32/include/usbmsshared.h.