BOOL USBHostAndroidInit(BYTE address, DWORD flags, BYTE clientDriverID) { USB_INTERFACE_INFO *pIntInfo; USB_DEVICE_DESCRIPTOR *pDev; USB_DEVICE_INFO *pDevInfo = USBHostGetDeviceInfo(); // Initialize state memset(&gc_DevData, 0, sizeof gc_DevData); // Save device the address, VID, & PID gc_DevData.ID.deviceAddress = address; pDev = (USB_DEVICE_DESCRIPTOR *) USBHostGetDeviceDescriptor(address); gc_DevData.ID.vid = pDev->idVendor; gc_DevData.ID.pid = pDev->idProduct; // Save the endpoint addresses for the interfaces for (pIntInfo = pDevInfo->pInterfaceList; pIntInfo; pIntInfo = pIntInfo->next) { int i; log_printf("Encoutered interface %d, class 0x%x, subclass 0x%x, protocol, 0x%x", pIntInfo->interface, pIntInfo->type.cls, pIntInfo->type.subcls, pIntInfo->type.proto); for (i = 0; i < ARRAY_SIZE(interfaceTable); ++i) { InterfaceTableEntry *pEntry = &interfaceTable[i]; if (0 == memcmp(&pEntry->type, &pIntInfo->type, sizeof(USB_INTERFACE_TYPE_INFO))) { pEntry->func(pIntInfo, pEntry->userData); break; } } } gc_DevData.initialized = 1; log_printf("Android Client Initalized: flags=0x%lx address=%d VID=0x%x PID=0x%x", flags, address, gc_DevData.ID.vid, gc_DevData.ID.pid); return TRUE; } // USBHostAndroidInit
BOOL USBHostAndroidInit(BYTE address, DWORD flags, BYTE clientDriverID) { USB_INTERFACE_INFO *pIntInfo; USB_DEVICE_DESCRIPTOR *pDev; USB_DEVICE_INFO *pDevInfo = USBHostGetDeviceInfo(); USB_ENDPOINT_INFO *pFirstEpInfo; USB_ENDPOINT_INFO *pSecondEpInfo; // Initialize state memset(&gc_DevData, 0, sizeof gc_DevData); // Save device the address, VID, & PID gc_DevData.ID.deviceAddress = address; pDev = (USB_DEVICE_DESCRIPTOR *) USBHostGetDeviceDescriptor(address); gc_DevData.ID.vid = pDev->idVendor; gc_DevData.ID.pid = pDev->idProduct; // Save the endpoint addresses for the interfaces for (pIntInfo = pDevInfo->pInterfaceList; pIntInfo; pIntInfo = pIntInfo->next) { ANDROID_INTERFACE *pInterface; BYTE iid = pIntInfo->interface; if (iid >= ANDROID_INTERFACE_MAX) return FALSE; pInterface = &gc_DevData.interfaces[iid]; pFirstEpInfo = pIntInfo->pCurrentSetting->pEndpointList; if (!pFirstEpInfo) return FALSE; pSecondEpInfo = pFirstEpInfo->next; if (!pSecondEpInfo) return FALSE; if (pSecondEpInfo->next) return FALSE; // we expect exactly 2 endpoints. if (pFirstEpInfo->bEndpointAddress & 0x80) { if (pSecondEpInfo->bEndpointAddress & 0x80) return FALSE; pInterface->inEndpoint = pFirstEpInfo->bEndpointAddress; pInterface->outEndpoint = pSecondEpInfo->bEndpointAddress; } else { if (!(pSecondEpInfo->bEndpointAddress & 0x80)) return FALSE; pInterface->inEndpoint = pSecondEpInfo->bEndpointAddress; pInterface->outEndpoint = pFirstEpInfo->bEndpointAddress; } gc_DevData.interfaces[iid].flags.initialized = 1; log_printf("Successfully initialized Android inteface %d. IN_EP=0x%x OUT_EP=0x%x", iid, pInterface->inEndpoint, pInterface->outEndpoint); } gc_DevData.initialized = 1; log_printf("Android Client Initalized: flags=0x%lx address=%d VID=0x%x PID=0x%x", flags, address, gc_DevData.ID.vid, gc_DevData.ID.pid); return TRUE; } // USBHostAndroidInit
BOOL USBHostAndroidInitInterface(BYTE address, DWORD iid, BYTE clientDriverID, USB_DEVICE_INFO *pDevInfo, USB_INTERFACE_INFO *pIntInfo) { USB_DEVICE_DESCRIPTOR *pDev = (USB_DEVICE_DESCRIPTOR *) USBHostGetDeviceDescriptor(address); USB_ENDPOINT_INFO *pFirstEpInfo; USB_ENDPOINT_INFO *pSecondEpInfo; ANDROID_INTERFACE *pInterface; log_printf("USBHostAndroidInitInterface(0x%x, 0x%lx, 0x%x)", address, iid, clientDriverID); assert(iid < ANDROID_INTERFACE_MAX); pInterface = &gc_DevData.interfaces[iid]; pFirstEpInfo = pIntInfo->pCurrentSetting->pEndpointList; if (!pFirstEpInfo) { log_printf("No end-points"); return FALSE; } pSecondEpInfo = pFirstEpInfo->next; if (!pSecondEpInfo) { log_printf("Only one end-point"); return FALSE; } if (pSecondEpInfo->next) { log_printf("Too many end-points"); return FALSE; } if (pFirstEpInfo->bEndpointAddress & 0x80) { if (pSecondEpInfo->bEndpointAddress & 0x80) { log_printf("Need one input and one output end-point"); return FALSE; } pInterface->inEndpoint = pFirstEpInfo->bEndpointAddress; pInterface->outEndpoint = pSecondEpInfo->bEndpointAddress; } else { if (!(pSecondEpInfo->bEndpointAddress & 0x80)) { log_printf("Need one input and one output end-point"); return FALSE; } pInterface->inEndpoint = pSecondEpInfo->bEndpointAddress; pInterface->outEndpoint = pFirstEpInfo->bEndpointAddress; } pInterface->flags.initialized = 1; log_printf("Successfully initialized Android inteface %ld. IN_EP=0x%x OUT_EP=0x%x", iid, pInterface->inEndpoint, pInterface->outEndpoint); // Save device the address, VID, & PID gc_DevData.ID.deviceAddress = address; gc_DevData.ID.vid = pDev->idVendor; gc_DevData.ID.pid = pDev->idProduct; return TRUE; }
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
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
uint8_t * ChipKITUSBHost::GetDeviceDescriptor(uint8_t deviceAddress) { return(USBHostGetDeviceDescriptor(deviceAddress)); }
/**************************************************************************** Function: void* AndroidInitialize_Pv1 ( BYTE address, DWORD flags, BYTE clientDriverID ) Summary: Per instance client driver for Android device. Called by USB host stack from the client driver table. Description: Per instance client driver for Android device. Called by USB host stack from the client driver table. Precondition: None Parameters: BYTE address - the address of the device that is being initialized DWORD flags - the initialization flags for the device BYTE clientDriverID - the clientDriverID for the device Return Values: TRUE - initialized successfully FALSE - does not support this device 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 ***************************************************************************/ void* AndroidInitialize_Pv1 ( BYTE address, DWORD flags, BYTE clientDriverID ) { BYTE *config_descriptor = NULL; BYTE *device_descriptor = NULL; WORD tempWord; BYTE *config_desc_end; ANDROID_PROTOCOL_V1_DEVICE_DATA* device = NULL; BYTE i; device_descriptor = USBHostGetDeviceDescriptor(address); ReadWORD(&tempWord, &device_descriptor[USB_DEV_DESC_VID_OFFSET]); if(tempWord == 0x18D1) { ReadWORD(&tempWord, &device_descriptor[USB_DEV_DESC_PID_OFFSET]); if((tempWord == 0x2D00) || (tempWord == 0x2D01)) { for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++) { if(devices_pv1[i].state == WAITING_FOR_ACCESSORY_RETURN) { device = &devices_pv1[i]; device->state = RETURN_OF_THE_ACCESSORY; break; } } } } //if this isn't an old accessory, then it must be a new one if(device == NULL) { //Find the first available device. for(i=0;i<NUM_ANDROID_DEVICES_SUPPORTED;i++) { if(devices_pv1[i].state == NO_DEVICE) { device = &devices_pv1[i]; if( (flags & ANDROID_INIT_FLAG_BYPASS_PROTOCOL) == ANDROID_INIT_FLAG_BYPASS_PROTOCOL) { device->state = RETURN_OF_THE_ACCESSORY; } else { device->state = DEVICE_ATTACHED; } break; } } } config_descriptor = USBHostGetCurrentConfigurationDescriptor( address ); //Save the total length for this configuration descriptor ReadWORD(&tempWord,&config_descriptor[2]); //Record the end of the descriptor so we know when to stop searching through // the descriptor list config_desc_end = config_descriptor + tempWord; //Skip past the configuration part of this descriptor to the next // descriptor in the configuration descriptor list. The size of the config // part of the descriptor is the first byte of the list. config_descriptor += *config_descriptor; //Search the entire configuration descriptor for COMM interfaces while(config_descriptor < config_desc_end) { //We are expecting a interface descriptor if(config_descriptor[USB_DESC_BDESCRIPTORTYPE_OFFSET] != USB_DESCRIPTOR_INTERFACE) { //Jump past this descriptor by adding the current descriptor length // to the current descriptor pointer. config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; //Jump back to the top of the while loop to continue searching through // this configuration for the next interface continue; } device->address = address; device->clientDriverID = clientDriverID; if( (config_descriptor[USB_INTERFACE_DESC_BINTERFACECLASS_OFFSET] == 0xFF) && (config_descriptor[USB_INTERFACE_DESC_BINTERFACESUBCLASS_OFFSET] == 0xFF) && (config_descriptor[USB_INTERFACE_DESC_BINTERFACEPROTOCOL_OFFSET] == 0x00)) { //Jump past this descriptor to the next descriptor. config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; //Parse through the rest of this interface. Stop when we reach the // next interface or the end of the configuration descriptor while((config_descriptor[USB_DESC_BDESCRIPTORTYPE_OFFSET] != USB_DESCRIPTOR_INTERFACE) && (config_descriptor < config_desc_end)) { if(config_descriptor[USB_DESC_BDESCRIPTORTYPE_OFFSET] == USB_DESCRIPTOR_ENDPOINT) { //If this is an endpoint descriptor in the DATA interface, then // copy all of the endpoint data to the device information. if((config_descriptor[USB_ENDPOINT_DESC_BENDPOINTADDRESS_OFFSET] & 0x80) == 0x80) { //If this is an IN endpoint, record the endpoint number device->INEndpointNum = config_descriptor[USB_ENDPOINT_DESC_BENDPOINTADDRESS_OFFSET]; //record the endpoint size (2 bytes) device->INEndpointSize = (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET]) + (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET+1] << 8); } else { //Otherwise this is an OUT endpoint, record the endpoint number device->OUTEndpointNum = config_descriptor[USB_ENDPOINT_DESC_BENDPOINTADDRESS_OFFSET]; //record the endpoint size (2 bytes) device->OUTEndpointSize = (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET]) + (config_descriptor[USB_ENDPOINT_DESC_WMAXPACKETSIZE_OFFSET+1] << 8); } } config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; } } else { //Jump past this descriptor by adding the current descriptor length // to the current descriptor pointer. config_descriptor += config_descriptor[USB_DESC_BLENGTH_OFFSET]; } } return device; }
BOOL USBHostBluetoothInit(BYTE address, DWORD flags, BYTE clientDriverID, USB_DEVICE_INFO *pDevInfo, USB_INTERFACE_INFO *pIntInfo) { USB_DEVICE_DESCRIPTOR *pDev; USB_ENDPOINT_INFO *pEndpoint; log_printf("USBHostBluetoothInit(0x%x, 0x%lx, 0x%x)", address, flags, clientDriverID); // Initialize state memset(&gc_BluetoothDevData, 0, sizeof gc_BluetoothDevData); // Save device the address, VID, & PID gc_BluetoothDevData.ID.deviceAddress = address; pDev = (USB_DEVICE_DESCRIPTOR *) USBHostGetDeviceDescriptor(address); gc_BluetoothDevData.ID.vid = pDev->idVendor; gc_BluetoothDevData.ID.pid = pDev->idProduct; gc_BluetoothDevData.driverID = clientDriverID; // We're looking for an interface with: // - class 0xe0 subclass 0x01 protocol 0x01 // - one bulk in, one bulk out, and one interrupt endpoints. // When found, save the endpoint addresses for the interfaces for (pIntInfo = pDevInfo->pInterfaceList; pIntInfo; pIntInfo = pIntInfo->next) { log_printf("Encoutered interface %d, class 0x%x, subclass 0x%x, protocol, 0x%x", pIntInfo->interface, pIntInfo->type.cls, pIntInfo->type.subcls, pIntInfo->type.proto); if (pIntInfo->type.cls != 0xE0 || pIntInfo->type.subcls != 0x01 || pIntInfo->type.proto != 0x01) continue; unsigned int found = 0; for (pEndpoint = pIntInfo->pCurrentSetting->pEndpointList; pEndpoint; pEndpoint = pEndpoint->next) { if (pEndpoint->bEndpointAddress & 0x80 && pEndpoint->bmAttributes.bfTransferType == USB_TRANSFER_TYPE_BULK && !(found & FOUND_BULK_IN)) { // found bulk input gc_BluetoothDevData.bulkIn.address = pEndpoint->bEndpointAddress; found |= FOUND_BULK_IN; } else if (!(pEndpoint->bEndpointAddress & 0x80) && pEndpoint->bmAttributes.bfTransferType == USB_TRANSFER_TYPE_BULK && !(found & FOUND_BULK_OUT)) { // found bulk input gc_BluetoothDevData.bulkOut.address = pEndpoint->bEndpointAddress; found |= FOUND_BULK_OUT; } else if (pEndpoint->bEndpointAddress & 0x80 && pEndpoint->bmAttributes.bfTransferType == USB_TRANSFER_TYPE_INTERRUPT && !(found & FOUND_INTERRUPT)) { // found bulk input gc_BluetoothDevData.intIn.address = pEndpoint->bEndpointAddress; found |= FOUND_INTERRUPT; } else { break; } } if ((found & FOUND_ALL) == FOUND_ALL) { gc_BluetoothDevData.interface = pIntInfo->interface; goto good; } } // if we got here, a matching interface was not found log_printf("Could not find a matching interface"); return FALSE; good: gc_BluetoothDevData.initialized = 1; log_printf("Bluetooth Client Initalized: flags=0x%lx address=%d VID=0x%x PID=0x%x", flags, address, gc_BluetoothDevData.ID.vid, gc_BluetoothDevData.ID.pid); USBHostBluetoothCallback(BLUETOOTH_EVENT_ATTACHED, USB_SUCCESS, NULL, 0); return TRUE; }