+ uint8_t ElementHeaderSize;
+ uint8_t TotalUUIDs = 0;
+
+ /* Retrieve the total size of the UUID container, and unwrap the outer Data Element Sequence container */
+ uint16_t ServicePatternLength = SDP_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
+ BT_SDP_DEBUG(2, "-- Total UUID Length: 0x%04X", ServicePatternLength);
+ while (ServicePatternLength)
+ {
+ /* Retrieve the size of the next UUID in the container and get a pointer to the next free UUID element in the list */
+ uint8_t* CurrentUUID = UUIDList[TotalUUIDs++];
+ uint8_t UUIDLength = SDP_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
+
+ /* 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 */
+ 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",
+ UUIDLength,
+ CurrentUUID[15], CurrentUUID[14], CurrentUUID[13], CurrentUUID[12],
+ CurrentUUID[11], CurrentUUID[10], CurrentUUID[9], CurrentUUID[8],
+ CurrentUUID[7], CurrentUUID[6], CurrentUUID[5], CurrentUUID[4],
+ CurrentUUID[3], CurrentUUID[2], CurrentUUID[1], CurrentUUID[0]);
+
+ ServicePatternLength -= (UUIDLength + ElementHeaderSize);
+ *CurrentParameter += UUIDLength;
+ }
+
+ return TotalUUIDs;
+}
+
+/** Retrieves the total size of the given locally stored (in PROGMEM) attribute Data Element container.
+ *
+ * \param[in] AttributeData Pointer to the start of the Attribute container, located in PROGMEM
+ *
+ * \return Size in bytes of the entire attribute container, including the header
+ */
+static uint32_t SDP_GetLocalAttributeContainerSize(const void* const AttributeData, uint8_t* const HeaderSize)
+{
+ /* Fetch the size of the Data Element structure from the header */
+ uint8_t SizeIndex = (pgm_read_byte(AttributeData) & 0x07);
+
+ /* Convert the Data Element size index into a size in bytes */
+ switch (SizeIndex)
+ {
+ case SDP_DATASIZE_Variable8Bit:
+ *HeaderSize = (1 + sizeof(uint8_t));
+ return pgm_read_byte(AttributeData + 1);
+ case SDP_DATASIZE_Variable16Bit:
+ *HeaderSize = (1 + sizeof(uint16_t));
+ return pgm_read_word(AttributeData + 1);
+ case SDP_DATASIZE_Variable32Bit:
+ *HeaderSize = (1 + sizeof(uint32_t));
+ return pgm_read_dword(AttributeData + 1);
+ default:
+ *HeaderSize = 1;
+ return (1 << SizeIndex);
+ }
+
+ return 0;
+}
+
+/** Retrieves the size of a Data Element container from the current input buffer, and advances the input buffer
+ * pointer to the start of the Data Element's contents.
+ *
+ * \param[in, out] DataElementHeader Pointer to the start of a Data Element header
+ * \param[out] ElementHeaderSize Size in bytes of the header that was skipped
+ *
+ * \return Size in bytes of the Data Element container's contents, minus the header
+ */
+static uint32_t SDP_GetDataElementSize(const void** const DataElementHeader, uint8_t* const ElementHeaderSize)
+{
+ /* Fetch the size of the Data Element structure from the header, increment the current buffer pos */