Fixed RNDISEthernet demos crashing when calculating checksums for Ethernet/TCP packets of more than ~500 bytes due to an overflow in the checksum calculation loop (thanks to Kevin Malec).

Removed string Attributes from the Service Discovery Protocol code to minimise the potential points of failure while the base code is being debugged.
pull/1469/head
Dean Camera 15 years ago
parent 8f3d4e69c3
commit 4a13a5484a

@ -120,7 +120,7 @@ uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes)
uint16_t* Words = (uint16_t*)Data; uint16_t* Words = (uint16_t*)Data;
uint32_t Checksum = 0; uint32_t Checksum = 0;
for (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++) for (uint16_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)
Checksum += Words[CurrWord]; Checksum += Words[CurrWord];
while (Checksum & 0xFFFF0000) while (Checksum & 0xFFFF0000)

@ -608,7 +608,7 @@ static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddre
Checksum += SwapEndian_16(PROTOCOL_TCP); Checksum += SwapEndian_16(PROTOCOL_TCP);
Checksum += SwapEndian_16(TCPOutSize); Checksum += SwapEndian_16(TCPOutSize);
for (uint8_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++) for (uint16_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++)
Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord]; Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord];
if (TCPOutSize & 0x01) if (TCPOutSize & 0x01)

@ -125,7 +125,7 @@ uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes)
uint16_t* Words = (uint16_t*)Data; uint16_t* Words = (uint16_t*)Data;
uint32_t Checksum = 0; uint32_t Checksum = 0;
for (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++) for (uint16_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)
Checksum += Words[CurrWord]; Checksum += Words[CurrWord];
while (Checksum & 0xFFFF0000) while (Checksum & 0xFFFF0000)

@ -605,7 +605,7 @@ static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddre
Checksum += SwapEndian_16(PROTOCOL_TCP); Checksum += SwapEndian_16(PROTOCOL_TCP);
Checksum += SwapEndian_16(TCPOutSize); Checksum += SwapEndian_16(TCPOutSize);
for (uint8_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++) for (uint16_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++)
Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord]; Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord];
if (TCPOutSize & 0x01) if (TCPOutSize & 0x01)

