From 559af022041942be21d7cabd398639f4d6db52ea Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Tue, 22 Jun 2010 07:55:02 +0000
Subject: [PATCH] Use a bitmask instead of an array of bools in the SDP UUID
 List matching algorithm to reduce the compiled code size and stack used.

---
 Demos/Host/Incomplete/BluetoothHost/Lib/SDP.c | 33 +++++++++----------
 Demos/Host/Incomplete/BluetoothHost/Lib/SDP.h |  2 +-
 2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.c b/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.c
index 0daf8e24e..d01225152 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.c
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.c
@@ -458,27 +458,20 @@ static void* SDP_GetAttributeValue(const ServiceAttributeTable_t* AttributeTable
 static bool SDP_SearchServiceTable(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs,
 			                       const ServiceAttributeTable_t* CurrAttributeTable)
 {
-	bool UUIDMatch[TotalUUIDs];	
-	
-	/* Set all the match flags to false (not matched) before starting the search */
-	memset(UUIDMatch, false, sizeof(UUIDMatch));
-
 	const void* CurrAttribute;
+	uint16_t    UUIDMatchFlags = 0;
 	
 	/* Search through the current attribute table, checking each attribute value for UUID matches */
 	while ((CurrAttribute = pgm_read_ptr(&CurrAttributeTable->Data)) != NULL)
 	{
-		SDP_CheckUUIDMatch(UUIDList, TotalUUIDs, UUIDMatch, CurrAttribute);
+		SDP_CheckUUIDMatch(UUIDList, TotalUUIDs, &UUIDMatchFlags, CurrAttribute);
 		CurrAttributeTable++;
 	}
 
 	/* Determine how many UUID matches in the list we have found */
-	uint8_t UUIDMatches = 0;
-	for (uint8_t i = 0; i < TotalUUIDs; i++)
-	{
-		if (UUIDMatch[i])
-		  UUIDMatches++;
-	}
+	uint8_t UUIDMatches;
+	for (UUIDMatches = 0; UUIDMatchFlags; UUIDMatches++)
+	  UUIDMatchFlags &= (UUIDMatchFlags - 1);
 	
 	/* If all UUIDs have been matched to the current service, return true */
 	return (UUIDMatches == TotalUUIDs);
@@ -494,7 +487,7 @@ static bool SDP_SearchServiceTable(uint8_t UUIDList[][UUID_SIZE_BYTES], const ui
  *
  *  \return True if all the UUIDs given in the UUID list appear in the given attribute table, false otherwise
  */
-static void SDP_CheckUUIDMatch(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs, bool UUIDMatch[],
+static void SDP_CheckUUIDMatch(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs, uint16_t* UUIDMatchFlags,
                                const void* CurrAttribute)
 {
 	uint8_t CurrAttributeType = (pgm_read_byte(CurrAttribute) & ~0x07);
@@ -502,16 +495,20 @@ static void SDP_CheckUUIDMatch(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_
 	/* Check the data type of the current attribute value - if UUID, compare, if Sequence, unwrap and recurse */
 	if (CurrAttributeType == SDP_DATATYPE_UUID)
 	{
+		uint16_t CurrUUIDMatchMask = (1 << 0);
+	
 		/* Look for matches in the UUID list against the current attribute UUID value */
 		for (uint8_t i = 0; i < TotalUUIDs; i++)
 		{
 			/* Check if the current unmatched UUID is identical to the search UUID */
-			if (!(UUIDMatch[i]) && !(memcmp_P(UUIDList[i], (CurrAttribute + 1), UUID_SIZE_BYTES)))
+			if (!(*UUIDMatchFlags & CurrUUIDMatchMask) && !(memcmp_P(UUIDList[i], (CurrAttribute + 1), UUID_SIZE_BYTES)))
 			{
 				/* Indicate match found for the current attribute UUID and early-abort */
-				UUIDMatch[i] = true;
+				*UUIDMatchFlags |= CurrUUIDMatchMask;
 				break;
 			}
+			
+			CurrUUIDMatchMask <<= 1;
 		}
 	}
 	else if (CurrAttributeType == SDP_DATATYPE_Sequence)
@@ -527,8 +524,10 @@ static void SDP_CheckUUIDMatch(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_
 			uint8_t  InnerHeaderSize;
 			uint16_t InnerSize = SDP_GetLocalAttributeContainerSize(CurrAttribute, &InnerHeaderSize);
 			
-			SDP_CheckUUIDMatch(UUIDList, TotalUUIDs, UUIDMatch, CurrAttribute);
-						
+			/* Recursively search of the next element in the sequence, trying to match UUIDs with the UUID list */
+			SDP_CheckUUIDMatch(UUIDList, TotalUUIDs, UUIDMatchFlags, CurrAttribute);
+
+			/* Skip to the next element in the sequence */
 			SequenceSize  -= InnerHeaderSize + InnerSize;
 			CurrAttribute += InnerHeaderSize + InnerSize;
 		}
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.h b/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.h
index c52477527..e7d02b0ab 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.h
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/SDP.h
@@ -218,7 +218,7 @@
 
 			static bool     SDP_SearchServiceTable(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs,
 			                                       const ServiceAttributeTable_t* CurrAttributeTable);
-			static void     SDP_CheckUUIDMatch(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs, bool UUIDMatch[],
+			static void     SDP_CheckUUIDMatch(uint8_t UUIDList[][UUID_SIZE_BYTES], const uint8_t TotalUUIDs, uint16_t* UUIDMatchFlags,
 			                                   const void* CurrAttribute);
 
 			static uint8_t  SDP_GetAttributeList(uint16_t AttributeList[][2], const void** const CurrentParameter);
-- 
GitLab