diff --git a/Demos/Host/ClassDriver/CDCHost/CDCHost.c b/Demos/Host/ClassDriver/CDCHost/CDCHost.c index 7aa8deeeeb..4f67f3fbeb 100644 --- a/Demos/Host/ClassDriver/CDCHost/CDCHost.c +++ b/Demos/Host/ClassDriver/CDCHost/CDCHost.c @@ -72,9 +72,8 @@ int main(void) uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; - if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) || - (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) || - (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData))) + if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, + sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { printf("Error Retrieving Configuration Descriptor.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); diff --git a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c index c9120d596b..d22e074008 100644 --- a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c +++ b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c @@ -71,9 +71,8 @@ int main(void) uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; - if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) || - (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) || - (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData))) + if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, + sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { printf("Error Retrieving Configuration Descriptor.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); diff --git a/Demos/Host/ClassDriver/MouseHost/MouseHost.c b/Demos/Host/ClassDriver/MouseHost/MouseHost.c index 9f76bc754b..844fa334c0 100644 --- a/Demos/Host/ClassDriver/MouseHost/MouseHost.c +++ b/Demos/Host/ClassDriver/MouseHost/MouseHost.c @@ -73,9 +73,8 @@ int main(void) uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; - if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) || - (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) || - (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData))) + if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, + sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { printf("Error Retrieving Configuration Descriptor.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); diff --git a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c index 2f0e5a2d1f..deb8a55047 100644 --- a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c +++ b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c @@ -72,9 +72,8 @@ int main(void) uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; - if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) || - (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) || - (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData))) + if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, + sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { printf("Error Retrieving Configuration Descriptor.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); diff --git a/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c b/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c index 948c4fcc65..f856262d67 100644 --- a/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c +++ b/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c @@ -32,34 +32,30 @@ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; uint8_t FoundEndpoints = 0; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlErrorDuringConfigRead; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlErrorDuringConfigRead; + } - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; - /* The bluetooth USB transport addendium mandates that the data (not streaming voice) endpoints be in the first interface descriptor (interface 0) */ - USB_GetNextDescriptorOfType(&ConfigDescriptorSize, &ConfigDescriptorData, DTYPE_Interface); + USB_GetNextDescriptorOfType(&CurrConfigBytesRem, &CurrConfigLocation, DTYPE_Interface); /* Ensure that an interface was found, and the end of the descriptor was not reached */ - if (!(ConfigDescriptorSize)) + if (!(CurrConfigBytesRem)) return NoInterfaceFound; /* Get the data IN, data OUT and event notification endpoints for the bluetooth interface */ @@ -67,8 +63,8 @@ uint8_t ProcessConfigurationDescriptor(void) (1 << BLUETOOTH_EVENTS_PIPE))) { /* Fetch the next endpoint from the current bluetooth interface */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - NextInterfaceBluetoothDataEndpoint)) + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, + NextInterfaceBluetoothDataEndpoint)) { /* Descriptor not found, error out */ return NoEndpointFound; diff --git a/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c b/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c index f68f957c01..9943521087 100644 --- a/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c +++ b/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c @@ -41,7 +41,8 @@ uint8_t ProcessDeviceDescriptor(void) /* Validate returned data - ensure the returned data is a device descriptor */ if (DeviceDescriptor.Header.Type != DTYPE_Device) return InvalidDeviceDataReturned; - + + /* Validate returned device Class, SubClass and Protocol values against the Bluetooth spec values */ if ((DeviceDescriptor.Class != BLUETOOTH_DEVICE_CLASS) || (DeviceDescriptor.SubClass != BLUETOOTH_DEVICE_SUBCLASS) || (DeviceDescriptor.Protocol != BLUETOOTH_DEVICE_PROTOCOL)) diff --git a/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c b/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c index f1a57cd740..f9671e2b3d 100644 --- a/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c @@ -47,30 +47,26 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; uint8_t FoundEndpoints = 0; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the CDC control interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -81,14 +77,14 @@ uint8_t ProcessConfigurationDescriptor(void) while (FoundEndpoints != ((1 << CDC_NOTIFICATIONPIPE) | (1 << CDC_DATAPIPE_IN) | (1 << CDC_DATAPIPE_OUT))) { /* Fetch the next bulk or interrupt endpoint from the current CDC interface */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Check to see if the control interface's notification pipe has been found, if so search for the data interface */ if (FoundEndpoints & (1 << CDC_NOTIFICATIONPIPE)) { /* Get the next CDC data interface from the configuration descriptor (CDC class has two CDC interfaces) */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -109,7 +105,7 @@ uint8_t ProcessConfigurationDescriptor(void) Pipe_DisablePipe(); /* Get the next CDC control interface from the configuration descriptor (CDC class has two CDC interfaces) */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -118,7 +114,7 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Fetch the next bulk or interrupt endpoint from the current CDC interface */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ diff --git a/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c b/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c index dbec62b637..dba62fd06d 100644 --- a/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c @@ -47,31 +47,26 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; - + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; uint8_t FoundEndpoints = 0; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the HID interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -81,7 +76,7 @@ uint8_t ProcessConfigurationDescriptor(void) while (FoundEndpoints != ((1 << HID_DATA_IN_PIPE) | (1 << HID_DATA_OUT_PIPE))) { /* Get the next HID interface's data endpoint descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceHIDDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Not all HID devices have an OUT endpoint - if we've reached the end of the HID descriptor diff --git a/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c b/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c index 4033060429..46fb94ee2c 100644 --- a/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c @@ -47,29 +47,25 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the keyboard interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Get the keyboard interface's data endpoint descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceKeyboardDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c b/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c index d9fd50f692..7ab0a1887d 100644 --- a/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c @@ -47,29 +47,25 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the keyboard interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Get the keyboard interface's HID descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -88,7 +84,7 @@ uint8_t ProcessConfigurationDescriptor(void) HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_HID_t).HIDReportLength; /* Get the keyboard interface's data endpoint descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceKeyboardDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ diff --git a/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c b/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c index 9f80b42eeb..1ba3244ed7 100644 --- a/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c @@ -47,30 +47,26 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; - uint8_t FoundEndpoints = 0; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; + uint8_t FoundEndpoints = 0; /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the mass storage interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMassStorageInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -81,7 +77,7 @@ uint8_t ProcessConfigurationDescriptor(void) while (FoundEndpoints != ((1 << MASS_STORE_DATA_IN_PIPE) | (1 << MASS_STORE_DATA_OUT_PIPE))) { /* Fetch the next bulk endpoint from the current mass storage interface */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ diff --git a/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c b/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c index e0be70b1b5..912f146bc6 100644 --- a/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c @@ -47,29 +47,25 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the mouse interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Get the mouse interface's data endpoint descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceMouseDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ diff --git a/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c b/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c index 1d28351ee2..fa06741188 100644 --- a/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c @@ -47,29 +47,25 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the mouse interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void) } /* Get the mouse interface's HID descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -88,7 +84,7 @@ uint8_t ProcessConfigurationDescriptor(void) HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_HID_t).HIDReportLength; /* Get the mouse interface's data endpoint descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceMouseDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ diff --git a/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c b/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c index d4eaff94a1..22d84c5aae 100644 --- a/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c @@ -36,32 +36,26 @@ uint8_t PrinterAltSetting; uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; - uint8_t ErrorCode; + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; uint8_t FoundEndpoints = 0; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the printer interface from the configuration descriptor */ - if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DComp_NextBidirectionalPrinterInterface))) + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextBidirectionalPrinterInterface)) { /* Descriptor not found, error out */ return NoInterfaceFound; @@ -74,8 +68,7 @@ uint8_t ProcessConfigurationDescriptor(void) while (FoundEndpoints != ((1 << PRINTER_DATA_OUT_PIPE) | (1 << PRINTER_DATA_IN_PIPE))) { /* Fetch the next bulk endpoint from the current printer interface */ - if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DComp_NextInterfaceBulkDataEndpoint))) + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceBulkDataEndpoint)) { /* Descriptor not found, error out */ return NoEndpointFound; diff --git a/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c b/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c index a2d4d48dd2..4e7751d710 100644 --- a/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c +++ b/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c @@ -47,30 +47,26 @@ */ uint8_t ProcessConfigurationDescriptor(void) { - uint8_t* ConfigDescriptorData; - uint16_t ConfigDescriptorSize; + uint8_t ConfigDescriptorData[512]; + uint8_t* CurrConfigLocation = ConfigDescriptorData; + uint16_t CurrConfigBytesRem; uint8_t FoundEndpoints = 0; - - /* Get Configuration Descriptor size from the device */ - if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) - return ControlError; - - /* Ensure that the Configuration Descriptor isn't too large */ - if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE) - return DescriptorTooLarge; - - /* Allocate enough memory for the entire config descriptor */ - ConfigDescriptorData = alloca(ConfigDescriptorSize); /* Retrieve the entire configuration descriptor into the allocated buffer */ - USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData); - - /* Validate returned data - ensure first entry is a configuration header descriptor */ - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return InvalidConfigDataReturned; + switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) + { + case HOST_GETCONFIG_Successful: + break; + case HOST_GETCONFIG_InvalidData: + return InvalidConfigDataReturned; + case HOST_GETCONFIG_BuffOverflow: + return DescriptorTooLarge; + default: + return ControlError; + } /* Get the Still Image interface from the configuration descriptor */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextStillImageInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ @@ -81,7 +77,7 @@ uint8_t ProcessConfigurationDescriptor(void) while (FoundEndpoints != ((1 << SIMAGE_EVENTS_PIPE) | (1 << SIMAGE_DATA_IN_PIPE) | (1 << SIMAGE_DATA_OUT_PIPE))) { /* Fetch the next endpoint from the current Still Image interface */ - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextStillImageInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c index 47982b806c..4c6fbfdabe 100644 --- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c +++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c @@ -31,9 +31,11 @@ #include "ConfigDescriptor.h" #if defined(USB_CAN_BE_HOST) -uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr) +uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, + void* BufferPtr, uint16_t BufferSize) { uint8_t ErrorCode; + uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; USB_ControlRequest = (USB_Request_Header_t) { @@ -46,26 +48,27 @@ uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const Conf Pipe_SelectPipe(PIPE_CONTROLPIPE); - if (BufferPtr == NULL) - { - uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; + if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful) + return ErrorCode; - ErrorCode = USB_Host_SendControlRequest(ConfigHeader); + #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) + *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize; + #else + *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength; + #endif - #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) - *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize; - #else - *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength; - #endif - } - else - { - USB_ControlRequest.wLength = *ConfigSizePtr; - - ErrorCode = USB_Host_SendControlRequest(BufferPtr); - } + if (*ConfigSizePtr > BufferSize) + return HOST_GETCONFIG_BuffOverflow; + + USB_ControlRequest.wLength = *ConfigSizePtr; + + if ((ErrorCode = USB_Host_SendControlRequest(BufferPtr)) != HOST_SENDCONTROL_Successful) + return ErrorCode; - return ErrorCode; + if (DESCRIPTOR_TYPE(BufferPtr) != DTYPE_Configuration) + return HOST_GETCONFIG_InvalidData; + + return HOST_GETCONFIG_Successful; } #endif diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h index a9b0b14230..8c4e2c2db1 100644 --- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h +++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h @@ -163,6 +163,23 @@ uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, uint8_t** CurrConfigLoc, ConfigComparatorPtr_t ComparatorRoutine); /* Enums: */ + enum USB_Host_GetConfigDescriptor_ErrorCodes_t + { + HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor */ + HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration + * descriptor + */ + HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request */ + HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration + * descriptor + */ + HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out */ + HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated + * buffer + */ + HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data */ + }; + /** Enum for return values of a descriptor comparator function. */ enum DSearch_Return_ErrorCodes_t { @@ -181,22 +198,19 @@ }; /* Function Prototypes: */ - /** Retrieves the configuration descriptor data or size from an attached device via a standard request. + /** Retrieves the configuration descriptor data from an attached device via a standard request into a buffer, + * including validity and size checking to prevent a buffer overflow. * * \param[in] ConfigNumber Device configuration descriptor number to fetch from the device (usually set to 1 for * single configuration devices) + * \param[in,out] ConfigSizePtr Pointer to a uint16_t for storing the retrieved configuration descriptor size + * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. + * \param[out] BufferSize Size of the allocated buffer where the configuration descriptor is to be stored * - * \param[in,out] ConfigSizePtr Pointer to a uint16_t for either storing or retrieving the configuration - * descriptor size - * - * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. If this is - * NULL, the size of the configuration descriptor will be retrieved instead and - * placed in the variable pointed to by ConfigSizePtr. If this is non-NULL, the number - * of bytes indicated by ConfigSizePtr of the configuration descriptor will be loaded - * into the buffer + * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum */ - uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr) - ATTR_NON_NULL_PTR_ARG(2); + uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr, + uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2, 3); /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value. * The bytes remaining value is automatically decremented. diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 8530f705fe..1750bfaeb9 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -29,6 +29,8 @@ * - Added new "Common" section to the class drivers, to hold all mode-independant definitions for clarity * - Moved SCSI command/sense constants into the Mass Storage Class driver, instead of the user-code * - Altered the SCSI commands in the LowLevel Mass Storage Host to save on FLASH space by reducing function calls + * - Changed the parameters and behaviour of the USB_GetDeviceConfigDescriptor() function so that it now performs size checks + * and data validations internally, to simplify user code * * Fixed: * - Fixed possible lockup in the CDC device class driver, when the host sends data that is a multiple of the diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt index d83043182b..9527a373ce 100644 --- a/LUFA/ManPages/MigrationInformation.txt +++ b/LUFA/ManPages/MigrationInformation.txt @@ -19,6 +19,12 @@ * - The SPI_Init() routine's parameters have changed, so that the clock polarity and data sampling modes can be set. See * the SPI_Init() function documentation for more details * + * Host Mode + * - The \ref USB_GetDeviceConfigDescriptor() function's parameters and behaviour has changed; the user is required to + * preallocate the largest allowable buffer, and pass the size of the buffer to the function. This allows for a single + * call to the function to retrieve, size check and validate the Configuration Descriptor rather than having the user + * application perform these intermediatary steps. + * * \section Sec_Migration090810 Migrating from 090605 to 090810 * * All