@ -31,40 +31,18 @@
#define INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C #define INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C
#include "ServiceDiscoveryProtocol.h" #include "ServiceDiscoveryProtocol.h"
/** Service Discovery Protocol attribute, indicationg the service's name. */ /** Service Discovery Protocol attribute, indicating the service's availability. */
const struct
{
uint8_t Header;
uint8_t Length;
uint8_t Data[];
} PROGMEM SDP_Attribute_Name = {(SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit), sizeof("SDP"), "SDP"};
/** Service Discovery Protocol attribute, indicationg the service's description. */
const struct
{
uint8_t Header;
uint8_t Length;
uint8_t Data[];
} PROGMEM SDP_Attribute_Description = {(SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit), sizeof("BT Service Discovery"), "BT Service Discovery"};
/** Service Discovery Protocol attribute, indicationg the service's availability. */
const struct const struct
{ {
uint8_t Header; uint8_t Header;
uint8_t Data; uint8_t Data;
} PROGMEM SDP_Attribute_Availability = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_8Bit), 0xFF}; } PROGMEM SDP_Attribute_Availability = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_8Bit), 0xFF};
const struct
{
uint8_t Header;
uint16_t Data;
} PROGMEM SDP_Attribute_LanguageOffset = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_16Bit), SDP_ATTRIBUTE_LANGOFFSET};
const struct const struct
{ {
uint8_t Header; uint8_t Header;
uint32_t Data; uint32_t Data;
} PROGMEM SDP_Attribute_ServiceHandle = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_32Bit), 0x00000001}; } PROGMEM SDP_Attribute_ServiceHandle = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_32Bit), 0x00010000};
const struct const struct
{ {
@ -102,9 +80,6 @@ const ServiceAttributeTable_t SDP_Attribute_Table[] PROGMEM =
{.AttributeID = SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE, .Data = &SDP_Attribute_ServiceHandle }, {.AttributeID = SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE, .Data = &SDP_Attribute_ServiceHandle },
{.AttributeID = SDP_ATTRIBUTE_ID_SERVICECLASSIDS, .Data = &SDP_Attribute_ServiceClassIDs }, {.AttributeID = SDP_ATTRIBUTE_ID_SERVICECLASSIDS, .Data = &SDP_Attribute_ServiceClassIDs },
{.AttributeID = SDP_ATTRIBUTE_ID_VERSION, .Data = &SDP_Attribute_Version }, {.AttributeID = SDP_ATTRIBUTE_ID_VERSION, .Data = &SDP_Attribute_Version },
{.AttributeID = SDP_ATTRIBUTE_ID_LANGIDOFFSET, .Data = &SDP_Attribute_LanguageOffset },
{.AttributeID = SDP_ATTRIBUTE_ID_NAME, .Data = &SDP_Attribute_Name },
{.AttributeID = SDP_ATTRIBUTE_ID_DESCRIPTION, .Data = &SDP_Attribute_Description },
SERVICE_ATTRIBUTE_TABLE_TERMINATOR SERVICE_ATTRIBUTE_TABLE_TERMINATOR
}; };
@ -118,12 +93,6 @@ const ServiceTable_t SDP_Services_Table[] PROGMEM =
.UUID = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x01}, .UUID = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x01},
.AttributeTable = SDP_Attribute_Table, .AttributeTable = SDP_Attribute_Table,
}, },
#if 0
{ // 128-bit UUID for the RFCOMM service
.UUID = {BASE_96BIT_UUID, 0x03, 0x00, 0x00, 0x00},
.AttributeTable = RFCOMM_Attribute_Table,
},
#endif
}; };
/** Base UUID value common to all standardized Bluetooth services */ /** Base UUID value common to all standardized Bluetooth services */
@ -220,7 +189,7 @@ static void SDP_ProcessServiceSearchAttribute(const SDP_PDUHeader_t* const SDPHe
if (MaxAttributeSize > sizeof(ResponsePacket.ResponseData)) if (MaxAttributeSize > sizeof(ResponsePacket.ResponseData))
MaxAttributeSize = sizeof(ResponsePacket.ResponseData); MaxAttributeSize = sizeof(ResponsePacket.ResponseData);
/* Add the outer Data Element Sequence header for the retrieved Attributes */ /* Add the outer Data Element Sequence header for all of the retrieved Attributes */
uint16_t* TotalResponseSize = SDP_AddDataElementHeader16(&CurrResponsePos, SDP_DATATYPE_Sequence); uint16_t* TotalResponseSize = SDP_AddDataElementHeader16(&CurrResponsePos, SDP_DATATYPE_Sequence);
/* Search through the list of UUIDs one at a time looking for matching search Attributes */ /* Search through the list of UUIDs one at a time looking for matching search Attributes */
@ -263,9 +232,12 @@ static void SDP_ProcessServiceSearchAttribute(const SDP_PDUHeader_t* const SDPHe
*TotalResponseSize += 3 + *CurrentUUIDResponseSize; *TotalResponseSize += 3 + *CurrentUUIDResponseSize;
} }
} }
/* Continuation state - always zero */
*((uint8_t*)CurrResponsePos) = 0;
/* Set the total response list size to the size of the outer container plus its header size */ /* Set the total response list size to the size of the outer container plus its header size and continuation state */
ResponsePacket.AttributeListByteCount = 3 + *TotalResponseSize; ResponsePacket.AttributeListByteCount = 4 + *TotalResponseSize;
/* Fill in the response packet's header */ /* Fill in the response packet's header */
ResponsePacket.SDPHeader.PDU = SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE; ResponsePacket.SDPHeader.PDU = SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE;
@ -367,11 +339,11 @@ static ServiceAttributeTable_t* SDP_GetAttributeTable(const uint8_t* const UUID)
while (ClassUUIDListSize) while (ClassUUIDListSize)
{ {
/* Current Service UUID's Class UUID list has a matching entry, return the Attribute table */ /* Current Service UUID's Class UUID list has a matching entry, return the Attribute table */
if (!(memcmp_P(UUID, (ClassUUIDs + 1), UUID_SIZE_BYTES))) if (!(memcmp_P(UUID, &((ClassUUID_t*)ClassUUIDs)->UUID, UUID_SIZE_BYTES)))
return CurrAttributeTable; return CurrAttributeTable;
ClassUUIDs += sizeof(uint8_t) + UUID_SIZE_BYTES; ClassUUIDListSize -= sizeof(ClassUUID_t);
ClassUUIDListSize -= sizeof(uint8_t) + UUID_SIZE_BYTES; ClassUUIDs += sizeof(ClassUUID_t);
} }
} }

