Much faster attribute range lookup - look through short list of attributes and compar...
authorDean Camera <dean@fourwalledcubicle.com>
Tue, 1 Jun 2010 11:07:29 +0000 (11:07 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Tue, 1 Jun 2010 11:07:29 +0000 (11:07 +0000)
Cleanups to SDP code. Add missing RFCOMM language base ID offset attribute. Fix incorrect definition of the SWAPENDIAN_32() macro.

Demos/Host/Incomplete/BluetoothHost/Lib/SDPServices.c
Demos/Host/Incomplete/BluetoothHost/Lib/SDPServices.h
Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c

index 537c81f..2530231 100644 (file)
@@ -38,8 +38,8 @@ const struct
 \r
 const struct\r
 {\r
-       uint8_t     Header;\r
-       uint16_t    Size;\r
+       uint8_t    Header;\r
+       uint16_t   Size;\r
        ItemUUID_t UUIDList[];\r
 } PROGMEM SDP_Attribute_ServiceClassIDs =\r
        {\r
@@ -50,32 +50,32 @@ const struct
                                {.Header = (SDP_DATATYPE_UUID | SDP_DATASIZE_128Bit), .UUID = {BASE_80BIT_UUID, {0x00, 0x00, 0x00, 0x00, 0x10, 0x00}},}\r
                        }\r
        };\r
-\r
+       \r
 const struct\r
 {\r
        uint8_t     Header;\r
        uint8_t     Size;\r
-       Item16Bit_t VersionList[];\r
-} PROGMEM SDP_Attribute_Version =\r
+       Item16Bit_t OffsetList[];\r
+} PROGMEM SDP_Attribute_LangOffset =\r
        {\r
                .Header = (SDP_DATATYPE_Sequence | SDP_DATASIZE_Variable8Bit),\r
                .Size   = (sizeof(Item16Bit_t) * 1),\r
-               .VersionList =\r
+               .OffsetList =\r
                        {\r
                                {.Header = (SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_16Bit), .Value = SWAPENDIAN_16(0x0100)}\r
                        }\r
-       };\r
+       };      \r
 \r
 const struct\r
 {\r
        uint8_t     Header;\r
        uint8_t     Size;\r
-       Item16Bit_t OffsetList[];\r
-} PROGMEM SDP_Attribute_LangOffset =\r
+       Item16Bit_t VersionList[];\r
+} PROGMEM SDP_Attribute_Version =\r
        {\r
                .Header = (SDP_DATATYPE_Sequence | SDP_DATASIZE_Variable8Bit),\r
                .Size   = (sizeof(Item16Bit_t) * 1),\r
-               .OffsetList =\r
+               .VersionList =\r
                        {\r
                                {.Header = (SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_16Bit), .Value = SWAPENDIAN_16(0x0100)}\r
                        }\r
@@ -83,9 +83,9 @@ const struct
 \r
 const struct\r
 {\r
-       uint8_t     Header;\r
-       uint8_t     Size;\r
-       char        Text[];\r
+       uint8_t Header;\r
+       uint8_t Size;\r
+       char    Text[];\r
 } PROGMEM SDP_Attribute_ServiceName =\r
        {\r
                .Header = (SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit),\r
@@ -95,9 +95,9 @@ const struct
 \r
 const struct\r
 {\r
-       uint8_t     Header;\r
-       uint8_t     Size;\r
-       char        Text[];\r
+       uint8_t Header;\r
+       uint8_t Size;\r
+       char    Text[];\r
 } PROGMEM SDP_Attribute_ServiceDescription =\r
        {\r
                .Header = (SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit),\r
@@ -110,8 +110,8 @@ const ServiceAttributeTable_t SDP_Attribute_Table[] PROGMEM =
        {\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE, .Data = &SDP_Attribute_ServiceHandle      },\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICECLASSIDS,     .Data = &SDP_Attribute_ServiceClassIDs    },\r
-               {.AttributeID = SDP_ATTRIBUTE_ID_VERSION,             .Data = &SDP_Attribute_Version            },\r
                {.AttributeID = SDP_ATTRIBUTE_ID_LANGIDOFFSET,        .Data = &SDP_Attribute_LangOffset         },\r
+               {.AttributeID = SDP_ATTRIBUTE_ID_VERSION,             .Data = &SDP_Attribute_Version            },\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICENAME,         .Data = &SDP_Attribute_ServiceName        },\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICEDESCRIPTION,  .Data = &SDP_Attribute_ServiceDescription },\r
 \r
