コード例 #1
0
BOOL USBHostChargerEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size )
{
    // Make sure the event is for a connected device
    if (!_USBHostCharger_FindDevice( address ))
    {
        return FALSE;
    }

    // Handle specific events.
    switch (event)
    {
        case EVENT_DETACH:
            // Notify that application that the device has been detached.
            USB_HOST_APP_EVENT_HANDLER(usbChargingDevices[currentChargingRecord].ID.deviceAddress, EVENT_CHARGER_DETACH, &usbChargingDevices[currentChargingRecord].ID.deviceAddress, sizeof(BYTE) );
            usbChargingDevices[currentChargingRecord].flags.val        = 0;
            usbChargingDevices[currentChargingRecord].ID.deviceAddress = 0;
            #ifdef DEBUG_MODE
                UART2PrintString( "USB Charging Client Device Detached: address=" );
                UART2PutDec( address );
                UART2PrintString( "\r\n" );
            #endif
            return TRUE;
            break;

        case EVENT_SUSPEND:
        case EVENT_RESUME:
        case EVENT_BUS_ERROR:
        default:
            break;
    }

    return FALSE;
} // USBHostChargerEventHandler
コード例 #2
0
BOOL USBHostBluetoothInit ( BYTE address, DWORD flags, BYTE clientDriverID )
{
    BYTE *pDesc;

    // Initialize state
    gc_DevData.rxEvtLength     = 0;
    gc_DevData.rxAclLength     = 0;
    gc_DevData.flags.val = 0;

    // Save device the address, VID, & PID
    gc_DevData.ID.deviceAddress = address;
    pDesc  = USBHostGetDeviceDescriptor(address);
    pDesc += 8;
    gc_DevData.ID.vid  =  (WORD)*pDesc;       pDesc++;
    gc_DevData.ID.vid |= ((WORD)*pDesc) << 8; pDesc++;
    gc_DevData.ID.pid  =  (WORD)*pDesc;       pDesc++;
    gc_DevData.ID.pid |= ((WORD)*pDesc) << 8; pDesc++;

    // Save the Client Driver ID
    gc_DevData.clientDriverID = clientDriverID;
    
    #ifdef USBHOSTBT_DEBUG
        SIOPrintString( "GEN: USB Generic Client Initalized: flags=0x" );
        SIOPutHex(      flags );
        SIOPrintString( " address=" );
        SIOPutDec( address );
        SIOPrintString( " VID=0x" );
        SIOPutHex(      gc_DevData.ID.vid >> 8   );
        SIOPutHex(      gc_DevData.ID.vid & 0xFF );
        SIOPrintString( " PID=0x"      );
        SIOPutHex(      gc_DevData.ID.pid >> 8   );
        SIOPutHex(      gc_DevData.ID.pid & 0xFF );
        SIOPrintString( "\r\n"         );
    #endif
	
    // Generic Client Driver Init Complete.
    gc_DevData.flags.initialized = 1;

    // Notify that application that we've been attached to a device.
    USB_HOST_APP_EVENT_HANDLER(address, EVENT_BLUETOOTH_ATTACH, &(gc_DevData.ID), sizeof(BLUETOOTH_DEVICE_ID) );

    return TRUE;

} // USBHostBluetoothInit
コード例 #3
0
BOOL USBHostChargerInitialize( BYTE address, DWORD flags, BYTE clientDriverID )
{
    BYTE    *pDesc;

    // Find a new entry
    for (currentChargingRecord=0; currentChargingRecord<USB_MAX_CHARGING_DEVICES; currentChargingRecord++)
    {
        if (!usbChargingDevices[currentChargingRecord].flags.inUse) break;
    }
    if (currentChargingRecord == USB_MAX_CHARGING_DEVICES)
    {
        #ifdef DEBUG_MODE
            UART2PrintString( "CHG: No more space\r\n" );
        #endif
        return FALSE;   // We have no more room for a new device.
    }

    // Initialize state - set the inUse flag.
    usbChargingDevices[currentChargingRecord].flags.val = 1;

    // Save device the address, VID, & PID
    usbChargingDevices[currentChargingRecord].ID.deviceAddress = address;
    usbChargingDevices[currentChargingRecord].ID.clientDriverID = clientDriverID;
    pDesc  = USBHostGetDeviceDescriptor(address);
    pDesc += 8;
    usbChargingDevices[currentChargingRecord].ID.vid  =  (WORD)*pDesc;       pDesc++;
    usbChargingDevices[currentChargingRecord].ID.vid |= ((WORD)*pDesc) << 8; pDesc++;
    usbChargingDevices[currentChargingRecord].ID.pid  =  (WORD)*pDesc;       pDesc++;
    usbChargingDevices[currentChargingRecord].ID.pid |= ((WORD)*pDesc) << 8; pDesc++;

    VID = usbChargingDevices[currentChargingRecord].ID.vid;
    PID = usbChargingDevices[currentChargingRecord].ID.pid;

    // Notify that application that we've been attached to a device.
    USB_HOST_APP_EVENT_HANDLER(address, EVENT_CHARGER_ATTACH,
            &(usbChargingDevices[currentChargingRecord].ID), sizeof(USB_CHARGING_DEVICE_ID) );

    return TRUE;

} // USBHostChargerInit
コード例 #4
0
/****************************************************************************
  Function:
    BOOL AndroidAppDataEventHandler_Pv1( BYTE address, USB_EVENT event, void *data, DWORD size )

  Summary:
    Handles data events from the host stack

  Description:
    Handles data events from the host stack

  Precondition:
    None

  Parameters:
    BYTE address - the address of the device that caused the event
    USB_EVENT event - the event that occured
    void* data - the data for the event
    DWORD size - the size of the data in bytes

  Return Values:
    TRUE - the event was handled
    FALSE - the event was not handled

  Remarks:
    This is a internal API only.  This should not be called by anything other
    than the USB host stack via the client driver table
  ***************************************************************************/
