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_connect.h"
17
18 #include "sdp_client_parse.h"
19 #include "sdp_server.h"
20 #include "sdp_util.h"
21
22 #include "l2cap_if.h"
23
24 #include "bt_endian.h"
25
26 #include "alarm.h"
27 #include "list.h"
28 #include "packet.h"
29
30 #include "../btm/btm_thread.h"
31
32 #include "allocator.h"
33 #include "log.h"
34
35 typedef struct {
36 BtAddr addr;
37 uint16_t lcid;
38 uint16_t mtu;
39 uint8_t outConnState;
40 uint8_t inConnState;
41 Alarm *timer;
42 bool flag; /// 0-server 1-client
43 Packet *packet; /// Fragment packet
44 uint16_t totalCount;
45 bool wait;
46 } SdpConnectInfo;
47
48 static void SdpSendConnectRequest(const BtAddr *addr);
49 static void SdpSendDisconnectRequest(uint16_t lcid, bool wait);
50 static void SdpReceiveConnectRequest(
51 uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *context);
52 static void SdpReceiveConnectResponse(
53 uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *context);
54 static void SdpReceiveConfigRequest(uint16_t lcid, uint8_t id, const L2capConfigInfo *config, void *context);
55 static void SdpReceiveConfigResponse(uint16_t lcid, const L2capConfigInfo *config, uint16_t result, void *context);
56 static void SdpReceiveDisconnectRequest(uint16_t lcid, uint8_t id, void *context);
57 static void SdpReceiveDisconnectResponse(uint16_t lcid, void *context);
58 static void SdpDisconnectAbnormal(uint16_t lcid, uint8_t reason, void *context);
59 static void SdpReceiveData(uint16_t lcid, Packet *packet, void *context);
60
61 /// Connect List for server and client
62 static List *g_connectList = NULL;
63 static L2capService g_registerInfo;
64
SdpRegisterToL2cap()65 void SdpRegisterToL2cap()
66 {
67 /// Register with L2CAP
68 (void)memset_s(&g_registerInfo, sizeof(L2capService), 0, sizeof(L2capService));
69 g_registerInfo.recvConnectionReq = SdpReceiveConnectRequest;
70 g_registerInfo.recvConnectionRsp = SdpReceiveConnectResponse;
71 g_registerInfo.recvConfigReq = SdpReceiveConfigRequest;
72 g_registerInfo.recvConfigRsp = SdpReceiveConfigResponse;
73 g_registerInfo.recvDisconnectionReq = SdpReceiveDisconnectRequest;
74 g_registerInfo.recvDisconnectionRsp = SdpReceiveDisconnectResponse;
75 g_registerInfo.disconnectAbnormal = SdpDisconnectAbnormal;
76 g_registerInfo.recvData = SdpReceiveData;
77 g_registerInfo.remoteBusy = NULL;
78
79 L2CIF_RegisterService(SDP_PSM, &g_registerInfo, NULL, NULL);
80 }
81
SdpDeregisterToL2cap()82 void SdpDeregisterToL2cap()
83 {
84 /// Deregister with L2CAP
85 L2CIF_DeregisterService(SDP_PSM, NULL);
86 }
87
SdpFreeConnectInfo(const void * data)88 static void SdpFreeConnectInfo(const void *data)
89 {
90 if (data == NULL) {
91 return;
92 }
93 SdpConnectInfo *connect = (SdpConnectInfo *)data;
94 if (connect->timer != NULL) {
95 AlarmDelete(connect->timer);
96 connect->timer = NULL;
97 }
98 if (connect->packet != NULL) {
99 PacketFree(connect->packet);
100 connect->packet = NULL;
101 }
102 MEM_MALLOC.free(connect);
103 connect = NULL;
104 }
105
SdpCreateConnectList()106 void SdpCreateConnectList()
107 {
108 g_connectList = ListCreate((void (*)(void *))SdpFreeConnectInfo);
109 }
110
SdpDestroyConnectList()111 void SdpDestroyConnectList()
112 {
113 if (g_connectList != NULL) {
114 ListDelete(g_connectList);
115 g_connectList = NULL;
116 }
117 }
118
SdpConnectWaitTimeTask(void * context)119 static void SdpConnectWaitTimeTask(void *context)
120 {
121 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
122
123 SdpConnectInfo *ctx = context;
124
125 if (!SdpGetEnableState()) {
126 return;
127 }
128
129 SdpSendDisconnectRequest(ctx->lcid, true);
130 MEM_MALLOC.free(ctx);
131
132 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
133 }
134
SdpConnectWaitTime(void * parameter)135 static void SdpConnectWaitTime(void *parameter)
136 {
137 int ret;
138 SdpConnectInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectInfo));
139 if (ctx == NULL) {
140 LOG_ERROR("point to NULL");
141 return;
142 }
143
144 (void)memset_s(ctx, sizeof(SdpConnectInfo), 0x00, sizeof(SdpConnectInfo));
145 (void)memcpy_s(ctx, sizeof(SdpConnectInfo), parameter, sizeof(SdpConnectInfo));
146
147 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpConnectWaitTimeTask, ctx);
148 if (ret != BT_SUCCESS) {
149 MEM_MALLOC.free(ctx);
150 return;
151 }
152 }
153
SdpConnectTimeoutTask(void * context)154 static void SdpConnectTimeoutTask(void *context)
155 {
156 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
157
158 SdpConnectInfo *ctx = context;
159
160 if (!SdpGetEnableState()) {
161 return;
162 }
163
164 if (ctx->flag) {
165 SdpRemoveAllRequestByAddress(&ctx->addr);
166 }
167 ListRemoveNode(g_connectList, ctx);
168 MEM_MALLOC.free(ctx);
169
170 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
171 }
172
SdpConnectTimeout(void * parameter)173 static void SdpConnectTimeout(void *parameter)
174 {
175 int ret;
176 SdpConnectInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectInfo));
177 if (ctx == NULL) {
178 LOG_ERROR("point to NULL");
179 return;
180 }
181 (void)memset_s(ctx, sizeof(SdpConnectInfo), 0x00, sizeof(SdpConnectInfo));
182 (void)memcpy_s(ctx, sizeof(SdpConnectInfo), parameter, sizeof(SdpConnectInfo));
183
184 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpConnectTimeoutTask, ctx);
185 if (ret != BT_SUCCESS) {
186 MEM_MALLOC.free(ctx);
187 return;
188 }
189 }
190
SdpFindConnectByCid(uint16_t lcid)191 static SdpConnectInfo *SdpFindConnectByCid(uint16_t lcid)
192 {
193 ListNode *node = NULL;
194 SdpConnectInfo *connect = NULL;
195
196 if (g_connectList == NULL) {
197 return NULL;
198 }
199 node = ListGetFirstNode(g_connectList);
200 while (node != NULL) {
201 connect = (SdpConnectInfo *)ListGetNodeData(node);
202 /// Find connect by local channel ID as a server or a client.
203 if ((connect->lcid == lcid) && (connect->outConnState != SDP_STATE_IDLE)) {
204 return connect;
205 }
206 node = ListGetNextNode(node);
207 }
208 return NULL;
209 }
210
SdpFindConnectByAddress(const BtAddr * addr)211 static SdpConnectInfo *SdpFindConnectByAddress(const BtAddr *addr)
212 {
213 ListNode *node = NULL;
214 SdpConnectInfo *connect = NULL;
215
216 if (g_connectList == NULL) {
217 return NULL;
218 }
219 node = ListGetFirstNode(g_connectList);
220 while (node != NULL) {
221 connect = (SdpConnectInfo *)ListGetNodeData(node);
222 if ((connect->flag) && (memcmp(&connect->addr, addr, sizeof(BtAddr)) == 0)) {
223 return connect;
224 }
225 node = ListGetNextNode(node);
226 }
227
228 return NULL;
229 }
230
SdpFindIdleConnectByAddress(const BtAddr * addr)231 static SdpConnectInfo *SdpFindIdleConnectByAddress(const BtAddr *addr)
232 {
233 ListNode *node = NULL;
234 SdpConnectInfo *connect = NULL;
235
236 if (g_connectList == NULL) {
237 return NULL;
238 }
239 node = ListGetFirstNode(g_connectList);
240 while (node != NULL) {
241 connect = (SdpConnectInfo *)ListGetNodeData(node);
242 if ((connect->flag) && (memcmp(&connect->addr, addr, sizeof(BtAddr)) == 0) &&
243 (connect->inConnState == SDP_STATE_IDLE) && (connect->outConnState == SDP_STATE_IDLE)) {
244 return connect;
245 }
246 node = ListGetNextNode(node);
247 }
248
249 return NULL;
250 }
251
SdpNextConnect(const BtAddr * addr)252 static void SdpNextConnect(const BtAddr *addr)
253 {
254 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
255
256 SdpClientRequest *request = NULL;
257
258 SdpRemoveRequestByAddress(addr);
259 request = SdpFindRequestByAddress(addr);
260 if (request != NULL) {
261 SdpSendConnectRequest(addr);
262 }
263
264 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
265 }
266
267 typedef struct {
268 BtAddr addr;
269 uint16_t lcid;
270 int result;
271 } SdpConnectCallbackInfo;
272
SdpConnectReqCallbackTask(const BtAddr * addr,uint16_t lcid,int result,void * context)273 static void SdpConnectReqCallbackTask(const BtAddr *addr, uint16_t lcid, int result, void *context)
274 {
275 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
276
277 SdpConnectInfo *connect = NULL;
278
279 if (!SdpGetEnableState()) {
280 return;
281 }
282
283 /// Check if L2CAP started the connection process
284 if ((result != BT_SUCCESS) || (lcid == 0)) {
285 LOG_ERROR("[%{public}s][%{public}d] Send connect request failed ", __FUNCTION__, __LINE__);
286 SdpNextConnect(addr);
287 return;
288 }
289
290 connect = SdpFindIdleConnectByAddress(addr);
291 /// Save channel id
292 connect->lcid = lcid;
293 /// Set connection state
294 connect->outConnState = SDP_STATE_CONN_SETUP;
295 connect->inConnState = SDP_STATE_CONN_SETUP;
296 /// Set timer
297 connect->timer = AlarmCreate(NULL, false);
298
299 /// Start timer
300 AlarmSet(connect->timer, SDP_CONNECT_TIMEOUT, SdpConnectTimeout, connect);
301
302 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
303 }
304
SdpConnectReqCallbackTsk(void * context)305 static void SdpConnectReqCallbackTsk(void *context)
306 {
307 SdpConnectCallbackInfo *ctx = context;
308 SdpConnectReqCallbackTask(&ctx->addr, ctx->lcid, ctx->result, NULL);
309 MEM_MALLOC.free(ctx);
310 }
311
SdpConnectReqCallback(const BtAddr * addr,uint16_t lcid,int result,void * context)312 static void SdpConnectReqCallback(const BtAddr *addr, uint16_t lcid, int result, void *context)
313 {
314 int ret;
315 SdpConnectCallbackInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectCallbackInfo));
316 if (ctx == NULL) {
317 LOG_ERROR("point to NULL");
318 return;
319 }
320 (void)memset_s(ctx, sizeof(SdpConnectCallbackInfo), 0x00, sizeof(SdpConnectCallbackInfo));
321
322 (void)memcpy_s(&ctx->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
323 ctx->lcid = lcid;
324 ctx->result = result;
325
326 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpConnectReqCallbackTsk, ctx);
327 if (ret != BT_SUCCESS) {
328 MEM_MALLOC.free(ctx);
329 return;
330 }
331 }
332
SdpConfigReqCallbackTask(uint16_t lcid,int result)333 static void SdpConfigReqCallbackTask(uint16_t lcid, int result)
334 {
335 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
336
337 SdpConnectInfo *connect = NULL;
338
339 if (!SdpGetEnableState()) {
340 return;
341 }
342
343 if (result != BT_SUCCESS) {
344 LOG_ERROR("[%{public}s][%{public}d] Send config request failed ", __FUNCTION__, __LINE__);
345 connect = SdpFindConnectByCid(lcid);
346 if ((connect != NULL) && (connect->flag)) {
347 SdpNextConnect(&connect->addr);
348 }
349 return;
350 }
351
352 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
353 }
354
SdpConfigReqCallbackTsk(void * context)355 static void SdpConfigReqCallbackTsk(void *context)
356 {
357 SdpConnectCallbackInfo *ctx = context;
358 SdpConfigReqCallbackTask(ctx->lcid, ctx->result);
359 MEM_MALLOC.free(ctx);
360 }
361
SdpConfigReqCallback(uint16_t lcid,int result)362 void SdpConfigReqCallback(uint16_t lcid, int result)
363 {
364 int ret;
365 SdpConnectCallbackInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectCallbackInfo));
366 if (ctx == NULL) {
367 LOG_ERROR("point to NULL");
368 return;
369 }
370 (void)memset_s(ctx, sizeof(SdpConnectCallbackInfo), 0x00, sizeof(SdpConnectCallbackInfo));
371
372 ctx->lcid = lcid;
373 ctx->result = result;
374
375 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpConfigReqCallbackTsk, ctx);
376 if (ret != BT_SUCCESS) {
377 MEM_MALLOC.free(ctx);
378 return;
379 }
380 }
381
SdpConnectRspCallbackTask(uint16_t lcid,int result)382 void SdpConnectRspCallbackTask(uint16_t lcid, int result)
383 {
384 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
385
386 SdpConnectInfo *connect = NULL;
387 L2capConfigInfo config;
388
389 if (!SdpGetEnableState()) {
390 return;
391 }
392
393 if (result != BT_SUCCESS) {
394 LOG_ERROR("[%{public}s][%{public}d] Send connect response failed ", __FUNCTION__, __LINE__);
395 return;
396 }
397
398 connect = MEM_MALLOC.alloc(sizeof(SdpConnectInfo));
399 if (connect == NULL) {
400 LOG_ERROR("point to NULL");
401 return;
402 }
403 (void)memset_s(connect, sizeof(SdpConnectInfo), 0, sizeof(SdpConnectInfo));
404 /// Save channel id
405 connect->lcid = lcid;
406 /// Set connection state, waiting for config
407 connect->outConnState = SDP_STATE_CONN_SETUP;
408 connect->inConnState = SDP_STATE_CONN_SETUP;
409 connect->flag = false;
410 connect->timer = NULL;
411 connect->wait = false;
412 ListAddLast(g_connectList, connect);
413
414 /// L2CAP default configuration. SDP only care about mtu.
415 (void)memset_s(&config, sizeof(L2capConfigInfo), 0, sizeof(L2capConfigInfo));
416 config.mtu = SDP_MTU_SIZE;
417 config.flushTimeout = 0xFFFF;
418 config.fcs = 0x01;
419 L2CIF_ConfigReq(lcid, &config, SdpConfigReqCallback);
420
421 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
422 }
423
SdpConnectRspCallbackTsk(void * context)424 static void SdpConnectRspCallbackTsk(void *context)
425 {
426 SdpConnectCallbackInfo *ctx = context;
427 SdpConnectRspCallbackTask(ctx->lcid, ctx->result);
428 MEM_MALLOC.free(ctx);
429 }
430
SdpConnectRspCallback(uint16_t lcid,int result)431 static void SdpConnectRspCallback(uint16_t lcid, int result)
432 {
433 int ret;
434 SdpConnectCallbackInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectCallbackInfo));
435 if (ctx == NULL) {
436 LOG_ERROR("point to NULL");
437 return;
438 }
439 (void)memset_s(ctx, sizeof(SdpConnectCallbackInfo), 0x00, sizeof(SdpConnectCallbackInfo));
440
441 ctx->lcid = lcid;
442 ctx->result = result;
443
444 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpConnectRspCallbackTsk, ctx);
445 if (ret != BT_SUCCESS) {
446 MEM_MALLOC.free(ctx);
447 return;
448 }
449 }
450
SdpConfigRspCallbackTask(uint16_t lcid,int result)451 static void SdpConfigRspCallbackTask(uint16_t lcid, int result)
452 {
453 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
454
455 SdpConnectInfo *connect = NULL;
456 SdpClientRequest *request = NULL;
457
458 if (!SdpGetEnableState()) {
459 return;
460 }
461
462 connect = SdpFindConnectByCid(lcid);
463 if (connect == NULL) {
464 LOG_ERROR("[%{public}s][%{public}d] Config response callback failed", __FUNCTION__, __LINE__);
465 return;
466 }
467
468 if (result != BT_SUCCESS) {
469 LOG_ERROR("[%{public}s][%{public}d] Send config response failed ", __FUNCTION__, __LINE__);
470 if ((connect != NULL) && (connect->flag)) {
471 SdpNextConnect(&connect->addr);
472 }
473 return;
474 }
475
476 connect->inConnState = SDP_STATE_CFG_REQ_SETUP;
477 if ((connect->outConnState == SDP_STATE_CFG_RSP_SETUP) && (connect->inConnState == SDP_STATE_CFG_REQ_SETUP)) {
478 connect->outConnState = SDP_STATE_CONNECTED;
479 connect->inConnState = SDP_STATE_CONNECTED;
480 if (connect->flag) {
481 // Send client packet
482 request = SdpFindRequestByAddress(&connect->addr);
483 request->packetState = SDP_PACKET_SEND;
484 SdpSendRequest(lcid, request->transactionId, 0, NULL, request->packet);
485 }
486 }
487 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
488 }
489
SdpConfigRspCallbackTsk(void * context)490 static void SdpConfigRspCallbackTsk(void *context)
491 {
492 SdpConnectCallbackInfo *ctx = context;
493 SdpConfigRspCallbackTask(ctx->lcid, ctx->result);
494 MEM_MALLOC.free(ctx);
495 }
496
SdpConfigRspCallback(uint16_t lcid,int result)497 static void SdpConfigRspCallback(uint16_t lcid, int result)
498 {
499 int ret;
500 SdpConnectCallbackInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectCallbackInfo));
501 if (ctx == NULL) {
502 LOG_ERROR("point to NULL");
503 return;
504 }
505 (void)memset_s(ctx, sizeof(SdpConnectCallbackInfo), 0x00, sizeof(SdpConnectCallbackInfo));
506
507 ctx->lcid = lcid;
508 ctx->result = result;
509
510 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpConfigRspCallbackTsk, ctx);
511 if (ret != BT_SUCCESS) {
512 MEM_MALLOC.free(ctx);
513 return;
514 }
515 }
516
SdpDisconnectionRspCallbackTask(uint16_t lcid,int result)517 static void SdpDisconnectionRspCallbackTask(uint16_t lcid, int result)
518 {
519 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
520
521 SdpConnectInfo *connect = NULL;
522
523 if (!SdpGetEnableState()) {
524 return;
525 }
526
527 if (result != BT_SUCCESS) {
528 LOG_ERROR("[%{public}s][%{public}d] Disconnect response callback failed", __FUNCTION__, __LINE__);
529 return;
530 }
531
532 connect = SdpFindConnectByCid(lcid);
533 if (connect == NULL) {
534 LOG_ERROR("[%{public}s][%{public}d] Disconnect response callback failed", __FUNCTION__, __LINE__);
535 return;
536 }
537 ListRemoveNode(g_connectList, connect);
538
539 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
540 }
541
SdpDisconnectionRspCallbackTsk(void * context)542 static void SdpDisconnectionRspCallbackTsk(void *context)
543 {
544 SdpConnectCallbackInfo *ctx = context;
545 SdpDisconnectionRspCallbackTask(ctx->lcid, ctx->result);
546 MEM_MALLOC.free(ctx);
547 }
548
SdpDisconnectionRspCallback(uint16_t lcid,int result)549 static void SdpDisconnectionRspCallback(uint16_t lcid, int result)
550 {
551 int ret;
552 SdpConnectCallbackInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectCallbackInfo));
553 if (ctx == NULL) {
554 LOG_ERROR("point to NULL");
555 return;
556 }
557 (void)memset_s(ctx, sizeof(SdpConnectCallbackInfo), 0x00, sizeof(SdpConnectCallbackInfo));
558
559 ctx->lcid = lcid;
560 ctx->result = result;
561
562 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpDisconnectionRspCallbackTsk, ctx);
563 if (ret != BT_SUCCESS) {
564 MEM_MALLOC.free(ctx);
565 return;
566 }
567 }
568
569 /**
570 * @brief Send connection request from L2CAP as a client.
571 *
572 * @param addr The Bluetooth address of the peer.
573 * @param packet The packet point for sending data.
574 * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
575 */
SdpSendConnectRequest(const BtAddr * addr)576 static void SdpSendConnectRequest(const BtAddr *addr)
577 {
578 SdpConnectInfo *connect = NULL;
579
580 connect = MEM_MALLOC.alloc(sizeof(SdpConnectInfo));
581 if (connect == NULL) {
582 LOG_ERROR("point to NULL");
583 return;
584 }
585 (void)memset_s(connect, sizeof(SdpConnectInfo), 0, sizeof(SdpConnectInfo));
586
587 /// Save address
588 (void)memcpy_s(&connect->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
589 /// Set client connect
590 connect->inConnState = SDP_STATE_IDLE;
591 connect->outConnState = SDP_STATE_IDLE;
592 connect->flag = true;
593 connect->wait = false;
594 ListAddLast(g_connectList, connect);
595
596 /// Send request to L2CAP
597 L2CIF_ConnectReq(addr, SDP_PSM, SDP_PSM, NULL, SdpConnectReqCallback);
598 }
599
600 typedef struct {
601 uint16_t lcid;
602 uint8_t id;
603 L2capConnectionInfo info;
604 uint16_t lpsm;
605 void *context;
606 } SdpReceiveConnectRequestInfo;
607 /**
608 * @brief Receive connection request from L2CAP as a server.
609 *
610 * @param lcid Local channel identifier.
611 * @param id Identifier.
612 * @param info L2CAP connection info.
613 * @param lpsm SDP_PSM (0x0001).
614 * @param context The context from upper layer.
615 */
SdpReceiveConnectRequestTask(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t lpsm,void * context)616 static void SdpReceiveConnectRequestTask(
617 uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *context)
618 {
619 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
620
621 if (!SdpGetEnableState()) {
622 return;
623 }
624
625 /// Send connect response to L2CAP
626 L2CIF_ConnectRsp(
627 lcid, id, L2CAP_CONNECTION_SUCCESSFUL, L2CAP_NO_FURTHER_INFORMATION_AVAILABLE, SdpConnectRspCallback);
628
629 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
630 }
631
SdpReceiveConnectRequestTsk(void * context)632 static void SdpReceiveConnectRequestTsk(void *context)
633 {
634 SdpReceiveConnectRequestInfo *ctx = context;
635 SdpReceiveConnectRequestTask(ctx->lcid, ctx->id, &ctx->info, ctx->lpsm, ctx->context);
636 MEM_MALLOC.free(ctx);
637 }
638
SdpReceiveConnectRequest(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t lpsm,void * context)639 static void SdpReceiveConnectRequest(
640 uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *context)
641 {
642 int ret;
643 SdpReceiveConnectRequestInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConnectRequestInfo));
644 if (ctx == NULL) {
645 LOG_ERROR("point to NULL");
646 return;
647 }
648 (void)memset_s(ctx, sizeof(SdpReceiveConnectRequestInfo), 0x00, sizeof(SdpReceiveConnectRequestInfo));
649
650 ctx->lcid = lcid;
651 ctx->id = id;
652 (void)memcpy_s(&ctx->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
653 ctx->lpsm = lpsm;
654 ctx->context = context;
655
656 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConnectRequestTsk, ctx);
657 if (ret != BT_SUCCESS) {
658 MEM_MALLOC.free(ctx);
659 return;
660 }
661 }
662
663 typedef struct {
664 uint16_t lcid;
665 L2capConnectionInfo info;
666 uint16_t result;
667 uint16_t status;
668 void *context;
669 } SdpReceiveConnectResponseInfo;
670 /**
671 * @brief Receive connection response from L2CAP as a client.
672 *
673 * @param lcid Local channel identifier
674 * @param info L2CAP connection info.
675 * @param result L2CAP result
676 * @param status L2CAP status
677 * @param context The context from upper layer.
678 */
SdpReceiveConnectResponseTask(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * context)679 static void SdpReceiveConnectResponseTask(
680 uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *context)
681 {
682 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
683
684 L2capConfigInfo config;
685 SdpConnectInfo *connect = NULL;
686
687 if (!SdpGetEnableState()) {
688 return;
689 }
690
691 connect = SdpFindConnectByCid(lcid);
692 if (connect == NULL) {
693 LOG_WARN("[%{public}s][%{public}d] Recv connect failed with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
694 SdpSendDisconnectRequest(lcid, false);
695 return;
696 }
697 if (result == L2CAP_CONNECTION_PENDING) {
698 LOG_WARN("[%{public}s][%{public}d] Recv connect response pending [0x%02x]", __FUNCTION__, __LINE__, lcid);
699 return;
700 } else if ((result != L2CAP_CONNECTION_SUCCESSFUL) || (connect->outConnState != SDP_STATE_CONN_SETUP) ||
701 (connect->inConnState != SDP_STATE_CONN_SETUP)) {
702 LOG_ERROR("[%{public}s][%{public}d] Recv connect response failed with cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
703 return;
704 }
705
706 /// stop timer when received a connect response
707 if (connect->timer != NULL) {
708 /// Cancel timeout
709 AlarmCancel(connect->timer);
710 }
711
712 /// L2CAP default configuration. SDP only care about mtu.
713 (void)memset_s(&config, sizeof(L2capConfigInfo), 0, sizeof(L2capConfigInfo));
714 config.mtu = SDP_MTU_SIZE;
715 config.flushTimeout = 0xFFFF;
716 config.fcs = 0x01;
717 L2CIF_ConfigReq(lcid, &config, SdpConfigReqCallback);
718
719 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
720 }
721
SdpReceiveConnectResponseTsk(void * context)722 static void SdpReceiveConnectResponseTsk(void *context)
723 {
724 SdpReceiveConnectResponseInfo *ctx = context;
725 SdpReceiveConnectResponseTask(ctx->lcid, &ctx->info, ctx->result, ctx->status, ctx->context);
726 MEM_MALLOC.free(ctx);
727 }
728
SdpReceiveConnectResponse(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * context)729 static void SdpReceiveConnectResponse(
730 uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *context)
731 {
732 int ret;
733 SdpReceiveConnectResponseInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConnectResponseInfo));
734 if (ctx == NULL) {
735 LOG_ERROR("point to NULL");
736 return;
737 }
738 (void)memset_s(ctx, sizeof(SdpReceiveConnectResponseInfo), 0x00, sizeof(SdpReceiveConnectResponseInfo));
739
740 ctx->lcid = lcid;
741 (void)memcpy_s(&ctx->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
742 ctx->result = result;
743 ctx->status = status;
744 ctx->context = context;
745
746 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConnectResponseTsk, ctx);
747 if (ret != BT_SUCCESS) {
748 MEM_MALLOC.free(ctx);
749 return;
750 }
751 }
752
753 typedef struct {
754 uint16_t lcid;
755 uint8_t id;
756 L2capConfigInfo config;
757 void *context;
758 } SdpReceiveConfigRequestInfo;
759 /**
760 * @brief Receive Configuration response from L2CAP as a server or a client.
761 *
762 * @param lcid Local channel identifier.
763 * @param id Identifier.
764 * @param config L2CAP configuration info.
765 * @param context The context from upper layer.
766 */
SdpReceiveConfigRequestTask(uint16_t lcid,uint8_t id,const L2capConfigInfo * config,void * context)767 static void SdpReceiveConfigRequestTask(uint16_t lcid, uint8_t id, const L2capConfigInfo *config, void *context)
768 {
769 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
770
771 SdpConnectInfo *connect = NULL;
772
773 if (!SdpGetEnableState()) {
774 return;
775 }
776
777 connect = SdpFindConnectByCid(lcid);
778 if (connect == NULL) {
779 LOG_ERROR("[%{public}s][%{public}d] Recv config request failed with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
780 return;
781 }
782 connect->mtu = config->mtu;
783 L2CIF_ConfigRsp(lcid, id, config, L2CAP_CONNECTION_SUCCESSFUL, SdpConfigRspCallback);
784
785 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
786 }
787
SdpReceiveConfigRequestTsk(void * context)788 static void SdpReceiveConfigRequestTsk(void *context)
789 {
790 SdpReceiveConfigRequestInfo *ctx = context;
791 SdpReceiveConfigRequestTask(ctx->lcid, ctx->id, &ctx->config, ctx->context);
792 MEM_MALLOC.free(ctx);
793 }
794
SdpReceiveConfigRequest(uint16_t lcid,uint8_t id,const L2capConfigInfo * config,void * context)795 static void SdpReceiveConfigRequest(uint16_t lcid, uint8_t id, const L2capConfigInfo *config, void *context)
796 {
797 int ret;
798 SdpReceiveConfigRequestInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConfigRequestInfo));
799 if (ctx == NULL) {
800 LOG_ERROR("point to NULL");
801 return;
802 }
803 (void)memset_s(ctx, sizeof(SdpReceiveConfigRequestInfo), 0x00, sizeof(SdpReceiveConfigRequestInfo));
804
805 ctx->lcid = lcid;
806 ctx->id = id;
807 (void)memcpy_s(&ctx->config, sizeof(L2capConfigInfo), config, sizeof(L2capConfigInfo));
808 ctx->context = context;
809
810 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConfigRequestTsk, ctx);
811 if (ret != BT_SUCCESS) {
812 MEM_MALLOC.free(ctx);
813 return;
814 }
815 }
816
817 typedef struct {
818 uint16_t lcid;
819 L2capConfigInfo config;
820 uint16_t result;
821 void *context;
822 } SdpReceiveConfigResponseInfo;
823 /**
824 * @brief Receive configuration response from L2CAP as a server or a client.
825 *
826 * @param lcid Local channel identifier.
827 * @param config L2CAP configuration info.
828 * @param result Connect result.
829 * @param context The context from upper layer.
830 */
SdpReceiveConfigResponseTask(uint16_t lcid,const L2capConfigInfo * config,uint16_t result,void * context)831 static void SdpReceiveConfigResponseTask(uint16_t lcid, const L2capConfigInfo *config, uint16_t result, void *context)
832 {
833 SdpClientRequest *request = NULL;
834 SdpConnectInfo *connect = NULL;
835
836 if (!SdpGetEnableState()) {
837 return;
838 }
839
840 connect = SdpFindConnectByCid(lcid);
841 if (connect == NULL) {
842 LOG_ERROR("[%{public}s][%{public}d] Recv connect with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
843 return;
844 }
845 if ((result != L2CAP_CONNECTION_SUCCESSFUL) && (connect->outConnState != SDP_STATE_CONN_SETUP)) {
846 return;
847 }
848
849 connect->outConnState = SDP_STATE_CFG_RSP_SETUP;
850 if ((connect->outConnState == SDP_STATE_CFG_RSP_SETUP) && (connect->inConnState == SDP_STATE_CFG_REQ_SETUP)) {
851 connect->outConnState = SDP_STATE_CONNECTED;
852 connect->inConnState = SDP_STATE_CONNECTED;
853 if (connect->flag) {
854 // Send client packet
855 request = SdpFindRequestByAddress(&connect->addr);
856 request->packetState = SDP_PACKET_SEND;
857 SdpSendRequest(connect->lcid, request->transactionId, 0, NULL, request->packet);
858 }
859 }
860 }
861
SdpReceiveConfigResponseTsk(void * context)862 static void SdpReceiveConfigResponseTsk(void *context)
863 {
864 SdpReceiveConfigResponseInfo *ctx = context;
865 SdpReceiveConfigResponseTask(ctx->lcid, &ctx->config, ctx->result, ctx->context);
866 MEM_MALLOC.free(ctx);
867 }
868
SdpReceiveConfigResponse(uint16_t lcid,const L2capConfigInfo * config,uint16_t result,void * context)869 static void SdpReceiveConfigResponse(uint16_t lcid, const L2capConfigInfo *config, uint16_t result, void *context)
870 {
871 int ret;
872 SdpReceiveConfigResponseInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConfigResponseInfo));
873 if (ctx == NULL) {
874 LOG_ERROR("point to NULL");
875 return;
876 }
877
878 (void)memset_s(ctx, sizeof(SdpReceiveConfigResponseInfo), 0x00, sizeof(SdpReceiveConfigResponseInfo));
879
880 ctx->lcid = lcid;
881 (void)memcpy_s(&ctx->config, sizeof(L2capConfigInfo), config, sizeof(L2capConfigInfo));
882 ctx->result = result;
883 ctx->context = context;
884
885 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConfigResponseTsk, ctx);
886 if (ret != BT_SUCCESS) {
887 MEM_MALLOC.free(ctx);
888 return;
889 }
890 }
891
892 /**
893 * @brief Send disconnection request from L2CAP as a client.
894 *
895 * @param lcid Local channel identifier.
896 */
SdpSendDisconnectRequest(uint16_t lcid,bool wait)897 static void SdpSendDisconnectRequest(uint16_t lcid, bool wait)
898 {
899 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
900
901 SdpConnectInfo *connect = SdpFindConnectByCid(lcid);
902 if (connect == NULL) {
903 LOG_WARN("[%{public}s][%{public}d] This connection has been disconnected.", __FUNCTION__, __LINE__);
904 return;
905 }
906 connect->inConnState = SDP_STATE_DISCONNECT;
907 connect->outConnState = SDP_STATE_DISCONNECT;
908 connect->wait = wait;
909
910 L2CIF_DisconnectionReq(lcid, NULL);
911
912 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
913 }
914
915 typedef struct {
916 uint16_t lcid;
917 uint8_t id;
918 void *context;
919 } SdpReceiveDisconnectRequestInfo;
920 /**
921 * @brief Receive disconnection request from L2CAP as a server.
922 *
923 * @param lcid Local channel identifier.
924 * @param id Identifier.
925 * @param context The context from upper layer.
926 */
SdpReceiveDisconnectRequestTask(uint16_t lcid,uint8_t id,void * context)927 static void SdpReceiveDisconnectRequestTask(uint16_t lcid, uint8_t id, void *context)
928 {
929 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
930
931 if (!SdpGetEnableState()) {
932 return;
933 }
934
935 L2CIF_DisconnectionRsp(lcid, id, SdpDisconnectionRspCallback);
936
937 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
938 }
939
SdpReceiveDisconnectRequestTsk(void * context)940 static void SdpReceiveDisconnectRequestTsk(void *context)
941 {
942 SdpReceiveDisconnectRequestInfo *ctx = context;
943 SdpReceiveDisconnectRequestTask(ctx->lcid, ctx->id, ctx->context);
944 MEM_MALLOC.free(ctx);
945 }
946
SdpReceiveDisconnectRequest(uint16_t lcid,uint8_t id,void * context)947 static void SdpReceiveDisconnectRequest(uint16_t lcid, uint8_t id, void *context)
948 {
949 int ret;
950 SdpReceiveDisconnectRequestInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveDisconnectRequestInfo));
951 if (ctx == NULL) {
952 LOG_ERROR("point to NULL");
953 return;
954 }
955 (void)memset_s(ctx, sizeof(SdpReceiveDisconnectRequestInfo), 0x00, sizeof(SdpReceiveDisconnectRequestInfo));
956
957 ctx->lcid = lcid;
958 ctx->id = id;
959 ctx->context = context;
960
961 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveDisconnectRequestTsk, ctx);
962 if (ret != BT_SUCCESS) {
963 MEM_MALLOC.free(ctx);
964 return;
965 }
966 }
967
968 typedef struct {
969 uint16_t lcid;
970 void *context;
971 } SdpReceiveDisconnectResponseInfo;
972 /**
973 * @brief Receive disconnection response from L2CAP as a client.
974 *
975 * @param lcid Local channel identifier.
976 * @param context The context from upper layer.
977 */
SdpReceiveDisconnectResponseTask(uint16_t lcid,void * context)978 static void SdpReceiveDisconnectResponseTask(uint16_t lcid, void *context)
979 {
980 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
981
982 SdpConnectInfo *connect = NULL;
983
984 if (!SdpGetEnableState()) {
985 return;
986 }
987
988 connect = SdpFindConnectByCid(lcid);
989 if (connect == NULL) {
990 LOG_WARN("[%{public}s][%{public}d] This connection has been disconnected.", __FUNCTION__, __LINE__);
991 return;
992 }
993 if (!connect->wait) {
994 SdpRemoveRequestByAddress(&connect->addr);
995 }
996 ListRemoveNode(g_connectList, connect);
997
998 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
999 }
1000
SdpReceiveDisconnectResponseTsk(void * context)1001 static void SdpReceiveDisconnectResponseTsk(void *context)
1002 {
1003 SdpReceiveDisconnectResponseInfo *ctx = context;
1004 SdpReceiveDisconnectResponseTask(ctx->lcid, ctx->context);
1005 MEM_MALLOC.free(ctx);
1006 }
1007
SdpReceiveDisconnectResponse(uint16_t lcid,void * context)1008 static void SdpReceiveDisconnectResponse(uint16_t lcid, void *context)
1009 {
1010 int ret;
1011 SdpReceiveDisconnectResponseInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveDisconnectResponseInfo));
1012 if (ctx == NULL) {
1013 LOG_ERROR("point to NULL");
1014 return;
1015 }
1016 (void)memset_s(ctx, sizeof(SdpReceiveDisconnectResponseInfo), 0x00, sizeof(SdpReceiveDisconnectResponseInfo));
1017
1018 ctx->lcid = lcid;
1019 ctx->context = context;
1020
1021 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveDisconnectResponseTsk, ctx);
1022 if (ret != BT_SUCCESS) {
1023 MEM_MALLOC.free(ctx);
1024 return;
1025 }
1026 }
1027
1028 typedef struct {
1029 uint16_t lcid;
1030 uint8_t reason;
1031 void *context;
1032 } SdpDisconnectAbnormalInfo;
1033 /**
1034 * @brief Receive abnormal disconnection response from L2CAP as a server or a client.
1035 *
1036 * @param lcid Local channel identifier.
1037 * @param reason The reason of abnormal disconnection.
1038 * @param context The context from upper layer.
1039 */
SdpDisconnectAbnormalTask(uint16_t lcid,uint8_t reason,void * context)1040 static void SdpDisconnectAbnormalTask(uint16_t lcid, uint8_t reason, void *context)
1041 {
1042 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x reason = 0x%02x start", __FUNCTION__, __LINE__, lcid, reason);
1043
1044 SdpConnectInfo *connect = NULL;
1045 SdpClientRequest *request = NULL;
1046
1047 if (!SdpGetEnableState()) {
1048 return;
1049 }
1050
1051 connect = SdpFindConnectByCid(lcid);
1052 if (connect == NULL) {
1053 LOG_WARN("[%{public}s][%{public}d] This connection has been disconnected.", __FUNCTION__, __LINE__);
1054 return;
1055 }
1056 #define HCI_COMMAND_DISALLOWED 0x0c
1057 if (connect->flag) {
1058 if (reason == HCI_COMMAND_DISALLOWED) {
1059 request = SdpFindRequestByAddress(&connect->addr);
1060 if (!request->resentFlag) {
1061 ListRemoveNode(g_connectList, connect);
1062 SdpSendConnectRequest(&request->addr);
1063 request->resentFlag = true;
1064 return;
1065 }
1066 } else if (reason == L2CAP_STATE_COLLISION) {
1067 request = SdpFindRequestByAddress(&connect->addr);
1068 ListRemoveNode(g_connectList, connect);
1069 SdpSendConnectRequest(&request->addr);
1070 return;
1071 }
1072 SdpRemoveAllRequestByAddress(&connect->addr);
1073 }
1074 ListRemoveNode(g_connectList, connect);
1075
1076 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
1077 }
1078
SdpDisconnectAbnormalTsk(void * context)1079 static void SdpDisconnectAbnormalTsk(void *context)
1080 {
1081 SdpDisconnectAbnormalInfo *ctx = context;
1082 SdpDisconnectAbnormalTask(ctx->lcid, ctx->reason, ctx->context);
1083 MEM_MALLOC.free(ctx);
1084 }
SdpDisconnectAbnormal(uint16_t lcid,uint8_t reason,void * context)1085 static void SdpDisconnectAbnormal(uint16_t lcid, uint8_t reason, void *context)
1086 {
1087 int ret;
1088 SdpDisconnectAbnormalInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpDisconnectAbnormalInfo));
1089 if (ctx == NULL) {
1090 LOG_ERROR("point to NULL");
1091 return;
1092 }
1093 (void)memset_s(ctx, sizeof(SdpDisconnectAbnormalInfo), 0x00, sizeof(SdpDisconnectAbnormalInfo));
1094
1095 ctx->lcid = lcid;
1096 ctx->reason = reason;
1097 ctx->context = context;
1098
1099 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpDisconnectAbnormalTsk, ctx);
1100 if (ret != BT_SUCCESS) {
1101 MEM_MALLOC.free(ctx);
1102 return;
1103 }
1104 }
1105
1106 typedef struct {
1107 uint16_t lcid;
1108 Packet *packet;
1109 void *context;
1110 } SdpReceiveDataInfo;
1111 /**
1112 * @brief Receive packet from L2CAP as a server or client.
1113 *
1114 * @param lcid Local channel identifier
1115 * @param packet The packet point for receiving data
1116 * @param context The context from upper layer.
1117 * @return void
1118 */
SdpReceiveDataTask(uint16_t lcid,const Packet * packet,void * context)1119 static void SdpReceiveDataTask(uint16_t lcid, const Packet *packet, void *context)
1120 {
1121 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
1122 SdpConnectInfo *connect = NULL;
1123 SdpClientRequest *request = NULL;
1124 bool flag = false;
1125
1126 if (!SdpGetEnableState()) {
1127 return;
1128 }
1129
1130 connect = SdpFindConnectByCid(lcid);
1131 if (connect == NULL) {
1132 LOG_ERROR("[%{public}s][%{public}d] Recv connect with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
1133 return;
1134 }
1135 if ((connect->outConnState == SDP_STATE_CONNECTED) && (connect->inConnState == SDP_STATE_CONNECTED)) {
1136 if (connect->flag) {
1137 SdpParseServerResponse(&connect->addr, lcid, packet);
1138 request = SdpFindRemainRequestByAddress(&connect->addr, &flag);
1139 if (request != NULL) {
1140 request->packetState = SDP_PACKET_SEND;
1141 SdpSendRequest(connect->lcid, request->transactionId, 0, NULL, request->packet);
1142 } else if (!flag) {
1143 AlarmSet(connect->timer, SDP_CONNECT_WAIT_TIME, SdpConnectWaitTime, connect);
1144 }
1145 } else {
1146 SdpParseClientRequest(lcid, packet);
1147 }
1148 }
1149 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
1150 }
1151
SdpReceiveDataTsk(void * context)1152 static void SdpReceiveDataTsk(void *context)
1153 {
1154 SdpReceiveDataInfo *ctx = context;
1155 SdpReceiveDataTask(ctx->lcid, ctx->packet, ctx->context);
1156 PacketFree(ctx->packet);
1157 ctx->packet = NULL;
1158 MEM_MALLOC.free(ctx);
1159 }
1160
SdpReceiveData(uint16_t lcid,Packet * packet,void * context)1161 static void SdpReceiveData(uint16_t lcid, Packet *packet, void *context)
1162 {
1163 int ret;
1164 SdpReceiveDataInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveDataInfo));
1165 if (ctx == NULL) {
1166 LOG_ERROR("point to NULL");
1167 return;
1168 }
1169 (void)memset_s(ctx, sizeof(SdpReceiveDataInfo), 0x00, sizeof(SdpReceiveDataInfo));
1170
1171 ctx->lcid = lcid;
1172 ctx->packet = PacketRefMalloc(packet);
1173 ctx->context = context;
1174
1175 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveDataTsk, ctx);
1176 if (ret != BT_SUCCESS) {
1177 PacketFree(ctx->packet);
1178 ctx->packet = NULL;
1179 MEM_MALLOC.free(ctx);
1180 return;
1181 }
1182 }
1183
SdpSendErrorResponse(uint16_t lcid,uint16_t transactionId,uint16_t errorCode)1184 void SdpSendErrorResponse(uint16_t lcid, uint16_t transactionId, uint16_t errorCode)
1185 {
1186 Packet *packet = NULL;
1187 uint8_t buffer[2] = {0};
1188 uint8_t *header = NULL;
1189 uint16_t offset = 0;
1190
1191 packet = PacketMalloc(SDP_PDU_HEADER_LENGTH, 0, SDP_UINT16_LENGTH);
1192 *(uint16_t *)buffer = H2BE_16(errorCode);
1193 PacketPayloadWrite(packet, buffer, 0, SDP_UINT16_LENGTH);
1194
1195 header = (uint8_t *)BufferPtr(PacketHead(packet));
1196 /// PduID
1197 header[0] = SDP_ERROR_RESPONSE;
1198 offset++;
1199 /// Transaction ID
1200 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1201 offset += SDP_UINT16_LENGTH;
1202 /// ParameterLength
1203 *(uint16_t *)(header + offset) = H2BE_16(SDP_UINT16_LENGTH);
1204
1205 L2CIF_SendData(lcid, packet, NULL);
1206 PacketFree(packet);
1207 packet = NULL;
1208 }
1209
SdpGetCurrentServiceRecordCount(uint16_t mtu,uint16_t maxCount,uint16_t totalServiceRecordCount)1210 static uint16_t SdpGetCurrentServiceRecordCount(uint16_t mtu, uint16_t maxCount, uint16_t totalServiceRecordCount)
1211 {
1212 uint16_t number = (mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1213 if (maxCount > number) {
1214 return number;
1215 }
1216 return maxCount;
1217 }
1218
SdpBuildSearchFragmentResponse(uint16_t transactionId,size_t size,uint16_t totalServiceRecordCount,uint16_t currentServiceRecordCount,Packet * fragmentPacket)1219 static Packet *SdpBuildSearchFragmentResponse(uint16_t transactionId, size_t size, uint16_t totalServiceRecordCount,
1220 uint16_t currentServiceRecordCount, Packet *fragmentPacket)
1221 {
1222 Packet *sendPacket = NULL;
1223 uint8_t *header = NULL;
1224 uint8_t *tail = NULL;
1225 uint16_t length = 0;
1226 uint16_t offset = 0;
1227
1228 /// ContinuationState
1229 if (size == 0) {
1230 sendPacket =
1231 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, SDP_PACKET_TAIL_ONE_BYTE);
1232 tail = BufferPtr(PacketTail(sendPacket));
1233 tail[0] = 0x00;
1234 length = currentServiceRecordCount * SDP_UINT32_LENGTH + SDP_UINT32_LENGTH + SDP_PACKET_TAIL_ONE_BYTE;
1235 } else if (size <= 0xFF) {
1236 sendPacket =
1237 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, SDP_PACKET_TAIL_TWO_BYTE);
1238 tail = BufferPtr(PacketTail(sendPacket));
1239 tail[0] = 0x01;
1240 tail[1] = size & 0xFF;
1241 length = currentServiceRecordCount * SDP_UINT32_LENGTH + SDP_UINT32_LENGTH + SDP_PACKET_TAIL_TWO_BYTE;
1242 } else if (size <= 0xFFFF) {
1243 sendPacket =
1244 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, SDP_PACKET_TAIL_THREE_BYTE);
1245 tail = BufferPtr(PacketTail(sendPacket));
1246 tail[0] = 0x02;
1247 *(uint16_t *)(tail + 1) = H2BE_16(size);
1248 length = currentServiceRecordCount * SDP_UINT32_LENGTH + SDP_UINT32_LENGTH + SDP_PACKET_TAIL_THREE_BYTE;
1249 } else {
1250 LOG_ERROR("[%{public}s][%{public}d] Invalid continuation length [%zu]", __FUNCTION__, __LINE__, size);
1251 return NULL;
1252 }
1253 header = BufferPtr(PacketHead(sendPacket));
1254 /// PduID
1255 header[offset] = SDP_SERVICE_SEARCH_RESPONSE;
1256 offset++;
1257 /// Transaction ID
1258 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1259 offset += SDP_UINT16_LENGTH;
1260 /// ParameterLength
1261 *(uint16_t *)(header + offset) = H2BE_16(length);
1262 offset += SDP_UINT16_LENGTH;
1263 /// TotalServiceRecordCount
1264 *(uint16_t *)(header + offset) = H2BE_16(totalServiceRecordCount);
1265 offset += SDP_UINT16_LENGTH;
1266 /// CurrentServiceRecordCount
1267 *(uint16_t *)(header + offset) = H2BE_16(currentServiceRecordCount);
1268
1269 return sendPacket;
1270 }
1271
SdpSendSearchFragmentResponse(uint16_t lcid,uint16_t transactionId,uint16_t maxCount,const Packet * searchPacket)1272 void SdpSendSearchFragmentResponse(uint16_t lcid, uint16_t transactionId, uint16_t maxCount, const Packet *searchPacket)
1273 {
1274 SdpConnectInfo *connect = NULL;
1275 uint16_t totalServiceRecordCount;
1276 uint16_t currentServiceRecordCount;
1277 Packet *packet = NULL;
1278 Packet *fragmentPacket = NULL;
1279 Packet *sendPacket = NULL;
1280 size_t size;
1281
1282 connect = SdpFindConnectByCid(lcid);
1283 if (connect == NULL) {
1284 return;
1285 }
1286
1287 if (searchPacket == NULL) {
1288 if (connect->packet == NULL) {
1289 return;
1290 }
1291 packet = connect->packet;
1292 totalServiceRecordCount = connect->totalCount;
1293 } else {
1294 packet = PacketRefMalloc(searchPacket);
1295 totalServiceRecordCount = PacketSize(packet) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1296 }
1297 currentServiceRecordCount = SdpGetCurrentServiceRecordCount(connect->mtu, maxCount, totalServiceRecordCount);
1298
1299 fragmentPacket = PacketMalloc(0, 0, 0);
1300 size = PacketFragment(packet, fragmentPacket, currentServiceRecordCount * SDP_SERVICE_RECORD_HANDLE_BYTE);
1301 currentServiceRecordCount = PacketSize(fragmentPacket) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1302
1303 sendPacket = SdpBuildSearchFragmentResponse(
1304 transactionId, size, totalServiceRecordCount, currentServiceRecordCount, fragmentPacket);
1305 if (sendPacket == NULL) {
1306 SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_CONT_STATE);
1307 PacketFree(fragmentPacket);
1308 fragmentPacket = NULL;
1309 return;
1310 }
1311
1312 /// Send data
1313 L2CIF_SendData(lcid, sendPacket, NULL);
1314
1315 if (size != 0) {
1316 connect->packet = packet;
1317 connect->totalCount = totalServiceRecordCount;
1318 } else {
1319 PacketFree(packet);
1320 connect->packet = NULL;
1321 packet = NULL;
1322 }
1323
1324 PacketFree(fragmentPacket);
1325 fragmentPacket = NULL;
1326 PacketFree(sendPacket);
1327 sendPacket = NULL;
1328 }
1329
SdpSendSearchResponse(uint16_t lcid,uint16_t transactionId,uint16_t offset,uint8_t * buffer,uint16_t maxCount)1330 void SdpSendSearchResponse(uint16_t lcid, uint16_t transactionId, uint16_t offset, uint8_t *buffer, uint16_t maxCount)
1331 {
1332 SdpConnectInfo *connect = NULL;
1333 uint16_t totalServiceRecordCount;
1334 uint16_t number;
1335 uint16_t length;
1336 Packet *packet = NULL;
1337 Packet *sendPacket = NULL;
1338 uint8_t *header = NULL;
1339 uint8_t *tail = NULL;
1340 uint16_t pos = 0;
1341
1342 connect = SdpFindConnectByCid(lcid);
1343 if (connect == NULL) {
1344 return;
1345 }
1346
1347 /// ServiceSearchPattern
1348 packet = PacketMalloc(0, 0, offset);
1349 PacketPayloadWrite(packet, buffer, 0, offset);
1350
1351 /// TotalServiceRecordCount
1352 totalServiceRecordCount = offset / SDP_SERVICE_RECORD_HANDLE_BYTE;
1353 if (totalServiceRecordCount > maxCount) {
1354 totalServiceRecordCount = maxCount;
1355 }
1356 number = (connect->mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH - 1) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1357 if (totalServiceRecordCount > number) {
1358 /// Fragment packet
1359 SdpSendSearchFragmentResponse(lcid, transactionId, maxCount, packet);
1360 PacketFree(packet);
1361 packet = NULL;
1362 return;
1363 }
1364
1365 /// Single packet
1366 length = totalServiceRecordCount * SDP_SERVICE_RECORD_HANDLE_BYTE + SDP_UINT32_LENGTH + 1;
1367 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, 1);
1368 header = BufferPtr(PacketHead(sendPacket));
1369 tail = BufferPtr(PacketTail(sendPacket));
1370 /// PduID
1371 header[pos] = SDP_SERVICE_SEARCH_RESPONSE;
1372 pos++;
1373 /// Transaction ID
1374 *(uint16_t *)(header + pos) = H2BE_16(transactionId);
1375 pos += SDP_UINT16_LENGTH;
1376 /// ParameterLength
1377 *(uint16_t *)(header + pos) = H2BE_16(length);
1378 pos += SDP_UINT16_LENGTH;
1379 /// TotalServiceRecordCount
1380 *(uint16_t *)(header + pos) = H2BE_16(totalServiceRecordCount);
1381 pos += SDP_UINT16_LENGTH;
1382 /// CurrentServiceRecordCount = TotalServiceRecordCount
1383 *(uint16_t *)(header + pos) = H2BE_16(totalServiceRecordCount);
1384 /// ContinuationState
1385 tail[0] = 0;
1386
1387 /// Send packet
1388 L2CIF_SendData(lcid, sendPacket, NULL);
1389
1390 PacketFree(packet);
1391 packet = NULL;
1392 PacketFree(sendPacket);
1393 sendPacket = NULL;
1394 }
1395
SdpBuildAttributeFragmentResponse(SdpPduId pduId,uint16_t transactionId,size_t size,Packet * fragmentPacket)1396 static Packet *SdpBuildAttributeFragmentResponse(
1397 SdpPduId pduId, uint16_t transactionId, size_t size, Packet *fragmentPacket)
1398 {
1399 Packet *sendPacket = NULL;
1400 uint16_t length = 0;
1401 uint16_t offset = 0;
1402 uint8_t *header = NULL;
1403 uint8_t *tail = NULL;
1404
1405 /// AttributeByteCount
1406 uint16_t attributeByteCount = (uint16_t)PacketSize(fragmentPacket);
1407
1408 /// ContinuationState
1409 if (size == 0) {
1410 sendPacket =
1411 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_ONE_BYTE);
1412 tail = BufferPtr(PacketTail(sendPacket));
1413 tail[0] = 0x00;
1414 length = attributeByteCount + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_ONE_BYTE;
1415 } else if (size <= 0xFF) {
1416 sendPacket =
1417 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_TWO_BYTE);
1418 tail = BufferPtr(PacketTail(sendPacket));
1419 tail[0] = 0x01;
1420 tail[1] = size & 0xFF;
1421 length = attributeByteCount + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_TWO_BYTE;
1422 } else if (size <= 0xFFFF) {
1423 sendPacket =
1424 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_THREE_BYTE);
1425 tail = BufferPtr(PacketTail(sendPacket));
1426 tail[0] = 0x02;
1427 *(uint16_t *)(tail + 1) = H2BE_16((uint16_t)size);
1428 length = attributeByteCount + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_THREE_BYTE;
1429 } else {
1430 LOG_ERROR("[%{public}s][%{public}d] Invalid continuation length [%zu]", __FUNCTION__, __LINE__, size);
1431 return NULL;
1432 }
1433
1434 header = BufferPtr(PacketHead(sendPacket));
1435 /// PduID
1436 header[offset] = pduId;
1437 offset++;
1438 /// Transaction ID
1439 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1440 offset += SDP_UINT16_LENGTH;
1441 /// ParameterLength
1442 *(uint16_t *)(header + offset) = H2BE_16(length);
1443 offset += SDP_UINT16_LENGTH;
1444 /// AttributeListByteCount
1445 *(uint16_t *)(header + offset) = H2BE_16(attributeByteCount);
1446
1447 return sendPacket;
1448 }
1449
SdpSendAttributeFragmentResponse(uint16_t lcid,SdpPduId pduId,uint16_t transactionId,uint16_t maxCount,const Packet * attributePacket)1450 void SdpSendAttributeFragmentResponse(
1451 uint16_t lcid, SdpPduId pduId, uint16_t transactionId, uint16_t maxCount, const Packet *attributePacket)
1452 {
1453 SdpConnectInfo *connect = NULL;
1454 Packet *packet = NULL;
1455 Packet *fragmentPacket = NULL;
1456 Packet *sendPacket = NULL;
1457 size_t size;
1458
1459 connect = SdpFindConnectByCid(lcid);
1460 if (connect == NULL) {
1461 return;
1462 }
1463
1464 if (attributePacket == NULL) {
1465 if (connect->packet == NULL) {
1466 return;
1467 }
1468 packet = connect->packet;
1469 } else {
1470 packet = PacketRefMalloc(attributePacket);
1471 }
1472
1473 fragmentPacket = PacketMalloc(0, 0, 0);
1474 size = PacketFragment(packet, fragmentPacket, maxCount);
1475
1476 sendPacket = SdpBuildAttributeFragmentResponse(pduId, transactionId, size, fragmentPacket);
1477 if (sendPacket == NULL) {
1478 SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_CONT_STATE);
1479 return;
1480 }
1481
1482 /// Send data
1483 L2CIF_SendData(lcid, sendPacket, NULL);
1484
1485 if (size != 0) {
1486 connect = SdpFindConnectByCid(lcid);
1487 if (connect == NULL) {
1488 LOG_ERROR("point to NULL");
1489 return;
1490 }
1491 /// store remain packet
1492 connect->packet = packet;
1493 } else {
1494 PacketFree(packet);
1495 packet = NULL;
1496 connect->packet = NULL;
1497 }
1498
1499 PacketFree(fragmentPacket);
1500 fragmentPacket = NULL;
1501 PacketFree(sendPacket);
1502 sendPacket = NULL;
1503 }
1504
SdpSendAttributeResponse(uint16_t lcid,uint16_t transactionId,SdpPduId pduId,uint16_t maxCount,const Packet * packet)1505 void SdpSendAttributeResponse(
1506 uint16_t lcid, uint16_t transactionId, SdpPduId pduId, uint16_t maxCount, const Packet *packet)
1507 {
1508 SdpConnectInfo *connect = NULL;
1509 Packet *sendPacket = NULL;
1510 uint16_t length;
1511 uint8_t *header = NULL;
1512 uint8_t *tail = NULL;
1513
1514 connect = SdpFindConnectByCid(lcid);
1515 if (connect == NULL) {
1516 LOG_ERROR("[%{public}s][%{public}d] There is no connect with cid [%hu]", __FUNCTION__, __LINE__, lcid);
1517 return;
1518 }
1519
1520 if (maxCount > (connect->mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH)) {
1521 maxCount = connect->mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH;
1522 }
1523
1524 length = PacketSize(packet);
1525 if (length > maxCount) {
1526 /// Fragment packet
1527 SdpSendAttributeFragmentResponse(lcid, pduId, transactionId, maxCount, packet);
1528 return;
1529 } else {
1530 /// Single packet
1531 uint16_t offset = 0;
1532 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_ONE_BYTE);
1533 header = BufferPtr(PacketHead(sendPacket));
1534 tail = BufferPtr(PacketTail(sendPacket));
1535 /// PduID
1536 header[offset] = pduId;
1537 offset++;
1538 /// Transaction ID
1539 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1540 offset += SDP_UINT16_LENGTH;
1541 /// ParameterLength
1542 *(uint16_t *)(header + offset) = H2BE_16(length + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_ONE_BYTE);
1543 offset += SDP_UINT16_LENGTH;
1544 /// AttributeListByteCount
1545 *(uint16_t *)(header + offset) = H2BE_16(length);
1546 /// ContinuationState
1547 tail[0] = 0;
1548
1549 /// Send packet
1550 L2CIF_SendData(lcid, sendPacket, NULL);
1551 PacketFree(sendPacket);
1552 sendPacket = NULL;
1553 }
1554 }
1555
SdpSendRequest(uint16_t lcid,uint16_t transactionId,uint8_t continuationStateLen,const uint8_t * continuationState,Packet * packet)1556 void SdpSendRequest(uint16_t lcid, uint16_t transactionId, uint8_t continuationStateLen,
1557 const uint8_t *continuationState, Packet *packet)
1558 {
1559 SdpClientRequest *request = NULL;
1560 Packet *sendPacket = NULL;
1561 uint8_t *header = NULL;
1562 uint8_t *tail = NULL;
1563
1564 uint16_t length = PacketPayloadSize(packet);
1565 /// ContinuationState
1566 if (continuationStateLen == 0) {
1567 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH, 1);
1568 tail = BufferPtr(PacketTail(sendPacket));
1569 tail[0] = 0x00;
1570 length += 1;
1571 } else {
1572 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH, continuationStateLen + 1);
1573 tail = BufferPtr(PacketTail(sendPacket));
1574 tail[0] = 0x01;
1575 (void)memcpy_s(tail, continuationStateLen + 1, continuationState, continuationStateLen + 1);
1576 length = length + continuationStateLen + 1;
1577 }
1578
1579 header = (uint8_t *)BufferPtr(PacketHead(sendPacket));
1580 /// PduID
1581 request = SdpFindRequestByTransactionId(transactionId);
1582 if (request == NULL) {
1583 return;
1584 }
1585 header[0] = request->pduId;
1586 /// Transaction ID
1587 *(uint16_t *)(header + 1) = H2BE_16(transactionId);
1588 /// ParameterLength
1589 *(uint16_t *)(header + SDP_UINT16_LENGTH + 1) = H2BE_16(length);
1590
1591 /// Send packet
1592 L2CIF_SendData(lcid, sendPacket, NULL);
1593
1594 PacketFree(sendPacket);
1595 sendPacket = NULL;
1596 }
1597
SdpClientConnect(SdpClientRequest * request)1598 int SdpClientConnect(SdpClientRequest *request)
1599 {
1600 SdpConnectInfo *connect = NULL;
1601
1602 if (g_connectList == NULL) {
1603 return BT_OPERATION_FAILED;
1604 }
1605 connect = SdpFindConnectByAddress(&request->addr);
1606 if (connect == NULL) {
1607 /// Create new channel
1608 SdpAddRequest(request);
1609 SdpSendConnectRequest(&request->addr);
1610 return BT_SUCCESS;
1611 }
1612 /// Use existed channel
1613 if ((connect->inConnState == SDP_STATE_CONNECTED) && (connect->outConnState == SDP_STATE_CONNECTED)) {
1614 /// Channel idle and send packet
1615 SdpClientRequest *tempRequest = SdpFindRequestByAddress(&connect->addr);
1616 if (tempRequest == NULL) {
1617 if (connect->timer != NULL) {
1618 AlarmCancel(connect->timer);
1619 }
1620 request->packetState = SDP_PACKET_SEND;
1621 SdpAddRequest(request);
1622 SdpSendRequest(connect->lcid, request->transactionId, 0, NULL, request->packet);
1623 } else {
1624 SdpAddRequest(request);
1625 }
1626 } else if ((connect->inConnState == SDP_STATE_DISCONNECT) && (connect->outConnState == SDP_STATE_DISCONNECT)) {
1627 /// Create new channel
1628 SdpAddRequest(request);
1629 SdpSendConnectRequest(&request->addr);
1630 } else {
1631 SdpAddRequest(request);
1632 }
1633
1634 return BT_SUCCESS;
1635 }
1636