@@ -126,8 +126,8 @@ const struct
 \r
 const struct\r
 {\r
-       uint8_t     Header;\r
-       uint16_t    Size;\r
+       uint8_t    Header;\r
+       uint16_t   Size;\r
        ItemUUID_t UUIDList[];\r
 } PROGMEM RFCOMM_Attribute_ServiceClassIDs =\r
        {\r
@@ -143,7 +143,22 @@ const struct
 {\r
        uint8_t     Header;\r
        uint8_t     Size;\r
-       char        Text[];\r
+       Item16Bit_t OffsetList[];\r
+} PROGMEM RFCOMM_Attribute_LangOffset =\r
+       {\r
+               .Header = (SDP_DATATYPE_Sequence | SDP_DATASIZE_Variable8Bit),\r
+               .Size   = (sizeof(Item16Bit_t) * 1),\r
+               .OffsetList =\r
+                       {\r
+                               {.Header = (SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_16Bit), .Value = SWAPENDIAN_16(0x0100)}\r
+                       }\r
+       };\r
+\r
+const struct\r
+{\r
+       uint8_t Header;\r
+       uint8_t Size;\r
+       char    Text[];\r
 } PROGMEM RFCOMM_Attribute_ServiceName =\r
        {\r
                .Header = (SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit),\r
@@ -153,9 +168,9 @@ const struct
 \r
 const struct\r
 {\r
-       uint8_t     Header;\r
-       uint8_t     Size;\r
-       char        Text[];\r
+       uint8_t Header;\r
+       uint8_t Size;\r
+       char    Text[];\r
 } PROGMEM RFCOMM_Attribute_ServiceDescription =\r
        {\r
                .Header = (SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit),\r
@@ -167,6 +182,7 @@ const ServiceAttributeTable_t RFCOMM_Attribute_Table[] PROGMEM =
        {\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE, .Data = &RFCOMM_Attribute_ServiceHandle      },\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICECLASSIDS,     .Data = &RFCOMM_Attribute_ServiceClassIDs    },\r
+               {.AttributeID = SDP_ATTRIBUTE_ID_LANGIDOFFSET,        .Data = &RFCOMM_Attribute_LangOffset         },\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICENAME,         .Data = &RFCOMM_Attribute_ServiceName        },\r
                {.AttributeID = SDP_ATTRIBUTE_ID_SERVICEDESCRIPTION,  .Data = &RFCOMM_Attribute_ServiceDescription },\r
 \r
index 92fe226..0fd0aa4 100644 (file)
                #define SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE    0x0000\r
                #define SDP_ATTRIBUTE_ID_SERVICECLASSIDS        0x0001\r
                #define SDP_ATTRIBUTE_ID_LANGIDOFFSET           0x0006\r
-               #define SDP_ATTRIBUTE_ID_AVAILABILITY           0x0008\r
                #define SDP_ATTRIBUTE_ID_VERSION                0x0200\r
                #define SDP_ATTRIBUTE_ID_SERVICENAME            0x0100\r
                #define SDP_ATTRIBUTE_ID_SERVICEDESCRIPTION     0x0101\r
                \r
                #define SWAPENDIAN_16(x)                        ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))\r
-               #define SWAPENDIAN_32(x)                        (SWAPENDIAN_16(((x) & 0xFFFF0000) >> 16) | SWAPENDIAN_16(((x) & 0x0000FFFF) << 16))\r
+               #define SWAPENDIAN_32(x)                        ((((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | \\r
+                                                                (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24))\r
                \r
                /** Terminator for a service attribute table of type \ref ServiceAttributeTable_t. */\r
                #define SERVICE_ATTRIBUTE_TABLE_TERMINATOR      {.Data = NULL}\r