BOOL AndroidAppDataEventHandler_Pv1( BYTE address, USB_EVENT event, void *data, DWORD size )
{
    BYTE i;

    switch (event)
    {
        case EVENT_SOF:              // Start of frame - NOT NEEDED
            return TRUE;
        case EVENT_1MS:              // 1ms timer
            for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++)
            {
                if(devices_pv1[i].state == WAITING_FOR_ACCESSORY_RETURN)
                {
                    switch(devices_pv1[i].countDown)
                    {
                        case 0:
                            //do nothing
                            break;
                        case 1:
                            USB_HOST_APP_EVENT_HANDLER(devices_pv1[i].address,EVENT_ANDROID_DETACH,&devices_pv1[i],sizeof(ANDROID_PROTOCOL_V1_DEVICE_DATA*));

                            //Device has timed out.  Destroy its info.
                            memset(&devices_pv1[i],0x00,sizeof(ANDROID_PROTOCOL_V1_DEVICE_DATA));
                            break;
                        default:
                            //for every other number, decrement the count
                            devices_pv1[i].countDown--;
                            break;
                    }
                }
            }
            return TRUE;
        default:
            break;
    }
    return FALSE;
}
コード例 #5
0
ファイル: usb_host_android.c プロジェクト: DIYzzuzpb/PIC32USB
/****************************************************************************
  Function:
    BOOL AndroidAppEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size )

  Summary:
    Handles events from the host stack

  Description:
    Handles events from the host stack

  Precondition:
    None

  Parameters:
    BYTE address - the address of the device that caused the event
    USB_EVENT event - the event that occured
    void* data - the data for the event
    DWORD size - the size of the data in bytes

  Return Values:
    TRUE - the event was handled
    FALSE - the event was not handled

  Remarks:
    This is a internal API only.  This should not be called by anything other
    than the USB host stack via the client driver table
  ***************************************************************************/
