WinCE Broadcom stack FindAttribute SDP_DISC_ATTTR_VAL 256Bytes limit

FindAttribute() is an API part of the Broadcom Bluetooth Stack SDK, that Searches the discovery record for the specified attribute ID and, if found, returns the attribute values to the caller.

Prototype
BOOL FindAttribute (UINT16 attr_id, SDP_DISC_ATTTR_VAL *p_val);
Parameters
attr_id The attribute ID being searched for.
p_val The location where the function should store the attribute.
Returns TRUE if the attribute was found. FALSE otherwise.

The structure SDP_DISC_ATTTR_VAL is defined in BtIfDefinitions.h. as following:

  1.  
  2. #define MAX_SEQ_ENTRIES 20
  3. #define MAX_ATTR_LEN 256
  4.  
  5. typedef struct
  6. {
  7. int num_elem;
  8.  
  9. struct
  10. {
  11. #define ATTR_TYPE_INT 0 // Attribute value is an integer
  12. #define ATTR_TYPE_TWO_COMP 1 // Attribute value is an 2's complement integer
  13. #define ATTR_TYPE_UUID 2 // Attribute value is a UUID
  14. #define ATTR_TYPE_BOOL 3 // Attribute value is a boolean
  15. #define ATTR_TYPE_ARRAY 4 // Attribute value is an array of bytes
  16.  
  17. int type;
  18. int len; // Length of the attribute
  19. BOOL start_of_seq; // TRUE for each start of sequence
  20. union
  21. {
  22. unsigned char u8; // 8-bit integer
  23. unsigned short u16; // 16-bit integer
  24. unsigned long u32; // 32-bit integer
  25. BOOL b; // Boolean
  26. unsigned char array[MAX_ATTR_LEN]; // Variable length array
  27. } val;
  28.  
  29. } elem [MAX_SEQ_ENTRIES];
  30.  
  31. } SDP_DISC_ATTTR_VAL;
  32.  

As you can see the "array" member of the union can only take 256bytes. The SDK has a note:

the structure allows for an attribute that is a sequence of up to MAX_SEQ_ENTRIES (=20), each with a value array up to MAX_ATTR_LEN (=256) bytes long. Nested sequences up to 5 levels deep are supported.

Assuming you need to retrieve an attribute that is bigger then 256 bytes, the first 256 bytes will be stored in elem[i].var.array and the following bytes in &elem[i+1], &elem[i+2], and so on.
Please note that the first set of 256 bytes is stored in elem[i].var.array, but for the rest, the whole elem structure is used, meaning you will have 268bytes (type, len and start_of_seq are included).

A quick calculation shows you can receive an attribute consisting of an array of maximum: 256+19*268bytes.

Good thing there is a way of getting more then 256 bytes!

  1.  
  2. BYTE *pRDData = (BYTE *)malloc(MAX_RD_SIZE * sizeof(BYTE));
  3. memset(pRDData,0,MAX_RD_SIZE * sizeof(BYTE));
  4. nRDSize = p_val.elem[i].len;
  5. if (nRDSize < MAX_ATTR_LEN)
  6. {
  7. memcpy(pRDData, p_val.elem[i].val.array, nRDSize);
  8.  
  9. }
  10. else
  11. {
  12. BYTE nBlocks = 0;
  13. memcpy(pRDData, p_val.elem[i].val.array, MAX_ATTR_LEN);
  14. nBlocks++; //we've just copied the first block
  15. for (int j=0;j<nRDSize / MAX_ATTR_LEN;j++)
  16. {
  17. memcpy(pRDData + nBlocks*MAX_ATTR_LEN, &p_val.elem[i+nBlocks], MAX_ATTR_LEN);
  18. nBlocks++; //another block has been copied
  19. }
  20. memcpy(pRDData + nBlocks*MAX_ATTR_LEN, &p_val.elem[i+nBlocks], nRDSize % MAX_ATTR_LEN);
  21. }
  22.  

Related Post

Leave a Reply