1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "sdp_server.h"
17 
18 #include <stdio.h>
19 #include <string.h>
20 
21 #include "sdp_connect.h"
22 #include "sdp_util.h"
23 
24 #include "allocator.h"
25 #include "bt_endian.h"
26 #include "packet.h"
27 
28 #include "list.h"
29 
30 #include "log.h"
31 
32 #define SDP_RECURSION_LEVEL_MAX 3
33 #define SDP_RESERVE_LENGTH 10
34 
35 typedef struct {
36     uint16_t attributeId;
37     uint16_t attributeLength;
38     uint8_t *attributeValue;
39 } AttributeItem;
40 
41 typedef struct {
42     uint32_t serviceRecordHandle;
43     uint16_t attributeNumber;                              /// Attribute count
44     uint16_t totalLength;                                  /// Attribute length
45     AttributeItem attributeItem[SDP_MAX_ATTRIBUTE_COUNT];  /// Attribute item
46     bool flag;                                             /// 1-Register 0-Deregister
47 } ServiceRecordItem;
48 
49 typedef struct {
50     uint8_t *buffer;
51     uint16_t length;
52 } BufferInfo;
53 /// Bluetooth Base UUID (00000000-0000-1000-8000-00805F9B34FB)
54 static const uint8_t G_BASE_UUID[] = {
55     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
56 };
57 /// Handle start after the reserved range
58 static uint32_t g_nextServiceRecordHandle = (uint32_t)SDP_MAX_RESERVED_RECORD_HANDLE + 1;
59 /// Service records list
60 static List *g_serviceRecordList = NULL;
61 
62 static int SdpAddServiceRecordHandle(uint32_t handle);
63 static uint16_t SdpAddAttributeForProtocolDescriptor(
64     uint8_t *buffer, uint16_t offset, const SdpProtocolParameter *parameter, uint16_t parameterNumber);
65 static uint16_t SdpAddAttributeForUuidSequence(uint8_t *buffer, uint16_t offset, const BtUuid *uuid);
66 static uint16_t SdpAddAttributeForValue(uint8_t *buffer, uint16_t offset, uint32_t value);
67 static uint16_t SdpAddAttributeForString(uint8_t *buffer, uint16_t offset, const char *name, uint16_t nameLen);
68 static uint16_t SdpAddAttributeForUrl(uint8_t *buffer, uint16_t offset, const uint8_t *url, uint16_t urlLen);
69 static int SdpAddAttributeToServiceRecord(
70     uint32_t handle, uint16_t attributeId, uint8_t attributeType, uint32_t attributeLength, const uint8_t *value);
71 static void SdpParseSearchRequest(uint16_t lcid, uint16_t transactionId, BufferInfo *bufferInfo);
72 static void SdpParseAttributeRequest(uint16_t lcid, uint16_t transactionId, BufferInfo *bufferInfo);
73 static void SdpParseSearchAttributeRequest(uint16_t lcid, uint16_t transactionId, BufferInfo *bufferInfo);
74 static void SortForAttributeId(AttributeItem *attributeItem, uint16_t attributeNumber);
75 static bool CompareUuid(const uint8_t *uuid1, uint16_t length1, const uint8_t *uuid2, uint16_t length2);
76 static uint16_t GetRecordHandleArray(
77     uint8_t uuidArray[][20], int uuidNum, uint32_t *handleArray, uint16_t handleNum, uint16_t maxRecordCount);
78 static ServiceRecordItem *FindServiceRecordItem(uint32_t handle);
79 
SdpFreeServiceRecord(void * data)80 static void SdpFreeServiceRecord(void *data)
81 {
82     ServiceRecordItem *item = (ServiceRecordItem *)data;
83 
84     for (int i = 0; i < item->attributeNumber; i++) {
85         MEM_MALLOC.free(item->attributeItem[i].attributeValue);
86     }
87     MEM_MALLOC.free(item);
88 }
89 
SdpInitializeServer()90 void SdpInitializeServer()
91 {
92     /// Create service record list
93     g_serviceRecordList = ListCreate(SdpFreeServiceRecord);
94 }
95 
SdpFinalizeServer()96 void SdpFinalizeServer()
97 {
98     /// Destroy service record list
99     if (g_serviceRecordList != NULL) {
100         ListDelete(g_serviceRecordList);
101         g_serviceRecordList = NULL;
102     }
103 }
104 
SdpCreateServiceRecord()105 uint32_t SdpCreateServiceRecord()
106 {
107     ServiceRecordItem *serviceRecordItem = MEM_MALLOC.alloc(sizeof(ServiceRecordItem));
108     if (serviceRecordItem == NULL) {
109         LOG_ERROR("point to NULL");
110         return 0;
111     }
112     uint32_t handle = 0;
113     int ret;
114 
115     if (!SdpGetEnableState()) {
116         return handle;
117     }
118 
119     (void)memset_s(serviceRecordItem, sizeof(ServiceRecordItem), 0, sizeof(ServiceRecordItem));
120     /// Get free record handle
121     handle = g_nextServiceRecordHandle;
122     if (g_nextServiceRecordHandle >= UINT32_MAX) {
123         g_nextServiceRecordHandle = (uint32_t)SDP_MAX_RESERVED_RECORD_HANDLE;
124     }
125     g_nextServiceRecordHandle++;
126 
127     /// Add record handle to list
128     serviceRecordItem->serviceRecordHandle = handle;
129     ListAddLast(g_serviceRecordList, serviceRecordItem);
130     ret = SdpAddServiceRecordHandle(handle);
131     if (ret != BT_SUCCESS) {
132         ListRemoveLast(g_serviceRecordList);
133         handle = 0;
134     }
135     LOG_INFO("[%{public}s][%u] handle = [0x%08x]", __FUNCTION__, __LINE__, handle);
136     return handle;
137 }
138 
SdpDestroyServiceRecord(uint32_t handle)139 int SdpDestroyServiceRecord(uint32_t handle)
140 {
141     LOG_INFO("[%{public}s][%u] handle = [0x%08x]", __FUNCTION__, __LINE__, handle);
142     ServiceRecordItem *item = NULL;
143 
144     if (!SdpGetEnableState()) {
145         return BT_BAD_STATUS;
146     }
147 
148     /// Remove service record from list
149     item = FindServiceRecordItem(handle);
150     if (item == NULL || item->flag) {
151         return BT_BAD_PARAM;
152     }
153     ListRemoveNode(g_serviceRecordList, item);
154 
155     return BT_SUCCESS;
156 }
157 
SdpRegisterServiceRecord(uint32_t handle)158 int SdpRegisterServiceRecord(uint32_t handle)
159 {
160     LOG_INFO("[%{public}s][%u] handle = [0x%08x]", __FUNCTION__, __LINE__, handle);
161     if (!SdpGetEnableState()) {
162         return BT_BAD_STATUS;
163     }
164     ServiceRecordItem *item = FindServiceRecordItem(handle);
165     if (item == NULL || item->flag) {
166         return BT_BAD_PARAM;
167     }
168     /// Sort attribute id
169     SortForAttributeId(item->attributeItem, item->attributeNumber);
170     /// Set registration flag
171     item->flag = true;
172 
173     return BT_SUCCESS;
174 }
175 
SdpDeregisterServiceRecord(uint32_t handle)176 int SdpDeregisterServiceRecord(uint32_t handle)
177 {
178     LOG_INFO("[%{public}s][%u] handle = [0x%08x]", __FUNCTION__, __LINE__, handle);
179     ServiceRecordItem *item = NULL;
180 
181     if (!SdpGetEnableState()) {
182         return BT_BAD_STATUS;
183     }
184 
185     item = FindServiceRecordItem(handle);
186     if ((item == NULL) || (!item->flag)) {
187         LOG_ERROR("[%{public}s][%u] There is no handle [0x%08x].", __FUNCTION__, __LINE__, handle);
188         return BT_BAD_PARAM;
189     }
190     /// Set deregistration flag
191     item->flag = false;
192 
193     return BT_SUCCESS;
194 }
195 
196 /**
197  * @brief    SdpAddServiceRecordHandle
198  * @detail   Add ServiceRecordHandle Attribute to service record
199  * @para[in] handle: record handle
200  * @return   Success(0) or error code
201  * @see      Refer to charter 5.1.1 of Core 5.0
202  */
SdpAddServiceRecordHandle(uint32_t handle)203 static int SdpAddServiceRecordHandle(uint32_t handle)
204 {
205     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
206     uint16_t offset = 0;
207     int ret;
208 
209     // Data Element: Unsigned Integer 4 bytes (0x0A)
210     buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32;
211     offset++;
212     /// 32-bit handle
213     *(uint32_t *)(buffer + 1) = H2BE_32(handle);
214     offset += SDP_SERVICE_RECORD_HANDLE_BYTE;
215 
216     /// Attribute ID: ServiceRecordHandle (0x0000)
217     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_SERVICE_RECORD_HANDLE, 0, offset, buffer);
218 
219     return ret;
220 }
221 
SdpAddServiceClassIdList(uint32_t handle,const BtUuid * classid,uint16_t classidNumber)222 int SdpAddServiceClassIdList(uint32_t handle, const BtUuid *classid, uint16_t classidNumber)
223 {
224     LOG_INFO("[%{public}s][%u] handle = [0x%08x], classidNumber = [%hu]", __FUNCTION__, __LINE__, handle, classidNumber);
225     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
226     uint16_t offset = 0;
227     uint8_t type;
228     int ret;
229 
230     if (!SdpGetEnableState()) {
231         return BT_BAD_STATUS;
232     }
233 
234     // Data Element: Sequence uint8 (0x35)
235     type = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
236     for (int i = 0; i < classidNumber; i++, classid++) {
237         uint16_t pos;
238         pos = offset;
239         offset = SdpAddAttributeForUuid(buffer, offset, classid);
240         if (pos == offset) {
241             LOG_ERROR("[%{public}s][%{public}d] Invalid uuid type [0x%x]", __FUNCTION__, __LINE__, classid->type);
242             return BT_BAD_PARAM;
243         }
244     }
245     /// Attribute ID: ServiceClassIDList (0x0001)
246     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST, type, offset, buffer);
247 
248     return ret;
249 }
250 
SdpAddServiceRecordState(uint32_t handle,uint32_t state)251 int SdpAddServiceRecordState(uint32_t handle, uint32_t state)
252 {
253     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], state = [0x%08x]", __FUNCTION__, __LINE__, handle, state);
254     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
255     uint16_t offset = 0;
256     int ret;
257 
258     // Data Element: Unsigned Integer 4 bytes (0x0A)
259     buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32;
260     offset++;
261     /// Data value
262     *(uint32_t *)(buffer + offset) = H2BE_32(state);
263     offset += SDP_UINT32_LENGTH;
264     /// Attribute ID: ServiceRecordState (0x0002)
265     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_SERVICE_RECORD_STATE, 0, offset, buffer);
266 
267     return ret;
268 }
269 
SdpAddServiceId(uint32_t handle,const BtUuid * serviceid)270 int SdpAddServiceId(uint32_t handle, const BtUuid *serviceid)
271 {
272     LOG_INFO("[%{public}s][%u] handle = [0x%08x], serviceid->type = [0x%02x]", __FUNCTION__, __LINE__, handle, serviceid->type);
273     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
274     uint16_t offset;
275     int ret;
276 
277     if (!SdpGetEnableState()) {
278         return BT_BAD_STATUS;
279     }
280 
281     if ((serviceid->type != BT_UUID_16) && (serviceid->type != BT_UUID_32) && (serviceid->type != BT_UUID_128)) {
282         LOG_ERROR("[%{public}s][%u] Get wrong type [0x%02x]", __FUNCTION__, __LINE__, serviceid->type);
283         return BT_BAD_PARAM;
284     }
285 
286     // Attribute Value
287     offset = SdpAddAttributeForUuid(buffer, 0, serviceid);
288     /// Attribute ID: ServiceID (0x0003)
289     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_SERVICE_ID, 0, offset, buffer);
290 
291     return ret;
292 }
293 
SdpAddProtocolDescriptorList(uint32_t handle,const SdpProtocolDescriptor * descriptor,uint16_t descriptorNumber)294 int SdpAddProtocolDescriptorList(uint32_t handle, const SdpProtocolDescriptor *descriptor, uint16_t descriptorNumber)
295 {
296     LOG_INFO("[%{public}s][%u] handle = [0x%08x], descriptorNumber = [%hu]", __FUNCTION__, __LINE__, handle, descriptorNumber);
297     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
298     uint8_t attributeType;
299     uint16_t offset = 0;
300     int ret;
301 
302     if (!SdpGetEnableState()) {
303         return BT_BAD_STATUS;
304     }
305 
306     /// Data Element: Sequence uint8 (0x35)
307     attributeType = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
308     /// Attribute Value
309     if (descriptorNumber > SDP_PROTOCOL_DESCRIPTOR_MAX_COUNT) {
310         descriptorNumber = SDP_PROTOCOL_DESCRIPTOR_MAX_COUNT;
311     }
312 
313     for (int i = 0; i < descriptorNumber; i++, descriptor++) {
314         uint16_t result;
315         uint16_t pos;
316         pos = offset;
317         result = SdpAddAttributeForUuidSequence(buffer, offset, &descriptor->protocolUuid);
318         if (result == offset) {
319             LOG_ERROR("[%{public}s][%{public}d] ", __FUNCTION__, __LINE__);
320             return BT_BAD_PARAM;
321         } else {
322             offset = result;
323         }
324         offset =
325             SdpAddAttributeForProtocolDescriptor(buffer, offset, descriptor->parameter, descriptor->parameterNumber);
326         if (offset == 0) {
327             return BT_BAD_PARAM;
328         }
329         // Data Element Var Size
330         buffer[pos + 1] = offset - pos - SDP_UINT16_LENGTH;
331     }
332     /// Attribute ID: ProtocolDescriptorList (0x0004)
333     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST, attributeType, offset, buffer);
334     return ret;
335 }
336 
SdpAddAdditionalProtocolDescriptorList(uint32_t handle,const SdpAdditionalProtocolDescriptor * descriptorList,uint16_t descriptorListNumber)337 int SdpAddAdditionalProtocolDescriptorList(
338     uint32_t handle, const SdpAdditionalProtocolDescriptor *descriptorList, uint16_t descriptorListNumber)
339 {
340     LOG_INFO("[%{public}s][%u] handle = [0x%08x], descriptorListNumber = [%hu]",
341         __FUNCTION__,
342         __LINE__,
343         handle,
344         descriptorListNumber);
345     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
346     uint16_t offset = 0;
347     uint8_t attributeType;
348     int ret;
349 
350     if (!SdpGetEnableState()) {
351         return BT_BAD_STATUS;
352     }
353 
354     /// Data Element: Sequence uint8 (0x35)
355     attributeType = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
356     // Attribute Value
357     for (int i = 0; i < descriptorListNumber; i++, descriptorList++) {
358         if (descriptorList->protocolDescriptorNumber == 0) {
359             continue;
360         }
361         uint16_t posAdditional = offset;
362         // Data Element: Sequence uint8 (0x35)
363         buffer[offset] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
364         offset += SDP_UINT16_LENGTH;
365 
366         const SdpProtocolDescriptor *descriptor = descriptorList->parameter;
367         int j;
368         for (j = 0; j < descriptorList->protocolDescriptorNumber; j++, descriptor++) {
369             uint16_t pos = offset;
370             uint16_t res = SdpAddAttributeForUuidSequence(buffer, offset, &descriptor->protocolUuid);
371             if (res == offset) {
372                 LOG_ERROR("[%{public}s][%{public}d]", __FUNCTION__, __LINE__);
373                 return BT_BAD_PARAM;
374             } else {
375                 offset = res;
376             }
377             offset = SdpAddAttributeForProtocolDescriptor(
378                 buffer, offset, descriptor->parameter, descriptor->parameterNumber);
379             if (offset == 0) {
380                 return BT_BAD_PARAM;
381             }
382             // Data Element Var Size
383             buffer[pos + 1] = offset - pos - SDP_UINT16_LENGTH;
384         }
385         buffer[posAdditional + 1] = offset - posAdditional - SDP_UINT16_LENGTH;
386     }
387 
388     /// Attribute ID: AdditionalProtocolDescriptorList (0x000D)
389     ret = SdpAddAttributeToServiceRecord(
390         handle, SDP_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST, attributeType, offset, buffer);
391     return ret;
392 }
393 
SdpAddBrowseGroupList(uint32_t handle,const BtUuid * browseUuid,uint16_t browseUuidNumber)394 int SdpAddBrowseGroupList(uint32_t handle, const BtUuid *browseUuid, uint16_t browseUuidNumber)
395 {
396     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], browseUuidNumber = [%hu]", __FUNCTION__, __LINE__, handle, browseUuidNumber);
397     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
398     uint16_t offset = 0;
399     uint8_t attributeType;
400     int ret;
401 
402     if (!SdpGetEnableState()) {
403         return BT_BAD_STATUS;
404     }
405 
406     /// Data Element: Sequence uint8 (0x35)
407     attributeType = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
408     // Attribute Value
409     // Data Element Var Size Length
410     for (int i = 0; i < browseUuidNumber; i++, browseUuid++) {
411         if (browseUuid->type == BT_UUID_16) {
412             if ((offset + SDP_UUID16_LENGTH + SDP_UINT16_LENGTH + 1) > SDP_MAX_ATTRIBUTE_LEN) {
413                 break;
414             }
415             offset = SdpAddAttributeForUuid(buffer, offset, browseUuid);
416         } else if (browseUuid->type == BT_UUID_32) {
417             if ((offset + SDP_UUID32_LENGTH + SDP_UINT16_LENGTH + 1) > SDP_MAX_ATTRIBUTE_LEN) {
418                 break;
419             }
420             offset = SdpAddAttributeForUuid(buffer, offset, browseUuid);
421         } else if (browseUuid->type == BT_UUID_128) {
422             if ((offset + SDP_UUID128_LENGTH + SDP_UINT16_LENGTH + 1) > SDP_MAX_ATTRIBUTE_LEN) {
423                 break;
424             }
425             offset = SdpAddAttributeForUuid(buffer, offset, browseUuid);
426         } else {
427             LOG_ERROR("[%{public}s][%{public}d] Get wrong type [0x%02x]", __FUNCTION__, __LINE__, browseUuid->type);
428             return BT_BAD_PARAM;
429         }
430     }
431     /// Attribute ID: BrowseGroupList (0x0005)
432     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_BROWSE_GROUP_LIST, attributeType, offset, buffer);
433 
434     return ret;
435 }
436 
SdpAddLanguageBaseAttributeIdList(uint32_t handle,const SdpLanguageBaseAttributeId * baseAttributeId,uint16_t baseAttributeIdNum)437 int SdpAddLanguageBaseAttributeIdList(
438     uint32_t handle, const SdpLanguageBaseAttributeId *baseAttributeId, uint16_t baseAttributeIdNum)
439 {
440     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], baseAttributeIdNumber = [%hu]",
441         __FUNCTION__,
442         __LINE__,
443         handle,
444         baseAttributeIdNum);
445     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
446     uint16_t offset = 0;
447     uint8_t attributeType;
448     int ret;
449 
450     if (!SdpGetEnableState()) {
451         return BT_BAD_STATUS;
452     }
453 
454     // Attribute Value
455     /* build the language base descriptor list. This consists of a data */
456     /* element sequence. The sequence consists of 9 bytes (3 UINt16 fields) */
457 
458     for (int i = 0; i < baseAttributeIdNum; i++) {
459         if ((offset + SDP_LANGUAGE_ATTRIBUTE_LENGTH) >= SDP_MAX_ATTRIBUTE_LEN) {
460             break;
461         }
462         /// Data Element: Unsigned Integer 2 bytes (0x09)
463         buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
464         offset++;
465         /// Language Code
466         *(uint16_t *)(buffer + offset) = H2BE_16(baseAttributeId[i].languageIdentifier);
467         offset += SDP_UINT16_LENGTH;
468         /// Data Element: Unsigned Integer 2 bytes (0x09)
469         buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
470         offset++;
471         // Language Encoding
472         *(uint16_t *)(buffer + offset) = H2BE_16(baseAttributeId[i].characterEncodingIdentifier);
473         offset += SDP_UINT16_LENGTH;
474         /// Data Element: Unsigned Integer 2 bytes (0x09)
475         buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
476         offset++;
477         /// Attribute Base
478         *(uint16_t *)(buffer + offset) = H2BE_16(baseAttributeId[i].baseAttributeId);
479         offset += SDP_UINT16_LENGTH;
480     }
481     /// Data Element Var Size Length
482     if (offset > 0xFF) {
483         /// Data Element: Sequence uint16 (0x36)
484         attributeType = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_16;
485     } else {
486         /// Data Element: Sequence uint8 (0x35)
487         attributeType = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
488     }
489     /// Attribute ID: LanguageBaseAttributeIDList (0x0006)
490     ret = SdpAddAttributeToServiceRecord(
491         handle, SDP_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST, attributeType, offset, buffer);
492 
493     return ret;
494 }
495 
SdpAddServiceInfoTimeToLive(uint32_t handle,uint32_t value)496 int SdpAddServiceInfoTimeToLive(uint32_t handle, uint32_t value)
497 {
498     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], value = [0x%08x]", __FUNCTION__, __LINE__, handle, value);
499 
500     if (!SdpGetEnableState()) {
501         return BT_BAD_STATUS;
502     }
503 
504     uint8_t buffer[10] = {0};
505     // Attribute Value
506     uint16_t offset = SdpAddAttributeForValue(buffer, 0, value);
507     /// Attribute ID: ServiceInfoTimeToLive (0x0007)
508     int ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_SERVICE_INFO_TIME_TO_LIVE, 0, offset, buffer);
509 
510     return ret;
511 }
512 
SdpAddServiceAvailability(uint32_t handle,uint8_t value)513 int SdpAddServiceAvailability(uint32_t handle, uint8_t value)
514 {
515     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], value = [0x%02x]", __FUNCTION__, __LINE__, handle, value);
516     uint8_t buffer[2] = {0};
517     int ret;
518 
519     if (!SdpGetEnableState()) {
520         return BT_BAD_STATUS;
521     }
522 
523     // Attribute Value
524     // Data Element: Unsigned Integer 1 bytes (0x08)
525     buffer[0] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_8;
526     buffer[1] = value;
527     /// Attribute ID: ServiceAvailability (0x0008)
528     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_SERVICE_AVAILABILITY, 0, SDP_UINT16_LENGTH, buffer);
529 
530     return ret;
531 }
532 
SdpAddBluetoothProfileDescriptorList(uint32_t handle,const SdpProfileDescriptor * profileDescriptor,uint16_t profileDescriptorNum)533 int SdpAddBluetoothProfileDescriptorList(
534     uint32_t handle, const SdpProfileDescriptor *profileDescriptor, uint16_t profileDescriptorNum)
535 {
536     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], profileDescriptorNumber = [%hu]",
537         __FUNCTION__,
538         __LINE__,
539         handle,
540         profileDescriptorNum);
541     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
542     uint16_t offset = 0;
543     uint8_t type;
544     int ret;
545 
546     if (!SdpGetEnableState()) {
547         return BT_BAD_STATUS;
548     }
549 
550     /// Attribute Value
551     /// Data Element: Sequence uint8 (0x35)
552     type = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
553 
554     for (int i = 0; i < profileDescriptorNum; i++, profileDescriptor++) {
555         uint16_t pos;
556         uint16_t result;
557         pos = offset;
558         result = SdpAddAttributeForUuidSequence(buffer, offset, &profileDescriptor->profileUuid);
559         if (result == offset) {
560             LOG_ERROR("[%{public}s][%{public}d]", __FUNCTION__, __LINE__);
561             return BT_BAD_PARAM;
562         } else {
563             offset = result;
564         }
565         /// Data Element: Unsigned Integer 2 bytes (0x09)
566         buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
567         offset++;
568         // Protocol Version uint16_t
569         *(uint16_t *)(buffer + offset) = H2BE_16(profileDescriptor->versionNumber);
570         offset += SDP_UINT16_LENGTH;
571         /// Data Element Var Size
572         buffer[pos + 1] = offset - pos - SDP_UINT16_LENGTH;
573     }
574     /// Attribute ID: BluetoothProfileDescriptorList (0x0009)
575     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, type, offset, buffer);
576 
577     return ret;
578 }
579 
SdpAddDocumentationUrl(uint32_t handle,const uint8_t * url,uint16_t urlLen)580 int SdpAddDocumentationUrl(uint32_t handle, const uint8_t *url, uint16_t urlLen)
581 {
582     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], url = [%{public}s], urlLen = [%hu]", __FUNCTION__, __LINE__, handle, url, urlLen);
583     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
584     uint16_t offset;
585     int ret;
586 
587     if (!SdpGetEnableState()) {
588         return BT_BAD_STATUS;
589     }
590 
591     /// Attribute Value
592     offset = SdpAddAttributeForUrl(buffer, 0, url, urlLen);
593     /// Attribute ID: DocumentationURL (0x000A)
594     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_DOCUMENTATION_URL, 0, offset, buffer);
595 
596     return ret;
597 }
598 
SdpAddClientExecutableUrl(uint32_t handle,const uint8_t * url,uint16_t urlLen)599 int SdpAddClientExecutableUrl(uint32_t handle, const uint8_t *url, uint16_t urlLen)
600 {
601     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], url = [%{public}s], urlLen = [%hu]", __FUNCTION__, __LINE__, handle, url, urlLen);
602     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
603     uint16_t offset;
604     int ret;
605 
606     if (!SdpGetEnableState()) {
607         return BT_BAD_STATUS;
608     }
609 
610     /// Attribute Value
611     offset = SdpAddAttributeForUrl(buffer, 0, url, urlLen);
612     /// Attribute ID: ClientExecutableURL (0x000B)
613     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_CLIENT_EXECUTABLE_URL, 0, offset, buffer);
614 
615     return ret;
616 }
617 
SdpAddIconUrl(uint32_t handle,const uint8_t * url,uint16_t urlLen)618 int SdpAddIconUrl(uint32_t handle, const uint8_t *url, uint16_t urlLen)
619 {
620     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], url = [%{public}s], urlLen = [%hu]", __FUNCTION__, __LINE__, handle, url, urlLen);
621     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
622     uint16_t offset;
623     int ret;
624 
625     if (!SdpGetEnableState()) {
626         return BT_BAD_STATUS;
627     }
628 
629     /// Attribute Value
630     offset = SdpAddAttributeForUrl(buffer, 0, url, urlLen);
631     /// Attribute ID: IconURL (0x000C)
632     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_ICON_URL, 0, offset, buffer);
633 
634     return ret;
635 }
636 
SdpAddServiceName(uint32_t handle,uint16_t baseAttributeId,const char * name,uint16_t nameLen)637 int SdpAddServiceName(uint32_t handle, uint16_t baseAttributeId, const char *name, uint16_t nameLen)
638 {
639     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], baseAttributeId = [0x%04x], name = [%{public}s], nameLen = [%hu]",
640         __FUNCTION__,
641         __LINE__,
642         handle,
643         baseAttributeId,
644         name,
645         nameLen);
646     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
647     uint16_t offset;
648     int ret;
649 
650     if (!SdpGetEnableState()) {
651         return BT_BAD_STATUS;
652     }
653 
654     /// Attribute Value
655     offset = SdpAddAttributeForString(buffer, 0, name, nameLen);
656     /// Attribute ID: ServiceName (0x0000 + baseAttributeId)
657     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_SERVICE_NAME + baseAttributeId, 0, offset, buffer);
658 
659     return ret;
660 }
661 
SdpAddServiceDescription(uint32_t handle,uint16_t baseAttributeId,const char * description,uint16_t descriptionLen)662 int SdpAddServiceDescription(
663     uint32_t handle, uint16_t baseAttributeId, const char *description, uint16_t descriptionLen)
664 {
665     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], baseAttributeId = [0x%04x], description = [%{public}s], descriptionLen = [%hu]",
666         __FUNCTION__,
667         __LINE__,
668         handle,
669         baseAttributeId,
670         description,
671         descriptionLen);
672     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
673     uint16_t offset;
674     int ret;
675 
676     if (!SdpGetEnableState()) {
677         return BT_BAD_STATUS;
678     }
679 
680     /// Attribute Value
681     offset = SdpAddAttributeForString(buffer, 0, description, descriptionLen);
682     /// Attribute ID: ProviderName (0x0001 + baseAttributeId)
683     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_DESCRIPTOR + baseAttributeId, 0, offset, buffer);
684 
685     return ret;
686 }
687 
SdpAddProviderName(uint32_t handle,uint16_t baseAttributeId,const char * name,uint16_t nameLen)688 int SdpAddProviderName(uint32_t handle, uint16_t baseAttributeId, const char *name, uint16_t nameLen)
689 {
690     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], baseAttributeId = [0x%04x], name = [%{public}s], nameLen = [%hu]",
691         __FUNCTION__,
692         __LINE__,
693         handle,
694         baseAttributeId,
695         name,
696         nameLen);
697     uint16_t offset;
698     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
699     int ret;
700 
701     if (!SdpGetEnableState()) {
702         return BT_BAD_STATUS;
703     }
704 
705     /// Attribute Value
706     offset = SdpAddAttributeForString(buffer, 0, name, nameLen);
707     /// Attribute ID: ProviderName (0x0002 + baseAttributeId)
708     ret = SdpAddAttributeToServiceRecord(handle, SDP_ATTRIBUTE_PROVIDER_NAME + baseAttributeId, 0, offset, buffer);
709 
710     return ret;
711 }
712 
SdpAddAttributeForCommon(SdpDataType type,const void * attributeValue,uint8_t * buffer,uint16_t length)713 static int SdpAddAttributeForCommon(SdpDataType type, const void *attributeValue, uint8_t *buffer, uint16_t length)
714 {
715     if (type == SDP_TYPE_BOOL) {
716         buffer[0] = (DE_TYPE_BOOL << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_8;
717         buffer[1] = *(uint8_t *)attributeValue;
718         length = SDP_UINT8_LENGTH + 1;
719     } else if (type == SDP_TYPE_UINT_8) {
720         buffer[0] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_8;
721         buffer[1] = *(uint8_t *)attributeValue;
722         length = SDP_UINT8_LENGTH + 1;
723     } else if (type == SDP_TYPE_UINT_16) {
724         buffer[0] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
725         *(uint16_t *)(buffer + 1) = H2BE_16(*(uint16_t *)attributeValue);
726         length = SDP_UINT16_LENGTH + 1;
727     } else if (type == SDP_TYPE_UINT_32) {
728         buffer[0] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32;
729         *(uint32_t *)(buffer + 1) = H2BE_32(*(uint32_t *)attributeValue);
730         length = SDP_UINT32_LENGTH + 1;
731     } else if (type == SDP_TYPE_INT_8) {
732         buffer[0] = (DE_TYPE_INT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_8;
733         buffer[1] = *(int8_t *)attributeValue;
734         length = SDP_INT8_LENGTH + 1;
735     } else if (type == SDP_TYPE_INT_16) {
736         buffer[0] = (DE_TYPE_INT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
737         int16_t value = *(int16_t *)attributeValue;
738         *(uint16_t *)(buffer + 1) = H2BE_16(value);
739         length = SDP_INT16_LENGTH + 1;
740     } else if (type == SDP_TYPE_INT_32) {
741         buffer[0] = (DE_TYPE_INT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32;
742         *(uint32_t *)(buffer + 1) = H2BE_32(*(int32_t *)attributeValue);
743         length = SDP_INT32_LENGTH + 1;
744     }
745 
746     return length;
747 }
748 
SdpAddAttribute(uint32_t handle,uint16_t attributeId,SdpDataType type,void * attributeValue,uint16_t attributeValueLength)749 int SdpAddAttribute(
750     uint32_t handle, uint16_t attributeId, SdpDataType type, void *attributeValue, uint16_t attributeValueLength)
751 {
752     LOG_INFO("[%{public}s] attributeId[0x%04x] type[%u] Length [%hu]", __FUNCTION__, attributeId, type, attributeValueLength);
753     uint8_t buffer[SDP_MAX_ATTRIBUTE_LEN] = {0};
754     uint16_t length = 0;
755     BtUuid uuid;
756     int ret;
757 
758     if (!SdpGetEnableState()) {
759         return BT_BAD_STATUS;
760     }
761 
762     // Attribute Value
763     switch (type) {
764         case SDP_TYPE_BOOL:
765         case SDP_TYPE_UINT_8:
766         case SDP_TYPE_UINT_16:
767         case SDP_TYPE_UINT_32:
768         case SDP_TYPE_INT_8:
769         case SDP_TYPE_INT_16:
770         case SDP_TYPE_INT_32:
771             length = SdpAddAttributeForCommon(type, attributeValue, buffer, 0);
772             break;
773         case SDP_TYPE_UUID_16:
774             uuid.type = BT_UUID_16;
775             uuid.uuid16 = *(uint16_t *)attributeValue;
776             length = SdpAddAttributeForUuid(buffer, 0, &uuid);
777             break;
778         case SDP_TYPE_UUID_32:
779             uuid.type = BT_UUID_32;
780             uuid.uuid32 = *(uint32_t *)attributeValue;
781             length = SdpAddAttributeForUuid(buffer, 0, &uuid);
782             break;
783         case SDP_TYPE_UUID_128:
784             uuid.type = BT_UUID_128;
785             SdpReverseForBigEndian((uint8_t *)attributeValue, uuid.uuid128, SDP_UUID128_LENGTH);
786             length = SdpAddAttributeForUuid(buffer, 0, &uuid);
787             break;
788         case SDP_TYPE_TEXT:
789             length = SdpAddAttributeForString(buffer, 0, attributeValue, attributeValueLength);
790             break;
791         case SDP_TYPE_URL:
792             length = SdpAddAttributeForUrl(buffer, 0, attributeValue, attributeValueLength);
793             break;
794         default:
795             return BT_BAD_PARAM;
796     }
797     ret = SdpAddAttributeToServiceRecord(handle, attributeId, 0, length, buffer);
798 
799     return ret;
800 }
801 
SdpAddSequenceAttribute(uint32_t handle,uint16_t attributeId,const uint8_t * attributeValue,uint16_t attributeValueLength)802 int SdpAddSequenceAttribute(
803     uint32_t handle, uint16_t attributeId, const uint8_t *attributeValue, uint16_t attributeValueLength)
804 {
805     LOG_INFO("[%{public}s][%{public}d] handle = [0x%08x], attributeId = [0x%04x], attributeValueLength = [%hu]",
806         __FUNCTION__,
807         __LINE__,
808         handle,
809         attributeId,
810         attributeValueLength);
811     uint8_t type;
812     int ret;
813 
814     if (!SdpGetEnableState()) {
815         return BT_BAD_STATUS;
816     }
817 
818     if (attributeValueLength > 0xFF) {
819         // Length > 0xFF
820         // Data Element: Sequence uint16 (0x36)
821         type = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_16;
822     } else {
823         /// Data Element: Sequence uint8 (0x35)
824         type = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
825     }
826     ret = SdpAddAttributeToServiceRecord(handle, attributeId, type, attributeValueLength, attributeValue);
827 
828     return ret;
829 }
830 
SdpAddAttributeForProtocolDescriptor(uint8_t * buffer,uint16_t offset,const SdpProtocolParameter * parameter,uint16_t parameterNumber)831 static uint16_t SdpAddAttributeForProtocolDescriptor(
832     uint8_t *buffer, uint16_t offset, const SdpProtocolParameter *parameter, uint16_t parameterNumber)
833 {
834     if (parameterNumber == 0) {
835         return offset;
836     }
837     if (parameterNumber > SDP_PROTOCOL_PARAMETER_MAX_COUNT) {
838         parameterNumber = SDP_PROTOCOL_PARAMETER_MAX_COUNT;
839     }
840 
841     for (int i = 0; i < parameterNumber; i++, parameter++) {
842         switch (parameter->type) {
843             case SDP_TYPE_UINT_8:
844                 // Data Element: Unsigned Integer 1 bytes (0x08)
845                 buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_8;
846                 offset++;
847                 // Data Value
848                 buffer[offset] = parameter->value & 0xFF;
849                 offset += SDP_UINT8_LENGTH;
850                 break;
851             case SDP_TYPE_UINT_16:
852                 // Data Element: Unsigned Integer 2 bytes (0x09)
853                 buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
854                 offset++;
855                 // Data Value
856                 *(uint16_t *)(buffer + offset) = H2BE_16(parameter->value & 0xFFFF);
857                 offset += SDP_UINT16_LENGTH;
858                 break;
859             case SDP_TYPE_UINT_32:
860                 // Data Element: Unsigned Integer 4 bytes (0x0A)
861                 buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32;
862                 offset++;
863                 // Data Value
864                 *(uint32_t *)(buffer + offset) = H2BE_32(parameter->value);
865                 offset += SDP_UINT32_LENGTH;
866                 break;
867             default:
868                 return 0;
869         }
870     }
871 
872     return offset;
873 }
874 
SdpAddAttributeForUuidSequence(uint8_t * buffer,uint16_t offset,const BtUuid * uuid)875 static uint16_t SdpAddAttributeForUuidSequence(uint8_t *buffer, uint16_t offset, const BtUuid *uuid)
876 {
877     switch (uuid->type) {
878         case BT_UUID_16:
879             /// Data Element: Sequence uint8 (0x35)
880             buffer[offset] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
881             offset++;
882             /// Data Element Var Size (0x03)
883             buffer[offset] = 0x03;
884             offset++;
885             offset = SdpAddAttributeForUuid(buffer, offset, uuid);
886             break;
887         case BT_UUID_32:
888             /// Data Element: Sequence uint8 (0x35)
889             buffer[offset] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
890             offset++;
891             /// Data Element Var Size (0x05)
892             buffer[offset] = 0x05;
893             offset++;
894             offset = SdpAddAttributeForUuid(buffer, offset, uuid);
895             break;
896         case BT_UUID_128:
897             /// Data Element: Sequence uint8 (0x35)
898             buffer[offset] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
899             offset++;
900             /// Data Element Var Size (0x11)
901             buffer[offset] = 0x11;
902             offset++;
903             offset = SdpAddAttributeForUuid(buffer, offset, uuid);
904             break;
905         default:
906             LOG_ERROR("[%{public}s][%{public}d] Get wrong type [0x%02x]", __FUNCTION__, __LINE__, uuid->type);
907             break;
908     }
909 
910     return offset;
911 }
912 
SdpAddAttributeForValue(uint8_t * buffer,uint16_t offset,uint32_t value)913 static uint16_t SdpAddAttributeForValue(uint8_t *buffer, uint16_t offset, uint32_t value)
914 {
915     // Data Element: Unsigned Integer 4 bytes (0x0A)
916     buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32;
917     offset++;
918     *(uint32_t *)(buffer + offset) = H2BE_32(value);
919     offset += SDP_UINT32_LENGTH;
920 
921     return offset;
922 }
923 
SdpAddAttributeForUrl(uint8_t * buffer,uint16_t offset,const uint8_t * url,uint16_t urlLen)924 static uint16_t SdpAddAttributeForUrl(uint8_t *buffer, uint16_t offset, const uint8_t *url, uint16_t urlLen)
925 {
926     // URL Length
927     if (urlLen > 0xFF) {
928         // Data Element: Url uint16 (0x46)
929         buffer[offset] = (DE_TYPE_URL << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_16;
930         offset++;
931         *(uint16_t *)(buffer + offset) = H2BE_16(urlLen);
932         offset += SDP_UINT16_LENGTH;
933     } else {
934         // Data Element: Url uint8 (0x45)
935         buffer[offset] = (DE_TYPE_URL << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
936         offset++;
937         buffer[offset] = urlLen;
938         offset++;
939     }
940     // URL
941     if (urlLen > (SDP_MAX_ATTRIBUTE_LEN - offset)) {
942         urlLen = SDP_MAX_ATTRIBUTE_LEN - offset;
943     }
944     if (memcpy_s(buffer + offset, urlLen, url, urlLen) != EOK) {
945         LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail", __FUNCTION__, __LINE__);
946         return offset;
947     }
948     offset += urlLen;
949 
950     return offset;
951 }
952 
SdpAddAttributeForString(uint8_t * buffer,uint16_t offset,const char * name,uint16_t nameLen)953 static uint16_t SdpAddAttributeForString(uint8_t *buffer, uint16_t offset, const char *name, uint16_t nameLen)
954 {
955     // Name Length
956     if (nameLen > 0xff) {
957         // Data Element: Text string uint16 (0x26)
958         buffer[offset] = (DE_TYPE_STRING << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_16;
959         offset++;
960         *(uint16_t *)(buffer + offset) = H2BE_16(nameLen);
961         offset += SDP_UINT16_LENGTH;
962     } else {
963         // Data Element: Text string uint8 (0x25)
964         buffer[offset] = (DE_TYPE_STRING << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
965         offset++;
966         buffer[offset] = nameLen;
967         offset++;
968     }
969     // Name
970     if (nameLen > SDP_MAX_ATTRIBUTE_LEN - offset) {
971         nameLen = SDP_MAX_ATTRIBUTE_LEN - offset;
972     }
973     if (memcpy_s(buffer + offset, nameLen, name, nameLen) != EOK) {
974         LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail", __FUNCTION__, __LINE__);
975         return offset;
976     }
977     offset += nameLen;
978 
979     return offset;
980 }
981 
SdpAddAttributeToServiceRecord(uint32_t handle,uint16_t attributeId,uint8_t attributeType,uint32_t attributeLength,const uint8_t * value)982 static int SdpAddAttributeToServiceRecord(
983     uint32_t handle, uint16_t attributeId, uint8_t attributeType, uint32_t attributeLength, const uint8_t *value)
984 {
985     uint8_t *attributeValue = NULL;
986     uint16_t offset = 0;
987     ServiceRecordItem *item = NULL;
988 
989     item = FindServiceRecordItem(handle);
990     if (item == NULL) {
991         return BT_BAD_PARAM;
992     }
993     /// Find duplicate attribute id
994     for (int i = 0; i < item->attributeNumber; i++) {
995         if (item->attributeItem[i].attributeId == attributeId) {
996             LOG_ERROR("[%{public}s][%{public}d] Add duplicate attribute [0x%04x]", __FUNCTION__, __LINE__, attributeId);
997             return BT_BAD_PARAM;
998         }
999     }
1000     item->attributeItem[item->attributeNumber].attributeValue =
1001         MEM_MALLOC.alloc(attributeLength + SDP_SERVICE_RECORD_OTHER);
1002     (void)memset_s(item->attributeItem[item->attributeNumber].attributeValue,
1003         attributeLength + SDP_SERVICE_RECORD_OTHER,
1004         0,
1005         attributeLength + SDP_SERVICE_RECORD_OTHER);
1006     attributeValue = item->attributeItem[item->attributeNumber].attributeValue;
1007     /// Data element: Unsigned Integer 2 bytes (0x09)
1008     attributeValue[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
1009     offset++;
1010     /// Attribute id
1011     *(uint16_t *)(attributeValue + offset) = H2BE_16(attributeId);
1012     item->attributeItem[item->attributeNumber].attributeId = attributeId;
1013     offset += SDP_UINT16_LENGTH;
1014 
1015     /// Attribute value
1016     /// Data element
1017     if (attributeType != 0) {
1018         attributeValue[offset] = attributeType;
1019         offset++;
1020         // Data element var size
1021         if (attributeLength > SDP_MAX_ATTRIBUTE_LEN) {
1022             attributeLength = SDP_MAX_ATTRIBUTE_LEN;
1023         }
1024         if (attributeLength > 0xFF) {
1025             *(uint16_t *)(attributeValue + offset) = H2BE_16(attributeLength);
1026             offset += SDP_UINT16_LENGTH;
1027         } else {
1028             attributeValue[offset] = attributeLength & 0xFF;
1029             offset++;
1030         }
1031     }
1032     /// Data element var
1033     if (memcpy_s(attributeValue + offset, attributeLength, value, attributeLength) != EOK) {
1034         LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail", __FUNCTION__, __LINE__);
1035         return BT_OPERATION_FAILED;
1036     }
1037     offset += attributeLength;
1038 
1039     item->attributeItem[item->attributeNumber].attributeLength = offset;
1040     item->totalLength += offset;
1041     item->attributeNumber++;
1042     return BT_SUCCESS;
1043 }
1044 
SdpParseClientRequest(uint16_t lcid,const Packet * data)1045 void SdpParseClientRequest(uint16_t lcid, const Packet *data)
1046 {
1047     uint8_t header[SDP_PDU_HEADER_LENGTH] = {0};
1048     uint16_t transactionId;
1049     uint16_t parameterLength;
1050     Packet *packet = PacketRefMalloc(data);
1051     PacketExtractHead(packet, header, sizeof(header));
1052     size_t size = PacketSize(packet);
1053     BufferInfo bufferInfo;
1054 
1055     /// PDU ID
1056     SdpPduId pduId = header[0];
1057     /// Transaction ID
1058     transactionId = BE2H_16(*(uint16_t *)(header + 1));
1059     /// ParameterLength
1060     parameterLength = BE2H_16(*(uint16_t *)(header + SDP_UINT16_LENGTH + 1));
1061     if (parameterLength != size) {
1062         LOG_ERROR("[%{public}s][%{public}d] Invalid pdu size [%hu] [%zu]", __FUNCTION__, __LINE__, parameterLength, size);
1063         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_PDU_SIZE);
1064         PacketFree(packet);
1065         packet = NULL;
1066         return;
1067     }
1068     LOG_INFO("[%{public}s][%{public}d] pduId[0x%x] transactionId[0x%02x] parameterLength[0x%02x]",
1069         __FUNCTION__,
1070         __LINE__,
1071         pduId,
1072         transactionId,
1073         parameterLength);
1074 
1075     uint8_t *buffer = MEM_MALLOC.alloc(parameterLength);
1076     if (buffer == NULL) {
1077         LOG_ERROR("point to NULL");
1078         return;
1079     }
1080     PacketRead(packet, buffer, 0, parameterLength);
1081 
1082     bufferInfo.buffer = buffer;
1083     bufferInfo.length = parameterLength;
1084 
1085     switch (pduId) {
1086         case SDP_SERVICE_SEARCH_REQUEST:
1087             SdpParseSearchRequest(lcid, transactionId, &bufferInfo);
1088             break;
1089         case SDP_SERVICE_ATTRIBUTE_REQUEST:
1090             SdpParseAttributeRequest(lcid, transactionId, &bufferInfo);
1091             break;
1092         case SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST:
1093             SdpParseSearchAttributeRequest(lcid, transactionId, &bufferInfo);
1094             break;
1095         default:
1096             LOG_ERROR("[%{public}s][%{public}d] Invalid PDU ID [%u]", __FUNCTION__, __LINE__, pduId);
1097             SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_REQ_SYNTAX);
1098             break;
1099     }
1100     MEM_MALLOC.free(buffer);
1101     PacketFree(packet);
1102     packet = NULL;
1103 }
1104 
SdpCreateSearchResponse(uint16_t lcid,uint16_t transactionId,uint8_t uuidArray[][20],int uuidNum,uint16_t maximumServiceRecordCount)1105 static void SdpCreateSearchResponse(
1106     uint16_t lcid, uint16_t transactionId, uint8_t uuidArray[][20], int uuidNum, uint16_t maximumServiceRecordCount)
1107 {
1108     uint8_t *buffer = NULL;
1109     uint32_t *handleArray = NULL;
1110     uint16_t handleNum = 0;
1111     uint16_t offset = 0;
1112 
1113     handleArray = (uint32_t *)MEM_MALLOC.alloc(maximumServiceRecordCount * SDP_SERVICE_RECORD_HANDLE_BYTE);
1114     if (handleArray == NULL) {
1115         LOG_ERROR("point to NULL");
1116         return;
1117     }
1118     buffer = MEM_MALLOC.alloc(SDP_MTU_SIZE);
1119     if (buffer == NULL) {
1120         LOG_ERROR("point to NULL");
1121         return;
1122     }
1123     (void)memset_s(buffer, SDP_MTU_SIZE, 0, SDP_MTU_SIZE);
1124 
1125     handleNum = GetRecordHandleArray(uuidArray, uuidNum, handleArray, handleNum, maximumServiceRecordCount);
1126 
1127     /// ServiceRecordHandleList
1128     for (int i = 0; i < handleNum; i++) {
1129         *(uint32_t *)(buffer + offset) = H2BE_32(handleArray[i]);
1130         offset += SDP_SERVICE_RECORD_HANDLE_BYTE;
1131     }
1132 
1133     SdpSendSearchResponse(lcid, transactionId, offset, buffer, maximumServiceRecordCount);
1134     MEM_MALLOC.free(buffer);
1135     MEM_MALLOC.free(handleArray);
1136 }
1137 
SdpGetUuidArray(uint8_t * buffer,uint16_t pos,uint16_t length,uint8_t uuidArray[][20])1138 static int SdpGetUuidArray(uint8_t *buffer, uint16_t pos, uint16_t length, uint8_t uuidArray[][20])
1139 {
1140     uint16_t uuidNum = 0;
1141     uint16_t offset = 0;
1142 
1143     while (offset < length) {
1144         uint8_t type;
1145         if (uuidNum >= SDP_MAX_UUID_COUNT) {
1146             break;
1147         }
1148         type = buffer[pos + offset];
1149         if (type == 0x19) {
1150             /// UUID 2 bytes (0x19)
1151             (void)memcpy_s(uuidArray + uuidNum, SDP_UUID16_LENGTH + 1, buffer + offset + pos, SDP_UUID16_LENGTH + 1);
1152             offset += SDP_UUID16_LENGTH + 1;
1153         } else if (type == 0x1A) {
1154             /// UUID 4 bytes (0x1A)
1155             (void)memcpy_s(uuidArray + uuidNum, SDP_UUID32_LENGTH + 1, buffer + offset + pos, SDP_UUID32_LENGTH + 1);
1156             offset += SDP_UUID32_LENGTH + 1;
1157         } else if (type == 0x1C) {
1158             /// UUID 16 bytes (0x1C)
1159             (void)memcpy_s(uuidArray + uuidNum, SDP_UUID128_LENGTH + 1, buffer + offset + pos, SDP_UUID128_LENGTH + 1);
1160             offset += SDP_UUID128_LENGTH + 1;
1161         } else {
1162             /// Not UUID
1163             return BT_BAD_PARAM;
1164         }
1165         uuidNum++;
1166     }
1167     return uuidNum;
1168 }
1169 
SdpParseSearchRequest(uint16_t lcid,uint16_t transactionId,BufferInfo * bufferInfo)1170 static void SdpParseSearchRequest(uint16_t lcid, uint16_t transactionId, BufferInfo *bufferInfo)
1171 {
1172     uint8_t uuidArray[SDP_MAX_UUID_COUNT][20];
1173     int uuidNum;
1174     uint16_t maximumServiceRecordCount;
1175     uint8_t continuationStateLen;
1176     uint32_t length = 0;
1177     uint16_t offset = 0;
1178     uint16_t pos;
1179 
1180     /// ServiceSearchPattern
1181     if (bufferInfo->length == 0) {
1182         LOG_ERROR("bufferInfo->length is 0");
1183         return;
1184     }
1185     uint8_t type = bufferInfo->buffer[offset];
1186     offset++;
1187     pos = SdpGetLengthFromType(bufferInfo->buffer + offset, type, &length);
1188     if (bufferInfo->length < offset + pos + length + SDP_UINT16_LENGTH + 1) {
1189         LOG_ERROR("[%{public}s][%{public}d] Wrong length.", __FUNCTION__, __LINE__);
1190         return;
1191     }
1192     offset += pos;
1193     pos = offset;
1194 
1195     /// MaximumServiceRecordCount - uint16_t
1196     offset += length;
1197     maximumServiceRecordCount = BE2H_16(*(uint16_t *)(bufferInfo->buffer + offset));
1198     offset += SDP_UINT16_LENGTH;
1199     LOG_INFO("maxServiceRecordCount [%hu]", maximumServiceRecordCount);
1200 
1201     /// ContinuationState
1202     continuationStateLen = bufferInfo->buffer[offset];
1203     offset++;
1204     LOG_INFO("[%{public}s][%{public}d] continuationStateLen [%hhu].", __FUNCTION__, __LINE__, continuationStateLen);
1205     /// ContinuationStateLen
1206     if (continuationStateLen > SDP_MAX_CONTINUATION_LEN || offset + continuationStateLen > bufferInfo->length) {
1207         LOG_ERROR("%{public}s: continuationStateLen(%{public}u) error", __FUNCTION__, continuationStateLen);
1208         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_CONT_STATE);
1209         return;
1210     }
1211     /// continuation state yes or no (is 0)
1212     if (continuationStateLen != 0) {
1213         uint8_t continuationState[SDP_MAX_CONTINUATION_LEN] = {0};
1214         if (memcpy_s(continuationState, SDP_MAX_CONTINUATION_LEN,
1215             bufferInfo->buffer + offset, continuationStateLen) != EOK) {
1216             LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail.", __FUNCTION__, __LINE__);
1217             return;
1218         }
1219         SdpSendSearchFragmentResponse(lcid, transactionId, maximumServiceRecordCount, NULL);
1220         return;
1221     }
1222 
1223     (void)memset_s(uuidArray, sizeof(uuidArray), 0, sizeof(uuidArray));
1224     uuidNum = SdpGetUuidArray(bufferInfo->buffer, pos, length, uuidArray);
1225     if (uuidNum < 0) {
1226         LOG_ERROR("[%{public}s][%{public}d] transactionId[%02x] Uuid is NULL.", __FUNCTION__, __LINE__, transactionId);
1227         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_REQ_SYNTAX);
1228         return;
1229     }
1230 
1231     SdpCreateSearchResponse(lcid, transactionId, uuidArray, uuidNum, maximumServiceRecordCount);
1232 }
1233 
BuildAttributeListByIdRange(uint32_t handle,uint8_t * buffer,uint8_t * attributeList)1234 static int BuildAttributeListByIdRange(uint32_t handle, uint8_t *buffer, uint8_t *attributeList)
1235 {
1236     ServiceRecordItem *item = NULL;
1237     uint16_t offset = 0;
1238     uint16_t start;
1239     uint16_t end;
1240 
1241     /// All attribute range 0x0000 - 0xFFFF
1242     uint8_t type = buffer[0];
1243     if (((type >> SDP_DESCRIPTOR_SIZE_BIT) != DE_TYPE_UINT) || ((type & 0x07) != DE_SIZE_32)) {
1244         LOG_ERROR("[%{public}s][%{public}d] Wrong type with AtriuteID Range [0x%02x].", __FUNCTION__, __LINE__, type);
1245         return BT_BAD_PARAM;
1246     }
1247     start = BE2H_16(*(uint16_t *)(buffer + 1));
1248     end = BE2H_16(*(uint16_t *)(buffer + SDP_UINT16_LENGTH + 1));
1249 
1250     item = FindServiceRecordItem(handle);
1251     if (item == NULL) {
1252         return BT_BAD_PARAM;
1253     }
1254     for (int i = 0; i < item->attributeNumber; i++) {
1255         if ((item->attributeItem[i].attributeId >= start) && (item->attributeItem[i].attributeId <= end)) {
1256             if ((item->attributeItem[i].attributeLength + offset) >= (SDP_MAX_LIST_BYTE_COUNT - SDP_RESERVE_LENGTH)) {
1257                 return BT_BAD_PARAM;
1258             }
1259             if (memcpy_s(attributeList + offset,
1260                 item->attributeItem[i].attributeLength,
1261                 item->attributeItem[i].attributeValue,
1262                 item->attributeItem[i].attributeLength) != EOK) {
1263                     LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail.", __FUNCTION__, __LINE__);
1264                     return BT_NO_MEMORY;
1265                 }
1266             offset += item->attributeItem[i].attributeLength;
1267         }
1268     }
1269     return offset;
1270 }
1271 
BuildAttributeListByIdList(uint32_t handle,uint16_t length,uint8_t * buffer,uint8_t * attributeList)1272 static int BuildAttributeListByIdList(uint32_t handle, uint16_t length, uint8_t *buffer, uint8_t *attributeList)
1273 {
1274     ServiceRecordItem *item = NULL;
1275     uint16_t offset = 0;
1276     uint16_t pos = 0;
1277     uint16_t number;
1278 
1279     item = FindServiceRecordItem(handle);
1280     if (item == NULL) {
1281         return BT_BAD_PARAM;
1282     }
1283     number = length / (SDP_UINT16_LENGTH + 1);
1284     for (int i = 0; i < number; i++) {
1285         uint16_t attributeId;
1286         uint8_t type;
1287         type = buffer[pos];
1288         if (((type >> SDP_DESCRIPTOR_SIZE_BIT) != DE_TYPE_UINT) || ((type & 0x07) != DE_SIZE_16)) {
1289             LOG_ERROR("[%{public}s][%{public}d] Wrong type with AtriuteID Range [0x%02x].", __FUNCTION__, __LINE__, type);
1290             return BT_BAD_PARAM;
1291         }
1292         pos++;
1293         attributeId = BE2H_16(*(uint16_t *)(buffer + pos));
1294         pos += SDP_UINT16_LENGTH;
1295 
1296         for (int j = 0; j < item->attributeNumber; j++) {
1297             if (item->attributeItem[j].attributeId == attributeId) {
1298                 (void)memcpy_s(attributeList + offset,
1299                     item->attributeItem[j].attributeLength,
1300                     item->attributeItem[j].attributeValue,
1301                     item->attributeItem[j].attributeLength);
1302                 offset += item->attributeItem[j].attributeLength;
1303                 break;
1304             }
1305         }
1306     }
1307 
1308     return offset;
1309 }
1310 
SdpCreateAttributeResponse(uint16_t lcid,uint16_t transactionId,uint8_t * attributeList,int length,uint16_t maximumAttributeByteCount)1311 static void SdpCreateAttributeResponse(
1312     uint16_t lcid, uint16_t transactionId, uint8_t *attributeList, int length, uint16_t maximumAttributeByteCount)
1313 {
1314     uint8_t *buffer = NULL;
1315     Packet *packet = NULL;
1316     uint16_t offset = 0;
1317 
1318     if (length <= 0xFF) {
1319         buffer = MEM_MALLOC.alloc(length + 1 + SDP_UINT8_LENGTH);
1320         if (buffer == NULL) {
1321             LOG_ERROR("point to NULL");
1322             return;
1323         }
1324         buffer[0] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
1325         buffer[1] = length & 0xFF;
1326         offset += 1 + SDP_UINT8_LENGTH;
1327     } else if (length <= 0xFFFF) {
1328         buffer = MEM_MALLOC.alloc(length + 1 + SDP_UINT16_LENGTH);
1329         if (buffer == NULL) {
1330             LOG_ERROR("point to NULL");
1331             return;
1332         }
1333         buffer[0] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_16;
1334         *(uint16_t *)(buffer + 1) = H2BE_16(length);
1335         offset += 1 + SDP_UINT16_LENGTH;
1336     } else {
1337         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_PDU_SIZE);
1338         return;
1339     }
1340     if (memcpy_s(buffer + offset, length, attributeList, length) != EOK) {
1341         LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail.", __FUNCTION__, __LINE__);
1342         MEM_MALLOC.free(buffer);
1343         return;
1344     }
1345     offset += length;
1346 
1347     packet = PacketMalloc(0, 0, offset);
1348     PacketPayloadWrite(packet, buffer, 0, offset);
1349     SdpSendAttributeResponse(lcid, transactionId, SDP_SERVICE_ATTRIBUTE_RESPONSE, maximumAttributeByteCount, packet);
1350 
1351     MEM_MALLOC.free(buffer);
1352     PacketFree(packet);
1353     packet = NULL;
1354 }
1355 
SdpParseAttributeRequest(uint16_t lcid,uint16_t transactionId,BufferInfo * bufferInfo)1356 static void SdpParseAttributeRequest(uint16_t lcid, uint16_t transactionId, BufferInfo *bufferInfo)
1357 {
1358     ServiceRecordItem *item = NULL;
1359     uint16_t maximumAttributeByteCount;
1360     uint8_t attributeList[SDP_MAX_LIST_BYTE_COUNT] = {0};
1361     uint8_t continuationStateLen;
1362     uint8_t type;
1363     uint32_t length = 0;
1364     uint16_t offset = 0;
1365     uint16_t pos;
1366     int result;
1367 
1368     /// ServiceRecordHandle
1369     uint32_t handle = BE2H_32(*(uint32_t *)(bufferInfo->buffer + offset));
1370     offset += SDP_SERVICE_RECORD_HANDLE_BYTE;
1371 
1372     /// MaximumAttributeByteCount
1373     maximumAttributeByteCount = BE2H_16(*(uint16_t *)(bufferInfo->buffer + offset));
1374     offset += SDP_UINT16_LENGTH;
1375 
1376     /// AttributeIDList
1377     type = bufferInfo->buffer[offset];
1378     offset++;
1379     pos = SdpGetLengthFromType(bufferInfo->buffer + offset, type, &length);
1380     if (bufferInfo->length < length) {
1381         LOG_ERROR("[%{public}s][%{public}d] Wrong length.", __FUNCTION__, __LINE__);
1382         return;
1383     }
1384     offset += pos;
1385     pos = offset;
1386 
1387     /// ContinuationState
1388     offset += length;
1389     continuationStateLen = bufferInfo->buffer[offset];
1390     offset++;
1391     LOG_INFO("[%{public}s][%{public}d] continuation state Length [%hhu].", __FUNCTION__, __LINE__, continuationStateLen);
1392     /// ContinuationStateLen
1393     if (continuationStateLen > SDP_MAX_CONTINUATION_LEN) {
1394         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_CONT_STATE);
1395         return;
1396     }
1397     /// continuation state yes or no (is 0)
1398     if (continuationStateLen != 0) {
1399         uint8_t continuationState[SDP_MAX_CONTINUATION_LEN] = {0};
1400         if (memcpy_s(continuationState, SDP_MAX_CONTINUATION_LEN,
1401             bufferInfo->buffer + offset, continuationStateLen) != EOK) {
1402             return;
1403         }
1404         SdpSendAttributeFragmentResponse(
1405             lcid, SDP_SERVICE_ATTRIBUTE_RESPONSE, transactionId, maximumAttributeByteCount, NULL);
1406         return;
1407     }
1408 
1409     item = FindServiceRecordItem(handle);
1410     if (item == NULL) {
1411         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_SERV_REC_HDL);
1412         return;
1413     }
1414 
1415     if (length == (SDP_UINT32_LENGTH + 1)) {
1416         /// Range of attribute id
1417         result = BuildAttributeListByIdRange(handle, bufferInfo->buffer + pos, attributeList);
1418     } else {
1419         /// List of attribute id
1420         result = BuildAttributeListByIdList(handle, length, bufferInfo->buffer + pos, attributeList);
1421     }
1422     if (result < 0) {
1423         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_REQ_SYNTAX);
1424         return;
1425     }
1426 
1427     SdpCreateAttributeResponse(lcid, transactionId, attributeList, result, maximumAttributeByteCount);
1428 }
1429 
BuildServiceRecordHandleList(const uint8_t * buffer,uint16_t pos,uint8_t * bufferEnd,uint32_t * handleArray)1430 static int BuildServiceRecordHandleList(const uint8_t *buffer, uint16_t pos, uint8_t *bufferEnd, uint32_t *handleArray)
1431 {
1432     uint8_t uuidArray[SDP_MAX_UUID_COUNT][20] = {0};
1433     int uuidNum = 0;
1434     uint16_t handleNum = 0;
1435 
1436     while (buffer + pos < bufferEnd) {
1437         uint8_t type;
1438         if (uuidNum >= SDP_MAX_UUID_COUNT) {
1439             LOG_INFO("UuidNum [%{public}d] is more than 12.", uuidNum);
1440             break;
1441         }
1442         type = *(buffer + pos);
1443         if (type == 0x19) {
1444             /// UUID 2 bytes (0x19)
1445             if (memcpy_s(uuidArray + uuidNum, SDP_UUID16_LENGTH + 1, buffer + pos, SDP_UUID16_LENGTH + 1) != EOK) {
1446                 LOG_ERROR("[%{public}s][%{public}d] memcpy_s SDP_UUID16 fail.", __FUNCTION__, __LINE__);
1447                 return BT_NO_MEMORY;
1448             }
1449             pos += SDP_UUID16_LENGTH + 1;
1450         } else if (type == 0x1A) {
1451             /// UUID 4 bytes (0x1A)
1452             if (memcpy_s(uuidArray + uuidNum, SDP_UUID32_LENGTH + 1, buffer + pos, SDP_UUID32_LENGTH + 1) != EOK) {
1453                 LOG_ERROR("[%{public}s][%{public}d] memcpy_s SDP_UUID32 fail.", __FUNCTION__, __LINE__);
1454                 return BT_NO_MEMORY;
1455             }
1456             pos += SDP_UUID32_LENGTH + 1;
1457         } else if (type == 0x1C) {
1458             /// UUID 16 bytes (0x1C)
1459             if (memcpy_s(uuidArray + uuidNum, SDP_UUID128_LENGTH + 1, buffer + pos, SDP_UUID128_LENGTH + 1) != EOK) {
1460                 LOG_ERROR("[%{public}s][%{public}d] memcpy_s SDP_UUID128 fail.", __FUNCTION__, __LINE__);
1461                 return BT_NO_MEMORY;
1462             }
1463             pos += SDP_UUID128_LENGTH + 1;
1464         } else {
1465             LOG_ERROR("The type [0x%02x] is wrong.", type);
1466             return BT_BAD_PARAM;
1467         }
1468         uuidNum++;
1469     }
1470 
1471     handleNum = GetRecordHandleArray(uuidArray, uuidNum, handleArray, handleNum, 0);
1472 
1473     return handleNum;
1474 }
1475 
BuildAttributeListArrayCommon(int offset,uint8_t * attributeList,Packet * packet)1476 static Packet *BuildAttributeListArrayCommon(int offset, uint8_t *attributeList, Packet *packet)
1477 {
1478     Buffer *newBuffer = NULL;
1479     uint8_t *bufferPtr = NULL;
1480 
1481     if (offset < 0) {
1482         return NULL;
1483     } else if (offset <= 0xFF) {
1484         newBuffer = BufferMalloc(offset + SDP_UINT8_LENGTH + 1);
1485         bufferPtr = BufferPtr(newBuffer);
1486         bufferPtr[0] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
1487         bufferPtr[1] = offset;
1488         if (memcpy_s(bufferPtr + SDP_UINT8_LENGTH + 1, offset, attributeList, offset) != EOK) {
1489             LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail.", __FUNCTION__, __LINE__);
1490             BufferFree(newBuffer);
1491             return NULL;
1492         }
1493     } else if (offset <= 0xFFFF) {
1494         newBuffer = BufferMalloc(offset + SDP_UINT16_LENGTH + 1);
1495         bufferPtr = BufferPtr(newBuffer);
1496         bufferPtr[0] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_16;
1497         *(uint16_t *)(bufferPtr + 1) = H2BE_16(offset);
1498         if (memcpy_s(bufferPtr + SDP_UINT16_LENGTH + 1, (uint16_t)offset, attributeList, (uint16_t)offset) != EOK) {
1499             LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail.", __FUNCTION__, __LINE__);
1500             BufferFree(newBuffer);
1501             return NULL;
1502         }
1503     } else {
1504         return NULL;
1505     }
1506     PacketPayloadAddLast(packet, newBuffer);
1507     BufferFree(newBuffer);
1508 
1509     return packet;
1510 }
1511 
BuildAttributeListArray(uint8_t * buffer,uint16_t length,uint32_t * handleArray,int handleNum)1512 static Packet *BuildAttributeListArray(uint8_t *buffer, uint16_t length, uint32_t *handleArray, int handleNum)
1513 {
1514     uint8_t attributeList[SDP_MAX_LIST_BYTE_COUNT] = {0};
1515     Packet *packet = NULL;
1516     int offset;
1517     int i;
1518 
1519     packet = PacketMalloc(0, 0, 0);
1520     if (length == (SDP_UINT32_LENGTH + 1)) {
1521         /// Range of attribute id
1522         if (buffer[0] != 0x0A) {
1523             return NULL;
1524         }
1525 
1526         for (i = 0; i < handleNum; i++) {
1527             offset = BuildAttributeListByIdRange(handleArray[i], buffer, attributeList);
1528             packet = BuildAttributeListArrayCommon(offset, attributeList, packet);
1529             if (packet == NULL) {
1530                 return NULL;
1531             }
1532         }
1533     } else {
1534         if (((length % (SDP_UINT16_LENGTH + 1)) != 0) || (buffer[0] != 0x09)) {
1535             return NULL;
1536         }
1537         /// List of attribute id
1538         for (i = 0; i < handleNum; i++) {
1539             offset = BuildAttributeListByIdList(handleArray[i], length, buffer, attributeList);
1540             packet = BuildAttributeListArrayCommon(offset, attributeList, packet);
1541             if (packet == NULL) {
1542                 return NULL;
1543             }
1544         }
1545     }
1546 
1547     return packet;
1548 }
1549 
SdpCreateSearchAttributeResponse(uint16_t lcid,uint16_t transactionId,Packet * payloadPacket,uint16_t maximumAttributeByteCount)1550 static void SdpCreateSearchAttributeResponse(
1551     uint16_t lcid, uint16_t transactionId, Packet *payloadPacket, uint16_t maximumAttributeByteCount)
1552 {
1553     Packet *packet = NULL;
1554     uint8_t *header = NULL;
1555     uint16_t length = PacketPayloadSize(payloadPacket);
1556     if (length <= 0xFF) {
1557         packet = PacketInheritMalloc(payloadPacket, SDP_UINT8_LENGTH + 1, 0);
1558         header = BufferPtr(PacketHead(packet));
1559         header[0] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
1560         header[1] = length;
1561     } else {
1562         packet = PacketInheritMalloc(payloadPacket, SDP_UINT16_LENGTH + 1, 0);
1563         header = BufferPtr(PacketHead(packet));
1564         header[0] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_16;
1565         *(uint16_t *)(header + 1) = H2BE_16(length);
1566     }
1567     SdpSendAttributeResponse(
1568         lcid, transactionId, SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE, maximumAttributeByteCount, packet);
1569 
1570     PacketFree(packet);
1571     packet = NULL;
1572 }
1573 
SdpParseSearchAttributeRequestCommon(uint16_t lcid,uint16_t transactionId,uint16_t maximumAttributeByteCount,uint8_t * buffer,uint16_t offset)1574 static uint16_t SdpParseSearchAttributeRequestCommon(
1575     uint16_t lcid, uint16_t transactionId, uint16_t maximumAttributeByteCount, uint8_t *buffer, uint16_t offset)
1576 {
1577     /// ContinuationState
1578     uint8_t continuationStateLen = buffer[offset];
1579 
1580     LOG_INFO("[%{public}s][%{public}d] continuation state Length [%hhu].", __FUNCTION__, __LINE__, continuationStateLen);
1581     offset++;
1582     /// ContinuationStateLen
1583     if (continuationStateLen > SDP_MAX_CONTINUATION_LEN) {
1584         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_CONT_STATE);
1585         return 0;
1586     }
1587     /// continuation state yes or no (is 0)
1588     if (continuationStateLen != 0) {
1589         uint8_t continuationState[SDP_MAX_CONTINUATION_LEN] = {0};
1590         if (memcpy_s(continuationState, SDP_MAX_CONTINUATION_LEN, buffer + offset, continuationStateLen) != EOK) {
1591             LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail.", __FUNCTION__, __LINE__);
1592             return 0;
1593         }
1594         SdpSendAttributeFragmentResponse(
1595             lcid, SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE, transactionId, maximumAttributeByteCount, NULL);
1596         return 0;
1597     }
1598 
1599     return offset;
1600 }
1601 
SdpParseSearchAttributeRequest(uint16_t lcid,uint16_t transactionId,BufferInfo * bufferInfo)1602 static void SdpParseSearchAttributeRequest(uint16_t lcid, uint16_t transactionId, BufferInfo *bufferInfo)
1603 {
1604     uint32_t serviceSearchPatternLength = 0;
1605     uint32_t attributeIDListLength = 0;
1606     uint16_t attributeIDListPos;
1607     uint16_t offset = 0;
1608 
1609     /// ServiceSearchPattern
1610     uint8_t type = bufferInfo->buffer[offset];
1611     offset++;
1612     uint16_t pos = SdpGetLengthFromType(bufferInfo->buffer + offset, type, &serviceSearchPatternLength);
1613     if (bufferInfo->length < serviceSearchPatternLength) {
1614         LOG_ERROR("[%{public}s][%{public}d] Wrong length.", __FUNCTION__, __LINE__);
1615         return;
1616     }
1617     offset += pos;
1618 
1619     uint16_t serviceSearchPatternPos = offset;
1620     offset += serviceSearchPatternLength;
1621 
1622     /// MaximumAttributeByteCount
1623     uint16_t maximumAttributeByteCount = BE2H_16(*(uint16_t *)(bufferInfo->buffer + offset));
1624     offset += SDP_UINT16_LENGTH;
1625 
1626     /// AttributeIDList
1627     type = bufferInfo->buffer[offset];
1628     offset++;
1629     pos = SdpGetLengthFromType(bufferInfo->buffer + offset, type, &attributeIDListLength);
1630     if (bufferInfo->length < attributeIDListLength) {
1631         LOG_ERROR("[%{public}s][%{public}d] Wrong length.", __FUNCTION__, __LINE__);
1632         return;
1633     }
1634     offset += pos;
1635 
1636     attributeIDListPos = offset;
1637     offset += attributeIDListLength;
1638 
1639     offset = SdpParseSearchAttributeRequestCommon(lcid, transactionId, maximumAttributeByteCount,
1640         bufferInfo->buffer, offset);
1641     if (offset == 0) {
1642         return;
1643     }
1644 
1645     uint16_t size = (uint16_t)ListGetSize(g_serviceRecordList);
1646     uint32_t *handleArray = (uint32_t *)MEM_MALLOC.alloc(SDP_UINT32_LENGTH * size);
1647     if (handleArray == NULL) {
1648         LOG_ERROR("point to NULL");
1649         return;
1650     }
1651     uint8_t *bufferEnd = bufferInfo->buffer + serviceSearchPatternPos + serviceSearchPatternLength;
1652     (void)memset_s(handleArray, SDP_UINT32_LENGTH * size, 0, SDP_UINT32_LENGTH * size);
1653     int handleNum = BuildServiceRecordHandleList(bufferInfo->buffer, serviceSearchPatternPos, bufferEnd, handleArray);
1654     LOG_INFO("[%{public}s][%{public}d] handleNum = [%{public}d]", __FUNCTION__, __LINE__, handleNum);
1655 
1656     if (handleNum >= 0) {
1657         Packet *packet =
1658             BuildAttributeListArray(bufferInfo->buffer + attributeIDListPos, attributeIDListLength,
1659                 handleArray, handleNum);
1660         if (packet != NULL) {
1661             SdpCreateSearchAttributeResponse(lcid, transactionId, packet, maximumAttributeByteCount);
1662             PacketFree(packet);
1663             packet = NULL;
1664         } else {
1665             LOG_ERROR("[%{public}s][%{public}d] transactionId[%02x] packet is NULL.",
1666                 __FUNCTION__, __LINE__, transactionId);
1667             SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_REQ_SYNTAX);
1668         }
1669     } else {
1670         SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_REQ_SYNTAX);
1671     }
1672     MEM_MALLOC.free(handleArray);
1673     handleArray = NULL;
1674 }
1675 
1676 /**
1677  * @brief    SortForAttributeId
1678  * @detail   Sort attribute by attribute id in ascending order.
1679  * @para[in] attributeItem: attribute items
1680  * @para[in] attributeNumber:       the number of attribute items
1681  * @return   void
1682  */
SortForAttributeId(AttributeItem * attributeItem,uint16_t attributeNumber)1683 static void SortForAttributeId(AttributeItem *attributeItem, uint16_t attributeNumber)
1684 {
1685     int i;
1686     int j;
1687     AttributeItem item;
1688 
1689     for (i = 0; i < attributeNumber - 1; i++) {
1690         for (j = 0; j < attributeNumber - 1 - i; j++) {
1691             if (attributeItem[j].attributeId > attributeItem[j + 1].attributeId) {
1692                 item = attributeItem[j + 1];
1693                 attributeItem[j + 1] = attributeItem[j];
1694                 attributeItem[j] = item;
1695             }
1696         }
1697     }
1698 }
1699 
1700 /**
1701  * @brief  If two UUIDs of differing sizes are to be compared, the shorter UUID must be converted to
1702  *         the longer UUID format before comparison.
1703  *
1704  * @return True or false.
1705  */
CompareUuid(const uint8_t * uuid1,uint16_t length1,const uint8_t * uuid2,uint16_t length2)1706 static bool CompareUuid(const uint8_t *uuid1, uint16_t length1, const uint8_t *uuid2, uint16_t length2)
1707 {
1708     uint8_t value1[SDP_UUID128_LENGTH] = {0};
1709     uint8_t value2[SDP_UUID128_LENGTH] = {0};
1710     bool result = false;
1711 
1712     if (((length1 != SDP_UUID16_LENGTH) && (length1 != SDP_UUID32_LENGTH) && (length1 != SDP_UUID128_LENGTH)) ||
1713         ((length2 != SDP_UUID16_LENGTH) && (length2 != SDP_UUID32_LENGTH) && (length2 != SDP_UUID128_LENGTH))) {
1714         LOG_ERROR("[%{public}s][%{public}d] Uuid length is invalid.", __FUNCTION__, __LINE__);
1715         return false;
1716     }
1717     if (length1 == SDP_UUID16_LENGTH) {
1718         /// uuid1 length is 2
1719         (void)memcpy_s(value1, SDP_UUID128_LENGTH, G_BASE_UUID, SDP_UUID128_LENGTH);
1720         (void)memcpy_s(value1 + SDP_UUID16_LENGTH, SDP_UUID16_LENGTH, uuid1, SDP_UUID16_LENGTH);
1721     } else if (length1 == SDP_UUID32_LENGTH) {
1722         // uuid2 length is 4
1723         (void)memcpy_s(value1, SDP_UUID128_LENGTH, G_BASE_UUID, SDP_UUID128_LENGTH);
1724         (void)memcpy_s(value1, SDP_UUID32_LENGTH, uuid1, SDP_UUID32_LENGTH);
1725     } else {
1726         (void)memcpy_s(value1, SDP_UUID128_LENGTH, uuid1, SDP_UUID128_LENGTH);
1727     }
1728 
1729     if (length2 == SDP_UUID16_LENGTH) {
1730         /// uuid1 length is 2
1731         (void)memcpy_s(value2, SDP_UUID128_LENGTH, G_BASE_UUID, SDP_UUID128_LENGTH);
1732         (void)memcpy_s(value2 + SDP_UUID16_LENGTH, SDP_UUID16_LENGTH, uuid2, SDP_UUID16_LENGTH);
1733     } else if (length2 == SDP_UUID32_LENGTH) {
1734         // uuid2 length is 4
1735         (void)memcpy_s(value2, SDP_UUID128_LENGTH, G_BASE_UUID, SDP_UUID128_LENGTH);
1736         if (memcpy_s(value2, SDP_UUID128_LENGTH, uuid2, SDP_UUID32_LENGTH) != EOK) {
1737             LOG_ERROR("[%{public}s][%{public}d] memcpy_s fail.", __FUNCTION__, __LINE__);
1738             return false;
1739         }
1740     } else {
1741         (void)memcpy_s(value2, SDP_UUID128_LENGTH, uuid2, SDP_UUID128_LENGTH);
1742     }
1743 
1744     result = (memcmp(value1, value2, SDP_UUID128_LENGTH) == 0) ? true : false;
1745 
1746     return result;
1747 }
1748 
GetUuidfromSequenceLevelThree(uint8_t * buffer,uint16_t bufferLen,uint8_t * uuid,uint16_t uuidLen)1749 static bool GetUuidfromSequenceLevelThree(uint8_t *buffer, uint16_t bufferLen, uint8_t *uuid, uint16_t uuidLen)
1750 {
1751     uint32_t length = 0;
1752     uint16_t offset = 0;
1753     uint16_t index = 0;
1754 
1755     while (index < bufferLen) {
1756         uint8_t type;
1757         type = buffer[offset];
1758         offset++;
1759         SdpGetLengthFromType(buffer + offset, type, &length);
1760         if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_UUID) {
1761             if (CompareUuid(buffer + offset, length, uuid, uuidLen)) {
1762                 return true;
1763             }
1764             offset += length;
1765         } else if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_DES) {
1766             return false;
1767         }
1768         index += offset;
1769     }
1770     return false;
1771 }
1772 
GetUuidfromSequenceLevelTwo(uint8_t * buffer,uint16_t bufferLen,uint8_t * uuid,uint16_t uuidLen)1773 static bool GetUuidfromSequenceLevelTwo(uint8_t *buffer, uint16_t bufferLen, uint8_t *uuid, uint16_t uuidLen)
1774 {
1775     uint32_t length = 0;
1776     uint16_t offset = 0;
1777     uint16_t index = 0;
1778 
1779     while (index < bufferLen) {
1780         uint8_t type;
1781         type = buffer[offset];
1782         offset++;
1783         uint16_t position = SdpGetLengthFromType(buffer + offset, type, &length);
1784         if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_UUID) {
1785             if (CompareUuid(buffer + offset, length, uuid, uuidLen)) {
1786                 return true;
1787             }
1788             offset += length;
1789         } else if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_DES) {
1790             offset += position;
1791             if (GetUuidfromSequenceLevelThree(buffer + offset, length, uuid, uuidLen)) {
1792                 return true;
1793             }
1794             offset += length;
1795         }
1796         index += offset;
1797     }
1798     return false;
1799 }
1800 
GetUuidfromSequenceLevelOne(uint8_t * buffer,uint16_t bufferLen,uint8_t * uuid,uint16_t uuidLen)1801 static bool GetUuidfromSequenceLevelOne(uint8_t *buffer, uint16_t bufferLen, uint8_t *uuid, uint16_t uuidLen)
1802 {
1803     uint32_t length = 0;
1804     uint16_t offset = 0;
1805     uint16_t index = 0;
1806 
1807     while (index < bufferLen) {
1808         uint8_t type;
1809         type = buffer[offset];
1810         offset++;
1811         uint16_t pos = SdpGetLengthFromType(buffer + offset, type, &length);
1812         if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_UUID) {
1813             if (CompareUuid(buffer + offset, length, uuid, uuidLen)) {
1814                 return true;
1815             }
1816             offset += length;
1817         } else if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_DES) {
1818             offset += pos;
1819             if (GetUuidfromSequenceLevelTwo(buffer + offset, length, uuid, uuidLen)) {
1820                 return true;
1821             }
1822             offset += length;
1823         }
1824         index += offset;
1825     }
1826     return false;
1827 }
1828 
GetUuidfromSequence(uint8_t * buffer,uint16_t bufferLen,uint8_t * uuid,uint16_t uuidLen)1829 static bool GetUuidfromSequence(uint8_t *buffer, uint16_t bufferLen, uint8_t *uuid, uint16_t uuidLen)
1830 {
1831     uint32_t length = 0;
1832     uint16_t offset = 0;
1833     uint16_t index = 0;
1834 
1835     while (index < bufferLen) {
1836         uint8_t type;
1837         uint16_t pos;
1838         type = buffer[offset];
1839         offset++;
1840         pos = SdpGetLengthFromType(buffer + offset, type, &length);
1841         if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_UUID) {
1842             if (CompareUuid(buffer + offset, length, uuid, uuidLen)) {
1843                 return true;
1844             }
1845             offset += length;
1846         } else if ((type >> SDP_DESCRIPTOR_SIZE_BIT) == DE_TYPE_DES) {
1847             offset += pos;
1848             if (GetUuidfromSequenceLevelOne(buffer + offset, length, uuid, uuidLen)) {
1849                 return true;
1850             }
1851             offset += length;
1852         }
1853         index += offset;
1854     }
1855     return false;
1856 }
1857 
GetRecordHandleArrayByUuid(ServiceRecordItem * item,uint8_t * uuid)1858 static bool GetRecordHandleArrayByUuid(ServiceRecordItem *item, uint8_t *uuid)
1859 {
1860     const uint16_t offset = 3;
1861     uint16_t uuidLen = 0;
1862     // Uuid type of request
1863     uint8_t uuidType = uuid[0];
1864 
1865     if (uuidType == 0x19) {
1866         uuidLen = SDP_UUID16_LENGTH;
1867     } else if (uuidType == 0x1A) {
1868         uuidLen = SDP_UUID32_LENGTH;
1869     } else if (uuidType == 0x1C) {
1870         uuidLen = SDP_UUID128_LENGTH;
1871     } else {
1872         return false;
1873     }
1874 
1875     for (int i = 0; i < item->attributeNumber; i++) {
1876         // Uuid type of attributeValue
1877         uint8_t type;
1878         type = item->attributeItem[i].attributeValue[offset] >> SDP_DESCRIPTOR_SIZE_BIT;
1879         bool ret;
1880         if (type == DE_TYPE_UUID) {
1881             /// Only one uuid
1882             ret = CompareUuid(item->attributeItem[i].attributeValue + offset + 1,
1883                 item->attributeItem[i].attributeLength - offset - 1,
1884                 uuid + 1,
1885                 uuidLen);
1886             if (ret) {
1887                 return true;
1888             }
1889         } else if (type == DE_TYPE_DES) {
1890             /// A sequence of uuids
1891             ret = GetUuidfromSequence(item->attributeItem[i].attributeValue + offset,
1892                 item->attributeItem[i].attributeLength - offset,
1893                 uuid + 1,
1894                 uuidLen);
1895             if (ret) {
1896                 return true;
1897             }
1898         }
1899     }
1900     return false;
1901 }
1902 
GetRecordHandleNumber(ServiceRecordItem * item,uint8_t uuidArray[][20],int uuidNum,uint32_t * handleArray,uint16_t handleNum)1903 static uint16_t GetRecordHandleNumber(
1904     ServiceRecordItem *item, uint8_t uuidArray[][20], int uuidNum, uint32_t *handleArray, uint16_t handleNum)
1905 {
1906     for (int i = 0; i < uuidNum; i++) {
1907         bool ret;
1908         ret = GetRecordHandleArrayByUuid(item, uuidArray[i]);
1909         if (ret) {
1910             handleArray[handleNum] = item->serviceRecordHandle;
1911             handleNum++;
1912             break;
1913         }
1914     }
1915     return handleNum;
1916 }
1917 
GetRecordHandleArray(uint8_t uuidArray[][20],int uuidNum,uint32_t * handleArray,uint16_t handleNum,uint16_t maxRecordCount)1918 static uint16_t GetRecordHandleArray(
1919     uint8_t uuidArray[][20], int uuidNum, uint32_t *handleArray, uint16_t handleNum, uint16_t maxRecordCount)
1920 {
1921     ServiceRecordItem *item = NULL;
1922     ListNode *node = NULL;
1923 
1924     if (g_serviceRecordList == NULL) {
1925         LOG_ERROR("[%{public}s][%{public}d] ServiceRecordList is empty.", __FUNCTION__, __LINE__);
1926         return 0;
1927     }
1928     node = ListGetFirstNode(g_serviceRecordList);
1929     while (node != NULL) {
1930         item = ListGetNodeData(node);
1931         handleNum = GetRecordHandleNumber(item, uuidArray, uuidNum, handleArray, handleNum);
1932         if ((maxRecordCount != 0) && (handleNum >= maxRecordCount)) {
1933             break;
1934         }
1935         node = ListGetNextNode(node);
1936     }
1937     return handleNum;
1938 }
1939 
FindServiceRecordItem(uint32_t handle)1940 static ServiceRecordItem *FindServiceRecordItem(uint32_t handle)
1941 {
1942     ServiceRecordItem *item = NULL;
1943     ListNode *node = NULL;
1944 
1945     if (g_serviceRecordList == NULL) {
1946         return NULL;
1947     }
1948     node = ListGetFirstNode(g_serviceRecordList);
1949     while (node != NULL) {
1950         item = ListGetNodeData(node);
1951         if (item->serviceRecordHandle == handle) {
1952             return item;
1953         }
1954         node = ListGetNextNode(node);
1955     }
1956     return NULL;
1957 }
1958