1 /*
2  * Copyright (C) 2021 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_util.h"
17 
18 #include <stdio.h>
19 #include <string.h>
20 
21 #include "bt_endian.h"
22 #include "log.h"
23 
24 static bool g_sdpEnableState = true;
25 
SdpSetEnableState()26 void SdpSetEnableState()
27 {
28     g_sdpEnableState = true;
29 }
30 
SdpSetDisableState()31 void SdpSetDisableState()
32 {
33     g_sdpEnableState = false;
34 }
35 
SdpGetEnableState()36 bool SdpGetEnableState()
37 {
38     return g_sdpEnableState;
39 }
40 
SdpReverseForBigEndian(const uint8_t * src,uint8_t * dst,int length)41 void SdpReverseForBigEndian(const uint8_t *src, uint8_t *dst, int length)
42 {
43     for (int i = 0; i < length; i++) {
44         dst[length - 1 - i] = src[i];
45     }
46 }
47 
SdpAddAttributeForUuid(uint8_t * buffer,uint16_t offset,const BtUuid * uuid)48 uint16_t SdpAddAttributeForUuid(uint8_t *buffer, uint16_t offset, const BtUuid *uuid)
49 {
50     switch (uuid->type) {
51         case BT_UUID_16:
52             /// Data Element: UUID 2 bytes (0x19)
53             buffer[offset] = (DE_TYPE_UUID << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
54             offset++;
55             /// UUID
56             *(uint16_t *)(buffer + offset) = H2BE_16(uuid->uuid16);
57             offset += SDP_UUID16_LENGTH;
58             break;
59         case BT_UUID_32:
60             /// Data Element: UUID 4 bytes (0x1A)
61             buffer[offset] = (DE_TYPE_UUID << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_32;
62             offset++;
63             /// UUID
64             *(uint32_t *)(buffer + offset) = H2BE_32(uuid->uuid32);
65             offset += SDP_UUID32_LENGTH;
66             break;
67         case BT_UUID_128:
68             /// Data Element: UUID 16 bytes (0x1C)
69             buffer[offset] = (DE_TYPE_UUID << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_128;
70             offset++;
71             /// UUID
72             SdpReverseForBigEndian(uuid->uuid128, buffer + offset, SDP_UUID128_LENGTH);
73             offset += SDP_UUID128_LENGTH;
74             break;
75         default:
76             LOG_ERROR("[%{public}s][%{public}d] Wrong type [0x%02x]", __FUNCTION__, __LINE__, uuid->type);
77             break;
78     }
79 
80     return offset;
81 }
82 
83 /**
84  * @brief Get length from type
85  * @details
86  * @param
87  * @return
88  */
SdpGetLengthFromType(const uint8_t * buffer,uint8_t type,uint32_t * length)89 uint16_t SdpGetLengthFromType(const uint8_t *buffer, uint8_t type, uint32_t *length)
90 {
91     uint16_t offset = 0;
92     SdpDescriptorSize size = type & 0x07;
93 
94     switch (size) {
95         case DE_SIZE_8:
96             offset = SDP_UINT8_LENGTH;
97             *length = SDP_UINT8_LENGTH;
98             break;
99         case DE_SIZE_16:
100             offset = SDP_UINT16_LENGTH;
101             *length = SDP_UINT16_LENGTH;
102             break;
103         case DE_SIZE_32:
104             offset = SDP_UINT32_LENGTH;
105             *length = SDP_UINT32_LENGTH;
106             break;
107         case DE_SIZE_64:
108             offset = SDP_UINT64_LENGTH;
109             *length = SDP_UINT64_LENGTH;
110             break;
111         case DE_SIZE_128:
112             offset = SDP_UINT128_LENGTH;
113             *length = SDP_UINT128_LENGTH;
114             break;
115         case DE_SIZE_VAR_8:
116             offset = 1;
117             *length = buffer[0];
118             break;
119         case DE_SIZE_VAR_16:
120             offset = SDP_UINT16_LENGTH;
121             *length = BE2H_16(*(uint16_t *)buffer);
122             break;
123         case DE_SIZE_VAR_32:
124             offset = SDP_UINT32_LENGTH;
125             *length = BE2H_32(*(uint32_t *)buffer);
126             break;
127         default:
128             LOG_ERROR("[%{public}s][%{public}d] Wrong size [%{public}d]", __FUNCTION__, __LINE__, size);
129             break;
130     }
131 
132     return offset;
133 }
134 
SdpGetUuid(uint8_t * buffer,BtUuid * uuid)135 uint16_t SdpGetUuid(uint8_t *buffer, BtUuid *uuid)
136 {
137     uint32_t length = 0;
138     uint16_t offset = 0;
139     uint8_t type = buffer[0];
140 
141     offset++;
142     SdpGetLengthFromType(buffer + offset, type, &length);
143     if ((type >> SDP_DESCRIPTOR_SIZE_BIT) != DE_TYPE_UUID) {
144         LOG_ERROR("[%{public}s][%{public}d] Wrong type [0x%02x]", __FUNCTION__, __LINE__, type);
145         return offset;
146     }
147     switch (length) {
148         case SDP_UUID16_LENGTH:
149             uuid->type = BT_UUID_16;
150             uuid->uuid16 = BE2H_16(*(uint16_t *)(buffer + offset));
151             break;
152         case SDP_UUID32_LENGTH:
153             uuid->type = BT_UUID_32;
154             uuid->uuid32 = BE2H_32(*(uint32_t *)(buffer + offset));
155             break;
156         case SDP_UUID128_LENGTH:
157             uuid->type = BT_UUID_128;
158             SdpReverseForBigEndian(buffer + offset, uuid->uuid128, SDP_UUID128_LENGTH);
159             break;
160         default:
161             LOG_ERROR("[%{public}s][%u] Wrong length [0x%02x]", __FUNCTION__, __LINE__, length);
162             break;
163     }
164     offset += length;
165 
166     return offset;
167 }
168