uint16_t ConfigDescriptorSize;\r
uint8_t ConfigDescriptorData[512];\r
\r
- if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||\r
- (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||\r
- (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))\r
+ if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,\r
+ sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)\r
{\r
printf("Error Retrieving Configuration Descriptor.\r\n");\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
uint16_t ConfigDescriptorSize;\r
uint8_t ConfigDescriptorData[512];\r
\r
- if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||\r
- (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||\r
- (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))\r
+ if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,\r
+ sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)\r
{\r
printf("Error Retrieving Configuration Descriptor.\r\n");\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
uint16_t ConfigDescriptorSize;\r
uint8_t ConfigDescriptorData[512];\r
\r
- if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||\r
- (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||\r
- (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))\r
+ if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,\r
+ sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)\r
{\r
printf("Error Retrieving Configuration Descriptor.\r\n");\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
uint16_t ConfigDescriptorSize;\r
uint8_t ConfigDescriptorData[512];\r
\r
- if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||\r
- (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||\r
- (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))\r
+ if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,\r
+ sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)\r
{\r
printf("Error Retrieving Configuration Descriptor.\r\n");\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
uint8_t FoundEndpoints = 0;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlErrorDuringConfigRead;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlErrorDuringConfigRead;\r
+ }\r
\r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
-\r
/* The bluetooth USB transport addendium mandates that the data (not streaming voice) endpoints\r
be in the first interface descriptor (interface 0) */\r
- USB_GetNextDescriptorOfType(&ConfigDescriptorSize, &ConfigDescriptorData, DTYPE_Interface);\r
+ USB_GetNextDescriptorOfType(&CurrConfigBytesRem, &CurrConfigLocation, DTYPE_Interface);\r
\r
/* Ensure that an interface was found, and the end of the descriptor was not reached */\r
- if (!(ConfigDescriptorSize))\r
+ if (!(CurrConfigBytesRem))\r
return NoInterfaceFound;\r
\r
/* Get the data IN, data OUT and event notification endpoints for the bluetooth interface */\r
(1 << BLUETOOTH_EVENTS_PIPE)))\r
{\r
/* Fetch the next endpoint from the current bluetooth interface */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
- NextInterfaceBluetoothDataEndpoint))\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
+ NextInterfaceBluetoothDataEndpoint))\r
{\r
/* Descriptor not found, error out */\r
return NoEndpointFound;\r
/* Validate returned data - ensure the returned data is a device descriptor */\r
if (DeviceDescriptor.Header.Type != DTYPE_Device)\r
return InvalidDeviceDataReturned;\r
- \r
+ \r
+ /* Validate returned device Class, SubClass and Protocol values against the Bluetooth spec values */\r
if ((DeviceDescriptor.Class != BLUETOOTH_DEVICE_CLASS) ||\r
(DeviceDescriptor.SubClass != BLUETOOTH_DEVICE_SUBCLASS) ||\r
(DeviceDescriptor.Protocol != BLUETOOTH_DEVICE_PROTOCOL))\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
uint8_t FoundEndpoints = 0;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the CDC control interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
while (FoundEndpoints != ((1 << CDC_NOTIFICATIONPIPE) | (1 << CDC_DATAPIPE_IN) | (1 << CDC_DATAPIPE_OUT)))\r
{\r
/* Fetch the next bulk or interrupt endpoint from the current CDC interface */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Check to see if the control interface's notification pipe has been found, if so search for the data interface */\r
if (FoundEndpoints & (1 << CDC_NOTIFICATIONPIPE))\r
{\r
/* Get the next CDC data interface from the configuration descriptor (CDC class has two CDC interfaces) */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, \r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, \r
DComp_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
Pipe_DisablePipe();\r
\r
/* Get the next CDC control interface from the configuration descriptor (CDC class has two CDC interfaces) */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
}\r
\r
/* Fetch the next bulk or interrupt endpoint from the current CDC interface */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
- \r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
uint8_t FoundEndpoints = 0;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the HID interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
while (FoundEndpoints != ((1 << HID_DATA_IN_PIPE) | (1 << HID_DATA_OUT_PIPE)))\r
{\r
/* Get the next HID interface's data endpoint descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceHIDDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Not all HID devices have an OUT endpoint - if we've reached the end of the HID descriptor\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the keyboard interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
}\r
\r
/* Get the keyboard interface's data endpoint descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceKeyboardDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the keyboard interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
}\r
\r
/* Get the keyboard interface's HID descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_HID_t).HIDReportLength;\r
\r
/* Get the keyboard interface's data endpoint descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceKeyboardDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
- uint8_t FoundEndpoints = 0;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
+ uint8_t FoundEndpoints = 0;\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the mass storage interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextMassStorageInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
while (FoundEndpoints != ((1 << MASS_STORE_DATA_IN_PIPE) | (1 << MASS_STORE_DATA_OUT_PIPE)))\r
{\r
/* Fetch the next bulk endpoint from the current mass storage interface */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the mouse interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
}\r
\r
/* Get the mouse interface's data endpoint descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceMouseDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the mouse interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
}\r
\r
/* Get the mouse interface's HID descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_HID_t).HIDReportLength;\r
\r
/* Get the mouse interface's data endpoint descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextInterfaceMouseDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
- uint8_t ErrorCode;\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
uint8_t FoundEndpoints = 0;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the printer interface from the configuration descriptor */\r
- if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
- DComp_NextBidirectionalPrinterInterface)))\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextBidirectionalPrinterInterface))\r
{\r
/* Descriptor not found, error out */\r
return NoInterfaceFound;\r
while (FoundEndpoints != ((1 << PRINTER_DATA_OUT_PIPE) | (1 << PRINTER_DATA_IN_PIPE)))\r
{\r
/* Fetch the next bulk endpoint from the current printer interface */\r
- if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
- DComp_NextInterfaceBulkDataEndpoint)))\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceBulkDataEndpoint))\r
{\r
/* Descriptor not found, error out */\r
return NoEndpointFound;\r
*/\r
uint8_t ProcessConfigurationDescriptor(void)\r
{\r
- uint8_t* ConfigDescriptorData;\r
- uint16_t ConfigDescriptorSize;\r
+ uint8_t ConfigDescriptorData[512];\r
+ uint8_t* CurrConfigLocation = ConfigDescriptorData;\r
+ uint16_t CurrConfigBytesRem;\r
uint8_t FoundEndpoints = 0;\r
- \r
- /* Get Configuration Descriptor size from the device */\r
- if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)\r
- return ControlError;\r
- \r
- /* Ensure that the Configuration Descriptor isn't too large */\r
- if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)\r
- return DescriptorTooLarge;\r
- \r
- /* Allocate enough memory for the entire config descriptor */\r
- ConfigDescriptorData = alloca(ConfigDescriptorSize);\r
\r
/* Retrieve the entire configuration descriptor into the allocated buffer */\r
- USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);\r
- \r
- /* Validate returned data - ensure first entry is a configuration header descriptor */\r
- if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
- return InvalidConfigDataReturned;\r
+ switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))\r
+ {\r
+ case HOST_GETCONFIG_Successful:\r
+ break;\r
+ case HOST_GETCONFIG_InvalidData:\r
+ return InvalidConfigDataReturned;\r
+ case HOST_GETCONFIG_BuffOverflow:\r
+ return DescriptorTooLarge;\r
+ default:\r
+ return ControlError;\r
+ }\r
\r
/* Get the Still Image interface from the configuration descriptor */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextStillImageInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
while (FoundEndpoints != ((1 << SIMAGE_EVENTS_PIPE) | (1 << SIMAGE_DATA_IN_PIPE) | (1 << SIMAGE_DATA_OUT_PIPE)))\r
{\r
/* Fetch the next endpoint from the current Still Image interface */\r
- if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
+ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,\r
DComp_NextStillImageInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
{\r
/* Descriptor not found, error out */\r
#include "ConfigDescriptor.h"\r
\r
#if defined(USB_CAN_BE_HOST)\r
-uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr)\r
+uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr,\r
+ void* BufferPtr, uint16_t BufferSize)\r
{\r
uint8_t ErrorCode;\r
+ uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)];\r
\r
USB_ControlRequest = (USB_Request_Header_t)\r
{\r
\r
Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
\r
- if (BufferPtr == NULL)\r
- {\r
- uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)];\r
+ if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful)\r
+ return ErrorCode;\r
\r
- ErrorCode = USB_Host_SendControlRequest(ConfigHeader);\r
+ #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)\r
+ *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize;\r
+ #else\r
+ *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength; \r
+ #endif\r
\r
- #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)\r
- *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize;\r
- #else\r
- *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength; \r
- #endif\r
- }\r
- else\r
- {\r
- USB_ControlRequest.wLength = *ConfigSizePtr;\r
- \r
- ErrorCode = USB_Host_SendControlRequest(BufferPtr); \r
- }\r
+ if (*ConfigSizePtr > BufferSize)\r
+ return HOST_GETCONFIG_BuffOverflow;\r
+ \r
+ USB_ControlRequest.wLength = *ConfigSizePtr;\r
+ \r
+ if ((ErrorCode = USB_Host_SendControlRequest(BufferPtr)) != HOST_SENDCONTROL_Successful)\r
+ return ErrorCode;\r
\r
- return ErrorCode;\r
+ if (DESCRIPTOR_TYPE(BufferPtr) != DTYPE_Configuration)\r
+ return HOST_GETCONFIG_InvalidData;\r
+ \r
+ return HOST_GETCONFIG_Successful;\r
}\r
#endif\r
\r
uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, uint8_t** CurrConfigLoc, ConfigComparatorPtr_t ComparatorRoutine);\r
\r
/* Enums: */\r
+ enum USB_Host_GetConfigDescriptor_ErrorCodes_t\r
+ {\r
+ HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor */\r
+ HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration\r
+ * descriptor\r
+ */\r
+ HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request */\r
+ HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration\r
+ * descriptor\r
+ */\r
+ HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out */\r
+ HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated\r
+ * buffer\r
+ */\r
+ HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data */\r
+ };\r
+ \r
/** Enum for return values of a descriptor comparator function. */\r
enum DSearch_Return_ErrorCodes_t\r
{\r
};\r
\r
/* Function Prototypes: */\r
- /** Retrieves the configuration descriptor data or size from an attached device via a standard request.\r
+ /** Retrieves the configuration descriptor data from an attached device via a standard request into a buffer,\r
+ * including validity and size checking to prevent a buffer overflow.\r
*\r
* \param[in] ConfigNumber Device configuration descriptor number to fetch from the device (usually set to 1 for\r
* single configuration devices)\r
+ * \param[in,out] ConfigSizePtr Pointer to a uint16_t for storing the retrieved configuration descriptor size\r
+ * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data.\r
+ * \param[out] BufferSize Size of the allocated buffer where the configuration descriptor is to be stored\r
*\r
- * \param[in,out] ConfigSizePtr Pointer to a uint16_t for either storing or retrieving the configuration\r
- * descriptor size\r
- *\r
- * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. If this is\r
- * NULL, the size of the configuration descriptor will be retrieved instead and\r
- * placed in the variable pointed to by ConfigSizePtr. If this is non-NULL, the number\r
- * of bytes indicated by ConfigSizePtr of the configuration descriptor will be loaded\r
- * into the buffer\r
+ * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum\r
*/\r
- uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr)\r
- ATTR_NON_NULL_PTR_ARG(2);\r
+ uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr,\r
+ uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2, 3);\r
\r
/** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value.\r
* The bytes remaining value is automatically decremented.\r
* - Added new "Common" section to the class drivers, to hold all mode-independant definitions for clarity\r
* - Moved SCSI command/sense constants into the Mass Storage Class driver, instead of the user-code\r
* - Altered the SCSI commands in the LowLevel Mass Storage Host to save on FLASH space by reducing function calls\r
+ * - Changed the parameters and behaviour of the USB_GetDeviceConfigDescriptor() function so that it now performs size checks\r
+ * and data validations internally, to simplify user code\r
*\r
* <b>Fixed:</b>\r
* - Fixed possible lockup in the CDC device class driver, when the host sends data that is a multiple of the\r
* - The SPI_Init() routine's parameters have changed, so that the clock polarity and data sampling modes can be set. See\r
* the SPI_Init() function documentation for more details\r
*\r
+ * <b>Host Mode</b>\r
+ * - The \ref USB_GetDeviceConfigDescriptor() function's parameters and behaviour has changed; the user is required to\r
+ * preallocate the largest allowable buffer, and pass the size of the buffer to the function. This allows for a single\r
+ * call to the function to retrieve, size check and validate the Configuration Descriptor rather than having the user\r
+ * application perform these intermediatary steps.\r
+ *\r
* \section Sec_Migration090810 Migrating from 090605 to 090810\r
*\r
* <b>All</b>\r