Exemplo n.º 1
0
/** Recursively unwraps the given locally stored attribute (in PROGMEM space), searching for UUIDs to match against
 *  the given UUID list. As matches are found, they are indicated in the UUIDMatch flag list.
 *
 *  \param[in]      UUIDList        List of UUIDs which must be matched within the service attribute table
 *  \param[in]      TotalUUIDs      Total number of UUIDs stored in the UUID list
 *  \param[in, out] UUIDMatchFlags  Array of flags indicating which UUIDs in the list have already been matched
 *  \param[in]      CurrAttribute   Pointer to the current attribute to search through
 *
 *  \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,
                               uint16_t* const UUIDMatchFlags,
                               const void* CurrAttribute)
{
	uint8_t CurrAttributeType = (pgm_read_byte(CurrAttribute) & ~0x07);

	/* 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 (!(*UUIDMatchFlags & CurrUUIDMatchMask) && !(memcmp_P(UUIDList[i], (CurrAttribute + 1), UUID_SIZE_BYTES)))
			{
				/* Indicate match found for the current attribute UUID and early-abort */
				*UUIDMatchFlags |= CurrUUIDMatchMask;
				break;
			}

			CurrUUIDMatchMask <<= 1;
		}
	}
	else if (CurrAttributeType == SDP_DATATYPE_Sequence)
	{
		uint8_t  SequenceHeaderSize;
		uint16_t SequenceSize = SDP_GetLocalAttributeContainerSize(CurrAttribute, &SequenceHeaderSize);

		CurrAttribute += SequenceHeaderSize;

		/* Recursively unwrap the sequence container, and re-search its contents for UUIDs */
		while (SequenceSize)
		{
			uint8_t  InnerHeaderSize;
			uint16_t InnerSize = SDP_GetLocalAttributeContainerSize(CurrAttribute, &InnerHeaderSize);

			/* 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;
		}
	}
}
Exemplo n.º 2
0
/** Retrieves the Attribute table for the given UUID list if it exists.
 *
 *  \param[in] ServiceEntry  Pointer to the service entry whose attribute table is to be examined
 *  \param[in] UUIDList      List of UUIDs which must be matched within the service attribute table
 *  \param[in] TotalUUIDs    Total number of UUIDs stored in the UUID list
 *
 *  \return True if all the UUIDs given in the UUID list appear in the given attribute table, false otherwise
 */
static bool SDP_SearchServiceTable(const SDP_ServiceEntry_t* const ServiceEntry,
								   uint8_t UUIDList[][UUID_SIZE_BYTES],
                                   const uint8_t TotalUUIDs)
{
	uint16_t UUIDMatchFlags = 0;

	/* Search through the current attribute table, checking each attribute value for UUID matches */\
	for (uint8_t i = 0; i < ServiceEntry->TotalTableAttributes; i++)
	{
		const void* CurrAttribute = pgm_read_ptr(&ServiceEntry->AttributeTable[i].Data);
		SDP_CheckUUIDMatch(UUIDList, TotalUUIDs, &UUIDMatchFlags, CurrAttribute);
	}

	/* Determine how many UUID matches in the list we have found */
	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);
}
Exemplo n.º 3
0
Arquivo: SDP.c Projeto: davr/lufa-lib
/** Retrieves the Attribute table for the given UUID list if it exists.
 *
 *  \param[in] UUIDList            List of UUIDs which must be matched within the service attribute table
 *  \param[in] TotalUUIDs          Total number of UUIDs stored in the UUID list
 *  \param[in] CurrAttributeTable  Pointer to the service attribute table to search through
 *
 *  \return True if all the UUIDs given in the UUID list appear in the given attribute table, false otherwise
 */
static bool SDP_SearchServiceTable(uint8_t UUIDList[][UUID_SIZE_BYTES],
                                   const uint8_t TotalUUIDs,
			                       const ServiceAttributeTable_t* CurrAttributeTable)
{
	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, &UUIDMatchFlags, CurrAttribute);
		CurrAttributeTable++;
	}

	/* Determine how many UUID matches in the list we have found */
	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);
}