//*****************************************************************************
//
//! Determines the number of individual descriptors of a particular type within
//! a supplied buffer.
//!
//! \param psDesc points to the first byte of a block of standard USB
//! descriptors.
//! \param ulSize is the number of bytes of descriptor data found at pointer
//! \e psDesc.
//! \param ulType identifies the type of descriptor that is to be found.  If
//! the value is \b USB_DESC_ANY, the function returns a pointer to the n-th
//! descriptor regardless of type.
//! \param ulIndex is the zero based index of the descriptor whose pointer is
//! to be returned.  For example, passing value 1 in \e ulIndex returns the
//! second matching descriptor.
//!
//! Return a pointer to the n-th descriptor of a particular type found in the
//! block of \e ulSize bytes starting at \e psDesc.
//!
//! \return Returns a pointer to the header of the required descriptor if
//! found or NULL otherwise.
//
//*****************************************************************************
tDescriptorHeader *
USBDescGet(tDescriptorHeader *psDesc,  unsigned long ulSize,
           unsigned long ulType, unsigned long ulIndex)
{
    tDescriptorHeader *psDescCheck;
    unsigned long ulTotLength;
    unsigned long ulCount;

    //
    // Set up for our descriptor counting loop.
    //
    psDescCheck = psDesc;
    ulTotLength = 0;
    ulCount = 0;

    //
    // Keep looking through the supplied data until we reach the end.
    //
    while(ulTotLength < ulSize)
    {
        //
        // Does this descriptor match the type passed (if a specific type
        // has been specified)?
        //
        if((ulType == USB_DESC_ANY) ||
           (psDescCheck->bDescriptorType == (unsigned char)(ulType & 0xFF)))
        {
            //
            // We found a matching descriptor.  If our count matches the
            // supplied index, we are done so return the pointer.
            //
            if(ulCount == ulIndex)
            {
                return(psDescCheck);
            }

            //
            // We have not found enough descriptors yet to satisfy the supplied
            // index so increment our count and continue.
            //
            ulCount++;
        }

        //
        // Move on to the next descriptor.
        //
        ulTotLength += (unsigned long)psDescCheck->bLength;
        psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
    }

    //
    // If we get here, we reached the end of the data without finding the
    // required descriptor.  Return NULL.
    //
    return((tDescriptorHeader *)0);
}
Ejemplo n.º 2
0
//*****************************************************************************
//
//! \internal
//!
//! Walk to the next descriptor after the supplied one within a section-based
//! config descriptor.
//!
//! \param psConfig points to the header structure for the configuration
//! descriptor which contains \e psDesc.
//! \param pulSec points to a variable containing the section within \e
//! psConfig which contains \e psDesc.
//! \param psDesc points to the descriptor that we want to step past.
//!
//! This function walks forward one descriptor within a config descriptor.  The
//! value returned is a pointer to the header of the next descriptor after the
//! descriptor supplied in \e psDesc.  If the next descriptor is in the next
//! section, \e *pulSec will be incremented accordlingly.
//!
//! \return Returns a pointer to the next descriptor in the config descrptor.
//
//*****************************************************************************
static tDescriptorHeader *
NextConfigDescGet(const tConfigHeader *psConfig, unsigned long *pulSec,
                  tDescriptorHeader *psDesc)
{
    //
    // Determine where the next descriptor after the supplied one should be
    // assuming it is within the current section.
    //
    psDesc = NEXT_USB_DESCRIPTOR(psDesc);

    //
    // Did we run off the end of the section?
    //
    if((unsigned char *)psDesc >= (psConfig->psSections[*pulSec]->pucData +
                                   psConfig->psSections[*pulSec]->usSize))
    {
        //
        // Yes - move to the next section.
        //
        (*pulSec)++;

        //
        // Are we still within the config descriptor?
        //
        if(*pulSec < psConfig->ucNumSections)
        {
            //
            // Yes - the new descriptor is at the start of the new section.
            //
            psDesc =
                (tDescriptorHeader *)psConfig->psSections[*pulSec]->pucData;
        }
        else
        {
            //
            // No - we ran off the end of the descriptor so return NULL.
            //
            psDesc = (tDescriptorHeader *)0;
        }
    }

    //
    // Return the new descriptor pointer.
    //
    return(psDesc);
}
//*****************************************************************************
//
//! Determines the number of different alternate configurations for a given
//! interface within a configuration descriptor.
//!
//! \param psConfig points to the first byte of a standard USB configuration
//! descriptor.
//! \param ucInterfaceNumber is the interface number for which the number of
//! alternate configurations is to be counted.
//!
//! This function can be used to count the number of alternate settings for a
//! specific interface within a configuration.
//!
//! \return Returns the number of alternate versions of the specified interface
//! or 0 if the interface number supplied cannot be found in the config
//! descriptor.
//
//*****************************************************************************
unsigned long
USBDescGetNumAlternateInterfaces(tConfigDescriptor *psConfig,
                                 unsigned char ucInterfaceNumber)
{
    tDescriptorHeader *psDescCheck;
    unsigned long ulTotLength;
    unsigned long ulCount;

    //
    // Set up for our descriptor counting loop.
    //
    psDescCheck = (tDescriptorHeader *)psConfig;
    ulTotLength = 0;
    ulCount = 0;

    //
    // Keep looking through the supplied data until we reach the end.
    //
    while(ulTotLength < (unsigned long)psConfig->wTotalLength)
    {
        //
        // Is this an interface descriptor with the required interface number?
        //
        if((psDescCheck->bDescriptorType == USB_DTYPE_INTERFACE) &&
            (((tInterfaceDescriptor *)psDescCheck)->bInterfaceNumber ==
             ucInterfaceNumber))
        {
            //
            // Yes - increment our count.
            //
            ulCount++;
        }

        //
        // Move on to the next descriptor.
        //
        ulTotLength += (unsigned long)psDescCheck->bLength;
        psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
    }

    //
    // Return the descriptor count to the caller.
    //
    return(ulCount);
}
//*****************************************************************************
//
//! Determines the number of individual descriptors of a particular type within
//! a supplied buffer.
//!
//! \param psDesc points to the first byte of a block of standard USB
//! descriptors.
//! \param ulSize is the number of bytes of descriptor data found at pointer
//! \e psDesc.
//! \param ulType identifies the type of descriptor that is to be counted.  If
//! the value is \b USB_DESC_ANY, the function returns the total number of
//! descriptors regardless of type.
//!
//! This function can be used to count the number of descriptors of a
//! particular type within a block of descriptors.  The caller can provide a
//! specific type value which the function matches against the second byte of
//! each descriptor or, alternatively, can specify \b USB_DESC_ANY to have the
//! function count all descriptors regardless of their type.
//!
//! \return Returns the number of descriptors found in the supplied block of
//! data.
//
//*****************************************************************************
unsigned long
USBDescGetNum(tDescriptorHeader *psDesc,  unsigned long ulSize,
              unsigned long ulType)
{
    tDescriptorHeader *psDescCheck;
    unsigned long ulTotLength;
    unsigned long ulCount;

    //
    // Set up for our descriptor counting loop.
    //
    psDescCheck = psDesc;
    ulTotLength = 0;
    ulCount = 0;

    //
    // Keep looking through the supplied data until we reach the end.
    //
    while(ulTotLength < ulSize)
    {
        //
        // Does this descriptor match the type passed (if a specific type
        // has been specified)?
        //
        if((ulType == USB_DESC_ANY) ||
           (psDescCheck->bDescriptorType == (unsigned char)(ulType & 0xFF)))
        {
            ulCount++;
        }

        //
        // Move on to the next descriptor.
        //
        ulTotLength += (unsigned long)psDescCheck->bLength;
        psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
    }

    //
    // Return the descriptor count to the caller.
    //
    return(ulCount);
}
//*****************************************************************************
//
//! Returns a pointer to the n-th interface descriptor in a config descriptor
//! with the supplied interface number.
//!
//! \param psConfig points to the first byte of a standard USB configuration
//! descriptor.
//! \param ucInterfaceNumber is the interface number of the descriptor that is
//! being queried.
//! \param ulIndex is the zero based index of the descriptor to return.
//!
//! This function returns a pointer to the n-th interface descriptor in the
//! supplied configuration which has the requested interface number.  It may be
//! used by a client to retrieve the descriptors for each alternate setting
//! of a given interface within the configuration passed.
//!
//! \return Returns a pointer to the n-th interface descriptor with interface
//! number as specified or NULL of this descriptor does not exist.
//
//*****************************************************************************
static tInterfaceDescriptor *
USBDescGetAlternateInterface(tConfigDescriptor *psConfig,
                             unsigned char ucInterfaceNumber,
                             unsigned long ulIndex)
{
    tDescriptorHeader *psDescCheck;
    unsigned long ulTotLength;
    unsigned long ulCount;

    //
    // Set up for our descriptor counting loop.
    //
    psDescCheck = (tDescriptorHeader *)psConfig;
    ulTotLength = 0;
    ulCount = 0;

    //
    // Keep looking through the supplied data until we reach the end.
    //
    while(ulTotLength < (unsigned long)psConfig->wTotalLength)
    {
        //
        // Does this descriptor match the type passed (if a specific type
        // has been specified)?
        //
        if((psDescCheck->bDescriptorType == USB_DTYPE_INTERFACE) &&
            (((tInterfaceDescriptor *)psDescCheck)->bInterfaceNumber ==
             ucInterfaceNumber))
        {
            //
            // This is an interface descriptor for interface ucInterfaceNumber.
            // Determine if this is the n-th one we have found and, if so,
            // return its pointer.
            //
            if(ulCount == ulIndex)
            {
                //
                // Found it - return the pointer.
                //
                return((tInterfaceDescriptor *)psDescCheck);
            }

            //
            // Increment our count of matching descriptors found and go back
            // to look for another since we have not yet reached the n-th
            // match.
            //
            ulCount++;
        }

        //
        // Move on to the next descriptor.
        //
        ulTotLength += (unsigned long)psDescCheck->bLength;
        psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
    }

    //
    // If we drop out the end of the loop, we did not find the requested
    // descriptor so return NULL.
    //
    return((tInterfaceDescriptor *)0);
}