BOOL AndroidAppEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size )
{
    HOST_TRANSFER_DATA* transfer_data = data ;
    BYTE i,j;

    //Throw the message to the protocol handlers if they match the address
    //  and are ready.
    for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++)
    {
        if((devices[i].state == READY) && (devices[i].address == address))
        {
            for(j=0;j<(sizeof(protocolVersions)/sizeof(ANDROID_PROTOCOL_VERSION));j++)
            {
                if(devices[i].protocol == protocolVersions[j].versionNumber)
                {
                    protocolVersions[j].handler(address, event, data, size);

                    //Force exit both for loops
                    i=NUM_ANDROID_DEVICES_SUPPORTED;
                    break;
                }
            }
        }
    }

    switch (event)
    {
        case EVENT_DETACH:           // USB cable has been detached (data: BYTE, address of device)
            for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++)
            {
                if(devices[i].address == address)
                {
                    if(devices[i].state == READY)
                    {
                        switch(devices[i].protocol)
                        {
                            case 1:
                                devices[i].countDown = ANDROID_DEVICE_ATTACH_TIMEOUT;
                                break;
                            default:
                                //USB_HOST_APP_EVENT_HANDLER(address,event,devices[i].protocolHandle,sizeof(ANDROID_DEVICE_DATA*));
                                break;
                        }
                    }
                    else
                    {
                        USB_HOST_APP_EVENT_HANDLER(address,event,devices[i].protocolHandle,sizeof(ANDROID_DEVICE_DATA*));
                        //Device has timed out.  Destroy its info.
                        memset(&devices[i],0x00,sizeof(ANDROID_DEVICE_DATA));
                    }
                }
            }
            
            return TRUE;
        case EVENT_TRANSFER:        
            for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++)
            {
                if((transfer_data->bEndpointAddress == 0x00) && (devices[i].state == GET_PROTOCOL_SENT))
                {
                    for(j=0;j<(sizeof(protocolVersions)/sizeof(ANDROID_PROTOCOL_VERSION));j++)
                    {
                        if(devices[i].protocol == protocolVersions[j].versionNumber)
                        {
                            //From this level standpoint, we are done.  The rest is
                            //  protocol layer specific
                            devices[i].state = READY;
                            devices[i].protocolHandle = protocolVersions[j].init(devices[i].address, devices[i].flags, devices[i].clientDriverID);
                            break;
                        }
                    }

                    if(j >= (sizeof(protocolVersions)/sizeof(ANDROID_PROTOCOL_VERSION)))
                    {
                        //If we don't support that protocol version, use the next best version

                        //Override the protocol version specified by the device
                        devices[i].protocol = protocolVersions[j-1].versionNumber;

                        devices[i].state = READY;
                        devices[i].protocolHandle = protocolVersions[j-1].init(devices[i].address, devices[i].flags, devices[i].clientDriverID);
                    }

                    return TRUE;
                }
            }
            return TRUE;
        case EVENT_NONE:             // No event occured (NULL event)
            //Fall through
        case EVENT_HUB_ATTACH:       // USB hub has been attached
            //Fall through           
        case EVENT_RESUME:           // Device-mode resume received
            //Fall through           
        case EVENT_SUSPEND:          // Device-mode suspend/idle event received
            //Fall through           
        case EVENT_RESET:            // Device-mode bus reset received
            //Fall through           
        case EVENT_STALL:            // A stall has occured
            //Fall through           
        case EVENT_BUS_ERROR:            // BUS error has occurred
            return TRUE;
        default:
            break;
    }
    return FALSE;
}
コード例 #6
0
BOOL USBHostBluetoothEventHandler ( BYTE address, USB_EVENT event, void *data, DWORD size )
{
    // Make sure it was for our device
    if ( address != gc_DevData.ID.deviceAddress)
    {
        return FALSE;
    }

    // Handle specific events.
    switch (event)
    {
        case EVENT_DETACH:
            // Notify that application that the device has been detached.
            USB_HOST_APP_EVENT_HANDLER(gc_DevData.ID.deviceAddress, EVENT_BLUETOOTH_DETACH, &gc_DevData.ID.deviceAddress, sizeof(BYTE) );
            gc_DevData.flags.val        = 0;
            gc_DevData.ID.deviceAddress = 0;
            #ifdef USBHOSTBT_DEBUG
                SIOPrintString( "USB Host Bluetooth Device Detached: address=%d\n", address );
            #endif
            return TRUE;

        case EVENT_TRANSFER:
            if ( (data != NULL) && (size == sizeof(HOST_TRANSFER_DATA)) )
            {
                DWORD dataCount = ((HOST_TRANSFER_DATA *)data)->dataCount;

                if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == (USB_IN_EP|USB_EP1) )	//GVG
                {
                    //SIOPrintString( "E\n" );
                    gc_DevData.flags.rxEvtBusy = 0;
                    gc_DevData.rxEvtLength = dataCount;
                    if(!dataCount) return FALSE;
                    USB_HOST_APP_EVENT_HANDLER(gc_DevData.ID.deviceAddress, EVENT_BLUETOOTH_RX1_DONE, &dataCount, sizeof(DWORD) );
                }
                else if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == (USB_IN_EP|USB_EP2) )	//GVG
                {
                    //if(!dataCount) return FALSE;
                    gc_DevData.flags.rxAclBusy = 0;
                    gc_DevData.rxAclLength = dataCount;
                    USB_HOST_APP_EVENT_HANDLER(gc_DevData.ID.deviceAddress, EVENT_BLUETOOTH_RX2_DONE, &dataCount, sizeof(DWORD) );
                }
                else if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == (USB_OUT_EP|USB_EP2) )	//GVG
                {
                    gc_DevData.flags.txAclBusy = 0;
                    USB_HOST_APP_EVENT_HANDLER(gc_DevData.ID.deviceAddress, EVENT_BLUETOOTH_TX2_DONE, &dataCount, sizeof(DWORD) );
                }
                else
                {
                    return FALSE;
                }

                return TRUE;

            }
            return FALSE;

        case EVENT_SUSPEND:
        case EVENT_RESUME:
        case EVENT_BUS_ERROR:
        default:
            break;
    }

    return FALSE;
} // USBHostBluetoothEventHandler
コード例 #7
0
/****************************************************************************
  Function:
    BOOL AndroidAppEventHandler_Pv1( BYTE address, USB_EVENT event, void *data, DWORD size )

  Summary:
    Handles events from the host stack

  Description:
    Handles events from the host stack

  Precondition:
    None

  Parameters:
    BYTE address - the address of the device that caused the event
    USB_EVENT event - the event that occured
    void* data - the data for the event
    DWORD size - the size of the data in bytes

  Return Values:
    TRUE - the event was handled
    FALSE - the event was not handled

  Remarks:
    This is a internal API only.  This should not be called by anything other
    than the USB host stack via the client driver table
  ***************************************************************************/
