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