Service Discovery ServiceSearchAttribute requests require the response to be grouped by UUID, so the response can't be generated as the attributes are read in. Buffer both UUIDs and Attributes instead and generate the response afterwards.

pull/1469/head
Dean Camera 15 years ago
parent 3e515cdfa8
commit 83b5c916c6

@ -64,7 +64,7 @@ const ServiceAttributeTable_t RFCOMM_Attribute_Table[] PROGMEM =
/** Master service table, listing all supported services (and their attribute tables) of the device, including /** Master service table, listing all supported services (and their attribute tables) of the device, including
* each service's UUID. * each service's UUID.
*/ */
const ServiceTable_t SDP_Services_Table[] = const ServiceTable_t SDP_Services_Table[] PROGMEM =
{ {
{ // 128-bit UUID for the SDP service { // 128-bit UUID for the SDP service
.UUID = {BASE_96BIT_UUID, 0x01, 0x00, 0x00, 0x00}, .UUID = {BASE_96BIT_UUID, 0x01, 0x00, 0x00, 0x00},
@ -77,7 +77,7 @@ const ServiceTable_t SDP_Services_Table[] =
}; };
/** Base UUID value common to all standardized Bluetooth services */ /** Base UUID value common to all standardized Bluetooth services */
const uint8_t BaseUUID[] = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x00}; const uint8_t BaseUUID[] PROGMEM = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x00};
/** Main Service Discovery Protocol packet processing routine. This function processes incomming SDP packets from /** Main Service Discovery Protocol packet processing routine. This function processes incomming SDP packets from
@ -133,6 +133,10 @@ static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPH
uint16_t MaxAttributeSize = ServiceDiscovery_Read16BitParameter(&CurrentParameter); uint16_t MaxAttributeSize = ServiceDiscovery_Read16BitParameter(&CurrentParameter);
BT_SDP_DEBUG(2, "-- Max Return Attribute Bytes: 0x%04X", MaxAttributeSize); BT_SDP_DEBUG(2, "-- Max Return Attribute Bytes: 0x%04X", MaxAttributeSize);
uint16_t AttributeList[20][2];
uint8_t TotalAttributes = ServiceDiscovery_GetAttributeList(AttributeList, &CurrentParameter);
BT_SDP_DEBUG(2, "-- Total Attributes: %d", TotalAttributes);
struct struct
{ {
SDP_PDUHeader_t SDPHeader; SDP_PDUHeader_t SDPHeader;
@ -140,12 +144,38 @@ static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPH
uint8_t ResponseData[100]; uint8_t ResponseData[100];
} ResponsePacket; } ResponsePacket;
uint8_t* CurrResponsePos = ResponsePacket.ResponseData;
if (MaxAttributeSize > sizeof(ResponsePacket.ResponseData)) if (MaxAttributeSize > sizeof(ResponsePacket.ResponseData))
MaxAttributeSize = sizeof(ResponsePacket.ResponseData); MaxAttributeSize = sizeof(ResponsePacket.ResponseData);
ResponsePacket.AttributeListByteCount = ServiceDiscovery_ProcessAttributes(UUIDList, TotalUUIDs, uint16_t* TotalResponseSize = ServiceDiscovery_AddDataElementHeader(&CurrResponsePos, SDP_DATATYPE_Sequence);
ResponsePacket.ResponseData, for (uint8_t CurrUUIDItem = 0; CurrUUIDItem < TotalUUIDs; CurrUUIDItem++)
MaxAttributeSize, &CurrentParameter); {
ServiceAttributeTable_t* AttributeTable = ServiceDiscovery_GetAttributeTable(UUIDList[CurrUUIDItem]);
if (AttributeTable == NULL)
continue;
uint16_t* CurrentUUIDResponseSize = ServiceDiscovery_AddDataElementHeader(&CurrResponsePos, SDP_DATATYPE_Sequence);
*TotalResponseSize += sizeof(ServiceAttributeData16Bit_t);
for (uint8_t CurrAttribute = 0; CurrAttribute < TotalAttributes; CurrAttribute++)
{
uint16_t* AttributeIDRange = AttributeList[CurrAttribute];
for (uint16_t CurrAttributeID = AttributeIDRange[0]; CurrAttributeID < AttributeIDRange[1]; CurrAttributeID++)
{
void* AttributeValue = ServiceDiscovery_GetAttributeValue(AttributeTable, CurrAttributeID);
if (AttributeValue == NULL)
continue;
BT_SDP_DEBUG(2, "GUID + ATTRIBUTE FOUND");
}
}
}
ResponsePacket.AttributeListByteCount = (*TotalResponseSize + sizeof(ServiceAttributeData16Bit_t));
ResponsePacket.SDPHeader.PDU = SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE; ResponsePacket.SDPHeader.PDU = SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE;
ResponsePacket.SDPHeader.TransactionID = SDPHeader->TransactionID; ResponsePacket.SDPHeader.TransactionID = SDPHeader->TransactionID;
ResponsePacket.SDPHeader.ParameterLength = (ResponsePacket.AttributeListByteCount + sizeof(ResponsePacket.AttributeListByteCount)); ResponsePacket.SDPHeader.ParameterLength = (ResponsePacket.AttributeListByteCount + sizeof(ResponsePacket.AttributeListByteCount));
@ -154,53 +184,55 @@ static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPH
Channel); Channel);
} }
static uint8_t ServiceDiscovery_ProcessAttributes(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs, uint8_t* ResponseBuffer, static void* ServiceDiscovery_GetAttributeValue(ServiceAttributeTable_t* AttributeTable, uint16_t AttributeID)
uint8_t MaxResponseSize, const void** CurrentParameter) {
while ((void*)pgm_read_word(&AttributeTable->Data) != NULL)
{
if (pgm_read_word(&AttributeTable->AttributeID) == AttributeID)
return &AttributeTable->Data;
AttributeTable++;
}
return NULL;
}
static ServiceAttributeTable_t* ServiceDiscovery_GetAttributeTable(uint8_t* UUID)
{
for (uint8_t CurrTableItem = 0; CurrTableItem < (sizeof(SDP_Services_Table) / sizeof(ServiceTable_t)); CurrTableItem++)
{
if (!(memcmp_P(UUID, SDP_Services_Table[CurrTableItem].UUID, UUID_SIZE_BYTES)))
return (ServiceAttributeTable_t*)pgm_read_word(&SDP_Services_Table[CurrTableItem].AttributeTable);
}
return NULL;
}
static uint8_t ServiceDiscovery_GetAttributeList(uint16_t AttributeList[][2], const void** CurrentParameter)
{ {
uint16_t* AttributeResponseSize = ServiceDiscovery_AddDataElementHeader(&ResponseBuffer, SDP_DATATYPE_UnsignedInt);
uint8_t ElementHeaderSize; uint8_t ElementHeaderSize;
uint8_t TotalAttributes = 0;
uint16_t AttributeIDListLength = ServiceDiscovery_GetDataElementSize(CurrentParameter, &ElementHeaderSize); uint16_t AttributeIDListLength = ServiceDiscovery_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
BT_SDP_DEBUG(2, "-- Total Attribute Length: 0x%04X", AttributeIDListLength); BT_SDP_DEBUG(2, "-- Total Attribute Length: 0x%04X", AttributeIDListLength);
while (AttributeIDListLength) while (AttributeIDListLength)
{ {
uint8_t AttributeLength = ServiceDiscovery_GetDataElementSize(CurrentParameter, &ElementHeaderSize); uint8_t AttributeLength = ServiceDiscovery_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
uint32_t Attribute = 0;
memcpy(&((char*)&Attribute)[sizeof(uint32_t) - AttributeLength], *CurrentParameter, AttributeLength); memcpy(&AttributeList[TotalAttributes][0], *CurrentParameter, AttributeLength);
BT_SDP_DEBUG(2, "-- Attribute(%d): 0x%08lX", AttributeLength, Attribute); if (AttributeLength == 2)
memcpy(&AttributeList[TotalAttributes][1], *CurrentParameter, 2);
*AttributeResponseSize += ServiceDiscovery_GetAttribute(UUIDList, TotalUUIDs, Attribute, &ResponseBuffer, BT_SDP_DEBUG(2, "-- Attribute: 0x%04X-0x%04X", AttributeList[TotalAttributes][0], AttributeList[TotalAttributes][1]);
(MaxResponseSize - *AttributeResponseSize));
TotalAttributes++;
AttributeIDListLength -= (AttributeLength + ElementHeaderSize); AttributeIDListLength -= (AttributeLength + ElementHeaderSize);
*CurrentParameter += AttributeLength; *CurrentParameter += AttributeLength;
} }
return *AttributeResponseSize; return TotalAttributes;
}
static uint8_t ServiceDiscovery_GetAttribute(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs, const uint32_t Attribute,
uint8_t** DataBuffer, uint8_t BufferLen)
{
for (uint8_t CurrTableItem = 0; CurrTableItem < (sizeof(SDP_Services_Table) / sizeof(ServiceTable_t)); CurrTableItem++)
{
for (uint8_t CurrUUIDIndex = 0; CurrUUIDIndex < TotalUUIDs; CurrUUIDIndex++)
{
if (!(memcmp(SDP_Services_Table[CurrTableItem].UUID, UUIDList[CurrUUIDIndex], UUID_SIZE_BYTES)))
{
const ServiceAttributeTable_t* AttributeTable = SDP_Services_Table[CurrTableItem].AttributeTable;
// TODO: Process attribute table
BT_SDP_DEBUG(2, "FOUND UUID IN TABLE");
break;
}
}
}
return 0;
} }
static uint8_t ServiceDiscovery_GetUUIDList(uint8_t UUIDList[][UUID_SIZE_BYTES], const void** CurrentParameter) static uint8_t ServiceDiscovery_GetUUIDList(uint8_t UUIDList[][UUID_SIZE_BYTES], const void** CurrentParameter)
@ -215,7 +247,7 @@ static uint8_t ServiceDiscovery_GetUUIDList(uint8_t UUIDList[][UUID_SIZE_BYTES],
uint8_t* CurrentUUID = UUIDList[TotalUUIDs++]; uint8_t* CurrentUUID = UUIDList[TotalUUIDs++];
uint8_t UUIDLength = ServiceDiscovery_GetDataElementSize(CurrentParameter, &ElementHeaderSize); uint8_t UUIDLength = ServiceDiscovery_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
memcpy(CurrentUUID, BaseUUID, sizeof(BaseUUID)); memcpy_P(CurrentUUID, BaseUUID, sizeof(BaseUUID));
memcpy(&CurrentUUID[(UUIDLength <= 4) ? (UUID_SIZE_BYTES - 4) : 0], *CurrentParameter, UUIDLength); memcpy(&CurrentUUID[(UUIDLength <= 4) ? (UUID_SIZE_BYTES - 4) : 0], *CurrentParameter, UUIDLength);
BT_SDP_DEBUG(2, "-- UUID (%d): 0x%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", BT_SDP_DEBUG(2, "-- UUID (%d): 0x%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",

@ -195,11 +195,9 @@
static void ServiceDiscovery_ProcessServiceAttribute(SDP_PDUHeader_t* SDPHeader, Bluetooth_Channel_t* Channel); static void ServiceDiscovery_ProcessServiceAttribute(SDP_PDUHeader_t* SDPHeader, Bluetooth_Channel_t* Channel);
static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPHeader, Bluetooth_Channel_t* Channel); static void ServiceDiscovery_ProcessServiceSearchAttribute(SDP_PDUHeader_t* SDPHeader, Bluetooth_Channel_t* Channel);
static uint8_t ServiceDiscovery_ProcessAttributes(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs, static void* ServiceDiscovery_GetAttributeValue(ServiceAttributeTable_t* AttributeTable, uint16_t AttributeID);
uint8_t* ResponseBuffer, uint8_t MaxResponseSize, static ServiceAttributeTable_t* ServiceDiscovery_GetAttributeTable(uint8_t* UUID);
const void** CurrentParameter); static uint8_t ServiceDiscovery_GetAttributeList(uint16_t AttributeList[][2], const void** CurrentParameter);
static uint8_t ServiceDiscovery_GetAttribute(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs,
const uint32_t Attribute, uint8_t** DataBuffer, uint8_t BufferLen);
static uint8_t ServiceDiscovery_GetUUIDList(uint8_t UUIDList[][UUID_SIZE_BYTES], const void** CurrentParameter); static uint8_t ServiceDiscovery_GetUUIDList(uint8_t UUIDList[][UUID_SIZE_BYTES], const void** CurrentParameter);
static uint32_t ServiceDiscovery_GetDataElementSize(const void** AttributeHeader, uint8_t* ElementHeaderSize); static uint32_t ServiceDiscovery_GetDataElementSize(const void** AttributeHeader, uint8_t* ElementHeaderSize);
#endif #endif

Loading…
Cancel
Save