BOOL AndroidAppEventHandler_Pv1( BYTE address, USB_EVENT event, void *data, DWORD size )
{
    HOST_TRANSFER_DATA* transfer_data = data ;
    ANDROID_PROTOCOL_V1_DEVICE_DATA *device = NULL;
    BYTE i;

    switch (event)
    {
        case EVENT_NONE:             // No event occured (NULL event)
            return TRUE;

        case EVENT_DETACH:           // USB cable has been detached (data: BYTE, address of device)
            for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++)
            {
                if(devices_pv1[i].address == address)
                {
                    if(devices_pv1[i].state == ACCESSORY_STARTING) 
                    {
                        devices_pv1[i].state = WAITING_FOR_ACCESSORY_RETURN;
                    }

                    if(devices_pv1[i].state != WAITING_FOR_ACCESSORY_RETURN)
                    {
                        device = &devices_pv1[i];

                        USBHostTerminateTransfer( device->address, device->OUTEndpointNum );
                        USBHostTerminateTransfer( device->address, device->INEndpointNum );
                        USB_HOST_APP_EVENT_HANDLER(device->address,EVENT_ANDROID_DETACH,device,sizeof(ANDROID_PROTOCOL_V1_DEVICE_DATA*));
                        
                        //Device has timed out.  Destroy its info.
                        memset(&devices_pv1[i],0x00,sizeof(ANDROID_PROTOCOL_V1_DEVICE_DATA));
                    }
                    //If we are WAITING_FOR_ACCESSORY_RETURN, then we will timeout in data handler instead
                }
            }

            return TRUE;
        case EVENT_HUB_ATTACH:       // USB hub has been attached
            return TRUE;

        case EVENT_TRANSFER:         // A USB transfer has completed - NOT USED

            for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++)
            {
                if(devices_pv1[i].address == address)
                {
                    device = &devices_pv1[i];
                }
            }

            //If this is for a device that we don't know about, get rid of it.
            if(device == NULL)
            {
                return FALSE;
            }

            //Otherwise, handle the data
            if(transfer_data->bEndpointAddress == 0x00)
            {
                //If the transfer was EP0, just clear the pending bit and 
                //  we will handle the rest in the tasks function so we don't
                //  duplicate state machine changes both here and there
                device->status.EP0TransferPending = 0;
            }
            
            return TRUE;
        case EVENT_RESUME:           // Device-mode resume received
            return TRUE;

        case EVENT_SUSPEND:          // Device-mode suspend/idle event received
            return TRUE;

        case EVENT_RESET:            // Device-mode bus reset received
            return TRUE;

        case EVENT_STALL:            // A stall has occured
            return TRUE;

        case EVENT_BUS_ERROR:            // BUS error has occurred
            return TRUE;

        default:
            break;
    }
    return FALSE;
}
コード例 #8
0
/****************************************************************************
  Function:
    void AndroidTasks_Pv1(void)

  Summary:
    Tasks function that keeps the Android client driver moving

  Description:
    Tasks function that keeps the Android client driver moving.  Keeps the driver
    processing requests and handling events.  This function should be called
    periodically (the same frequency as USBHostTasks() would be helpful).

  Precondition:
    AndroidAppStart() function has been called before the first calling of this function

  Parameters:
    None

  Return Values:
    None

  Remarks:
    This function should be called periodically to keep the Android driver moving.
  ***************************************************************************/