index 82cb60e..3731e1f 100644 (file)
@@ -116,11 +116,10 @@ static void SDP_ProcessServiceSearch(const SDP_PDUHeader_t* const SDPHeader, Blu
        /* Search through the list of UUIDs one at a time looking for matching search Attributes */
        for (uint8_t CurrUUIDItem = 0; CurrUUIDItem < TotalUUIDs; CurrUUIDItem++)
        {
+               ServiceAttributeTable_t* AttributeTable;
+
                /* Retrieve the attribute table of the current search UUID from the global UUID table if it exists */
-               ServiceAttributeTable_t* AttributeTable = SDP_GetAttributeTable(UUIDList[CurrUUIDItem]);
-               
-               /* If the UUID does not exist in the global UUID table, continue on to the next search UUID */
-               if (AttributeTable == NULL)
+               if ((AttributeTable = SDP_GetAttributeTable(UUIDList[CurrUUIDItem])) == NULL)
                  continue;
                  
                BT_SDP_DEBUG(2, " -- Found UUID %d in table", CurrUUIDItem);
@@ -216,9 +215,12 @@ static void SDP_ProcessServiceAttribute(const SDP_PDUHeader_t* const SDPHeader,
                /* Get the size of the header for the Service Record Handle */
                uint8_t AttrHeaderSize;
                SDP_GetLocalAttributeContainerSize(ServiceRecord, &AttrHeaderSize);
-
+               
+               /* Retrieve the endian-swapped service handle of the current service being examined */
+               uint32_t CurrServiceHandle = SwapEndian_32(pgm_read_dword(ServiceRecord + AttrHeaderSize));
+               
                /* Check if the current service in the service table has the requested service handle */
-               if (memcmp_P(ServiceRecord + AttrHeaderSize, &ServiceHandle, sizeof(uint32_t)) == 0)
+               if (ServiceHandle == CurrServiceHandle)
                {
                        *TotalResponseSize += SDP_AddListedAttributesToResponse(CurrAttributeTable, AttributeList, TotalAttributes,
                                                                            &CurrResponsePos);
@@ -300,15 +302,15 @@ static void SDP_ProcessServiceSearchAttribute(const SDP_PDUHeader_t* const SDPHe
        /* Search through the list of UUIDs one at a time looking for matching search Attributes */
        for (uint8_t CurrUUIDItem = 0; CurrUUIDItem < TotalUUIDs; CurrUUIDItem++)
        {
+               ServiceAttributeTable_t* AttributeTable;
+
                /* Retrieve the attribute table of the current search UUID from the global UUID table if it exists */
-               ServiceAttributeTable_t* AttributeTable = SDP_GetAttributeTable(UUIDList[CurrUUIDItem]);
-               
-               /* If the UUID does not exist in the global UUID table, continue on to the next search UUID */
-               if (AttributeTable == NULL)
+               if ((AttributeTable = SDP_GetAttributeTable(UUIDList[CurrUUIDItem])) == NULL)
                  continue;
                  
                BT_SDP_DEBUG(2, " -- Found UUID %d in table", CurrUUIDItem);
 
+               /* Add the listed attributes for the found UUID to the response */
                *TotalResponseSize += SDP_AddListedAttributesToResponse(AttributeTable, AttributeList, TotalAttributes,
                                                                        &CurrResponsePos);
        }
@@ -361,21 +363,24 @@ static uint16_t SDP_AddListedAttributesToResponse(const ServiceAttributeTable_t*
        for (uint8_t CurrAttribute = 0; CurrAttribute < TotalAttributes; CurrAttribute++)
        {
                uint16_t* AttributeIDRange = AttributeList[CurrAttribute];
-       
-               /* Look in the current Attribute Range for a matching Attribute ID in the UUID's Attribute table */
-               for (uint32_t CurrAttributeID = AttributeIDRange[0]; CurrAttributeID <= AttributeIDRange[1]; CurrAttributeID++)
+               void*     AttributeValue;
+               
+               /* Look through the current service's attribute list, examining all the attributes */
+               while ((AttributeValue = (void*)pgm_read_word(&AttributeTable->Data)) != NULL)
                {
-                       /* Retrieve a PROGMEM pointer to the value of the current Attribute ID, if it exists in the UUID's Attribute table */
-                       const void* AttributeValue = SDP_GetAttributeValue(AttributeTable, CurrAttributeID);
-                       
-                       /* If the Attribute does not exist in the current UUID's Attribute table, continue to the next Attribute ID */
-                       if (AttributeValue == NULL)
-                         continue;
-                       
-                       BT_SDP_DEBUG(2, " -- Add Attribute 0x%04X", CurrAttributeID);
+                       /* Get the current Attribute's ID from the current attribute table entry */
+                       uint16_t CurrAttributeID = pgm_read_word(&AttributeTable->AttributeID);
+
+                       /* Check if the current Attribute's ID is within the current Attribute range */
+                       if ((CurrAttributeID >= AttributeIDRange[0]) && (CurrAttributeID <= AttributeIDRange[1]))
+                       {
+                               BT_SDP_DEBUG(2, " -- Add Attribute 0x%04X", CurrAttributeID);
 
-                       /* Increment the current UUID's returned Attribute container size by the number of added bytes */
-                       *AttributeListSize += SDP_AddAttributeToResponse(CurrAttributeID, AttributeValue, BufferPos);
+                               /* Increment the current UUID's returned Attribute container size by the number of added bytes */
+                               *AttributeListSize += SDP_AddAttributeToResponse(CurrAttributeID, AttributeValue, BufferPos);                   
+                       }
+                       
+                       AttributeTable++;
                }
 
                /* Increment the outer container size by the number of added bytes */
@@ -551,12 +556,8 @@ static uint8_t SDP_GetUUIDList(uint8_t UUIDList[][UUID_SIZE_BYTES], const void**
                /* Copy over the base UUID value to the free UUID slot in the list */
                memcpy_P(CurrentUUID, &BaseUUID, sizeof(BaseUUID));
 
-               /* Copy over UUID from the container to the free slot - if a short UUID (<= 4 bytes) it replaces the lower
-                  4 bytes of the base UUID, otherwise it replaces the UUID completely */
-               if (UUIDLength <= 4)
-                 memcpy(&CurrentUUID[UUID_SIZE_BYTES - UUIDLength], *CurrentParameter, UUIDLength);
-               else
-                 memcpy(&CurrentUUID[0], *CurrentParameter, UUIDLength);               
+               /* Copy over UUID from the container to the free slot */
+               memcpy(&CurrentUUID[UUID_SIZE_BYTES - UUIDLength], *CurrentParameter, UUIDLength);
                
                BT_SDP_DEBUG(2, "-- UUID (%d): %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
                                UUIDLength,