• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "sdp_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