void AndroidTasks_Pv1(void)
{
    BYTE i;
    ANDROID_PROTOCOL_V1_DEVICE_DATA* device;
    BYTE errorCode;
    DWORD byteCount;

    //See if any of the devices need to do something
    for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++)
    {
        device = &devices_pv1[i];

        switch(device->state)
        {
            case DEVICE_ATTACHED:
                //Fall through
            case SEND_MANUFACTUER_STRING:
                //Check to see if something else is going on with EP0
                //TODO: should switch this to use the transfer events instead.  It is safer.
                if(AndroidIsLastCommandComplete(device->address, &errorCode, &byteCount) == TRUE)
                {
                    //If not, then let's send the manufacturer's string
                    AndroidCommandSendString_Pv1(device, ANDROID_ACCESSORY_STRING_MANUFACTURER, accessoryInfo->manufacturer, accessoryInfo->manufacturer_size);

                    device->status.EP0TransferPending = 1;
                    device->state = SEND_MODEL_STRING;
                }
                break;

            case SEND_MODEL_STRING:
                if(device->status.EP0TransferPending == 0)
                {
                    //The manufacturing string is sent.  Now try to send the model string
                    //TODO: should switch this to use the transfer events instead.  It is safer.
                    if(AndroidIsLastCommandComplete(device->address, &errorCode, &byteCount) == TRUE)
                    {
                        //If not, then let's send the manufacturer's string
                        AndroidCommandSendString_Pv1(device, ANDROID_ACCESSORY_STRING_MODEL, accessoryInfo->model, accessoryInfo->model_size);
    
                        device->status.EP0TransferPending = 1;
                        device->state = SEND_DESCRIPTION_STRING;
                    }
                }
                break;

            case SEND_DESCRIPTION_STRING:
                if(device->status.EP0TransferPending == 0)
                {
                    //The manufacturing string is sent.  Now try to send the model string
                    //TODO: should switch this to use the transfer events instead.  It is safer.
                    if(AndroidIsLastCommandComplete(device->address, &errorCode, &byteCount) == TRUE)
                    {
                        //If not, then let's send the manufacturer's string
                        AndroidCommandSendString_Pv1(device, ANDROID_ACCESSORY_STRING_DESCRIPTION, accessoryInfo->description, accessoryInfo->description_size);
    
                        device->status.EP0TransferPending = 1;
                        device->state = SEND_VERSION_STRING;
                    }
                }
                break;

            case SEND_VERSION_STRING:
                if(device->status.EP0TransferPending == 0)
                {
                    //The manufacturing string is sent.  Now try to send the model string
                    //TODO: should switch this to use the transfer events instead.  It is safer.
                    if(AndroidIsLastCommandComplete(device->address, &errorCode, &byteCount) == TRUE)
                    {
                        //If not, then let's send the manufacturer's string
                        AndroidCommandSendString_Pv1(device, ANDROID_ACCESSORY_STRING_VERSION, accessoryInfo->version, accessoryInfo->version_size);
    
                        device->status.EP0TransferPending = 1;
                        device->state = SEND_URI_STRING;
                    }
                }
                break;

            case SEND_URI_STRING:
                if(device->status.EP0TransferPending == 0)
                {
                    //The manufacturing string is sent.  Now try to send the model string
                    //TODO: should switch this to use the transfer events instead.  It is safer.
                    if(AndroidIsLastCommandComplete(device->address, &errorCode, &byteCount) == TRUE)
                    {
                        //If not, then let's send the manufacturer's string
                        AndroidCommandSendString_Pv1(device, ANDROID_ACCESSORY_STRING_URI, accessoryInfo->URI, accessoryInfo->URI_size);
    
                        device->status.EP0TransferPending = 1;
                        device->state = SEND_SERIAL_STRING;
                    }
                }
                break;

            case SEND_SERIAL_STRING:
                if(device->status.EP0TransferPending == 0)
                {
                    //The manufacturing string is sent.  Now try to send the model string
                    //TODO: should switch this to use the transfer events instead.  It is safer.
                    if(AndroidIsLastCommandComplete(device->address, &errorCode, &byteCount) == TRUE)
                    {
                        //If not, then let's send the manufacturer's string
                        AndroidCommandSendString_Pv1(device, ANDROID_ACCESSORY_STRING_SERIAL, accessoryInfo->serial, accessoryInfo->serial_size);
    
                        device->status.EP0TransferPending = 1;
                        device->state = START_ACCESSORY;
                    }
                }
                break;

            case START_ACCESSORY:
                if(device->status.EP0TransferPending == 0)
                {
                    //The manufacturing string is sent.  Now try to send the model string
                    //TODO: should switch this to use the transfer events instead.  It is safer.
                    if(AndroidIsLastCommandComplete(device->address, &errorCode, &byteCount) == TRUE)
                    {
                        //Set up a timer to remove the device if it hasn't returned to us as an
                        //  accessory mode device in a specified time, we kill the device
                        device->countDown = ANDROID_DEVICE_ATTACH_TIMEOUT;

                        //If not, then let's send the manufacturer's string
                        AndroidCommandStart_Pv1(device);
    
                        device->status.EP0TransferPending = 1;
                        device->state = ACCESSORY_STARTING;
                    }
                }
                break;

            case ACCESSORY_STARTING:
                if(device->status.EP0TransferPending == 0)
                {
                    device->state = WAITING_FOR_ACCESSORY_RETURN;
                }   
                break;

            case WAITING_FOR_ACCESSORY_RETURN:
                break;

            case RETURN_OF_THE_ACCESSORY:
                //The accessory has returned and has been initialialized.  It is now ready to use.
                device->state = READY;
                USB_HOST_APP_EVENT_HANDLER(device->address,EVENT_ANDROID_ATTACH,device,sizeof(ANDROID_PROTOCOL_V1_DEVICE_DATA*));
                break; 
             
            case READY:
                break;

            default:
                //Don't know what state the device is in.  Do some recovery here?
                break;
        }
    }
}
コード例 #9
0
BOOL USBHostMIDIEventHandler ( BYTE address, USB_EVENT event, void *data, DWORD size )
{
    unsigned char i;
    
    // Make sure it was for one of our devices
    for( i = 0; i < USB_MAX_MIDI_DEVICES; i++)
    {
        if ( address == devices[i].deviceAddress)
        {
            break;
        }
    
    }
    if(i == USB_MAX_MIDI_DEVICES)
    {
        return FALSE;
    }    
    
    // Handle specific events
    switch (event)
    {
        case EVENT_DETACH:
            // Notify that application that the device has been detached.
            USB_HOST_APP_EVENT_HANDLER(devices[i].deviceAddress, EVENT_MIDI_DETACH, &devices[i], sizeof(MIDI_DEVICE) );
            devices[i].deviceAddress = 0;
            free(devices[i].endpoints);
            devices[i].endpoints = NULL;
            #ifdef DEBUG_MODE
                UART2PrintString( "USB MIDI Client Device Detached: address=" );
                UART2PutDec( address );
                UART2PrintString( "\r\n" );
            #endif
            return TRUE;
    
        #ifdef USB_ENABLE_TRANSFER_EVENT
        case EVENT_TRANSFER:
            if ( (data != NULL) && (size == sizeof(HOST_TRANSFER_DATA)) )
            {
                unsigned char currentEndpoint;
                //DWORD dataCount = ((HOST_TRANSFER_DATA *)data)->dataCount;
    
                for(currentEndpoint = 0; currentEndpoint < devices[i].numEndpoints; currentEndpoint++)
                {
                    if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == devices[i].endpoints[currentEndpoint].endpointAddress )
                    {
                        devices[i].endpoints[currentEndpoint].busy = 0;
                        USB_HOST_APP_EVENT_HANDLER(devices[i].deviceAddress, EVENT_MIDI_TRANSFER_DONE, &devices[i].endpoints[currentEndpoint], sizeof(MIDI_ENDPOINT_DATA));
                        return TRUE;
                    }
                }    
            }
            return FALSE;
        #endif
    
        case EVENT_SUSPEND:
        case EVENT_RESUME:
        case EVENT_BUS_ERROR:
        default:
            break;
    }

    return FALSE;
} // USBHostMIDIEventHandler
コード例 #10
0
BOOL USBHostMIDIInit ( BYTE address, DWORD flags, BYTE clientDriverID )
{
    BYTE *config_descriptor;
    BYTE *ptr;
    BYTE bDescriptorType;
    BYTE bLength;
    BYTE bNumEndpoints;
    BYTE bNumInterfaces;
    BYTE bInterfaceNumber;
    BYTE bAlternateSetting;
    BYTE Class;
    BYTE SubClass;
    BYTE Protocol;
    BYTE currentEndpoint;
    WORD wTotalLength;
    
    BYTE index = 0;
    BOOL error = FALSE;
    
    MIDI_DEVICE *device = &devices[0];
    
    config_descriptor = USBHostGetCurrentConfigurationDescriptor(address);
    ptr = config_descriptor;
    
    // Load up the values from the Configuration Descriptor
    bLength              = *ptr++;
    bDescriptorType      = *ptr++;
    wTotalLength         = *ptr++;           // In case these are not word aligned
    wTotalLength        += (*ptr++) << 8;
    bNumInterfaces       = *ptr++;
    
    // Skip over the rest of the Configuration Descriptor
    index += bLength;
    ptr    = &config_descriptor[index];

    while (!error && (index < wTotalLength))
    {
        // Check the descriptor length and type
        bLength         = *ptr++;
        bDescriptorType = *ptr++;

        // Find an interface descriptor
        if (bDescriptorType != USB_DESCRIPTOR_INTERFACE)
        {
            // Skip over the rest of the Descriptor
            index += bLength;
            ptr = &config_descriptor[index];
        }
        else
        {
            // Read some data from the interface descriptor
            bInterfaceNumber  = *ptr++;
            bAlternateSetting = *ptr++;
            bNumEndpoints     = *ptr++;
            Class             = *ptr++;
            SubClass          = *ptr++;
            Protocol          = *ptr++;

            // Check to see if this is a MIDI inteface descripter
            if (Class != AUDIO_CLASS || SubClass != MIDI_SUB_CLASS || Protocol != MIDI_PROTOCOL)
            {
                // If we cannot support this interface, skip it.
                index += bLength;
                ptr = &config_descriptor[index];
                continue;
            }

            // Initialize the device
            device->deviceAddress = address;
            device->clientDriverID = clientDriverID;
            device->numEndpoints = bNumEndpoints;
            
            
            // Allocate enough memory for each endpoint
            if ((device->endpoints = (MIDI_ENDPOINT_DATA*)malloc( sizeof(MIDI_ENDPOINT_DATA) * bNumEndpoints)) == NULL)
            {
                // Out of memory
                error = TRUE;   
            }
             
            if (!error)   
            {
                // Skip over the rest of the Interface Descriptor
                index += bLength;
                ptr = &config_descriptor[index];

                // Find the Endpoint Descriptors.  There might be Class and Vendor descriptors in here
                currentEndpoint = 0;
                while (!error && (index < wTotalLength) && (currentEndpoint < bNumEndpoints))
                {
                    bLength = *ptr++;
                    bDescriptorType = *ptr++;

                    if (bDescriptorType != USB_DESCRIPTOR_ENDPOINT)
                    {
                        // Skip over the rest of the Descriptor
                        index += bLength;
                        ptr = &config_descriptor[index];
                    }
                    else
                    {
                        device->endpoints[currentEndpoint].endpointAddress = *ptr++;
                        ptr++;
                        device->endpoints[currentEndpoint].endpointSize = *ptr++;
                        device->endpoints[currentEndpoint].endpointSize += (*ptr++) << 8;
                        device->endpoints[currentEndpoint].busy = FALSE;
                        
                        if(device->endpoints[currentEndpoint].endpointSize > 64)
                        {
                            // For full speed bulk endpoints, only 8, 16, 32, and 64 byte packets are supported
                            // But we will accept anything less than or equal to 64.
                            error = TRUE;
                        }
                        
                        // Get ready for the next endpoint.
                        currentEndpoint++;
                        index += bLength;
                        ptr = &config_descriptor[index];
                    }
                }
            }    

            // Ensure that we found all the endpoints for this interface.
            if (currentEndpoint != bNumEndpoints)
            {
                error = TRUE;
            }
        }
    }

    if (error)
    {
        // Destroy whatever list of interfaces, settings, and endpoints we created.
        // The "new" variables point to the current node we are trying to remove.
        if (device->endpoints != NULL)
        {           
            free( device->endpoints );
            device->endpoints = NULL;
        }    
        return FALSE;
    }
    
    #ifdef DEBUG_MODE
        UART2PrintString( "USB MIDI Client Initalized: " );
        UART2PrintString( " address=" );
        UART2PutDec( address );
        UART2PrintString( " Number of Endpoings=" );
        UART2PutHex( bNumEndpoints );
        UART2PrintString( "\r\n" );
    #endif

    // Notify that application that we've been attached to a device.
    USB_HOST_APP_EVENT_HANDLER(address, EVENT_MIDI_ATTACH, device, sizeof(MIDI_DEVICE) );

    return TRUE;

} // USBHostMIDIInit