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