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 if (request == NULL) {
484 LOG_ERROR("[%{public}s][%{public}d] SdpFindRequestByAddress() return nullptr", __FUNCTION__, __LINE__);
485 return;
486 }
487 request->packetState = SDP_PACKET_SEND;
488 SdpSendRequest(lcid, request->transactionId, 0, NULL, request->packet);
489 }
490 }
491 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
492 }
493
SdpConfigRspCallbackTsk(void * context)494 static void SdpConfigRspCallbackTsk(void *context)
495 {
496 SdpConnectCallbackInfo *ctx = context;
497 SdpConfigRspCallbackTask(ctx->lcid, ctx->result);
498 MEM_MALLOC.free(ctx);
499 }
500
SdpConfigRspCallback(uint16_t lcid,int result)501 static void SdpConfigRspCallback(uint16_t lcid, int result)
502 {
503 int ret;
504 SdpConnectCallbackInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectCallbackInfo));
505 if (ctx == NULL) {
506 LOG_ERROR("point to NULL");
507 return;
508 }
509 (void)memset_s(ctx, sizeof(SdpConnectCallbackInfo), 0x00, sizeof(SdpConnectCallbackInfo));
510
511 ctx->lcid = lcid;
512 ctx->result = result;
513
514 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpConfigRspCallbackTsk, ctx);
515 if (ret != BT_SUCCESS) {
516 MEM_MALLOC.free(ctx);
517 return;
518 }
519 }
520
SdpDisconnectionRspCallbackTask(uint16_t lcid,int result)521 static void SdpDisconnectionRspCallbackTask(uint16_t lcid, int result)
522 {
523 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
524
525 SdpConnectInfo *connect = NULL;
526
527 if (!SdpGetEnableState()) {
528 return;
529 }
530
531 if (result != BT_SUCCESS) {
532 LOG_ERROR("[%{public}s][%{public}d] Disconnect response callback failed", __FUNCTION__, __LINE__);
533 return;
534 }
535
536 connect = SdpFindConnectByCid(lcid);
537 if (connect == NULL) {
538 LOG_ERROR("[%{public}s][%{public}d] Disconnect response callback failed", __FUNCTION__, __LINE__);
539 return;
540 }
541 ListRemoveNode(g_connectList, connect);
542
543 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
544 }
545
SdpDisconnectionRspCallbackTsk(void * context)546 static void SdpDisconnectionRspCallbackTsk(void *context)
547 {
548 SdpConnectCallbackInfo *ctx = context;
549 SdpDisconnectionRspCallbackTask(ctx->lcid, ctx->result);
550 MEM_MALLOC.free(ctx);
551 }
552
SdpDisconnectionRspCallback(uint16_t lcid,int result)553 static void SdpDisconnectionRspCallback(uint16_t lcid, int result)
554 {
555 int ret;
556 SdpConnectCallbackInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpConnectCallbackInfo));
557 if (ctx == NULL) {
558 LOG_ERROR("point to NULL");
559 return;
560 }
561 (void)memset_s(ctx, sizeof(SdpConnectCallbackInfo), 0x00, sizeof(SdpConnectCallbackInfo));
562
563 ctx->lcid = lcid;
564 ctx->result = result;
565
566 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpDisconnectionRspCallbackTsk, ctx);
567 if (ret != BT_SUCCESS) {
568 MEM_MALLOC.free(ctx);
569 return;
570 }
571 }
572
573 /**
574 * @brief Send connection request from L2CAP as a client.
575 *
576 * @param addr The Bluetooth address of the peer.
577 * @param packet The packet point for sending data.
578 * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
579 */
SdpSendConnectRequest(const BtAddr * addr)580 static void SdpSendConnectRequest(const BtAddr *addr)
581 {
582 SdpConnectInfo *connect = NULL;
583
584 connect = MEM_MALLOC.alloc(sizeof(SdpConnectInfo));
585 if (connect == NULL) {
586 LOG_ERROR("point to NULL");
587 return;
588 }
589 (void)memset_s(connect, sizeof(SdpConnectInfo), 0, sizeof(SdpConnectInfo));
590
591 /// Save address
592 (void)memcpy_s(&connect->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
593 /// Set client connect
594 connect->inConnState = SDP_STATE_IDLE;
595 connect->outConnState = SDP_STATE_IDLE;
596 connect->flag = true;
597 connect->wait = false;
598 ListAddLast(g_connectList, connect);
599
600 /// Send request to L2CAP
601 L2CIF_ConnectReq(addr, SDP_PSM, SDP_PSM, NULL, SdpConnectReqCallback);
602 }
603
604 typedef struct {
605 uint16_t lcid;
606 uint8_t id;
607 L2capConnectionInfo info;
608 uint16_t lpsm;
609 void *context;
610 } SdpReceiveConnectRequestInfo;
611 /**
612 * @brief Receive connection request from L2CAP as a server.
613 *
614 * @param lcid Local channel identifier.
615 * @param id Identifier.
616 * @param info L2CAP connection info.
617 * @param lpsm SDP_PSM (0x0001).
618 * @param context The context from upper layer.
619 */
SdpReceiveConnectRequestTask(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t lpsm,void * context)620 static void SdpReceiveConnectRequestTask(
621 uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *context)
622 {
623 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
624
625 if (!SdpGetEnableState()) {
626 return;
627 }
628
629 /// Send connect response to L2CAP
630 L2CIF_ConnectRsp(
631 lcid, id, L2CAP_CONNECTION_SUCCESSFUL, L2CAP_NO_FURTHER_INFORMATION_AVAILABLE, SdpConnectRspCallback);
632
633 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
634 }
635
SdpReceiveConnectRequestTsk(void * context)636 static void SdpReceiveConnectRequestTsk(void *context)
637 {
638 SdpReceiveConnectRequestInfo *ctx = context;
639 SdpReceiveConnectRequestTask(ctx->lcid, ctx->id, &ctx->info, ctx->lpsm, ctx->context);
640 MEM_MALLOC.free(ctx);
641 }
642
SdpReceiveConnectRequest(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t lpsm,void * context)643 static void SdpReceiveConnectRequest(
644 uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *context)
645 {
646 int ret;
647 SdpReceiveConnectRequestInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConnectRequestInfo));
648 if (ctx == NULL) {
649 LOG_ERROR("point to NULL");
650 return;
651 }
652 (void)memset_s(ctx, sizeof(SdpReceiveConnectRequestInfo), 0x00, sizeof(SdpReceiveConnectRequestInfo));
653
654 ctx->lcid = lcid;
655 ctx->id = id;
656 (void)memcpy_s(&ctx->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
657 ctx->lpsm = lpsm;
658 ctx->context = context;
659
660 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConnectRequestTsk, ctx);
661 if (ret != BT_SUCCESS) {
662 MEM_MALLOC.free(ctx);
663 return;
664 }
665 }
666
667 typedef struct {
668 uint16_t lcid;
669 L2capConnectionInfo info;
670 uint16_t result;
671 uint16_t status;
672 void *context;
673 } SdpReceiveConnectResponseInfo;
674 /**
675 * @brief Receive connection response from L2CAP as a client.
676 *
677 * @param lcid Local channel identifier
678 * @param info L2CAP connection info.
679 * @param result L2CAP result
680 * @param status L2CAP status
681 * @param context The context from upper layer.
682 */
SdpReceiveConnectResponseTask(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * context)683 static void SdpReceiveConnectResponseTask(
684 uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *context)
685 {
686 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
687
688 L2capConfigInfo config;
689 SdpConnectInfo *connect = NULL;
690
691 if (!SdpGetEnableState()) {
692 return;
693 }
694
695 connect = SdpFindConnectByCid(lcid);
696 if (connect == NULL) {
697 LOG_WARN("[%{public}s][%{public}d] Recv connect failed with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
698 SdpSendDisconnectRequest(lcid, false);
699 return;
700 }
701 if (result == L2CAP_CONNECTION_PENDING) {
702 LOG_WARN("[%{public}s][%{public}d] Recv connect response pending [0x%02x]", __FUNCTION__, __LINE__, lcid);
703 return;
704 } else if ((result != L2CAP_CONNECTION_SUCCESSFUL) || (connect->outConnState != SDP_STATE_CONN_SETUP) ||
705 (connect->inConnState != SDP_STATE_CONN_SETUP)) {
706 LOG_ERROR("[%{public}s][%{public}d] Recv connect response failed with cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
707 return;
708 }
709
710 /// stop timer when received a connect response
711 if (connect->timer != NULL) {
712 /// Cancel timeout
713 AlarmCancel(connect->timer);
714 }
715
716 /// L2CAP default configuration. SDP only care about mtu.
717 (void)memset_s(&config, sizeof(L2capConfigInfo), 0, sizeof(L2capConfigInfo));
718 config.mtu = SDP_MTU_SIZE;
719 config.flushTimeout = 0xFFFF;
720 config.fcs = 0x01;
721 L2CIF_ConfigReq(lcid, &config, SdpConfigReqCallback);
722
723 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
724 }
725
SdpReceiveConnectResponseTsk(void * context)726 static void SdpReceiveConnectResponseTsk(void *context)
727 {
728 SdpReceiveConnectResponseInfo *ctx = context;
729 SdpReceiveConnectResponseTask(ctx->lcid, &ctx->info, ctx->result, ctx->status, ctx->context);
730 MEM_MALLOC.free(ctx);
731 }
732
SdpReceiveConnectResponse(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * context)733 static void SdpReceiveConnectResponse(
734 uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *context)
735 {
736 int ret;
737 SdpReceiveConnectResponseInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConnectResponseInfo));
738 if (ctx == NULL) {
739 LOG_ERROR("point to NULL");
740 return;
741 }
742 (void)memset_s(ctx, sizeof(SdpReceiveConnectResponseInfo), 0x00, sizeof(SdpReceiveConnectResponseInfo));
743
744 ctx->lcid = lcid;
745 (void)memcpy_s(&ctx->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
746 ctx->result = result;
747 ctx->status = status;
748 ctx->context = context;
749
750 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConnectResponseTsk, ctx);
751 if (ret != BT_SUCCESS) {
752 MEM_MALLOC.free(ctx);
753 return;
754 }
755 }
756
757 typedef struct {
758 uint16_t lcid;
759 uint8_t id;
760 L2capConfigInfo config;
761 void *context;
762 } SdpReceiveConfigRequestInfo;
763 /**
764 * @brief Receive Configuration response from L2CAP as a server or a client.
765 *
766 * @param lcid Local channel identifier.
767 * @param id Identifier.
768 * @param config L2CAP configuration info.
769 * @param context The context from upper layer.
770 */
SdpReceiveConfigRequestTask(uint16_t lcid,uint8_t id,const L2capConfigInfo * config,void * context)771 static void SdpReceiveConfigRequestTask(uint16_t lcid, uint8_t id, const L2capConfigInfo *config, void *context)
772 {
773 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
774
775 SdpConnectInfo *connect = NULL;
776
777 if (!SdpGetEnableState()) {
778 return;
779 }
780
781 connect = SdpFindConnectByCid(lcid);
782 if (connect == NULL) {
783 LOG_ERROR("[%{public}s][%{public}d] Recv config request failed with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
784 return;
785 }
786 connect->mtu = config->mtu;
787 L2CIF_ConfigRsp(lcid, id, config, L2CAP_CONNECTION_SUCCESSFUL, SdpConfigRspCallback);
788
789 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
790 }
791
SdpReceiveConfigRequestTsk(void * context)792 static void SdpReceiveConfigRequestTsk(void *context)
793 {
794 SdpReceiveConfigRequestInfo *ctx = context;
795 SdpReceiveConfigRequestTask(ctx->lcid, ctx->id, &ctx->config, ctx->context);
796 MEM_MALLOC.free(ctx);
797 }
798
SdpReceiveConfigRequest(uint16_t lcid,uint8_t id,const L2capConfigInfo * config,void * context)799 static void SdpReceiveConfigRequest(uint16_t lcid, uint8_t id, const L2capConfigInfo *config, void *context)
800 {
801 int ret;
802 SdpReceiveConfigRequestInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConfigRequestInfo));
803 if (ctx == NULL) {
804 LOG_ERROR("point to NULL");
805 return;
806 }
807 (void)memset_s(ctx, sizeof(SdpReceiveConfigRequestInfo), 0x00, sizeof(SdpReceiveConfigRequestInfo));
808
809 ctx->lcid = lcid;
810 ctx->id = id;
811 (void)memcpy_s(&ctx->config, sizeof(L2capConfigInfo), config, sizeof(L2capConfigInfo));
812 ctx->context = context;
813
814 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConfigRequestTsk, ctx);
815 if (ret != BT_SUCCESS) {
816 MEM_MALLOC.free(ctx);
817 return;
818 }
819 }
820
821 typedef struct {
822 uint16_t lcid;
823 L2capConfigInfo config;
824 uint16_t result;
825 void *context;
826 } SdpReceiveConfigResponseInfo;
827 /**
828 * @brief Receive configuration response from L2CAP as a server or a client.
829 *
830 * @param lcid Local channel identifier.
831 * @param config L2CAP configuration info.
832 * @param result Connect result.
833 * @param context The context from upper layer.
834 */
SdpReceiveConfigResponseTask(uint16_t lcid,const L2capConfigInfo * config,uint16_t result,void * context)835 static void SdpReceiveConfigResponseTask(uint16_t lcid, const L2capConfigInfo *config, uint16_t result, void *context)
836 {
837 SdpClientRequest *request = NULL;
838 SdpConnectInfo *connect = NULL;
839
840 if (!SdpGetEnableState()) {
841 return;
842 }
843
844 connect = SdpFindConnectByCid(lcid);
845 if (connect == NULL) {
846 LOG_ERROR("[%{public}s][%{public}d] Recv connect with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
847 return;
848 }
849 if ((result != L2CAP_CONNECTION_SUCCESSFUL) && (connect->outConnState != SDP_STATE_CONN_SETUP)) {
850 return;
851 }
852
853 connect->outConnState = SDP_STATE_CFG_RSP_SETUP;
854 if ((connect->outConnState == SDP_STATE_CFG_RSP_SETUP) && (connect->inConnState == SDP_STATE_CFG_REQ_SETUP)) {
855 connect->outConnState = SDP_STATE_CONNECTED;
856 connect->inConnState = SDP_STATE_CONNECTED;
857 if (connect->flag) {
858 // Send client packet
859 request = SdpFindRequestByAddress(&connect->addr);
860 if (request == NULL) {
861 LOG_ERROR("[%{public}s][%{public}d] SdpFindRequestByAddress() return nullptr", __FUNCTION__, __LINE__);
862 return;
863 }
864 request->packetState = SDP_PACKET_SEND;
865 SdpSendRequest(connect->lcid, request->transactionId, 0, NULL, request->packet);
866 }
867 }
868 }
869
SdpReceiveConfigResponseTsk(void * context)870 static void SdpReceiveConfigResponseTsk(void *context)
871 {
872 SdpReceiveConfigResponseInfo *ctx = context;
873 SdpReceiveConfigResponseTask(ctx->lcid, &ctx->config, ctx->result, ctx->context);
874 MEM_MALLOC.free(ctx);
875 }
876
SdpReceiveConfigResponse(uint16_t lcid,const L2capConfigInfo * config,uint16_t result,void * context)877 static void SdpReceiveConfigResponse(uint16_t lcid, const L2capConfigInfo *config, uint16_t result, void *context)
878 {
879 int ret;
880 SdpReceiveConfigResponseInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveConfigResponseInfo));
881 if (ctx == NULL) {
882 LOG_ERROR("point to NULL");
883 return;
884 }
885
886 (void)memset_s(ctx, sizeof(SdpReceiveConfigResponseInfo), 0x00, sizeof(SdpReceiveConfigResponseInfo));
887
888 ctx->lcid = lcid;
889 (void)memcpy_s(&ctx->config, sizeof(L2capConfigInfo), config, sizeof(L2capConfigInfo));
890 ctx->result = result;
891 ctx->context = context;
892
893 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveConfigResponseTsk, ctx);
894 if (ret != BT_SUCCESS) {
895 MEM_MALLOC.free(ctx);
896 return;
897 }
898 }
899
900 /**
901 * @brief Send disconnection request from L2CAP as a client.
902 *
903 * @param lcid Local channel identifier.
904 */
SdpSendDisconnectRequest(uint16_t lcid,bool wait)905 static void SdpSendDisconnectRequest(uint16_t lcid, bool wait)
906 {
907 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
908
909 SdpConnectInfo *connect = SdpFindConnectByCid(lcid);
910 if (connect == NULL) {
911 LOG_WARN("[%{public}s][%{public}d] This connection has been disconnected.", __FUNCTION__, __LINE__);
912 return;
913 }
914 connect->inConnState = SDP_STATE_DISCONNECT;
915 connect->outConnState = SDP_STATE_DISCONNECT;
916 connect->wait = wait;
917
918 L2CIF_DisconnectionReq(lcid, NULL);
919
920 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
921 }
922
923 typedef struct {
924 uint16_t lcid;
925 uint8_t id;
926 void *context;
927 } SdpReceiveDisconnectRequestInfo;
928 /**
929 * @brief Receive disconnection request from L2CAP as a server.
930 *
931 * @param lcid Local channel identifier.
932 * @param id Identifier.
933 * @param context The context from upper layer.
934 */
SdpReceiveDisconnectRequestTask(uint16_t lcid,uint8_t id,void * context)935 static void SdpReceiveDisconnectRequestTask(uint16_t lcid, uint8_t id, void *context)
936 {
937 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
938
939 if (!SdpGetEnableState()) {
940 return;
941 }
942
943 L2CIF_DisconnectionRsp(lcid, id, SdpDisconnectionRspCallback);
944
945 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
946 }
947
SdpReceiveDisconnectRequestTsk(void * context)948 static void SdpReceiveDisconnectRequestTsk(void *context)
949 {
950 SdpReceiveDisconnectRequestInfo *ctx = context;
951 SdpReceiveDisconnectRequestTask(ctx->lcid, ctx->id, ctx->context);
952 MEM_MALLOC.free(ctx);
953 }
954
SdpReceiveDisconnectRequest(uint16_t lcid,uint8_t id,void * context)955 static void SdpReceiveDisconnectRequest(uint16_t lcid, uint8_t id, void *context)
956 {
957 int ret;
958 SdpReceiveDisconnectRequestInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveDisconnectRequestInfo));
959 if (ctx == NULL) {
960 LOG_ERROR("point to NULL");
961 return;
962 }
963 (void)memset_s(ctx, sizeof(SdpReceiveDisconnectRequestInfo), 0x00, sizeof(SdpReceiveDisconnectRequestInfo));
964
965 ctx->lcid = lcid;
966 ctx->id = id;
967 ctx->context = context;
968
969 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveDisconnectRequestTsk, ctx);
970 if (ret != BT_SUCCESS) {
971 MEM_MALLOC.free(ctx);
972 return;
973 }
974 }
975
976 typedef struct {
977 uint16_t lcid;
978 void *context;
979 } SdpReceiveDisconnectResponseInfo;
980 /**
981 * @brief Receive disconnection response from L2CAP as a client.
982 *
983 * @param lcid Local channel identifier.
984 * @param context The context from upper layer.
985 */
SdpReceiveDisconnectResponseTask(uint16_t lcid,void * context)986 static void SdpReceiveDisconnectResponseTask(uint16_t lcid, void *context)
987 {
988 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x start", __FUNCTION__, __LINE__, lcid);
989
990 SdpConnectInfo *connect = NULL;
991
992 if (!SdpGetEnableState()) {
993 return;
994 }
995
996 connect = SdpFindConnectByCid(lcid);
997 if (connect == NULL) {
998 LOG_WARN("[%{public}s][%{public}d] This connection has been disconnected.", __FUNCTION__, __LINE__);
999 return;
1000 }
1001 if (!connect->wait) {
1002 SdpRemoveRequestByAddress(&connect->addr);
1003 }
1004 ListRemoveNode(g_connectList, connect);
1005
1006 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
1007 }
1008
SdpReceiveDisconnectResponseTsk(void * context)1009 static void SdpReceiveDisconnectResponseTsk(void *context)
1010 {
1011 SdpReceiveDisconnectResponseInfo *ctx = context;
1012 SdpReceiveDisconnectResponseTask(ctx->lcid, ctx->context);
1013 MEM_MALLOC.free(ctx);
1014 }
1015
SdpReceiveDisconnectResponse(uint16_t lcid,void * context)1016 static void SdpReceiveDisconnectResponse(uint16_t lcid, void *context)
1017 {
1018 int ret;
1019 SdpReceiveDisconnectResponseInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveDisconnectResponseInfo));
1020 if (ctx == NULL) {
1021 LOG_ERROR("point to NULL");
1022 return;
1023 }
1024 (void)memset_s(ctx, sizeof(SdpReceiveDisconnectResponseInfo), 0x00, sizeof(SdpReceiveDisconnectResponseInfo));
1025
1026 ctx->lcid = lcid;
1027 ctx->context = context;
1028
1029 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveDisconnectResponseTsk, ctx);
1030 if (ret != BT_SUCCESS) {
1031 MEM_MALLOC.free(ctx);
1032 return;
1033 }
1034 }
1035
1036 typedef struct {
1037 uint16_t lcid;
1038 uint8_t reason;
1039 void *context;
1040 } SdpDisconnectAbnormalInfo;
1041 /**
1042 * @brief Receive abnormal disconnection response from L2CAP as a server or a client.
1043 *
1044 * @param lcid Local channel identifier.
1045 * @param reason The reason of abnormal disconnection.
1046 * @param context The context from upper layer.
1047 */
SdpDisconnectAbnormalTask(uint16_t lcid,uint8_t reason,void * context)1048 static void SdpDisconnectAbnormalTask(uint16_t lcid, uint8_t reason, void *context)
1049 {
1050 LOG_DEBUG("[%{public}s][%{public}d] lcid = 0x%04x reason = 0x%02x start", __FUNCTION__, __LINE__, lcid, reason);
1051
1052 SdpConnectInfo *connect = NULL;
1053 SdpClientRequest *request = NULL;
1054
1055 if (!SdpGetEnableState()) {
1056 return;
1057 }
1058
1059 connect = SdpFindConnectByCid(lcid);
1060 if (connect == NULL) {
1061 LOG_WARN("[%{public}s][%{public}d] This connection has been disconnected.", __FUNCTION__, __LINE__);
1062 return;
1063 }
1064 #define HCI_COMMAND_DISALLOWED 0x0c
1065 if (connect->flag) {
1066 if (reason == HCI_COMMAND_DISALLOWED) {
1067 request = SdpFindRequestByAddress(&connect->addr);
1068 if (request == NULL) {
1069 LOG_ERROR("[%{public}s][%{public}d] SdpFindRequestByAddress() return nullptr", __FUNCTION__, __LINE__);
1070 return;
1071 }
1072 if (!request->resentFlag) {
1073 ListRemoveNode(g_connectList, connect);
1074 SdpSendConnectRequest(&request->addr);
1075 request->resentFlag = true;
1076 return;
1077 }
1078 } else if (reason == L2CAP_STATE_COLLISION) {
1079 request = SdpFindRequestByAddress(&connect->addr);
1080 if (request == NULL) {
1081 LOG_ERROR("[%{public}s][%{public}d] SdpFindRequestByAddress() return nullptr", __FUNCTION__, __LINE__);
1082 return;
1083 }
1084 ListRemoveNode(g_connectList, connect);
1085 SdpSendConnectRequest(&request->addr);
1086 return;
1087 }
1088 SdpRemoveAllRequestByAddress(&connect->addr);
1089 }
1090 ListRemoveNode(g_connectList, connect);
1091
1092 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
1093 }
1094
SdpDisconnectAbnormalTsk(void * context)1095 static void SdpDisconnectAbnormalTsk(void *context)
1096 {
1097 SdpDisconnectAbnormalInfo *ctx = context;
1098 SdpDisconnectAbnormalTask(ctx->lcid, ctx->reason, ctx->context);
1099 MEM_MALLOC.free(ctx);
1100 }
SdpDisconnectAbnormal(uint16_t lcid,uint8_t reason,void * context)1101 static void SdpDisconnectAbnormal(uint16_t lcid, uint8_t reason, void *context)
1102 {
1103 int ret;
1104 SdpDisconnectAbnormalInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpDisconnectAbnormalInfo));
1105 if (ctx == NULL) {
1106 LOG_ERROR("point to NULL");
1107 return;
1108 }
1109 (void)memset_s(ctx, sizeof(SdpDisconnectAbnormalInfo), 0x00, sizeof(SdpDisconnectAbnormalInfo));
1110
1111 ctx->lcid = lcid;
1112 ctx->reason = reason;
1113 ctx->context = context;
1114
1115 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpDisconnectAbnormalTsk, ctx);
1116 if (ret != BT_SUCCESS) {
1117 MEM_MALLOC.free(ctx);
1118 return;
1119 }
1120 }
1121
1122 typedef struct {
1123 uint16_t lcid;
1124 Packet *packet;
1125 void *context;
1126 } SdpReceiveDataInfo;
1127 /**
1128 * @brief Receive packet from L2CAP as a server or client.
1129 *
1130 * @param lcid Local channel identifier
1131 * @param packet The packet point for receiving data
1132 * @param context The context from upper layer.
1133 * @return void
1134 */
SdpReceiveDataTask(uint16_t lcid,const Packet * packet,void * context)1135 static void SdpReceiveDataTask(uint16_t lcid, const Packet *packet, void *context)
1136 {
1137 LOG_DEBUG("[%{public}s][%{public}d] start", __FUNCTION__, __LINE__);
1138 SdpConnectInfo *connect = NULL;
1139 SdpClientRequest *request = NULL;
1140 bool flag = false;
1141
1142 if (!SdpGetEnableState()) {
1143 return;
1144 }
1145
1146 connect = SdpFindConnectByCid(lcid);
1147 if (connect == NULL) {
1148 LOG_ERROR("[%{public}s][%{public}d] Recv connect with unknown cid [0x%02x]", __FUNCTION__, __LINE__, lcid);
1149 return;
1150 }
1151 if ((connect->outConnState == SDP_STATE_CONNECTED) && (connect->inConnState == SDP_STATE_CONNECTED)) {
1152 if (connect->flag) {
1153 SdpParseServerResponse(&connect->addr, lcid, packet);
1154 request = SdpFindRemainRequestByAddress(&connect->addr, &flag);
1155 if (request != NULL) {
1156 request->packetState = SDP_PACKET_SEND;
1157 SdpSendRequest(connect->lcid, request->transactionId, 0, NULL, request->packet);
1158 } else if (!flag) {
1159 AlarmSet(connect->timer, SDP_CONNECT_WAIT_TIME, SdpConnectWaitTime, connect);
1160 }
1161 } else {
1162 SdpParseClientRequest(lcid, packet);
1163 }
1164 }
1165 LOG_DEBUG("[%{public}s][%{public}d] end", __FUNCTION__, __LINE__);
1166 }
1167
SdpReceiveDataTsk(void * context)1168 static void SdpReceiveDataTsk(void *context)
1169 {
1170 SdpReceiveDataInfo *ctx = context;
1171 SdpReceiveDataTask(ctx->lcid, ctx->packet, ctx->context);
1172 PacketFree(ctx->packet);
1173 ctx->packet = NULL;
1174 MEM_MALLOC.free(ctx);
1175 }
1176
SdpReceiveData(uint16_t lcid,Packet * packet,void * context)1177 static void SdpReceiveData(uint16_t lcid, Packet *packet, void *context)
1178 {
1179 int ret;
1180 SdpReceiveDataInfo *ctx = MEM_MALLOC.alloc(sizeof(SdpReceiveDataInfo));
1181 if (ctx == NULL) {
1182 LOG_ERROR("point to NULL");
1183 return;
1184 }
1185 (void)memset_s(ctx, sizeof(SdpReceiveDataInfo), 0x00, sizeof(SdpReceiveDataInfo));
1186
1187 ctx->lcid = lcid;
1188 ctx->packet = PacketRefMalloc(packet);
1189 ctx->context = context;
1190
1191 ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_SDP, SdpReceiveDataTsk, ctx);
1192 if (ret != BT_SUCCESS) {
1193 PacketFree(ctx->packet);
1194 ctx->packet = NULL;
1195 MEM_MALLOC.free(ctx);
1196 return;
1197 }
1198 }
1199
SdpSendErrorResponse(uint16_t lcid,uint16_t transactionId,uint16_t errorCode)1200 void SdpSendErrorResponse(uint16_t lcid, uint16_t transactionId, uint16_t errorCode)
1201 {
1202 Packet *packet = NULL;
1203 uint8_t buffer[2] = {0};
1204 uint8_t *header = NULL;
1205 uint16_t offset = 0;
1206
1207 packet = PacketMalloc(SDP_PDU_HEADER_LENGTH, 0, SDP_UINT16_LENGTH);
1208 *(uint16_t *)buffer = H2BE_16(errorCode);
1209 PacketPayloadWrite(packet, buffer, 0, SDP_UINT16_LENGTH);
1210
1211 header = (uint8_t *)BufferPtr(PacketHead(packet));
1212 /// PduID
1213 header[0] = SDP_ERROR_RESPONSE;
1214 offset++;
1215 /// Transaction ID
1216 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1217 offset += SDP_UINT16_LENGTH;
1218 /// ParameterLength
1219 *(uint16_t *)(header + offset) = H2BE_16(SDP_UINT16_LENGTH);
1220
1221 L2CIF_SendData(lcid, packet, NULL);
1222 PacketFree(packet);
1223 packet = NULL;
1224 }
1225
SdpGetCurrentServiceRecordCount(uint16_t mtu,uint16_t maxCount,uint16_t totalServiceRecordCount)1226 static uint16_t SdpGetCurrentServiceRecordCount(uint16_t mtu, uint16_t maxCount, uint16_t totalServiceRecordCount)
1227 {
1228 uint16_t number = (mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1229 if (maxCount > number) {
1230 return number;
1231 }
1232 return maxCount;
1233 }
1234
SdpBuildSearchFragmentResponse(uint16_t transactionId,size_t size,uint16_t totalServiceRecordCount,uint16_t currentServiceRecordCount,Packet * fragmentPacket)1235 static Packet *SdpBuildSearchFragmentResponse(uint16_t transactionId, size_t size, uint16_t totalServiceRecordCount,
1236 uint16_t currentServiceRecordCount, Packet *fragmentPacket)
1237 {
1238 Packet *sendPacket = NULL;
1239 uint8_t *header = NULL;
1240 uint8_t *tail = NULL;
1241 uint16_t length = 0;
1242 uint16_t offset = 0;
1243
1244 /// ContinuationState
1245 if (size == 0) {
1246 sendPacket =
1247 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, SDP_PACKET_TAIL_ONE_BYTE);
1248 tail = BufferPtr(PacketTail(sendPacket));
1249 tail[0] = 0x00;
1250 length = currentServiceRecordCount * SDP_UINT32_LENGTH + SDP_UINT32_LENGTH + SDP_PACKET_TAIL_ONE_BYTE;
1251 } else if (size <= 0xFF) {
1252 sendPacket =
1253 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, SDP_PACKET_TAIL_TWO_BYTE);
1254 tail = BufferPtr(PacketTail(sendPacket));
1255 tail[0] = 0x01;
1256 tail[1] = size & 0xFF;
1257 length = currentServiceRecordCount * SDP_UINT32_LENGTH + SDP_UINT32_LENGTH + SDP_PACKET_TAIL_TWO_BYTE;
1258 } else if (size <= 0xFFFF) {
1259 sendPacket =
1260 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, SDP_PACKET_TAIL_THREE_BYTE);
1261 tail = BufferPtr(PacketTail(sendPacket));
1262 tail[0] = 0x02;
1263 *(uint16_t *)(tail + 1) = H2BE_16(size);
1264 length = currentServiceRecordCount * SDP_UINT32_LENGTH + SDP_UINT32_LENGTH + SDP_PACKET_TAIL_THREE_BYTE;
1265 } else {
1266 LOG_ERROR("[%{public}s][%{public}d] Invalid continuation length [%zu]", __FUNCTION__, __LINE__, size);
1267 return NULL;
1268 }
1269 header = BufferPtr(PacketHead(sendPacket));
1270 /// PduID
1271 header[offset] = SDP_SERVICE_SEARCH_RESPONSE;
1272 offset++;
1273 /// Transaction ID
1274 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1275 offset += SDP_UINT16_LENGTH;
1276 /// ParameterLength
1277 *(uint16_t *)(header + offset) = H2BE_16(length);
1278 offset += SDP_UINT16_LENGTH;
1279 /// TotalServiceRecordCount
1280 *(uint16_t *)(header + offset) = H2BE_16(totalServiceRecordCount);
1281 offset += SDP_UINT16_LENGTH;
1282 /// CurrentServiceRecordCount
1283 *(uint16_t *)(header + offset) = H2BE_16(currentServiceRecordCount);
1284
1285 return sendPacket;
1286 }
1287
SdpSendSearchFragmentResponse(uint16_t lcid,uint16_t transactionId,uint16_t maxCount,const Packet * searchPacket)1288 void SdpSendSearchFragmentResponse(uint16_t lcid, uint16_t transactionId, uint16_t maxCount, const Packet *searchPacket)
1289 {
1290 SdpConnectInfo *connect = NULL;
1291 uint16_t totalServiceRecordCount;
1292 uint16_t currentServiceRecordCount;
1293 Packet *packet = NULL;
1294 Packet *fragmentPacket = NULL;
1295 Packet *sendPacket = NULL;
1296 size_t size;
1297
1298 connect = SdpFindConnectByCid(lcid);
1299 if (connect == NULL) {
1300 return;
1301 }
1302
1303 if (searchPacket == NULL) {
1304 if (connect->packet == NULL) {
1305 return;
1306 }
1307 packet = connect->packet;
1308 totalServiceRecordCount = connect->totalCount;
1309 } else {
1310 packet = PacketRefMalloc(searchPacket);
1311 totalServiceRecordCount = PacketSize(packet) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1312 }
1313 currentServiceRecordCount = SdpGetCurrentServiceRecordCount(connect->mtu, maxCount, totalServiceRecordCount);
1314
1315 fragmentPacket = PacketMalloc(0, 0, 0);
1316 size = PacketFragment(packet, fragmentPacket, currentServiceRecordCount * SDP_SERVICE_RECORD_HANDLE_BYTE);
1317 currentServiceRecordCount = PacketSize(fragmentPacket) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1318
1319 sendPacket = SdpBuildSearchFragmentResponse(
1320 transactionId, size, totalServiceRecordCount, currentServiceRecordCount, fragmentPacket);
1321 if (sendPacket == NULL) {
1322 SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_CONT_STATE);
1323 PacketFree(fragmentPacket);
1324 fragmentPacket = NULL;
1325 return;
1326 }
1327
1328 /// Send data
1329 L2CIF_SendData(lcid, sendPacket, NULL);
1330
1331 if (size != 0) {
1332 connect->packet = packet;
1333 connect->totalCount = totalServiceRecordCount;
1334 } else {
1335 PacketFree(packet);
1336 connect->packet = NULL;
1337 packet = NULL;
1338 }
1339
1340 PacketFree(fragmentPacket);
1341 fragmentPacket = NULL;
1342 PacketFree(sendPacket);
1343 sendPacket = NULL;
1344 }
1345
SdpSendSearchResponse(uint16_t lcid,uint16_t transactionId,uint16_t offset,uint8_t * buffer,uint16_t maxCount)1346 void SdpSendSearchResponse(uint16_t lcid, uint16_t transactionId, uint16_t offset, uint8_t *buffer, uint16_t maxCount)
1347 {
1348 SdpConnectInfo *connect = NULL;
1349 uint16_t totalServiceRecordCount;
1350 uint16_t number;
1351 uint16_t length;
1352 Packet *packet = NULL;
1353 Packet *sendPacket = NULL;
1354 uint8_t *header = NULL;
1355 uint8_t *tail = NULL;
1356 uint16_t pos = 0;
1357
1358 connect = SdpFindConnectByCid(lcid);
1359 if (connect == NULL) {
1360 return;
1361 }
1362
1363 /// ServiceSearchPattern
1364 packet = PacketMalloc(0, 0, offset);
1365 PacketPayloadWrite(packet, buffer, 0, offset);
1366
1367 /// TotalServiceRecordCount
1368 totalServiceRecordCount = offset / SDP_SERVICE_RECORD_HANDLE_BYTE;
1369 if (totalServiceRecordCount > maxCount) {
1370 totalServiceRecordCount = maxCount;
1371 }
1372 number = (connect->mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH - 1) / SDP_SERVICE_RECORD_HANDLE_BYTE;
1373 if (totalServiceRecordCount > number) {
1374 /// Fragment packet
1375 SdpSendSearchFragmentResponse(lcid, transactionId, maxCount, packet);
1376 PacketFree(packet);
1377 packet = NULL;
1378 return;
1379 }
1380
1381 /// Single packet
1382 length = totalServiceRecordCount * SDP_SERVICE_RECORD_HANDLE_BYTE + SDP_UINT32_LENGTH + 1;
1383 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH + SDP_UINT32_LENGTH, 1);
1384 header = BufferPtr(PacketHead(sendPacket));
1385 tail = BufferPtr(PacketTail(sendPacket));
1386 /// PduID
1387 header[pos] = SDP_SERVICE_SEARCH_RESPONSE;
1388 pos++;
1389 /// Transaction ID
1390 *(uint16_t *)(header + pos) = H2BE_16(transactionId);
1391 pos += SDP_UINT16_LENGTH;
1392 /// ParameterLength
1393 *(uint16_t *)(header + pos) = H2BE_16(length);
1394 pos += SDP_UINT16_LENGTH;
1395 /// TotalServiceRecordCount
1396 *(uint16_t *)(header + pos) = H2BE_16(totalServiceRecordCount);
1397 pos += SDP_UINT16_LENGTH;
1398 /// CurrentServiceRecordCount = TotalServiceRecordCount
1399 *(uint16_t *)(header + pos) = H2BE_16(totalServiceRecordCount);
1400 /// ContinuationState
1401 tail[0] = 0;
1402
1403 /// Send packet
1404 L2CIF_SendData(lcid, sendPacket, NULL);
1405
1406 PacketFree(packet);
1407 packet = NULL;
1408 PacketFree(sendPacket);
1409 sendPacket = NULL;
1410 }
1411
SdpBuildAttributeFragmentResponse(SdpPduId pduId,uint16_t transactionId,size_t size,Packet * fragmentPacket)1412 static Packet *SdpBuildAttributeFragmentResponse(
1413 SdpPduId pduId, uint16_t transactionId, size_t size, Packet *fragmentPacket)
1414 {
1415 Packet *sendPacket = NULL;
1416 uint16_t length = 0;
1417 uint16_t offset = 0;
1418 uint8_t *header = NULL;
1419 uint8_t *tail = NULL;
1420
1421 /// AttributeByteCount
1422 uint16_t attributeByteCount = (uint16_t)PacketSize(fragmentPacket);
1423
1424 /// ContinuationState
1425 if (size == 0) {
1426 sendPacket =
1427 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_ONE_BYTE);
1428 tail = BufferPtr(PacketTail(sendPacket));
1429 tail[0] = 0x00;
1430 length = attributeByteCount + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_ONE_BYTE;
1431 } else if (size <= 0xFF) {
1432 sendPacket =
1433 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_TWO_BYTE);
1434 tail = BufferPtr(PacketTail(sendPacket));
1435 tail[0] = 0x01;
1436 tail[1] = size & 0xFF;
1437 length = attributeByteCount + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_TWO_BYTE;
1438 } else if (size <= 0xFFFF) {
1439 sendPacket =
1440 PacketInheritMalloc(fragmentPacket, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_THREE_BYTE);
1441 tail = BufferPtr(PacketTail(sendPacket));
1442 tail[0] = 0x02;
1443 *(uint16_t *)(tail + 1) = H2BE_16((uint16_t)size);
1444 length = attributeByteCount + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_THREE_BYTE;
1445 } else {
1446 LOG_ERROR("[%{public}s][%{public}d] Invalid continuation length [%zu]", __FUNCTION__, __LINE__, size);
1447 return NULL;
1448 }
1449
1450 header = BufferPtr(PacketHead(sendPacket));
1451 /// PduID
1452 header[offset] = pduId;
1453 offset++;
1454 /// Transaction ID
1455 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1456 offset += SDP_UINT16_LENGTH;
1457 /// ParameterLength
1458 *(uint16_t *)(header + offset) = H2BE_16(length);
1459 offset += SDP_UINT16_LENGTH;
1460 /// AttributeListByteCount
1461 *(uint16_t *)(header + offset) = H2BE_16(attributeByteCount);
1462
1463 return sendPacket;
1464 }
1465
SdpSendAttributeFragmentResponse(uint16_t lcid,SdpPduId pduId,uint16_t transactionId,uint16_t maxCount,const Packet * attributePacket)1466 void SdpSendAttributeFragmentResponse(
1467 uint16_t lcid, SdpPduId pduId, uint16_t transactionId, uint16_t maxCount, const Packet *attributePacket)
1468 {
1469 SdpConnectInfo *connect = NULL;
1470 Packet *packet = NULL;
1471 Packet *fragmentPacket = NULL;
1472 Packet *sendPacket = NULL;
1473 size_t size;
1474
1475 connect = SdpFindConnectByCid(lcid);
1476 if (connect == NULL) {
1477 return;
1478 }
1479
1480 if (attributePacket == NULL) {
1481 if (connect->packet == NULL) {
1482 return;
1483 }
1484 packet = connect->packet;
1485 } else {
1486 packet = PacketRefMalloc(attributePacket);
1487 }
1488
1489 fragmentPacket = PacketMalloc(0, 0, 0);
1490 size = PacketFragment(packet, fragmentPacket, maxCount);
1491
1492 sendPacket = SdpBuildAttributeFragmentResponse(pduId, transactionId, size, fragmentPacket);
1493 if (sendPacket == NULL) {
1494 SdpSendErrorResponse(lcid, transactionId, SDP_INVALID_CONT_STATE);
1495 return;
1496 }
1497
1498 /// Send data
1499 L2CIF_SendData(lcid, sendPacket, NULL);
1500
1501 if (size != 0) {
1502 connect = SdpFindConnectByCid(lcid);
1503 if (connect == NULL) {
1504 LOG_ERROR("point to NULL");
1505 return;
1506 }
1507 /// store remain packet
1508 connect->packet = packet;
1509 } else {
1510 PacketFree(packet);
1511 packet = NULL;
1512 connect->packet = NULL;
1513 }
1514
1515 PacketFree(fragmentPacket);
1516 fragmentPacket = NULL;
1517 PacketFree(sendPacket);
1518 sendPacket = NULL;
1519 }
1520
SdpSendAttributeResponse(uint16_t lcid,uint16_t transactionId,SdpPduId pduId,uint16_t maxCount,const Packet * packet)1521 void SdpSendAttributeResponse(
1522 uint16_t lcid, uint16_t transactionId, SdpPduId pduId, uint16_t maxCount, const Packet *packet)
1523 {
1524 SdpConnectInfo *connect = NULL;
1525 Packet *sendPacket = NULL;
1526 uint16_t length;
1527 uint8_t *header = NULL;
1528 uint8_t *tail = NULL;
1529
1530 connect = SdpFindConnectByCid(lcid);
1531 if (connect == NULL) {
1532 LOG_ERROR("[%{public}s][%{public}d] There is no connect with cid [%hu]", __FUNCTION__, __LINE__, lcid);
1533 return;
1534 }
1535
1536 if (maxCount > (connect->mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH)) {
1537 maxCount = connect->mtu - SDP_PACKET_HEADER_AND_TAIL_LENGTH;
1538 }
1539
1540 length = PacketSize(packet);
1541 if (length > maxCount) {
1542 /// Fragment packet
1543 SdpSendAttributeFragmentResponse(lcid, pduId, transactionId, maxCount, packet);
1544 return;
1545 } else {
1546 /// Single packet
1547 uint16_t offset = 0;
1548 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH + SDP_UINT16_LENGTH, SDP_PACKET_TAIL_ONE_BYTE);
1549 header = BufferPtr(PacketHead(sendPacket));
1550 tail = BufferPtr(PacketTail(sendPacket));
1551 /// PduID
1552 header[offset] = pduId;
1553 offset++;
1554 /// Transaction ID
1555 *(uint16_t *)(header + offset) = H2BE_16(transactionId);
1556 offset += SDP_UINT16_LENGTH;
1557 /// ParameterLength
1558 *(uint16_t *)(header + offset) = H2BE_16(length + SDP_UINT16_LENGTH + SDP_PACKET_TAIL_ONE_BYTE);
1559 offset += SDP_UINT16_LENGTH;
1560 /// AttributeListByteCount
1561 *(uint16_t *)(header + offset) = H2BE_16(length);
1562 /// ContinuationState
1563 tail[0] = 0;
1564
1565 /// Send packet
1566 L2CIF_SendData(lcid, sendPacket, NULL);
1567 PacketFree(sendPacket);
1568 sendPacket = NULL;
1569 }
1570 }
1571
SdpSendRequest(uint16_t lcid,uint16_t transactionId,uint8_t continuationStateLen,const uint8_t * continuationState,Packet * packet)1572 void SdpSendRequest(uint16_t lcid, uint16_t transactionId, uint8_t continuationStateLen,
1573 const uint8_t *continuationState, Packet *packet)
1574 {
1575 SdpClientRequest *request = NULL;
1576 Packet *sendPacket = NULL;
1577 uint8_t *header = NULL;
1578 uint8_t *tail = NULL;
1579
1580 uint16_t length = PacketPayloadSize(packet);
1581 /// ContinuationState
1582 if (continuationStateLen == 0) {
1583 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH, 1);
1584 tail = BufferPtr(PacketTail(sendPacket));
1585 tail[0] = 0x00;
1586 length += 1;
1587 } else {
1588 sendPacket = PacketInheritMalloc(packet, SDP_PDU_HEADER_LENGTH, continuationStateLen + 1);
1589 tail = BufferPtr(PacketTail(sendPacket));
1590 tail[0] = 0x01;
1591 (void)memcpy_s(tail, continuationStateLen + 1, continuationState, continuationStateLen + 1);
1592 length = length + continuationStateLen + 1;
1593 }
1594
1595 header = (uint8_t *)BufferPtr(PacketHead(sendPacket));
1596 /// PduID
1597 request = SdpFindRequestByTransactionId(transactionId);
1598 if (request == NULL) {
1599 return;
1600 }
1601 header[0] = request->pduId;
1602 /// Transaction ID
1603 *(uint16_t *)(header + 1) = H2BE_16(transactionId);
1604 /// ParameterLength
1605 *(uint16_t *)(header + SDP_UINT16_LENGTH + 1) = H2BE_16(length);
1606
1607 /// Send packet
1608 L2CIF_SendData(lcid, sendPacket, NULL);
1609
1610 PacketFree(sendPacket);
1611 sendPacket = NULL;
1612 }
1613
SdpClientConnect(SdpClientRequest * request)1614 int SdpClientConnect(SdpClientRequest *request)
1615 {
1616 SdpConnectInfo *connect = NULL;
1617
1618 if (g_connectList == NULL) {
1619 return BT_OPERATION_FAILED;
1620 }
1621 connect = SdpFindConnectByAddress(&request->addr);
1622 if (connect == NULL) {
1623 /// Create new channel
1624 SdpAddRequest(request);
1625 SdpSendConnectRequest(&request->addr);
1626 } else {
1627 /// Use existed channel
1628 if ((connect->inConnState == SDP_STATE_CONNECTED) && (connect->outConnState == SDP_STATE_CONNECTED)) {
1629 /// Channel idle and send packet
1630 if (connect->timer != NULL) {
1631 AlarmCancel(connect->timer);
1632 }
1633 request->packetState = SDP_PACKET_SEND;
1634 SdpAddRequest(request);
1635 SdpSendRequest(connect->lcid, request->transactionId, 0, NULL, request->packet);
1636 } else if ((connect->inConnState == SDP_STATE_DISCONNECT) && (connect->outConnState == SDP_STATE_DISCONNECT)) {
1637 /// Create new channel
1638 SdpAddRequest(request);
1639 SdpSendConnectRequest(&request->addr);
1640 } else {
1641 SdpAddRequest(request);
1642 }
1643 }
1644
1645 return BT_SUCCESS;
1646 }
1647