@ -59,12 +59,7 @@
#define SDP_ATTRIBUTE_ID_LANGIDOFFSET 0x0006 #define SDP_ATTRIBUTE_ID_LANGIDOFFSET 0x0006
#define SDP_ATTRIBUTE_ID_AVAILABILITY 0x0008 #define SDP_ATTRIBUTE_ID_AVAILABILITY 0x0008
#define SDP_ATTRIBUTE_ID_VERSION 0x0200 #define SDP_ATTRIBUTE_ID_VERSION 0x0200
#define SDP_ATTRIBUTE_ID_NAME (0x0000 + SDP_ATTRIBUTE_LANGOFFSET)
#define SDP_ATTRIBUTE_ID_DESCRIPTION (0x0001 + SDP_ATTRIBUTE_LANGOFFSET)
/** Attribute ID offset for localised language string attributes. */
#define SDP_ATTRIBUTE_LANGOFFSET 0x0100
/** Size of a full 128 bit UUID, in bytes. */ /** Size of a full 128 bit UUID, in bytes. */
#define UUID_SIZE_BYTES 16 #define UUID_SIZE_BYTES 16

@ -167,7 +167,7 @@
static inline void SwapEndian_n(void* Data, uint8_t Bytes); static inline void SwapEndian_n(void* Data, uint8_t Bytes);
static inline void SwapEndian_n(void* Data, uint8_t Bytes) static inline void SwapEndian_n(void* Data, uint8_t Bytes)
{ {
uint8_t* CurrDataPos = Data; uint8_t* CurrDataPos = (uint8_t*)Data;
while (Bytes) while (Bytes)
{ {

@ -18,6 +18,8 @@
* the last page of FLASH (thanks to Gerard Sexton) * the last page of FLASH (thanks to Gerard Sexton)
* - Fixed AVRISP project not sending a full erase-and-write EEPROM command to XMEGA targets when writing to the EEPROM * - Fixed AVRISP project not sending a full erase-and-write EEPROM command to XMEGA targets when writing to the EEPROM
* instead of the split write-only command (thanks to Tim Margush) * instead of the split write-only command (thanks to Tim Margush)
* - Fixed RNDISEthernet demos crashing when calculating checksums for Ethernet/TCP packets of more than ~500 bytes due to
* an overflow in the checksum calculation loop (thanks to Kevin Malec)
* *
* \section Sec_ChangeLog100513 Version 100513 * \section Sec_ChangeLog100513 Version 100513
* <b>New:</b> * <b>New:</b>
@ -92,7 +94,6 @@
* HID_HOST_BOOT_PROTOCOL_ONLY compile time option is set * HID_HOST_BOOT_PROTOCOL_ONLY compile time option is set
* - Fixed INTERRUPT_CONTROL_ENDPOINT compile time option preventing other interrupts from occuring while the control endpoint * - Fixed INTERRUPT_CONTROL_ENDPOINT compile time option preventing other interrupts from occuring while the control endpoint
* request is being processed, causing possible lockups if a USB interrupt occurs during a transfer * request is being processed, causing possible lockups if a USB interrupt occurs during a transfer
* - Fixed TeensyHID bootloader not working on some USB AVR models with the official TeensyLoader GUI application
* - Remove incorrect Abstract Call Management class specific descriptor from the CDC demos, bootloaders and projects * - Remove incorrect Abstract Call Management class specific descriptor from the CDC demos, bootloaders and projects
* *
* \section Sec_ChangeLog100219 Version 100219 * \section Sec_ChangeLog100219 Version 100219

Loading…
Cancel
Save