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 "rfcomm_defs.h"
17 
18 #include "platform/include/module.h"
19 
20 #define WAIT_TIME (-1)
21 
RfcommInitializeTsk(void * context)22 static void RfcommInitializeTsk(void *context)
23 {
24     LOG_INFO("%{public}s", __func__);
25 
26     Event *ctx = context;
27 
28     if (ctx == NULL) {
29         LOG_ERROR("%{public}s context is NULL.", __func__);
30         return;
31     }
32 
33     RfcommInitialize();
34 
35     EventSet(ctx);
36 }
37 
38 /**
39  * @brief This function is used to initialize rfcomm resources and
40  *        register the callback function to L2CAP.
41  *
42  * @since 6
43  */
RFCOMM_Startup()44 static void RFCOMM_Startup()
45 {
46     LOG_INFO("%{public}s", __func__);
47 
48     Event *ctx = EventCreate(true);
49 
50     int ret = BTM_CreateProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, BTM_PROCESSING_QUEUE_SIZE_DEFAULT);
51     if (ret != BT_SUCCESS) {
52         EventDelete(ctx);
53         return;
54     }
55 
56     ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommInitializeTsk, ctx);
57     if (ret != BT_SUCCESS) {
58         EventDelete(ctx);
59         return;
60     }
61 
62     EventWait(ctx, WAIT_TIME);
63     EventDelete(ctx);
64 }
65 
RfcommFinalizeTsk(void * context)66 static void RfcommFinalizeTsk(void *context)
67 {
68     LOG_INFO("%{public}s", __func__);
69 
70     Event *ctx = context;
71 
72     if (ctx == NULL) {
73         LOG_ERROR("%{public}s context is NULL.", __func__);
74         return;
75     }
76 
77     RfcommFinalize();
78 
79     BTM_DeleteProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM);
80 
81     EventSet(ctx);
82 }
83 
84 /**
85  * @brief This function is used to release rfcomm internal resources and
86  *        deregister the callback function to L2CAP.
87  *
88  * @since 6
89  */
RFCOMM_Shutdown()90 static void RFCOMM_Shutdown()
91 {
92     LOG_INFO("%{public}s", __func__);
93 
94     Event *ctx = EventCreate(true);
95 
96     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommFinalizeTsk, ctx);
97     if (ret != BT_SUCCESS) {
98         EventDelete(ctx);
99         return;
100     }
101 
102     EventWait(ctx, WAIT_TIME);
103     EventDelete(ctx);
104 }
105 
106 typedef struct {
107     uint8_t scn;
108     Event *event;
109 } RfcommAssignScnInfo;
110 
RfcommAssignServerNumTsk(void * context)111 static void RfcommAssignServerNumTsk(void *context)
112 {
113     LOG_INFO("%{public}s", __func__);
114 
115     RfcommAssignScnInfo *ctx = context;
116 
117     if (ctx == NULL) {
118         LOG_ERROR("%{public}s context is NULL.", __func__);
119         return;
120     }
121 
122     ctx->scn = RfcommAssignServerNum();
123 
124     if (ctx->event != NULL) {
125         EventSet(ctx->event);
126     }
127 }
128 
129 /**
130  * @brief The function is used to assign server numbers to individual servers.
131  *        Server number is used to register with the RFCOMM service interface, range is 1~30.
132  *        When the return value is 0, it means that there is no available server number.
133  *        This Server number shall be registered in the Service Discovery Database;
134  *        RFCOMM_SPEC_V12 #5.4
135  *
136  * @return Server number.0(unavailable number),1~30(available number)
137  * @since 6
138  */
RFCOMM_AssignServerNum()139 uint8_t RFCOMM_AssignServerNum()
140 {
141     LOG_INFO("%{public}s", __func__);
142 
143     uint8_t scn = 0;
144     RfcommAssignScnInfo *ctx = malloc(sizeof(RfcommAssignScnInfo));
145     if (ctx == NULL) {
146         return scn;
147     }
148 
149     (void)memset_s(ctx, sizeof(RfcommAssignScnInfo), 0x00, sizeof(RfcommAssignScnInfo));
150     ctx->event = EventCreate(true);
151 
152     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommAssignServerNumTsk, ctx);
153     if (ret != BT_SUCCESS) {
154         EventDelete(ctx->event);
155         free(ctx);
156         return scn;
157     }
158 
159     EventWait(ctx->event, WAIT_TIME);
160     EventDelete(ctx->event);
161     scn = ctx->scn;
162 
163     free(ctx);
164     return scn;
165 }
166 
167 typedef struct {
168     uint8_t scn;
169 } RfcommFreeScnInfo;
170 
RfcommFreeServerNumTsk(void * context)171 static void RfcommFreeServerNumTsk(void *context)
172 {
173     LOG_INFO("%{public}s", __func__);
174 
175     RfcommFreeScnInfo *ctx = context;
176 
177     if (ctx == NULL) {
178         LOG_ERROR("%{public}s context is NULL.", __func__);
179         return;
180     }
181 
182     RfcommFreeServerNum(ctx->scn);
183 
184     free(ctx);
185 }
186 
187 /**
188  * @brief After close the server, free the server number.
189  *
190  * @param scn Server number.
191  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
192  * @since 6
193  */
RFCOMM_FreeServerNum(uint8_t scn)194 int RFCOMM_FreeServerNum(uint8_t scn)
195 {
196     LOG_INFO("%{public}s scn:%hhu", __func__, scn);
197 
198     RfcommFreeScnInfo *ctx = malloc(sizeof(RfcommFreeScnInfo));
199     if (ctx == NULL) {
200         return BT_NO_MEMORY;
201     }
202 
203     ctx->scn = scn;
204 
205     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommFreeServerNumTsk, ctx);
206     if (ret != BT_SUCCESS) {
207         free(ctx);
208     }
209 
210     return ret;
211 }
212 
213 typedef struct {
214     RfcommConnectReqInfo reqInfo;
215     uint16_t handle;
216     Event *event;
217     int result;
218 } RfcommConnectDlcInfo;
219 
RfcommConnectChannelTsk(void * context)220 static void RfcommConnectChannelTsk(void *context)
221 {
222     LOG_INFO("%{public}s", __func__);
223 
224     uint16_t handle = 0;
225     RfcommConnectDlcInfo *ctx = context;
226 
227     if (ctx == NULL) {
228         LOG_ERROR("%{public}s context is NULL.", __func__);
229         return;
230     }
231 
232     int ret = RfcommConnectChannel(&ctx->reqInfo, &handle);
233     ctx->handle = handle;
234     ctx->result = ret;
235 
236     if (ctx->event != NULL) {
237         EventSet(ctx->event);
238     }
239 }
240 
241 /**
242  * @brief The function is used by the client to establish a connection of the channel
243  *
244  * @param reqInfo   Connection request information.
245  * @param handle    The handle of the channel created by rfcomm.
246  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
247  * @since 6
248  */
RFCOMM_ConnectChannel(const RfcommConnectReqInfo * reqInfo,uint16_t * handle)249 int RFCOMM_ConnectChannel(const RfcommConnectReqInfo *reqInfo, uint16_t *handle)
250 {
251     LOG_INFO("%{public}s", __func__);
252 
253     RfcommConnectDlcInfo *ctx = malloc(sizeof(RfcommConnectDlcInfo));
254     if (ctx == NULL) {
255         return BT_NO_MEMORY;
256     }
257 
258     (void)memset_s(ctx, sizeof(RfcommConnectDlcInfo), 0x00, sizeof(RfcommConnectDlcInfo));
259     (void)memcpy_s(&ctx->reqInfo, sizeof(RfcommConnectReqInfo), reqInfo, sizeof(RfcommConnectReqInfo));
260     ctx->event = EventCreate(true);
261 
262     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommConnectChannelTsk, ctx);
263     if (ret != BT_SUCCESS) {
264         EventDelete(ctx->event);
265         free(ctx);
266         return ret;
267     }
268 
269     EventWait(ctx->event, WAIT_TIME);
270     EventDelete(ctx->event);
271     *handle = ctx->handle;
272     ret = ctx->result;
273 
274     free(ctx);
275     return ret;
276 }
277 
278 typedef struct {
279     uint8_t scn;
280     uint16_t mtu;
281     uint32_t eventMask;
282     RFCOMM_EventCallback callback;
283     void *context;
284     Event *event;
285     int retValue;
286 } RfcommRegistServerInfo;
287 
RfcommRegisterServerTsk(void * context)288 static void RfcommRegisterServerTsk(void *context)
289 {
290     LOG_INFO("%{public}s", __func__);
291 
292     RfcommRegistServerInfo *ctx = context;
293 
294     if (ctx == NULL) {
295         LOG_ERROR("%{public}s context is NULL.", __func__);
296         return;
297     }
298 
299     int ret = RfcommRegisterServer(ctx->scn, ctx->mtu, ctx->eventMask, ctx->callback, ctx->context);
300     ctx->retValue = ret;
301 
302     if (ctx->event != NULL) {
303         EventSet(ctx->event);
304     }
305 }
306 
307 /**
308  * @brief The function is used for the server to register with RFCOMM and
309  *        wait for the client to connect.
310  *
311  * @param scn       The server's number.
312  * @param mtu       The maximum size of data received at a time.
313  * @param eventMask The collection of events followed by upper layers.
314  * @param callback  The callback function used by rfcomm to notify uppers of data or events.
315  * @param context   The content passed in from the upper layer.
316  *                  It will be brought back to the upper layer when callback is called.
317  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
318  * @since 6
319  */
RFCOMM_RegisterServer(uint8_t scn,uint16_t mtu,uint32_t eventMask,RFCOMM_EventCallback callback,void * context)320 int RFCOMM_RegisterServer(uint8_t scn, uint16_t mtu, uint32_t eventMask,
321                           RFCOMM_EventCallback callback, void *context)
322 {
323     LOG_INFO("%{public}s", __func__);
324 
325     RfcommRegistServerInfo *ctx = malloc(sizeof(RfcommRegistServerInfo));
326     if (ctx == NULL) {
327         return BT_NO_MEMORY;
328     }
329 
330     (void)memset_s(ctx, sizeof(RfcommRegistServerInfo), 0x00, sizeof(RfcommRegistServerInfo));
331     ctx->scn = scn;
332     ctx->mtu = mtu;
333     ctx->eventMask = eventMask;
334     ctx->callback = callback;
335     ctx->context = context;
336     ctx->event = EventCreate(true);
337 
338     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommRegisterServerTsk, ctx);
339     if (ret != BT_SUCCESS) {
340         EventDelete(ctx->event);
341         free(ctx);
342         return ret;
343     }
344 
345     EventWait(ctx->event, WAIT_TIME);
346     EventDelete(ctx->event);
347     ret = ctx->retValue;
348 
349     free(ctx);
350     return ret;
351 }
352 
353 typedef struct {
354     uint16_t handle;
355 } RfcommAcceptConnectionInfo;
356 
RfcommAcceptConnectionTsk(void * context)357 static void RfcommAcceptConnectionTsk(void *context)
358 {
359     LOG_INFO("%{public}s", __func__);
360 
361     RfcommAcceptConnectionInfo *ctx = context;
362 
363     if (ctx == NULL) {
364         LOG_ERROR("%{public}s context is NULL.", __func__);
365         return;
366     }
367 
368     RfcommAcceptConnection(ctx->handle);
369 
370     free(ctx);
371 }
372 
373 /**
374  * @brief The function is used to tell RFCOMM to accept the connection request when the server
375  *        receives the connection notification(eventId is RFCOMM_EVENT_CONNECT_INCOMING).
376  *        After receiving the response from the upper layer, RFCOMM notifies the client
377  *        of the peer device to accept the connection request.
378  *
379  * @param handle The channel(DLC)'s handle number
380  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
381  * @since 6
382  */
RFCOMM_AcceptConnection(uint16_t handle)383 int RFCOMM_AcceptConnection(uint16_t handle)
384 {
385     LOG_INFO("%{public}s handle:%hu", __func__, handle);
386 
387     RfcommAcceptConnectionInfo *ctx = malloc(sizeof(RfcommAcceptConnectionInfo));
388     if (ctx == NULL) {
389         return BT_NO_MEMORY;
390     }
391 
392     ctx->handle = handle;
393 
394     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommAcceptConnectionTsk, ctx);
395     if (ret != BT_SUCCESS) {
396         free(ctx);
397     }
398 
399     return ret;
400 }
401 
402 typedef struct {
403     uint16_t handle;
404 } RfcommRejectConnectionInfo;
405 
RfcommRejectConnectionTsk(void * context)406 static void RfcommRejectConnectionTsk(void *context)
407 {
408     LOG_INFO("%{public}s", __func__);
409 
410     RfcommRejectConnectionInfo *ctx = context;
411 
412     if (ctx == NULL) {
413         LOG_ERROR("%{public}s context is NULL.", __func__);
414         return;
415     }
416 
417     RfcommRejectConnection(ctx->handle);
418 
419     free(ctx);
420 }
421 
422 /**
423  * @brief This function is used to tell RFCOMM to reject the connection request when the server
424  *        receives the connection notification(eventId is RFCOMM_EVENT_CONNECT_INCOMING).
425  *        After receiving the response from the upper layer, RFCOMM notifies the client
426  *        of the peer device to reject the connection request.
427  *
428  * @param handle The channel(DLC)'s handle number
429  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
430  * @since 6
431  */
RFCOMM_RejectConnection(uint16_t handle)432 int RFCOMM_RejectConnection(uint16_t handle)
433 {
434     LOG_INFO("%{public}s handle:%hu", __func__, handle);
435 
436     RfcommRejectConnectionInfo *ctx = malloc(sizeof(RfcommRejectConnectionInfo));
437     if (ctx == NULL) {
438         return BT_NO_MEMORY;
439     }
440 
441     ctx->handle = handle;
442 
443     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommRejectConnectionTsk, ctx);
444     if (ret != BT_SUCCESS) {
445         free(ctx);
446     }
447 
448     return ret;
449 }
450 
451 typedef struct {
452     uint16_t handle;
453 } RfcommDisconnectChannelInfo;
454 
RfcommDisconnectChannelTsk(void * context)455 static void RfcommDisconnectChannelTsk(void *context)
456 {
457     LOG_INFO("%{public}s", __func__);
458 
459     RfcommRejectConnectionInfo *ctx = context;
460 
461     if (ctx == NULL) {
462         LOG_ERROR("%{public}s context is NULL.", __func__);
463         return;
464     }
465 
466     RfcommDisconnectChannel(ctx->handle);
467 
468     free(ctx);
469 }
470 
471 /**
472  * @brief The function is used to disconnect the specified channel.
473  *        RFCOMM_SPEC_V12 #5.2
474  *
475  * @param handle The channel(DLC)'s handle number
476  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
477  * @since 6
478  */
RFCOMM_DisconnectChannel(uint16_t handle)479 int RFCOMM_DisconnectChannel(uint16_t handle)
480 {
481     LOG_INFO("%{public}s handle:%hu", __func__, handle);
482 
483     RfcommDisconnectChannelInfo *ctx = malloc(sizeof(RfcommDisconnectChannelInfo));
484     if (ctx == NULL) {
485         return BT_NO_MEMORY;
486     }
487 
488     ctx->handle = handle;
489 
490     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommDisconnectChannelTsk, ctx);
491     if (ret != BT_SUCCESS) {
492         free(ctx);
493     }
494 
495     return ret;
496 }
497 
498 typedef struct {
499     uint8_t scn;
500     bool isRemoveCallback;
501     Event *event;
502 } RfcommDeregisterServerInfo;
503 
RfcommDeregisterServerTsk(void * context)504 static void RfcommDeregisterServerTsk(void *context)
505 {
506     LOG_INFO("%{public}s", __func__);
507 
508     RfcommDeregisterServerInfo *ctx = context;
509 
510     if (ctx == NULL) {
511         LOG_ERROR("%{public}s context is NULL.", __func__);
512         return;
513     }
514 
515     RfcommDeregisterServer(ctx->scn, ctx->isRemoveCallback);
516 
517     if (ctx->event != NULL) {
518         EventSet(ctx->event);
519     }
520 }
521 
522 /**
523  * @brief When the server is shut down, call this function to
524  *        release the resources about the server held in RFCOMM.
525  *
526  * @param scn The server's number
527  * @param isRemoveCallback true:remove callback,RFCOMM will not notify event to upper layer.otherwise:false.
528  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
529  * @since 6
530  */
RFCOMM_DeregisterServer(uint8_t scn,bool isRemoveCallback)531 int RFCOMM_DeregisterServer(uint8_t scn, bool isRemoveCallback)
532 {
533     LOG_INFO("%{public}s scn:%hhu, isRemoveCallback:%{public}d.", __func__, scn, isRemoveCallback);
534 
535     RfcommDeregisterServerInfo *ctx = malloc(sizeof(RfcommDeregisterServerInfo));
536     if (ctx == NULL) {
537         return BT_NO_MEMORY;
538     }
539 
540     (void)memset_s(ctx, sizeof(RfcommDeregisterServerInfo), 0x00, sizeof(RfcommDeregisterServerInfo));
541     ctx->scn = scn;
542     ctx->isRemoveCallback = isRemoveCallback;
543     ctx->event = EventCreate(true);
544 
545     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommDeregisterServerTsk, ctx);
546     if (ret != BT_SUCCESS) {
547         EventDelete(ctx->event);
548         free(ctx);
549         return ret;
550     }
551 
552     EventWait(ctx->event, WAIT_TIME);
553     EventDelete(ctx->event);
554 
555     free(ctx);
556     return ret;
557 }
558 
559 typedef struct {
560     uint16_t handle;
561     RfcommRemotePortConfig config;
562 } RfcommSetRpnInfo;
563 
RfcommSetPortConfigTsk(void * context)564 static void RfcommSetPortConfigTsk(void *context)
565 {
566     LOG_INFO("%{public}s", __func__);
567 
568     RfcommSetRpnInfo *ctx = context;
569 
570     if (ctx == NULL) {
571         LOG_ERROR("%{public}s context is NULL.", __func__);
572         return;
573     }
574 
575     RfcommSetPortConfig(ctx->handle, &ctx->config);
576 
577     free(ctx);
578 }
579 
580 /**
581  * @brief The function is used for set the remote port communication settings.
582  *        The command may be used before a new DLC is opened and shall be used
583  *        whenever the port settings change.
584  *        RFCOMM_SPEC_V12 #5.5.1
585  *
586  * @param handle The channel(DLC)'s handle number
587  * @param config Remote port negotiation parameters
588  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
589  * @since 6
590  */
RFCOMM_SetPortConfig(uint16_t handle,const RfcommRemotePortConfig * config)591 int RFCOMM_SetPortConfig(uint16_t handle, const RfcommRemotePortConfig *config)
592 {
593     LOG_INFO("%{public}s handle:%hu", __func__, handle);
594 
595     RfcommSetRpnInfo *ctx = malloc(sizeof(RfcommSetRpnInfo));
596     if (ctx == NULL) {
597         return BT_NO_MEMORY;
598     }
599 
600     (void)memset_s(ctx, sizeof(RfcommSetRpnInfo), 0x00, sizeof(RfcommSetRpnInfo));
601     ctx->handle = handle;
602     (void)memcpy_s(&ctx->config, sizeof(RfcommRemotePortConfig), config, sizeof(RfcommRemotePortConfig));
603 
604     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommSetPortConfigTsk, ctx);
605     if (ret != BT_SUCCESS) {
606         free(ctx);
607     }
608 
609     return ret;
610 }
611 
612 typedef struct {
613     uint16_t handle;
614 } RfcommReqPortConfigInfo;
615 
RfcommReqPortConfigTsk(void * context)616 static void RfcommReqPortConfigTsk(void *context)
617 {
618     LOG_INFO("%{public}s", __func__);
619 
620     RfcommReqPortConfigInfo *ctx = context;
621 
622     if (ctx == NULL) {
623         LOG_ERROR("%{public}s context is NULL.", __func__);
624         return;
625     }
626 
627     RfcommReqPortConfig(ctx->handle);
628 
629     free(ctx);
630 }
631 
632 /**
633  * @brief The function is used to obtain the remote port negotiation information
634  *        of the peer device.
635  *
636  * @param handle The channel(DLC)'s handle number
637  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
638  * @since 6
639  */
RFCOMM_ReqPortConfig(uint16_t handle)640 int RFCOMM_ReqPortConfig(uint16_t handle)
641 {
642     LOG_INFO("%{public}s handle:%hu", __func__, handle);
643 
644     RfcommReqPortConfigInfo *ctx = malloc(sizeof(RfcommReqPortConfigInfo));
645     if (ctx == NULL) {
646         return BT_NO_MEMORY;
647     }
648 
649     ctx->handle = handle;
650 
651     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommReqPortConfigTsk, ctx);
652     if (ret != BT_SUCCESS) {
653         free(ctx);
654     }
655 
656     return ret;
657 }
658 
659 typedef struct {
660     uint16_t handle;
661     RfcommRemoteLineStatus lineStatus;
662 } RfcommSendRlsInfo;
663 
RfcommSendRemoteLineStatusTsk(void * context)664 static void RfcommSendRemoteLineStatusTsk(void *context)
665 {
666     LOG_INFO("%{public}s", __func__);
667 
668     RfcommSendRlsInfo *ctx = context;
669 
670     if (ctx == NULL) {
671         LOG_ERROR("%{public}s context is NULL.", __func__);
672         return;
673     }
674 
675     RfcommSendRemoteLineStatus(ctx->handle, &ctx->lineStatus);
676 
677     free(ctx);
678 }
679 
680 /**
681  * @brief The function is used for indication of remote port line status.
682  *        RFCOMM_SPEC_V12 #5.5.2
683  *
684  * @param handle     The channel(DLC)'s handle number
685  * @param lineStatus Remote line status
686  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
687  * @since 6
688  */
RFCOMM_SendRemoteLineStatus(uint16_t handle,const RfcommRemoteLineStatus * lineStatus)689 int RFCOMM_SendRemoteLineStatus(uint16_t handle, const RfcommRemoteLineStatus *lineStatus)
690 {
691     LOG_INFO("%{public}s handle:%hu", __func__, handle);
692 
693     RfcommSendRlsInfo *ctx = malloc(sizeof(RfcommSendRlsInfo));
694     if (ctx == NULL) {
695         return BT_NO_MEMORY;
696     }
697 
698     (void)memset_s(ctx, sizeof(RfcommSendRlsInfo), 0x00, sizeof(RfcommSendRlsInfo));
699     ctx->handle = handle;
700     (void)memcpy_s(&ctx->lineStatus, sizeof(RfcommRemoteLineStatus), lineStatus, sizeof(RfcommRemoteLineStatus));
701 
702     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommSendRemoteLineStatusTsk, ctx);
703     if (ret != BT_SUCCESS) {
704         free(ctx);
705     }
706 
707     return ret;
708 }
709 
710 typedef struct {
711     uint16_t handle;
712     RfcommModemStatus modemStatus;
713 } RfcommSetMscInfo;
714 
RfcommSetModemStatusTsk(void * context)715 static void RfcommSetModemStatusTsk(void *context)
716 {
717     LOG_INFO("%{public}s", __func__);
718 
719     RfcommSetMscInfo *ctx = context;
720 
721     if (ctx == NULL) {
722         LOG_ERROR("%{public}s context is NULL.", __func__);
723         return;
724     }
725 
726     RfcommSetModemStatus(ctx->handle, &ctx->modemStatus);
727 
728     free(ctx);
729 }
730 
731 /**
732  * @brief The function is used to convey the RS-232 control signals and the break signal.
733  *        RFCOMM_SPEC_V12 #2.2
734  *
735  * @param handle      The channel(DLC)'s handle number
736  * @param modemStatus Control signals and the break signal
737  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
738  * @since 6
739  */
RFCOMM_SetModemStatus(uint16_t handle,const RfcommModemStatus * modemStatus)740 int RFCOMM_SetModemStatus(uint16_t handle, const RfcommModemStatus *modemStatus)
741 {
742     LOG_INFO("%{public}s handle:%hu", __func__, handle);
743 
744     RfcommSetMscInfo *ctx = malloc(sizeof(RfcommSetMscInfo));
745     if (ctx == NULL) {
746         return BT_NO_MEMORY;
747     }
748 
749     (void)memset_s(ctx, sizeof(RfcommSetMscInfo), 0x00, sizeof(RfcommSetMscInfo));
750     ctx->handle = handle;
751     (void)memcpy_s(&ctx->modemStatus, sizeof(RfcommModemStatus), modemStatus, sizeof(RfcommModemStatus));
752 
753     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommSetModemStatusTsk, ctx);
754     if (ret != BT_SUCCESS) {
755         free(ctx);
756     }
757 
758     return ret;
759 }
760 
761 typedef struct {
762     uint16_t handle;
763     RfcommPortState state;
764     Event *event;
765     int result;
766 } RfcommGetPortStInfo;
767 
RfcommGetPortStateTsk(void * context)768 static void RfcommGetPortStateTsk(void *context)
769 {
770     LOG_INFO("%{public}s", __func__);
771 
772     RfcommGetPortStInfo *ctx = context;
773 
774     if (ctx == NULL) {
775         LOG_ERROR("%{public}s context is NULL.", __func__);
776         return;
777     }
778 
779     int ret = RfcommGetPortState(ctx->handle, &ctx->state);
780     ctx->result = ret;
781 
782     if (ctx->event != NULL) {
783         EventSet(ctx->event);
784     }
785 }
786 
787 /**
788  * @brief This function is used to obtain port related information.
789  *        Currently, the amount of data sent and received by the port can be obtained.
790  *
791  * @param handle The channel(DLC)'s handle number
792  * @param state  The port's information
793  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
794  * @since 6
795  */
RFCOMM_GetPortState(uint16_t handle,RfcommPortState * state)796 int RFCOMM_GetPortState(uint16_t handle, RfcommPortState *state)
797 {
798     LOG_INFO("%{public}s handle:%hu", __func__, handle);
799 
800     RfcommGetPortStInfo *ctx = malloc(sizeof(RfcommGetPortStInfo));
801     if (ctx == NULL) {
802         return BT_NO_MEMORY;
803     }
804 
805     (void)memset_s(ctx, sizeof(RfcommGetPortStInfo), 0x00, sizeof(RfcommGetPortStInfo));
806     ctx->handle = handle;
807     ctx->event = EventCreate(true);
808 
809     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommGetPortStateTsk, ctx);
810     if (ret != BT_SUCCESS) {
811         EventDelete(ctx->event);
812         free(ctx);
813         return ret;
814     }
815 
816     EventWait(ctx->event, WAIT_TIME);
817     EventDelete(ctx->event);
818     (void)memcpy_s(state, sizeof(RfcommPortState), &ctx->state, sizeof(RfcommPortState));
819     ret = ctx->result;
820 
821     free(ctx);
822     return ret;
823 }
824 
825 /**
826  * @brief This function is used to get the payload packet sent by the peer from RFCOMM.
827  *        After the caller finishes using this interface, it creates a packet reference or
828  *        reads the payload buffer as needed, and must free the packet obtained from RFCOMM.
829  *
830  * @param handle The channel(DLC)'s handle number
831  * @param pkt    The packet point for receiving data
832  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
833  * @since 6
834  */
RFCOMM_Read(uint16_t handle,Packet ** pkt)835 int RFCOMM_Read(uint16_t handle, Packet **pkt)
836 {
837     LOG_INFO("%{public}s handle:%hu", __func__, handle);
838 
839     RfcommReadLock();
840     int ret = RfcommRead(handle, pkt);
841     RfcommReadUnlock();
842     return ret;
843 }
844 
845 typedef struct {
846     uint16_t handle;
847     Packet *pkt;
848     Event *event;
849     int result;
850 } RfcommWriteInfo;
851 
RfcommWriteTsk(void * context)852 static void RfcommWriteTsk(void *context)
853 {
854     LOG_INFO("%{public}s", __func__);
855 
856     RfcommWriteInfo *ctx = context;
857 
858     if (ctx == NULL) {
859         LOG_ERROR("%{public}s context is NULL.", __func__);
860         return;
861     }
862 
863     int ret = RfcommWrite(ctx->handle, ctx->pkt);
864     ctx->result = ret;
865 
866     if (ctx->event != NULL) {
867         EventSet(ctx->event);
868     }
869 }
870 
871 /**
872  * @brief This function is used to write the data to be transmitted to the opposite end to RFCOMM.
873  *
874  * @param handle The channel(DLC)'s handle number
875  * @param pkt    The packet for sending data
876  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
877  * @since 6
878  */
RFCOMM_Write(uint16_t handle,Packet * pkt)879 int RFCOMM_Write(uint16_t handle, Packet *pkt)
880 {
881     LOG_INFO("%{public}s handle:%hu", __func__, handle);
882 
883     RfcommWriteInfo *ctx = malloc(sizeof(RfcommWriteInfo));
884     if (ctx == NULL) {
885         return BT_NO_MEMORY;
886     }
887 
888     (void)memset_s(ctx, sizeof(RfcommWriteInfo), 0x00, sizeof(RfcommWriteInfo));
889     ctx->handle = handle;
890     ctx->pkt = pkt;
891     ctx->event = EventCreate(true);
892 
893     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommWriteTsk, ctx);
894     if (ret != BT_SUCCESS) {
895         EventDelete(ctx->event);
896         free(ctx);
897         return ret;
898     }
899 
900     EventWait(ctx->event, WAIT_TIME);
901     EventDelete(ctx->event);
902     ret = ctx->result;
903 
904     free(ctx);
905     return ret;
906 }
907 
908 typedef struct {
909     uint16_t handle;
910     Packet *pkt;
911 } RfcommSendTestCmdInfo;
912 
RfcommSendTestCmdTsk(void * context)913 static void RfcommSendTestCmdTsk(void *context)
914 {
915     LOG_INFO("%{public}s", __func__);
916 
917     RfcommSendTestCmdInfo *ctx = context;
918 
919     if (ctx == NULL) {
920         LOG_ERROR("%{public}s context is NULL.", __func__);
921         return;
922     }
923 
924     RfcommSendTestCmd(ctx->handle, ctx->pkt);
925 
926     PacketFree(ctx->pkt);
927     free(ctx);
928 }
929 
930 /**
931  * @brief This function is used to send Test Command to the peer.
932  *
933  * @param handle The channel(DLC)'s handle number
934  * @param pkt    The packet for sending data
935  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
936  * @since 6
937  */
RFCOMM_SendTestCmd(uint16_t handle,Packet * pkt)938 int RFCOMM_SendTestCmd(uint16_t handle, Packet *pkt)
939 {
940     LOG_INFO("%{public}s handle:%hu", __func__, handle);
941 
942     RfcommSendTestCmdInfo *ctx = malloc(sizeof(RfcommSendTestCmdInfo));
943     if (ctx == NULL) {
944         return BT_NO_MEMORY;
945     }
946 
947     (void)memset_s(ctx, sizeof(RfcommSendTestCmdInfo), 0x00, sizeof(RfcommSendTestCmdInfo));
948     ctx->handle = handle;
949     ctx->pkt = PacketRefMalloc(pkt);
950 
951     int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommSendTestCmdTsk, ctx);
952     if (ret != BT_SUCCESS) {
953         PacketFree(ctx->pkt);
954         free(ctx);
955     }
956 
957     return ret;
958 }
959 
RFCOMM_Init(int traceLevel)960 static void RFCOMM_Init(int traceLevel)
961 {
962     LOG_INFO("%{public}s", __func__);
963 
964     (void)traceLevel;
965 
966     return;
967 }
968 
RFCOMM_Cleanup()969 static void RFCOMM_Cleanup()
970 {
971     LOG_INFO("%{public}s", __func__);
972 
973     return;
974 }
975 
976 static Module g_rfcomm = {
977     .name = MODULE_NAME_RFCOMM,
978     .init = RFCOMM_Init,
979     .startup = RFCOMM_Startup,
980     .shutdown = RFCOMM_Shutdown,
981     .cleanup = RFCOMM_Cleanup,
982     .dependencies = {MODULE_NAME_L2CAP, MODULE_NAME_GAP},
983 };
984 
985 MODULE_DECL(g_rfcomm)