• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_client.h"
17 
18 #include <string.h>
19 
20 #include "allocator.h"
21 
22 #include "sdp_client_parse.h"
23 #include "sdp_connect.h"
24 #include "sdp_util.h"
25 
26 #include "bt_endian.h"
27 #include "log.h"
28 #include "packet.h"
29 
30 #define SDP_UUID_ATTRIBUTE_LENGTH 17
31 #define SDP_SEARCH_LENGTH 5
32 #define SDP_ATTRIBUTE_LENGTH 15
33 #define SDP_SEARCH_ATTRIBUTE_LENGTH 20
34 #define SDP_BROWSE_LENGTH 8
35 
36 /**
37  * @brief   The function is used to initialize sdp client.
38  *
39  */
SdpInitializeClient()40 void SdpInitializeClient()
41 {
42     SdpCreateConnectList();
43     SdpCreateRequestList();
44 }
45 
46 /**
47  * @brief The function is used to finalize sdp client.
48  *
49  */
SdpFinalizeClient()50 void SdpFinalizeClient()
51 {
52     SdpDestroyConnectList();
53     SdpDestroyRequestList();
54 }
55 
SdpBuildPacket(const uint8_t * buffer,uint16_t length)56 static Packet *SdpBuildPacket(const uint8_t *buffer, uint16_t length)
57 {
58     Packet *packet = NULL;
59 
60     packet = PacketMalloc(0, 0, length);
61     PacketPayloadWrite(packet, buffer, 0, length);
62 
63     return packet;
64 }
65 
SdpBuildAttributeList(SdpAttributeIdList attributeIdList,uint8_t * buffer,uint16_t offset)66 static uint16_t SdpBuildAttributeList(SdpAttributeIdList attributeIdList, uint8_t *buffer, uint16_t offset)
67 {
68     if (attributeIdList.type == SDP_TYPE_RANGE) {
69         uint8_t idRange[] = {0x35, 0x05, 0x0A, 0x00, 0x00, 0x00, 0x00};
70         uint16_t pos = 1;
71         /// Range of Attribute IDs (All Attribute: 0x0000 - 0xffff)
72         pos += SDP_UINT16_LENGTH;
73         *(uint16_t *)(idRange + pos) = H2BE_16(attributeIdList.attributeIdRange.start);
74         pos += SDP_UINT16_LENGTH;
75         *(uint16_t *)(idRange + pos) = H2BE_16(attributeIdList.attributeIdRange.end);
76         pos += SDP_UINT16_LENGTH;
77         if (memcpy_s(buffer + offset, pos, idRange, pos) != EOK) {
78             LOG_ERROR("[%{public}s][%{public}d] memcpy_s failed", __FUNCTION__, __LINE__);
79             return offset;
80         }
81         offset += pos;
82     } else {
83         if (attributeIdList.attributeIdList.attributeIdNumber > SDP_ATTRIBUTE_ID_LIST_MAX_COUNT) {
84             attributeIdList.attributeIdList.attributeIdNumber = SDP_ATTRIBUTE_ID_LIST_MAX_COUNT;
85         }
86         /// Data Element Sequence uint8 (0x35)
87         buffer[offset] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
88         offset++;
89         /// Data Element Var Size
90         buffer[offset] = attributeIdList.attributeIdList.attributeIdNumber * (SDP_UINT16_LENGTH + 1);
91         offset++;
92         /// Each Attribute ID
93         for (int i = 0; i < attributeIdList.attributeIdList.attributeIdNumber; i++) {
94             /// Data Element Unsigned Integer 2 bytes (0x09)
95             buffer[offset] = (DE_TYPE_UINT << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_16;
96             offset++;
97             /// Data Value 16-bit unsigned integer
98             *(uint16_t *)(buffer + offset) = H2BE_16(attributeIdList.attributeIdList.attributeId[i]);
99             offset += SDP_UINT16_LENGTH;
100         }
101     }
102 
103     return offset;
104 }
105 
SdpCreateSearchRequest(const BtUuid * uuidArray,uint16_t uuidNum,uint8_t * buffer)106 static uint16_t SdpCreateSearchRequest(const BtUuid *uuidArray, uint16_t uuidNum, uint8_t *buffer)
107 {
108     uint16_t offset = 0;
109 
110     // Data Element: Sequence uint8 (0x35)
111     buffer[offset] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
112     offset += SDP_UINT16_LENGTH;
113     /// ServiceSearchPattern (min 1, max 12)
114     for (int i = 0; i < uuidNum; i++) {
115         offset = SdpAddAttributeForUuid(buffer, offset, &uuidArray[i]);
116     }
117     /// ParameterLength
118     buffer[1] = offset - SDP_UINT16_LENGTH;
119     /// MaximumServiceRecordCount - uint16_t (0x0001 - 0xFFFF)
120     *(uint16_t *)(buffer + offset) = H2BE_16(SDP_MAX_RECORD_HANDLE_COUNT);
121     offset += SDP_UINT16_LENGTH;
122 
123     return offset;
124 }
125 
SdpCreateAttributeRequest(uint32_t handle,SdpAttributeIdList attributeIdList,uint8_t * buffer)126 static uint16_t SdpCreateAttributeRequest(uint32_t handle, SdpAttributeIdList attributeIdList, uint8_t *buffer)
127 {
128     uint16_t offset = 0;
129 
130     /// ServiceRecordHandle
131     *(uint32_t *)(buffer + offset) = H2BE_32(handle);
132     offset += SDP_SERVICE_RECORD_HANDLE_BYTE;
133     /// MaximumAttributeByteCount - uint16_t (0x0001 - 0xFFFF)
134     *(uint16_t *)(buffer + offset) = H2BE_16(SDP_MAX_ATTRIBUTE_BYTE_COUNT);
135     offset += SDP_UINT16_LENGTH;
136     /// AttributeIDList
137     offset = SdpBuildAttributeList(attributeIdList, buffer, offset);
138 
139     return offset;
140 }
141 
SdpCreateSearchAttributeRequest(const BtUuid * uuidArray,uint16_t uuidNum,SdpAttributeIdList attributeIdList,uint8_t * buffer)142 static uint16_t SdpCreateSearchAttributeRequest(
143     const BtUuid *uuidArray, uint16_t uuidNum, SdpAttributeIdList attributeIdList, uint8_t *buffer)
144 {
145     uint16_t offset = 0;
146 
147     // Data Element: Sequence uint8 (0x35)
148     buffer[offset] = (DE_TYPE_DES << SDP_DESCRIPTOR_SIZE_BIT) | DE_SIZE_VAR_8;
149     offset += SDP_UINT16_LENGTH;
150     /// ServiceSearchPattern (min 1, max 12)
151     for (int i = 0; i < uuidNum; i++) {
152         offset = SdpAddAttributeForUuid(buffer, offset, &uuidArray[i]);
153     }
154     /// ParameterLength
155     buffer[1] = offset - SDP_UINT16_LENGTH;
156     /// MaximumAttributeByteCount - uint16_t (0x0001 - 0xFFFF)
157     *(uint16_t *)(buffer + offset) = H2BE_16(SDP_MAX_ATTRIBUTE_BYTE_COUNT);
158     offset += SDP_UINT16_LENGTH;
159     /// AttributeIDList
160     offset = SdpBuildAttributeList(attributeIdList, buffer, offset);
161 
162     return offset;
163 }
164 
SdpCreateServiceBrowseRequest(uint8_t * buffer)165 static uint16_t SdpCreateServiceBrowseRequest(uint8_t *buffer)
166 {
167     uint16_t length;
168     BtUuid uuid;
169 
170     uuid.type = BT_UUID_16;
171     uuid.uuid16 = SDP_PUBLIC_BROWSE_GROUP_ROOT_UUID;
172     length = SdpCreateSearchRequest(&uuid, 1, buffer);
173 
174     return length;
175 }
176 
SdpServiceSearch(const BtAddr * addr,const SdpUuid * uuidArray,void * context,void (* serviceSearchCb)(const BtAddr * addr,const uint32_t * handleArray,uint16_t handleNum,void * context))177 int SdpServiceSearch(const BtAddr *addr, const SdpUuid *uuidArray, void *context,
178     void (*serviceSearchCb)(const BtAddr *addr, const uint32_t *handleArray, uint16_t handleNum, void *context))
179 {
180     LOG_INFO("[%{public}s][%{public}d] uuidNum = [%hu]", __FUNCTION__, __LINE__, uuidArray->uuidNum);
181     SdpClientRequest *request = NULL;
182     uint8_t *buffer = NULL;
183     uint16_t length;
184     int ret;
185 
186     if (SdpGetEnableState() == false) {
187         return BT_BAD_STATUS;
188     }
189 
190     /// Create service search request
191     request = MEM_MALLOC.alloc(sizeof(SdpClientRequest));
192     (void)memset_s(request, sizeof(SdpClientRequest), 0, sizeof(SdpClientRequest));
193     buffer = MEM_MALLOC.alloc(uuidArray->uuidNum * SDP_UUID_ATTRIBUTE_LENGTH + SDP_SEARCH_LENGTH);
194     (void)memset_s(buffer,
195         (uuidArray->uuidNum * SDP_UUID_ATTRIBUTE_LENGTH + SDP_SEARCH_LENGTH),
196         0,
197         (uuidArray->uuidNum * SDP_UUID_ATTRIBUTE_LENGTH + SDP_SEARCH_LENGTH));
198 
199     length = SdpCreateSearchRequest(uuidArray->uuid, uuidArray->uuidNum, buffer);
200     if (length == 0) {
201         LOG_ERROR("[%{public}s][%{public}d] Create search request failed", __FUNCTION__, __LINE__);
202         return BT_BAD_PARAM;
203     }
204 
205     (void)memcpy_s(&request->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
206     request->pduId = SDP_SERVICE_SEARCH_REQUEST;
207     request->transactionId = SdpGetTransactionId();
208     request->resentFlag = false;
209     request->packetState = SDP_PACKET_WAIT;
210     request->packet = SdpBuildPacket(buffer, length);
211     request->assemblePacket = NULL;
212     request->callback.ServiceSearchCb = serviceSearchCb;
213     request->context = context;
214 
215     ret = SdpClientConnect(request);
216     MEM_MALLOC.free(buffer);
217 
218     return ret;
219 }
220 
SdpServiceAttribute(const BtAddr * addr,uint32_t handle,SdpAttributeIdList attributeIdList,void * context,void (* serviceAttributeCb)(const BtAddr * addr,const SdpService * service,void * context))221 int SdpServiceAttribute(const BtAddr *addr, uint32_t handle, SdpAttributeIdList attributeIdList, void *context,
222     void (*serviceAttributeCb)(const BtAddr *addr, const SdpService *service, void *context))
223 {
224     LOG_INFO("[%{public}s][%{public}d] handle = [%08x], type = [%u]", __FUNCTION__, __LINE__, handle, attributeIdList.type);
225     uint16_t length;
226     uint8_t *buffer = NULL;
227     SdpClientRequest *request = NULL;
228     int ret;
229 
230     if (SdpGetEnableState() == false) {
231         return BT_BAD_STATUS;
232     }
233 
234     request = MEM_MALLOC.alloc(sizeof(SdpClientRequest));
235     (void)memset_s(request, sizeof(SdpClientRequest), 0, sizeof(SdpClientRequest));
236     /// Create service attribute request
237     buffer = MEM_MALLOC.alloc(sizeof(SdpAttributeIdList) + SDP_ATTRIBUTE_LENGTH);
238     (void)memset_s(buffer,
239         (sizeof(SdpAttributeIdList) + SDP_ATTRIBUTE_LENGTH),
240         0,
241         (sizeof(SdpAttributeIdList) + SDP_ATTRIBUTE_LENGTH));
242 
243     length = SdpCreateAttributeRequest(handle, attributeIdList, buffer);
244     if (length == 0) {
245         LOG_ERROR("[%{public}s][%{public}d] Create attribute request failed", __FUNCTION__, __LINE__);
246         return BT_BAD_PARAM;
247     }
248 
249     (void)memcpy_s(&request->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
250     request->pduId = SDP_SERVICE_ATTRIBUTE_REQUEST;
251     request->transactionId = SdpGetTransactionId();
252     request->resentFlag = false;
253     request->packetState = SDP_PACKET_WAIT;
254     request->packet = SdpBuildPacket(buffer, length);
255     request->assemblePacket = NULL;
256     request->callback.ServiceAttributeCb = serviceAttributeCb;
257     request->context = context;
258 
259     ret = SdpClientConnect(request);
260     MEM_MALLOC.free(buffer);
261 
262     return ret;
263 }
264 
SdpServiceSearchAttribute(const BtAddr * addr,const SdpUuid * uuidArray,SdpAttributeIdList attributeIdList,void * context,void (* searchAttributeCb)(const BtAddr * addr,const SdpService * serviceArray,uint16_t serviceNum,void * context))265 int SdpServiceSearchAttribute(const BtAddr *addr, const SdpUuid *uuidArray, SdpAttributeIdList attributeIdList,
266     void *context,
267     void (*searchAttributeCb)(const BtAddr *addr, const SdpService *serviceArray, uint16_t serviceNum, void *context))
268 {
269     LOG_INFO("[%{public}s][%{public}d] uuidNum = [%hu], type = [%u]", __FUNCTION__, __LINE__, uuidArray->uuidNum, attributeIdList.type);
270     uint16_t length;
271     uint8_t *buffer = NULL;
272     SdpClientRequest *request = NULL;
273     int ret;
274 
275     if (SdpGetEnableState() == false) {
276         return BT_BAD_STATUS;
277     }
278 
279     /// Create service search attribute request
280     request = MEM_MALLOC.alloc(sizeof(SdpClientRequest));
281     (void)memset_s(request, sizeof(SdpClientRequest), 0, sizeof(SdpClientRequest));
282     buffer = MEM_MALLOC.alloc(
283         sizeof(SdpAttributeIdList) + (uuidArray->uuidNum * SDP_UUID_ATTRIBUTE_LENGTH) + SDP_SEARCH_ATTRIBUTE_LENGTH);
284     (void)memset_s(buffer,
285         (sizeof(SdpAttributeIdList) + (uuidArray->uuidNum * SDP_UUID_ATTRIBUTE_LENGTH) + SDP_SEARCH_ATTRIBUTE_LENGTH),
286         0,
287         (sizeof(SdpAttributeIdList) + (uuidArray->uuidNum * SDP_UUID_ATTRIBUTE_LENGTH) + SDP_SEARCH_ATTRIBUTE_LENGTH));
288 
289     length = SdpCreateSearchAttributeRequest(uuidArray->uuid, uuidArray->uuidNum, attributeIdList, buffer);
290     if (length == 0) {
291         LOG_ERROR("[%{public}s][%{public}d] Create search attribute request failed", __FUNCTION__, __LINE__);
292         return BT_BAD_PARAM;
293     }
294 
295     (void)memcpy_s(&request->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
296     request->pduId = SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST;
297     request->transactionId = SdpGetTransactionId();
298     request->resentFlag = false;
299     request->packetState = SDP_PACKET_WAIT;
300     request->packet = SdpBuildPacket(buffer, length);
301     request->assemblePacket = NULL;
302     request->callback.ServiceSearchAttributeCb = searchAttributeCb;
303     request->context = context;
304 
305     ret = SdpClientConnect(request);
306     MEM_MALLOC.free(buffer);
307 
308     return ret;
309 }
310 
SdpServiceBrowse(const BtAddr * addr,void * context,void (* serviceBrowseCb)(const BtAddr * addr,const uint32_t * handleArray,uint16_t handleNum,void * context))311 int SdpServiceBrowse(const BtAddr *addr, void *context,
312     void (*serviceBrowseCb)(const BtAddr *addr, const uint32_t *handleArray, uint16_t handleNum, void *context))
313 {
314     SdpClientRequest *request = NULL;
315     uint8_t *buffer = NULL;
316     uint16_t length;
317     int ret;
318 
319     if (SdpGetEnableState() == false) {
320         return BT_BAD_STATUS;
321     }
322 
323     /// Create service search request
324     request = MEM_MALLOC.alloc(sizeof(SdpClientRequest));
325     (void)memset_s(request, sizeof(SdpClientRequest), 0, sizeof(SdpClientRequest));
326 
327     buffer = MEM_MALLOC.alloc(SDP_BROWSE_LENGTH);
328     (void)memset_s(buffer, SDP_BROWSE_LENGTH, 0, SDP_BROWSE_LENGTH);
329 
330     length = SdpCreateServiceBrowseRequest(buffer);
331     if (length == 0) {
332         LOG_ERROR("[%{public}s][%{public}d] Setup search request failed", __FUNCTION__, __LINE__);
333         return BT_BAD_PARAM;
334     }
335 
336     (void)memcpy_s(&request->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
337     request->pduId = SDP_SERVICE_SEARCH_REQUEST;
338     request->transactionId = SdpGetTransactionId();
339     request->resentFlag = false;
340     request->packetState = SDP_PACKET_WAIT;
341     request->packet = SdpBuildPacket(buffer, length);
342     request->assemblePacket = NULL;
343     request->callback.ServiceSearchCb = serviceBrowseCb;
344     request->context = context;
345 
346     ret = SdpClientConnect(request);
347     MEM_MALLOC.free(buffer);
348 
349     return ret;
350 }