accbee5ab79a7c505955fb6e14fa8f7189b443e0
[pub/USBasp.git] / Demos / Host / Incomplete / BluetoothHost / Lib / ServiceDiscoveryProtocol.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2010.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 #define INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C
32 #include "ServiceDiscoveryProtocol.h"
33
34 /** Service Discovery Protocol attribute, indicating the service's availability. */
35 const struct
36 {
37 uint8_t Header;
38 uint8_t Data;
39 } PROGMEM SDP_Attribute_Availability = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_8Bit), 0xFF};
40
41 const struct
42 {
43 uint8_t Header;
44 uint32_t Data;
45 } PROGMEM SDP_Attribute_ServiceHandle = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_32Bit), 0x00010000};
46
47 const struct
48 {
49 uint8_t Header;
50 uint8_t Size;
51 Version_t VersionList[];
52 } PROGMEM SDP_Attribute_Version =
53 {
54 .Header = (SDP_DATATYPE_Sequence | SDP_DATASIZE_Variable8Bit),
55 .Size = (sizeof(Version_t) * 1),
56 .VersionList =
57 {
58 {.Header = (SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_16Bit), .Version = 0x0100}
59 }
60 };
61
62 const struct
63 {
64 uint8_t Header;
65 uint16_t Size;
66 ClassUUID_t UUIDList[];
67 } PROGMEM SDP_Attribute_ServiceClassIDs =
68 {
69 .Header = (SDP_DATATYPE_Sequence | SDP_DATASIZE_Variable16Bit),
70 .Size = (sizeof(ClassUUID_t) * 1),
71 .UUIDList =
72 {
73 {.Header = (SDP_DATATYPE_UUID | SDP_DATASIZE_128Bit), .UUID = {BASE_96BIT_UUID, 0x01, 0x00, 0x00, 0x00}}
74 }
75 };
76
77 /** Service Discovery Protocol attribute table, listing all supported attributes of the service. */
78 const ServiceAttributeTable_t SDP_Attribute_Table[] PROGMEM =
79 {
80 {.AttributeID = SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE, .Data = &SDP_Attribute_ServiceHandle },
81 {.AttributeID = SDP_ATTRIBUTE_ID_SERVICECLASSIDS, .Data = &SDP_Attribute_ServiceClassIDs },
82 {.AttributeID = SDP_ATTRIBUTE_ID_VERSION, .Data = &SDP_Attribute_Version },
83
84 SERVICE_ATTRIBUTE_TABLE_TERMINATOR
85 };
86
87 /** Master service table, listing all supported services (and their attribute tables) of the device, including
88 * each service's UUID.
89 */
90 const ServiceTable_t SDP_Services_Table[] PROGMEM =
91 {
92 { // 128-bit UUID for the SDP service
93 .UUID = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x01},
94 .AttributeTable = SDP_Attribute_Table,
95 },
96 };
97
98 /** Base UUID value common to all standardized Bluetooth services */
99 const uint8_t BaseUUID[] PROGMEM = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x00};
100
101
102 /** Main Service Discovery Protocol packet processing routine. This function processes incomming SDP packets from
103 * a connected Bluetooth device, and sends back appropriate responses to allow other devices to determine the
104 * services the local device exposes.
105 *
106 * \param[in] Data Incomming packet data containing the SDP request
107 * \param[in] Channel Channel the request was issued to by the remote device
108 */
109 void SDP_ProcessPacket(void* Data, Bluetooth_Channel_t* Channel)
110 {
111 SDP_PDUHeader_t* SDPHeader = (SDP_PDUHeader_t*)Data;
112 SDPHeader->ParameterLength = SwapEndian_16(SDPHeader->ParameterLength);
113
114 BT_SDP_DEBUG(1, "SDP Packet Received");
115 BT_SDP_DEBUG(2, "-- PDU ID: 0x%02X", SDPHeader->PDU);
116 BT_SDP_DEBUG(2, "-- Param Length: 0x%04X", SDPHeader->ParameterLength);
117
118 switch (SDPHeader->PDU)
119 {
120 case SDP_PDU_SERVICESEARCHREQUEST:
121 SDP_ProcessServiceSearch(SDPHeader, Channel);
122 break;
123 case SDP_PDU_SERVICEATTRIBUTEREQUEST:
124 SDP_ProcessServiceAttribute(SDPHeader, Channel);
125 break;
126 case SDP_PDU_SERVICESEARCHATTRIBUTEREQUEST:
127 SDP_ProcessServiceSearchAttribute(SDPHeader, Channel);
128 break;
129 }
130 }
131
132 /** Internal processing routine for SDP Service Search Requests.
133 *
134 * \param[in] SDPHeader Pointer to the start of the issued SDP request
135 * \param[in] Channel Pointer to the Bluetooth channel structure the request was issued to
136 */
137 static void SDP_ProcessServiceSearch(const SDP_PDUHeader_t* const SDPHeader, Bluetooth_Channel_t* const Channel)
138 {
139 BT_SDP_DEBUG(1, "<< Service Search");
140 }
141
142 /** Internal processing routine for SDP Service Attribute Requests.
143 *
144 * \param[in] SDPHeader Pointer to the start of the issued SDP request
145 * \param[in] Channel Pointer to the Bluetooth channel structure the request was issued to
146 */
147 static void SDP_ProcessServiceAttribute(const SDP_PDUHeader_t* const SDPHeader, Bluetooth_Channel_t* const Channel)
148 {
149 BT_SDP_DEBUG(1, "<< Service Attribute");
150 }
151
152 /** Internal processing routine for SDP Service Search Attribute Requests.
153 *
154 * \param[in] SDPHeader Pointer to the start of the issued SDP request
155 * \param[in] Channel Pointer to the Bluetooth channel structure the request was issued to
156 */
157 static void SDP_ProcessServiceSearchAttribute(const SDP_PDUHeader_t* const SDPHeader, Bluetooth_Channel_t* const Channel)
158 {
159 const void* CurrentParameter = ((void*)SDPHeader + sizeof(SDP_PDUHeader_t));
160
161 BT_SDP_DEBUG(1, "<< Service Search Attribute");
162
163 /* Retrieve the list of search UUIDs from the request */
164 uint8_t UUIDList[12][UUID_SIZE_BYTES];
165 uint8_t TotalUUIDs = SDP_GetUUIDList(UUIDList, &CurrentParameter);
166 BT_SDP_DEBUG(2, "-- Total UUIDs: %d", TotalUUIDs);
167
168 /* Retrieve the maximum Attribute reponse size from the request */
169 uint16_t MaxAttributeSize = *((uint16_t*)CurrentParameter);
170 CurrentParameter += sizeof(uint16_t);
171 BT_SDP_DEBUG(2, "-- Max Return Attribute Bytes: 0x%04X", MaxAttributeSize);
172
173 /* Retrieve the list of Attributes from the request */
174 uint16_t AttributeList[15][2];
175 uint8_t TotalAttributes = SDP_GetAttributeList(AttributeList, &CurrentParameter);
176 BT_SDP_DEBUG(2, "-- Total Attributes: %d", TotalAttributes);
177
178 struct
179 {
180 SDP_PDUHeader_t SDPHeader;
181 uint16_t AttributeListByteCount;
182 uint8_t ResponseData[100];
183 } ResponsePacket;
184
185 /* Create a pointer to the buffer to indicate the current location for response data to be added */
186 void* CurrResponsePos = ResponsePacket.ResponseData;
187
188 /* Clamp the maximum attribute size to the size of the allocated buffer */
189 if (MaxAttributeSize > sizeof(ResponsePacket.ResponseData))
190 MaxAttributeSize = sizeof(ResponsePacket.ResponseData);
191
192 /* Add the outer Data Element Sequence header for all of the retrieved Attributes */
193 uint16_t* TotalResponseSize = SDP_AddDataElementHeader16(&CurrResponsePos, SDP_DATATYPE_Sequence);
194
195 /* Search through the list of UUIDs one at a time looking for matching search Attributes */
196 for (uint8_t CurrUUIDItem = 0; CurrUUIDItem < TotalUUIDs; CurrUUIDItem++)
197 {
198 /* Retrieve the attribute table of the current search UUID from the global UUID table if it exists */
199 ServiceAttributeTable_t* AttributeTable = SDP_GetAttributeTable(UUIDList[CurrUUIDItem]);
200
201 /* If the UUID does not exist in the global UUID table, continue on to the next search UUID */
202 if (AttributeTable == NULL)
203 continue;
204
205 BT_SDP_DEBUG(2, " -- Found UUID %d in table", CurrUUIDItem);
206
207 /* Add an inner Data Element Sequence header for the current UUID's found Attributes */
208 uint16_t* CurrentUUIDResponseSize = SDP_AddDataElementHeader16(&CurrResponsePos, SDP_DATATYPE_Sequence);
209
210 /* Search through the list of Attributes one at a time looking for values in the current UUID's Attribute table */
211 for (uint8_t CurrAttribute = 0; CurrAttribute < TotalAttributes; CurrAttribute++)
212 {
213 uint16_t* AttributeIDRange = AttributeList[CurrAttribute];
214
215 /* Look in the current Attribute Range for a matching Attribute ID in the UUID's Attribute table */
216 for (uint32_t CurrAttributeID = AttributeIDRange[0]; CurrAttributeID <= AttributeIDRange[1]; CurrAttributeID++)
217 {
218 /* Retrieve a PROGMEM pointer to the value of the current Attribute ID, if it exists in the UUID's Attribute table */
219 const void* AttributeValue = SDP_GetAttributeValue(AttributeTable, CurrAttributeID);
220
221 /* If the Attribute does not exist in the current UUID's Attribute table, continue to the next Attribute ID */
222 if (AttributeValue == NULL)
223 continue;
224
225 BT_SDP_DEBUG(2, " -- Add Attribute 0x%04X", CurrAttributeID);
226
227 /* Increment the current UUID's returned Attribute container size by the number of added bytes */
228 *CurrentUUIDResponseSize += SDP_AddAttributeToResponse(CurrAttributeID, AttributeValue, &CurrResponsePos);
229 }
230
231 /* Increment the outer container size by the number of added bytes */
232 *TotalResponseSize += 3 + *CurrentUUIDResponseSize;
233 }
234 }
235
236 /* Continuation state - always zero */
237 *((uint8_t*)CurrResponsePos) = 0;
238
239 /* Set the total response list size to the size of the outer container plus its header size and continuation state */
240 ResponsePacket.AttributeListByteCount = 4 + *TotalResponseSize;
241
242 /* Fill in the response packet's header */
243 ResponsePacket.SDPHeader.PDU = SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE;
244 ResponsePacket.SDPHeader.TransactionID = SDPHeader->TransactionID;
245 ResponsePacket.SDPHeader.ParameterLength = (ResponsePacket.AttributeListByteCount + sizeof(ResponsePacket.AttributeListByteCount));
246
247 BT_SDP_DEBUG(1, ">> Service Search Attribute Response");
248 BT_SDP_DEBUG(2, "-- Total Parameter Length: 0x%04X", ResponsePacket.SDPHeader.ParameterLength);
249
250 /* Send the completed response packet to the sender */
251 Bluetooth_SendPacket(&ResponsePacket, (sizeof(ResponsePacket.SDPHeader) + ResponsePacket.SDPHeader.ParameterLength),
252 Channel);
253 }
254
255 /** Adds the given attribute ID and value to the reponse buffer, and advances the response buffer pointer past the added data.
256 *
257 * \param[in] AttributeID Attribute ID to add to the response buffer
258 * \param[in] AttributeValue Pointer to the start of the Attribute's value, located in PROGMEM
259 * \param[in, out] ResponseBuffer Pointer to a buffer where the Attribute and Attribute Value is to be added
260 *
261 * \return Number of bytes added to the response buffer
262 */
263 static uint16_t SDP_AddAttributeToResponse(const uint16_t AttributeID, const void* AttributeValue, void** ResponseBuffer)
264 {
265 /* Retrieve the size of the attribute value from its container header */
266 uint8_t AttributeHeaderLength;
267 uint32_t AttributeValueLength = SDP_GetLocalAttributeContainerSize(AttributeValue, &AttributeHeaderLength);
268
269 /* Add a Data Element header to the response for the Attribute ID */
270 *((uint8_t*)*ResponseBuffer) = (SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_16Bit);
271 *ResponseBuffer += sizeof(uint8_t);
272
273 /* Add the Attribute ID to the created Data Element */
274 *((uint16_t*)*ResponseBuffer) = AttributeID;
275 *ResponseBuffer += sizeof(uint16_t);
276
277 /* Copy over the Attribute value Data Element container to the response */
278 memcpy_P(*ResponseBuffer, AttributeValue, AttributeHeaderLength + AttributeValueLength);
279 *ResponseBuffer += AttributeHeaderLength + AttributeValueLength;
280
281 return (sizeof(uint8_t) + sizeof(uint16_t) + AttributeHeaderLength + AttributeValueLength);
282 }
283
284 /** Retrieves a pointer to the value of the given Attribute ID from the given Attribute table.
285 *
286 * \param[in] AttributeTable Pointer to the Attribute table to search in
287 * \param[in] AttributeID Attribute ID to search for within the table
288 *
289 * \return Pointer to the start of the Attribute's value if found within the table, NULL otherwise
290 */
291 static void* SDP_GetAttributeValue(const ServiceAttributeTable_t* AttributeTable, const uint16_t AttributeID)
292 {
293 void* CurrTableItemData;
294
295 /* Search through the current Attribute table, abort when the terminator item has been reached */
296 while ((CurrTableItemData = (void*)pgm_read_word(&AttributeTable->Data)) != NULL)
297 {
298 /* Check if the current Attribute ID matches the search ID - if so return a pointer to it */
299 if (pgm_read_word(&AttributeTable->AttributeID) == AttributeID)
300 return CurrTableItemData;
301
302 AttributeTable++;
303 }
304
305 return NULL;
306 }
307
308 /** Retrieves the Attribute table for the given UUID if it exists.
309 *
310 * \param[in] UUID UUID to search for
311 *
312 * \return Pointer to the UUID's associated Attribute table if found in the global UUID table, NULL otherwise
313 */
314 static ServiceAttributeTable_t* SDP_GetAttributeTable(const uint8_t* const UUID)
315 {
316 /* Search through the global UUID list an item at a time */
317 for (uint8_t CurrTableItem = 0; CurrTableItem < (sizeof(SDP_Services_Table) / sizeof(ServiceTable_t)); CurrTableItem++)
318 {
319 /* Read in a pointer to the current UUID table entry's Attribute table */
320 ServiceAttributeTable_t* CurrAttributeTable = (ServiceAttributeTable_t*)pgm_read_word(&SDP_Services_Table[CurrTableItem].AttributeTable);
321
322 /* If the current table item's UUID matches the search UUID, return a pointer the table item's Attribute table */
323 if (!(memcmp_P(UUID, SDP_Services_Table[CurrTableItem].UUID, UUID_SIZE_BYTES)))
324 return CurrAttributeTable;
325
326 /* Retrieve the list of the service's Class UUIDs from its Attribute table */
327 void* ClassUUIDs = SDP_GetAttributeValue(CurrAttributeTable, SDP_ATTRIBUTE_ID_SERVICECLASSIDS);
328
329 /* Go to the next UUID in the table if the current item does not have a list of Class UUIDs */
330 if (ClassUUIDs == NULL)
331 continue;
332
333 /* Retrieve the size of the Class UUID list and skip past the header to the first Class UUID in the list */
334 uint8_t ClassUUIDListHeaderSize;
335 uint32_t ClassUUIDListSize = SDP_GetLocalAttributeContainerSize(ClassUUIDs, &ClassUUIDListHeaderSize);
336 ClassUUIDs += ClassUUIDListHeaderSize;
337
338 /* Check each class UUID in turn for a match */
339 while (ClassUUIDListSize)
340 {
341 /* Current Service UUID's Class UUID list has a matching entry, return the Attribute table */
342 if (!(memcmp_P(UUID, &((ClassUUID_t*)ClassUUIDs)->UUID, UUID_SIZE_BYTES)))
343 return CurrAttributeTable;
344
345 ClassUUIDListSize -= sizeof(ClassUUID_t);
346 ClassUUIDs += sizeof(ClassUUID_t);
347 }
348 }
349
350 return NULL;
351 }
352
353 /** Reads in the collection of Attribute ranges from the input buffer's Data Element Sequence container, into the given
354 * Attribute list for later use. Once complete, the input buffer pointer is advanced to the end of the Attribute container.
355 *
356 * \param[out] AttributeList Pointer to a buffer where the list of Attribute ranges are to be stored
357 * \param[in] CurrentParameter Pointer to a Buffer containing a Data Element Sequence of Attribute and Attribute Range elements
358 *
359 * \return Total number of Attribute ranges stored in the Data Element Sequence
360 */
361 static uint8_t SDP_GetAttributeList(uint16_t AttributeList[][2], const void** const CurrentParameter)
362 {
363 uint8_t ElementHeaderSize;
364 uint8_t TotalAttributes = 0;
365
366 /* Retrieve the total size of the Attribute container, and unwrap the outer Data Element Sequence container */
367 uint16_t AttributeIDListLength = SDP_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
368 BT_SDP_DEBUG(2, "-- Total Attribute Length: 0x%04X", AttributeIDListLength);
369 while (AttributeIDListLength)
370 {
371 /* Retrieve the size of the next Attribute in the container and get a pointer to the next free Attribute element in the list */
372 uint16_t* CurrentAttributeRange = AttributeList[TotalAttributes++];
373 uint8_t AttributeLength = SDP_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
374
375 /* Copy over the starting Attribute ID and (if it the current element is a range) the ending Attribute ID */
376 memcpy(&CurrentAttributeRange[0], *CurrentParameter, AttributeLength);
377
378 /* If the element is not an Attribute Range, copy over the starting ID to the ending ID to make a range of 1 */
379 if (AttributeLength == 2)
380 memcpy(&CurrentAttributeRange[1], *CurrentParameter, 2);
381
382 BT_SDP_DEBUG(2, "-- Attribute: 0x%04X-0x%04X", CurrentAttributeRange[0], CurrentAttributeRange[1]);
383
384 AttributeIDListLength -= (AttributeLength + ElementHeaderSize);
385 *CurrentParameter += AttributeLength;
386 }
387
388 return TotalAttributes;
389 }
390
391 /** Reads in the collection of UUIDs from the input buffer's Data Element Sequence container, into the given
392 * UUID list for later use. Once complete, the input buffer pointer is advanced to the end of the UUID container.
393 *
394 * \param[out] UUIDList Pointer to a buffer where the list of UUIDs are to be stored
395 * \param[in] CurrentParameter Pointer to a Buffer containing a Data Element Sequence of UUID elements
396 *
397 * \return Total number of UUIDs stored in the Data Element Sequence
398 */
399 static uint8_t SDP_GetUUIDList(uint8_t UUIDList[][UUID_SIZE_BYTES], const void** const CurrentParameter)
400 {
401 uint8_t ElementHeaderSize;
402 uint8_t TotalUUIDs = 0;
403
404 /* Retrieve the total size of the UUID container, and unwrap the outer Data Element Sequence container */
405 uint16_t ServicePatternLength = SDP_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
406 BT_SDP_DEBUG(2, "-- Total UUID Length: 0x%04X", ServicePatternLength);
407 while (ServicePatternLength)
408 {
409 /* Retrieve the size of the next UUID in the container and get a pointer to the next free UUID element in the list */
410 uint8_t* CurrentUUID = UUIDList[TotalUUIDs++];
411 uint8_t UUIDLength = SDP_GetDataElementSize(CurrentParameter, &ElementHeaderSize);
412
413 /* Copy over the base UUID value to the free UUID slot in the list */
414 memcpy_P(CurrentUUID, BaseUUID, sizeof(BaseUUID));
415
416 /* Copy over UUID from the container to the free slot - if a short UUID (<= 4 bytes) it replaces the lower
417 4 bytes of the base UUID, otherwise it replaces the UUID completely */
418 memcpy(&CurrentUUID[(UUIDLength <= 4) ? (UUID_SIZE_BYTES - 4) : 0], *CurrentParameter, UUIDLength);
419
420 BT_SDP_DEBUG(2, "-- UUID (%d): 0x%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
421 UUIDLength,
422 CurrentUUID[15], CurrentUUID[14], CurrentUUID[13], CurrentUUID[12],
423 CurrentUUID[11], CurrentUUID[10], CurrentUUID[9], CurrentUUID[8],
424 CurrentUUID[7], CurrentUUID[6], CurrentUUID[5], CurrentUUID[4],
425 CurrentUUID[3], CurrentUUID[2], CurrentUUID[1], CurrentUUID[0]);
426
427 ServicePatternLength -= (UUIDLength + ElementHeaderSize);
428 *CurrentParameter += UUIDLength;
429 }
430
431 return TotalUUIDs;
432 }
433
434 /** Retrieves the total size of the given locally stored (in PROGMEM) attribute Data Element container.
435 *
436 * \param[in] AttributeData Pointer to the start of the Attribute container, located in PROGMEM
437 *
438 * \return Size in bytes of the entire attribute container, including the header
439 */
440 static uint32_t SDP_GetLocalAttributeContainerSize(const void* const AttributeData, uint8_t* const HeaderSize)
441 {
442 /* Fetch the size of the Data Element structure from the header */
443 uint8_t SizeIndex = (pgm_read_byte(AttributeData) & 0x07);
444
445 /* Convert the Data Element size index into a size in bytes */
446 switch (SizeIndex)
447 {
448 case SDP_DATASIZE_Variable8Bit:
449 *HeaderSize = (1 + sizeof(uint8_t));
450 return pgm_read_byte(AttributeData + 1);
451 case SDP_DATASIZE_Variable16Bit:
452 *HeaderSize = (1 + sizeof(uint16_t));
453 return pgm_read_word(AttributeData + 1);
454 case SDP_DATASIZE_Variable32Bit:
455 *HeaderSize = (1 + sizeof(uint32_t));
456 return pgm_read_dword(AttributeData + 1);
457 default:
458 *HeaderSize = 1;
459 return (1 << SizeIndex);
460 }
461
462 return 0;
463 }
464
465 /** Retrieves the size of a Data Element container from the current input buffer, and advances the input buffer
466 * pointer to the start of the Data Element's contents.
467 *
468 * \param[in, out] DataElementHeader Pointer to the start of a Data Element header
469 * \param[out] ElementHeaderSize Size in bytes of the header that was skipped
470 *
471 * \return Size in bytes of the Data Element container's contents, minus the header
472 */
473 static uint32_t SDP_GetDataElementSize(const void** const DataElementHeader, uint8_t* const ElementHeaderSize)
474 {
475 /* Fetch the size of the Data Element structure from the header, increment the current buffer pos */
476 uint8_t SizeIndex = (*((uint8_t*)*DataElementHeader) & 0x07);
477 *DataElementHeader += sizeof(uint8_t);
478
479 uint32_t ElementValue;
480
481 /* Convert the Data Element size index into a size in bytes */
482 switch (SizeIndex)
483 {
484 case SDP_DATASIZE_Variable8Bit:
485 ElementValue = *((uint8_t*)*DataElementHeader);
486 *DataElementHeader += sizeof(uint8_t);
487 *ElementHeaderSize = (1 + sizeof(uint8_t));
488 break;
489 case SDP_DATASIZE_Variable16Bit:
490 ElementValue = *((uint16_t*)*DataElementHeader);
491 *DataElementHeader += sizeof(uint16_t);
492 *ElementHeaderSize = (1 + sizeof(uint16_t));
493 break;
494 case SDP_DATASIZE_Variable32Bit:
495 ElementValue = *((uint32_t*)*DataElementHeader);
496 *DataElementHeader += sizeof(uint32_t);
497 *ElementHeaderSize = (1 + sizeof(uint32_t));
498 break;
499 default:
500 ElementValue = (1 << SizeIndex);
501 *ElementHeaderSize = 1;
502 break;
503 }
504
505 return ElementValue;
506 }