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 static List *g_channelList;
19 static bool g_channelHandle[MAX_DLC_COUNT] = {false};
20 static Mutex *g_readLock = NULL;
21 
RfcommReadLock()22 void RfcommReadLock()
23 {
24     LOG_INFO("%{public}s", __func__);
25 
26     if (g_readLock != NULL) {
27         MutexLock(g_readLock);
28     }
29 }
30 
RfcommReadUnlock()31 void RfcommReadUnlock()
32 {
33     LOG_INFO("%{public}s", __func__);
34 
35     if (g_readLock != NULL) {
36         MutexUnlock(g_readLock);
37     }
38 }
39 
40 /**
41  * @brief Create channel list when RFCOMM initialize.
42  *
43  */
RfcommCreateChannelList()44 void RfcommCreateChannelList()
45 {
46     LOG_INFO("%{public}s", __func__);
47 
48     for (uint8_t cnt = 0; cnt < MAX_DLC_COUNT; cnt++) {
49         g_channelHandle[cnt] = false;
50     }
51 
52     g_channelList = ListCreate(NULL);
53 
54     g_readLock = MutexCreate();
55 }
56 
57 /**
58  * @brief Free channel list when RFCOMM finalize.
59  */
RfcommDestroyChannelList()60 void RfcommDestroyChannelList()
61 {
62     LOG_INFO("%{public}s", __func__);
63 
64     RfcommChannelInfo *channel = NULL;
65     ListNode *node = NULL;
66 
67     for (uint8_t cnt = 0; cnt < MAX_DLC_COUNT; cnt++) {
68         g_channelHandle[cnt] = false;
69     }
70 
71     if (g_channelList == NULL) {
72         LOG_DEBUG("%{public}s Channel list is NULL.", __func__);
73         return;
74     }
75 
76     // Release channel information.
77     node = ListGetFirstNode(g_channelList);
78     while (node != NULL) {
79         channel = ListGetNodeData(node);
80         node = ListGetNextNode(node);
81         RfcommRemoveChannel(channel);
82     }
83 
84     // Free channel list.
85     ListDelete(g_channelList);
86     g_channelList = NULL;
87 
88     // Destroy read lock.
89     if (g_readLock != NULL) {
90         MutexDelete(g_readLock);
91         g_readLock = NULL;
92     }
93 }
94 
95 /**
96  * @brief The function is used to assign handle to individual DLC.
97  *
98  * @return Handle number.0(unavailable handle),1~36(available handle)
99  */
RfcommAssignHandle()100 static uint16_t RfcommAssignHandle()
101 {
102     LOG_INFO("%{public}s", __func__);
103 
104     uint16_t handle = 0;
105 
106     for (uint8_t index = 0; index < MAX_DLC_COUNT; index++) {
107         if (g_channelHandle[index]) {
108             continue;
109         }
110         g_channelHandle[index] = true;
111         handle = index + 1;
112         LOG_DEBUG("%{public}s DLC handle is %hu.", __func__, handle);
113         break;
114     }
115 
116     return handle;
117 }
118 
119 /**
120  * @brief After disconnect the DLC, free the handle.
121  *
122  * @param handle Handle.
123  */
RfcommFreeHandle(uint16_t handle)124 static void RfcommFreeHandle(uint16_t handle)
125 {
126     if ((handle < 1) || (handle > MAX_DLC_COUNT)) {
127         LOG_DEBUG("%{public}s handle(%hu) is overrun.", __func__, handle);
128         return;
129     }
130 
131     g_channelHandle[handle - 1] = false;
132 }
133 
134 /**
135  * @brief Initialize channel information.
136  *
137  * @param channel The pointer of the channel in the channel list.
138  */
RfcommInitChannelInfo(RfcommChannelInfo * channel)139 static void RfcommInitChannelInfo(RfcommChannelInfo *channel)
140 {
141     LOG_INFO("%{public}s", __func__);
142 
143     RfcommRemotePortConfig defaultCfg = {
144         BAUDRATE_9600, DATA_BIT_8, STOP_BIT_1, NO_PARITY, ODD_PARITY, NO_FLC, XON_DC1, XOFF_DC3, 0x00, 0x00
145     };
146 
147     // Init channel information.
148     (void)memset_s(channel, sizeof(RfcommChannelInfo), 0x00, sizeof(RfcommChannelInfo));
149     channel->channelState = ST_CHANNEL_CLOSED;
150     channel->peerMtu = RFCOMM_PEER_DEFAULT_MTU;
151     channel->sendQueue = ListCreate(NULL);
152     channel->recvQueue = ListCreate(NULL);
153     channel->timer = AlarmCreate(NULL, false);
154     channel->localCreditMax = MAX_CREDIT_COUNT;
155     channel->peerChannelFc = false;
156     // Set remote port default value.
157     channel->portConfig = defaultCfg;
158 }
159 
160 /**
161  * @brief The timeout's processing.
162  *
163  * @param parameter The parametr info registered to alarm.
164  */
RfcommChannelTimeout(void * parameter)165 void RfcommChannelTimeout(void *parameter)
166 {
167     LOG_INFO("%{public}s", __func__);
168 
169     bool isChannelValid = RfcommIsChannelValid((RfcommChannelInfo *)parameter);
170     if (!isChannelValid) {
171         LOG_ERROR("%{public}s:Channel is closed.", __func__);
172         return;
173     }
174 
175     RfcommChannelEvtFsm((RfcommChannelInfo *)parameter, EV_CHANNEL_TIMEOUT, NULL);
176 }
177 
178 /**
179  * @brief The timeout callback function registered to alarm.
180  *
181  * @param parameter The parametr info registered to alarm.
182  */
RfcommChannelTimeoutCallback(void * context)183 static void RfcommChannelTimeoutCallback(void *context)
184 {
185     LOG_INFO("%{public}s", __func__);
186 
187     if (context == NULL) {
188         LOG_ERROR("%{public}s:DLC is closed.", __func__);
189         return;
190     }
191 
192     BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_RFCOMM, RfcommChannelTimeout, context);
193 
194     return;
195 }
196 
197 /**
198  * @brief Start channel's timer.
199  *
200  * @param channel The pointer of the channel in the channel list.
201  * @param timeout Timeout value.
202  */
RfcommStartChannelTimer(RfcommChannelInfo * channel,uint8_t timeout)203 void RfcommStartChannelTimer(RfcommChannelInfo *channel, uint8_t timeout)
204 {
205     LOG_INFO("%{public}s", __func__);
206 
207     if (channel->timer == NULL) {
208         LOG_ERROR("%{public}s Channel's timer is NULL.", __func__);
209         return;
210     }
211 
212     AlarmSet(channel->timer, timeout * RFCOMM_PER_SEC, RfcommChannelTimeoutCallback, channel);
213 }
214 
215 /**
216  * @brief Stop channel's timer.
217  *
218  * @param  channel The pointer of the channel in the channel list.
219  */
RfcommStopChannelTimer(RfcommChannelInfo * channel)220 void RfcommStopChannelTimer(RfcommChannelInfo *channel)
221 {
222     LOG_INFO("%{public}s", __func__);
223 
224     if (channel->timer == NULL) {
225         LOG_ERROR("%{public}s Channel's timer is NULL.", __func__);
226         return;
227     }
228 
229     AlarmCancel(channel->timer);
230 }
231 
232 /**
233  * @brief This function is used to register data link related information and
234  *        generate the handle of the data link connection
235  *
236  * @param createChannelInfo Channel creation information.
237  * @return The pointer of the new channel in the channel list.
238  */
RfcommCreateChannel(const RfcommCreateChannelInfo * createChannelInfo)239 RfcommChannelInfo *RfcommCreateChannel(const RfcommCreateChannelInfo *createChannelInfo)
240 {
241     LOG_INFO("%{public}s", __func__);
242 
243     if (g_channelList == NULL) {
244         LOG_ERROR("%{public}s Channel list is NULL.", __func__);
245         return NULL;
246     }
247 
248     uint16_t count = (uint16_t)ListGetSize(g_channelList);
249     // If the max number of links has been exceeded, no more links will be created.
250     if (count >= MAX_DLC_COUNT) {
251         LOG_ERROR("%{public}s Channel count is over 36.", __func__);
252         return NULL;
253     }
254 
255     RfcommChannelInfo *channel = malloc(sizeof(RfcommChannelInfo));
256     if (channel == NULL) {
257         return NULL;
258     }
259     // Init channel information.
260     RfcommInitChannelInfo(channel);
261     channel->session = createChannelInfo->session;
262     channel->isServer = createChannelInfo->isServer;
263     channel->scn = createChannelInfo->dlci >> RFCOMM_DLCI_SHIFT_SCN;
264     if (createChannelInfo->mtu > 0) {
265         channel->localMtu = (createChannelInfo->mtu > RFCOMM_LOCAL_DEFAULT_MTU) ?
266                             RFCOMM_LOCAL_DEFAULT_MTU : createChannelInfo->mtu;
267     } else {
268         channel->localMtu = RFCOMM_LOCAL_DEFAULT_MTU;
269     }
270     channel->context = createChannelInfo->context;
271     channel->callBack = createChannelInfo->callback;
272     channel->eventMask = createChannelInfo->eventMask;
273     channel->dlci = createChannelInfo->dlci;
274     // Set handle.
275     channel->handle = RfcommAssignHandle();
276 
277     // Add the new channel into channel list.
278     RfcommReadLock();
279     ListAddLast(g_channelList, channel);
280     RfcommReadUnlock();
281 
282     // return channel.
283     return channel;
284 }
285 
286 /**
287  * @brief The server is currently connected, create a channel associated with the server.
288  *
289  * @param session The pointer of the session in the session list.
290  * @param dlci    The dlci value.
291  * @param event   The event id.
292  * @return The pointer of the new channel in the channel list.
293  */
RfcommCreateChannelOfServer(RfcommSessionInfo * session,uint8_t dlci,int event)294 RfcommChannelInfo *RfcommCreateChannelOfServer(RfcommSessionInfo *session, uint8_t dlci, int event)
295 {
296     LOG_INFO("%{public}s", __func__);
297 
298     // If the event is SABM cmd, PN req, RPN req, RPN cmd, find the server and
299     // create a channel associated with the server.
300     if (!IS_FIRST_CMD(event)) {
301         LOG_DEBUG("%{public}s:Event(%{public}d) is not first cmd.", __func__, event);
302         return NULL;
303     }
304 
305     uint8_t scn = dlci >> RFCOMM_DLCI_SHIFT_SCN;
306     RfcommServerInfo *server = RfcommGetServerByScn(scn);
307     if (server == NULL) {
308         LOG_ERROR("%{public}s:Server(scn:%hhu) does not exist.", __func__, scn);
309         return NULL;
310     }
311 
312     RfcommCreateChannelInfo createChannelInfo;
313     createChannelInfo.session = session;
314     createChannelInfo.isServer = true;
315     createChannelInfo.dlci = dlci;
316     createChannelInfo.mtu = server->maxRevSize;
317     createChannelInfo.eventMask = server->eventMask;
318     createChannelInfo.callback = server->callBack;
319     createChannelInfo.context = server->context;
320 
321     RfcommChannelInfo *channel = RfcommCreateChannel(&createChannelInfo);
322 
323     return channel;
324 }
325 
326 /**
327  * @brief Remove channel node from channel list and free the channel resources.
328  *
329  * @param channel The pointer of the channel in the channel list.
330  */
RfcommRemoveChannel(RfcommChannelInfo * channel)331 void RfcommRemoveChannel(RfcommChannelInfo *channel)
332 {
333     LOG_INFO("%{public}s", __func__);
334 
335     RfcommReadLock();
336 
337     // Release cache data.
338     RfcommReleaseCachePkt(channel);
339 
340     // Release alarm resource.
341     if (channel->timer != NULL) {
342         AlarmDelete(channel->timer);
343         channel->timer = NULL;
344     }
345 
346     // Free handle.
347     RfcommFreeHandle(channel->handle);
348 
349     // Remove channel node.
350     ListRemoveNode(g_channelList, channel);
351 
352     // Release channel resource.
353     free(channel);
354 
355     RfcommReadUnlock();
356 }
357 
358 /**
359  * @brief Remove packet from send queue and free the queue resources.
360  *
361  * @param channel The pointer of the channel in the channel list.
362  */
RfcommReleaseCachePkt(RfcommChannelInfo * channel)363 void RfcommReleaseCachePkt(RfcommChannelInfo *channel)
364 {
365     LOG_INFO("%{public}s", __func__);
366 
367     Packet *pkt = NULL;
368     ListNode *node = NULL;
369 
370     if (channel->sendQueue != NULL) {
371         // Release send queue's cache data.
372         node = ListGetFirstNode(channel->sendQueue);
373         while (node != NULL) {
374             pkt = ListGetNodeData(node);
375             PacketFree(pkt);
376             node = ListGetNextNode(node);
377         }
378         // Release send queue resource.
379         ListDelete(channel->sendQueue);
380         channel->sendQueue = NULL;
381     }
382 
383     if (channel->recvQueue != NULL) {
384         // Release receive queue's cache data.
385         node = ListGetFirstNode(channel->recvQueue);
386         while (node != NULL) {
387             pkt = ListGetNodeData(node);
388             PacketFree(pkt);
389             node = ListGetNextNode(node);
390         }
391         // Release receive queue resource.
392         ListDelete(channel->recvQueue);
393         channel->recvQueue = NULL;
394     }
395 }
396 
397 /**
398  * @brief During the DLC disconnection process, the upper layer sends a DLC connection request,
399  *        reset part of DLC data.
400  *
401  * @param channel The pointer of the channel in the channel list.
402  */
RfcommResetChannelInfo(RfcommChannelInfo * channel)403 void RfcommResetChannelInfo(RfcommChannelInfo *channel)
404 {
405     LOG_INFO("%{public}s", __func__);
406 
407     RfcommRemotePortConfig defaultCfg = {
408         BAUDRATE_9600, DATA_BIT_8, STOP_BIT_1, NO_PARITY, ODD_PARITY, NO_FLC, XON_DC1, XOFF_DC3, 0x00, 0x00
409     };
410 
411     RfcommReadLock();
412 
413     RfcommStopChannelTimer(channel);
414     RfcommReleaseCachePkt(channel);
415     channel->sendQueue = ListCreate(NULL);
416     channel->recvQueue = ListCreate(NULL);
417     channel->peerMtu = RFCOMM_PEER_DEFAULT_MTU;
418     channel->channelState = ST_CHANNEL_CLOSED;
419     channel->localCredit = 0;
420     channel->peerCredit = 0;
421     channel->transferReady = 0;
422     channel->localFcToPeer = false;
423     channel->localFcToUpper = false;
424     channel->peerChannelFc = false;
425     channel->receivedBytes = 0;
426     channel->transmittedBytes = 0;
427     // Set remote port default value.
428     channel->portConfig = defaultCfg;
429 
430     (void)memset_s(&channel->lineStatus, sizeof(RfcommRemoteLineStatus), 0x00, sizeof(RfcommRemoteLineStatus));
431     (void)memset_s(&channel->peerModemSt, sizeof(RfcommModemStatusInfo), 0x00, sizeof(RfcommModemStatusInfo));
432 
433     RfcommReadUnlock();
434 }
435 
436 /**
437  * @brief Initialize channel information.
438  *
439  * @param channel   The pointer of the channel in the channel list.
440  * @param eventId   The eventId to be notified to the upper layer.
441  * @param eventData The data to be notified to the upper layer.
442  */
443 NO_SANITIZE("cfi")
RfcommNotifyEvtToUpper(const RfcommChannelInfo * channel,uint32_t eventId,const void * eventData)444 void RfcommNotifyEvtToUpper(const RfcommChannelInfo *channel, uint32_t eventId, const void *eventData)
445 {
446     LOG_INFO("%{public}s event is %u", __func__, eventId);
447 
448     uint32_t event = eventId & channel->eventMask;
449 
450     if (!event) {
451         LOG_DEBUG("%{public}s:No event that the upper layer cares.", __func__);
452         return;
453     }
454 
455     if ((channel->channelState == ST_CHANNEL_CLOSED) && (!IS_DISCONNECTED(eventId))) {
456         LOG_DEBUG("%{public}s:Channel is disconnected.", __func__);
457         return;
458     }
459 
460     if (channel->callBack) {
461         LOG_DEBUG("%{public}s:eventId(%u), handle(%hu)", __func__, eventId, channel->handle);
462         channel->callBack(channel->handle, event, eventData, channel->context);
463         LOG_DEBUG("%{public}s:End.", __func__);
464     }
465 }
466 
467 /**
468  * @brief This function is used to find the specified channel using dlci and session.
469  *
470  * @param session The pointer of the session in the session list.
471  * @param dlci    The dlci value.
472  * @return The pointer of the channel in the channel list.
473  */
RfcommGetChannelByDlci(const RfcommSessionInfo * session,uint8_t dlci)474 RfcommChannelInfo *RfcommGetChannelByDlci(const RfcommSessionInfo *session, uint8_t dlci)
475 {
476     LOG_INFO("%{public}s dlci:%hhu", __func__, dlci);
477 
478     RfcommChannelInfo *channel = NULL;
479     ListNode *node = NULL;
480 
481     if (g_channelList == NULL) {
482         LOG_ERROR("%{public}s Channel list is NULL.", __func__);
483         return NULL;
484     }
485 
486     node = ListGetFirstNode(g_channelList);
487     while (node != NULL) {
488         channel = ListGetNodeData(node);
489         if ((channel->session == session) && (channel->dlci == dlci)) {
490             return channel;
491         }
492         node = ListGetNextNode(node);
493     }
494 
495     return NULL;
496 }
497 
498 /**
499  * @brief This function is used to get the first channel on the session.
500  *
501  * @param session The pointer of the session in the session list.
502  * @return The pointer of the channel in the channel list.
503  */
RfcommGetFirstChannelOnSession(const RfcommSessionInfo * session)504 RfcommChannelInfo *RfcommGetFirstChannelOnSession(const RfcommSessionInfo *session)
505 {
506     LOG_INFO("%{public}s", __func__);
507 
508     RfcommChannelInfo *channel = NULL;
509     ListNode *node = NULL;
510 
511     if (g_channelList == NULL) {
512         LOG_ERROR("%{public}s Channel list is NULL.", __func__);
513         return NULL;
514     }
515 
516     node = ListGetFirstNode(g_channelList);
517     while (node != NULL) {
518         channel = ListGetNodeData(node);
519         if (channel->session == session) {
520             return channel;
521         }
522         node = ListGetNextNode(node);
523     }
524 
525     return NULL;
526 }
527 
528 /**
529  * @brief This function is used to find the specified channel using handle.
530  *
531  * @param handle The channel's handle.
532  * @return The pointer of the channel in the channel list.
533  */
RfcommGetChannelByHandle(uint16_t handle)534 RfcommChannelInfo *RfcommGetChannelByHandle(uint16_t handle)
535 {
536     LOG_INFO("%{public}s handle:%hu", __func__, handle);
537 
538     RfcommChannelInfo *channel = NULL;
539     ListNode *node = NULL;
540 
541     if (g_channelList == NULL) {
542         LOG_ERROR("%{public}s Channel list is NULL.", __func__);
543         return NULL;
544     }
545 
546     node = ListGetFirstNode(g_channelList);
547     while (node != NULL) {
548         channel = ListGetNodeData(node);
549         if (channel->handle == handle) {
550             return channel;
551         }
552         node = ListGetNextNode(node);
553     }
554 
555     return NULL;
556 }
557 
558 /**
559  * @brief If there is no channel on the particular session, then close the session.
560  *
561  * @param session The pointer of the session in the session list.
562  */
RfcommCheckSessionValid(const RfcommSessionInfo * session)563 bool RfcommCheckSessionValid(const RfcommSessionInfo *session)
564 {
565     LOG_INFO("%{public}s", __func__);
566 
567     RfcommChannelInfo *channel = NULL;
568     ListNode *node = NULL;
569 
570     // Check if there is a channel on the session.
571     node = ListGetFirstNode(g_channelList);
572     while (node != NULL) {
573         channel = ListGetNodeData(node);
574         if (channel->session == session) {
575             LOG_DEBUG("%{public}s There are channels on the session.", __func__);
576             return true;
577         }
578         node = ListGetNextNode(node);
579     }
580 
581     return false;
582 }
583 
584 /**
585  * @brief Check if the channel is valid.
586  *
587  * @param channel The pointer of the channel.
588  * @return True if the channel exists,false if the channel doesn't exist.
589  */
RfcommIsChannelValid(const RfcommChannelInfo * channel)590 bool RfcommIsChannelValid(const RfcommChannelInfo *channel)
591 {
592     LOG_INFO("%{public}s", __func__);
593 
594     RfcommChannelInfo *channelInfo = NULL;
595     ListNode *node = NULL;
596 
597     if (g_channelList == NULL) {
598         LOG_ERROR("%{public}s Channel list is NULL.", __func__);
599         return NULL;
600     }
601 
602     // Check if there is a channel on the session.
603     node = ListGetFirstNode(g_channelList);
604     while (node != NULL) {
605         channelInfo = ListGetNodeData(node);
606         if (channelInfo == channel) {
607             LOG_DEBUG("%{public}s The channel is valid.", __func__);
608             return true;
609         }
610         node = ListGetNextNode(node);
611     }
612 
613     return false;
614 }
615 
616 /**
617  * @brief Create all data link connections on the session.
618  *
619  * @param session The pointer of the session in the session list.
620  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
621  */
RfcommOpenAllChannelOnSession(const RfcommSessionInfo * session)622 int RfcommOpenAllChannelOnSession(const RfcommSessionInfo *session)
623 {
624     LOG_INFO("%{public}s", __func__);
625 
626     int ret = 0;
627     RfcommChannelInfo *channel = NULL;
628     ListNode *node = NULL;
629 
630     node = ListGetFirstNode(g_channelList);
631     while (node != NULL) {
632         channel = ListGetNodeData(node);
633         if (channel->session == session) {
634             ret = RfcommChannelEvtFsm(channel, EV_CHANNEL_SEND_OPEN_REQ, NULL);
635         }
636         node = ListGetNextNode(node);
637     }
638 
639     return ret;
640 }
641 
642 /**
643  * @brief Reset all channel's information on the session.
644  *
645  * @param session The pointer of the session in the session list.
646  */
RfcommResetAllChannelOnSession(const RfcommSessionInfo * session)647 void RfcommResetAllChannelOnSession(const RfcommSessionInfo *session)
648 {
649     LOG_INFO("%{public}s", __func__);
650 
651     RfcommChannelInfo *channel = NULL;
652     ListNode *node = NULL;
653 
654     node = ListGetFirstNode(g_channelList);
655     while (node != NULL) {
656         channel = ListGetNodeData(node);
657         if (channel->session == session) {
658             RfcommResetChannelInfo(channel);
659         }
660         node = ListGetNextNode(node);
661     }
662 }
663 
664 /**
665  * @brief Send the buffered data to be sent on all channels.
666  *
667  * @param session The pointer of the session in the session list.
668  */
RfcommSendAllCachePktOnSession(const RfcommSessionInfo * session)669 void RfcommSendAllCachePktOnSession(const RfcommSessionInfo *session)
670 {
671     LOG_INFO("%{public}s", __func__);
672 
673     RfcommChannelInfo *channel = NULL;
674     ListNode *node = NULL;
675 
676     node = ListGetFirstNode(g_channelList);
677     while (node != NULL) {
678         channel = ListGetNodeData(node);
679         if (channel->session == session) {
680             RfcommSendCachePkt(channel);
681             RfcommSetFlcToUpper(channel);
682         }
683         node = ListGetNextNode(node);
684     }
685 }
686 
687 /**
688  * @brief Notify all channels on the session event.
689  *
690  * @param session The pointer of the session in the session list.
691  * @param eventId The eventId to be notified to the upper layer.
692  */
RfcommNotifyAllChannelEvtOnSession(const RfcommSessionInfo * session,uint32_t eventId)693 void RfcommNotifyAllChannelEvtOnSession(const RfcommSessionInfo *session, uint32_t eventId)
694 {
695     LOG_INFO("%{public}s", __func__);
696 
697     RfcommChannelInfo *channel = NULL;
698     ListNode *node = NULL;
699 
700     node = ListGetFirstNode(g_channelList);
701     while (node != NULL) {
702         channel = ListGetNodeData(node);
703         if (channel->session == session) {
704             if (IS_DISCONNECTED(eventId)) {
705                 channel->channelState = ST_CHANNEL_CLOSED;
706             }
707             RfcommNotifyEvtToUpper(channel, eventId, NULL);
708         }
709         node = ListGetNextNode(node);
710     }
711 }
712 
713 /**
714  * @brief Delete all channels on the specified Session.
715  *
716  * @param session The pointer of the session in the session list.
717  */
RfcommRemoveAllChannelOnSession(const RfcommSessionInfo * session)718 void RfcommRemoveAllChannelOnSession(const RfcommSessionInfo *session)
719 {
720     LOG_INFO("%{public}s", __func__);
721 
722     RfcommChannelInfo *channel = NULL;
723     ListNode *node = NULL;
724 
725     node = ListGetFirstNode(g_channelList);
726     while (node != NULL) {
727         channel = ListGetNodeData(node);
728         node = ListGetNextNode(node);
729         if (channel->session == session) {
730             // Release cache data.
731             RfcommRemoveChannel(channel);
732         }
733     }
734 }
735 
736 /**
737  * @brief When receiving DISC0(timeout occurs at the opposite end),
738  *        delete all channels on the session(except the channel to be connected).
739  *
740  * @param session The pointer of the session.
741  */
RfcommRemoveInvalidChannelOnSession(const RfcommSessionInfo * session)742 void RfcommRemoveInvalidChannelOnSession(const RfcommSessionInfo *session)
743 {
744     LOG_INFO("%{public}s", __func__);
745 
746     RfcommChannelInfo *channel = NULL;
747     ListNode *node = NULL;
748 
749     node = ListGetFirstNode(g_channelList);
750     while (node != NULL) {
751         channel = ListGetNodeData(node);
752         node = ListGetNextNode(node);
753         if (channel->session != session) {
754             continue;
755         }
756         switch (channel->channelState) {
757             case ST_CHANNEL_CLOSED:
758                 // fall-through
759             case ST_CHANNEL_WAIT_RESTART:
760                 // fall-through
761             case ST_CHANNEL_WAIT_PN_RSP:
762                 // fall-through
763                 LOG_DEBUG("%{public}s The channel is waiting to be opened", __func__);
764                 break;
765             case ST_CHANNEL_CLIENT_WAIT_SECURITY_RESULT:
766                 // fall-through
767             case ST_CHANNEL_SABM_REQ_WAIT_UA:
768                 // fall-through
769             case ST_CHANNEL_SERVER_WAIT_SECURITY_RESULT:
770                 RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_FAIL, NULL);
771                 RfcommRemoveChannel(channel);
772                 break;
773             case ST_CHANNEL_WAIT_UPPER_RESPONSE:
774                 // fall-through
775             case ST_CHANNEL_DISC_REQ_WAIT_UA:
776                 // fall-through
777             case ST_CHANNEL_CONNECTED:
778                 RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECTED, NULL);
779                 RfcommRemoveChannel(channel);
780                 break;
781             case ST_CHANNEL_WAIT_SABM:
782                 RfcommRemoveChannel(channel);
783                 break;
784             default:
785                 break;
786         }
787     }
788 }
789 
790 /**
791  * @brief Remove the callback from channel list about the scn and disconnect the channel.
792  *
793  * @param scn Server number.
794  * @param isRemoveCallback true:remove callback,RFCOMM will not notify event to upper layer.otherwise:false.
795  */
RfcommRemoveChannelCallback(uint8_t scn)796 void RfcommRemoveChannelCallback(uint8_t scn)
797 {
798     LOG_INFO("%{public}s", __func__);
799 
800     RfcommChannelInfo *channel = NULL;
801     ListNode *node = NULL;
802 
803     node = ListGetFirstNode(g_channelList);
804     while (node != NULL) {
805         channel = ListGetNodeData(node);
806         node = ListGetNextNode(node);
807         if ((channel->scn == scn) && (channel->isServer)) {
808             channel->callBack = NULL;
809             RfcommChannelEvtFsm(channel, EV_CHANNEL_SEND_CLOSE_REQ, NULL);
810         }
811     }
812 }
813 
814 /**
815  * @brief Send data in the buffer queue.
816  *
817  * @param channel The pointer of the channel in the channel list.
818  */
RfcommSendCachePkt(RfcommChannelInfo * channel)819 void RfcommSendCachePkt(RfcommChannelInfo *channel)
820 {
821     LOG_INFO("%{public}s", __func__);
822 
823     RfcommSessionInfo *session = channel->session;
824     Packet *pkt = NULL;
825     ListNode *node = NULL;
826 
827     if (channel->transferReady != TRANSFER_READY) {
828         LOG_DEBUG("%{public}s:Not ready to send data.", __func__);
829         return;
830     }
831 
832     node = ListGetFirstNode(channel->sendQueue);
833     if (node == NULL) {
834         LOG_DEBUG("%{public}s:There is no cache data.", __func__);
835         return;
836     }
837 
838     if (session->fcType == FC_TYPE_CREDIT) {
839         while ((channel->peerCredit) && (node)) {
840             pkt = ListGetNodeData(node);
841             node = ListGetNextNode(node);
842             uint8_t newCredit = channel->localCreditMax - channel->localCredit;
843             newCredit = (newCredit < MAX_ONCE_NEWCREDIT) ? newCredit : MAX_ONCE_NEWCREDIT;
844             channel->localCredit += newCredit;
845             // Add transmite data bytes value.
846             channel->transmittedBytes += PacketPayloadSize(pkt);
847             // Send data to peer.
848             RfcommSendUihData(session, channel->dlci, newCredit, pkt);
849             ListRemoveNode(channel->sendQueue, pkt);
850             PacketFree(pkt);
851             // Decrease credits.
852             channel->peerCredit--;
853         }
854     } else if ((!channel->peerChannelFc) && (!session->peerSessionFc)) {
855         while (node != NULL) {
856             pkt = ListGetNodeData(node);
857             node = ListGetNextNode(node);
858             // Add transmite data bytes value.
859             channel->transmittedBytes += PacketPayloadSize(pkt);
860             // Send data to peer.
861             RfcommSendUihData(session, channel->dlci, 0, pkt);
862             ListRemoveNode(channel->sendQueue, pkt);
863             PacketFree(pkt);
864         }
865     }
866 }
867 
868 /**
869  * @brief Notify the upper layer whether RFCOMM can receive data.
870  *
871  * @param channel The pointer of the channel in the channel list.
872  */
RfcommSetFlcToUpper(RfcommChannelInfo * channel)873 void RfcommSetFlcToUpper(RfcommChannelInfo *channel)
874 {
875     LOG_INFO("%{public}s", __func__);
876 
877     if (channel->localFcToUpper) {
878         RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_FC_ON, NULL);
879         channel->localFcToUpper = false;
880     }
881 }
882 
883 /**
884  * @brief Send further credits to peer.
885  *
886  * @param channel The pointer of the channel in the channel list.
887  * @param credits The number of credits that can be received locally.
888  */
RfcommSendCredits(const RfcommChannelInfo * channel,uint8_t credits)889 static void RfcommSendCredits(const RfcommChannelInfo *channel, uint8_t credits)
890 {
891     LOG_INFO("%{public}s", __func__);
892 
893     RfcommSendUihData(channel->session, channel->dlci, credits, NULL);
894 }
895 
896 /**
897  * @brief Notify the peer whether local can receive data.
898  *
899  * @param channel The pointer of the channel in the channel list.
900  * @param enable  Whether local can receive data.true:yes,false:no
901  */
RfcommSetFlcToPeer(RfcommChannelInfo * channel,bool enable)902 void RfcommSetFlcToPeer(RfcommChannelInfo *channel, bool enable)
903 {
904     LOG_INFO("%{public}s", __func__);
905 
906     RfcommSessionInfo *session = channel->session;
907     RfcommModemStatusInfo modemStatus;
908     (void)memset_s(&modemStatus, sizeof(modemStatus), 0x00, sizeof(modemStatus));
909 
910     if (session->fcType == FC_TYPE_CREDIT) {
911         if (!enable) {
912             return;
913         }
914         // Send new credit.
915         uint8_t newCredits = channel->localCreditMax - channel->localCredit;
916         newCredits = (newCredits >= MAX_ONCE_NEWCREDIT) ? (MAX_ONCE_NEWCREDIT - 1) : newCredits;
917         channel->localCredit += newCredits;
918         RfcommSendCredits(channel, newCredits + 1);
919     } else {
920         RfcommReadLock();
921         uint8_t count = ListGetSize(channel->recvQueue);
922         RfcommReadUnlock();
923         if ((enable) && (channel->localFcToPeer)) {
924             modemStatus.signals = MSC_RTC | MSC_RTR | MSC_DV;
925             channel->localFcToPeer = false;
926         } else if ((!enable) && (count >= MAX_QUEUE_COUNT)) {
927             modemStatus.signals = MSC_FC | MSC_RTC | MSC_RTR | MSC_DV;
928             channel->localFcToPeer = true;
929         } else {
930             return;
931         }
932         RfcommSendUihMsc(channel->session, channel->dlci, true, &modemStatus);
933         // Start timer.
934         RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
935     }
936 }
937 
938 /**
939  * @brief Set the peer's modem status, and notify the upper layer if the status changes.
940  *        And if the current flow control is not based on credit,
941  *        set the fc state and send the data in the queue if the peer can receive data.
942  *
943  * @param channel  The pointer of the channel in the channel list.
944  * @param modemSts Peer's modem status.
945  */
RfcommSetPeerModemStatus(RfcommChannelInfo * channel,const RfcommModemStatusInfo * modemSts)946 void RfcommSetPeerModemStatus(RfcommChannelInfo *channel, const RfcommModemStatusInfo *modemSts)
947 {
948     LOG_INFO("%{public}s", __func__);
949 
950     RfcommSessionInfo *session = channel->session;
951     RfcommModemStatus status;
952     (void)memset_s(&status, sizeof(status), 0x00, sizeof(status));
953 
954     // Notify the upper layer the peer's status if the status changes.
955     if (memcmp(&channel->peerModemSt, modemSts, sizeof(RfcommModemStatusInfo))) {
956         (void)memcpy_s(&channel->peerModemSt, sizeof(RfcommModemStatusInfo), modemSts, sizeof(RfcommModemStatusInfo));
957         status.fc = (modemSts->signals & MSC_FC) ? 1 : 0;
958         status.rtc = (modemSts->signals & MSC_RTC) ? 1 : 0;
959         status.rtr = (modemSts->signals & MSC_RTR) ? 1 : 0;
960         status.ic = (modemSts->signals & MSC_IC) ? 1 : 0;
961         status.dv = (modemSts->signals & MSC_DV) ? 1 : 0;
962         status.break_signal = (modemSts->breakSignal & MSC_BREAK) ? 1 : 0;
963         status.break_length = (modemSts->breakSignal & MSC_BREAK_LEN) >> RFCOMM_MSC_SHIFT_BREAKLEN;
964         RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_MODEM_STATUS, &status);
965     }
966     // When credit based flow control is being used on a session,
967     // the FC-bit in the MSC-command has no meaning;
968     // it shall be set to zero in MSCcommands, and it shall be ignored by a receiver.
969     // Ref-RFCOMM_SPEC_V12(6.5.3)
970     if (session->fcType == FC_TYPE_CREDIT) {
971         LOG_DEBUG("%{public}s:Credit based fc is used, ignore FC-bit.", __func__);
972         return;
973     }
974     channel->peerChannelFc = (modemSts->signals & MSC_FC) ? true : false;
975     if (!channel->peerChannelFc) {
976         RfcommSendCachePkt(channel);
977         RfcommSetFlcToUpper(channel);
978     }
979 }
980 
981 /**
982  * @brief After DLC is established, determine the mtu size of the opposite end.
983  *
984  * @param channel The pointer of the channel in the channel list.
985  */
RfcommDeterminePeerMtu(RfcommChannelInfo * channel)986 void RfcommDeterminePeerMtu(RfcommChannelInfo *channel)
987 {
988     LOG_INFO("%{public}s", __func__);
989 
990     RfcommSessionInfo *session = channel->session;
991 
992     // If PN communication is performed, set the minimum value between PN negotiation and L2CAP configuration.
993     // If there is no PN communication, take the minimum value between the default mtu (127) of RFCOMM and
994     // the value with L2CAP configuration.
995     channel->peerMtu = (channel->peerMtu < (session->l2capPeerMtu - RFCOMM_HEAD_MAX_LEN)) ?
996         channel->peerMtu : (session->l2capPeerMtu - RFCOMM_HEAD_MAX_LEN);
997 }
998 
999 /**
1000  * @brief The device closing the last connection (DLC) on a particular session
1001  *        shall close the multiplexer.
1002  *
1003  * @param session The pointer of the session in the session list.
1004  */
RfcommCloseInvalidSession(RfcommSessionInfo * session)1005 void RfcommCloseInvalidSession(RfcommSessionInfo *session)
1006 {
1007     LOG_INFO("%{public}s", __func__);
1008 
1009     // Check if the session is valid.
1010     bool sessionValid = RfcommCheckSessionValid(session);
1011     if (!sessionValid) {
1012         // If there is no channel on the session, close the session.
1013         RfcommSessionEvtFsm(session, EV_SESSION_SEND_CLOSE_REQ, NULL);
1014     }
1015 }
1016 
1017 /**
1018  * @brief Update the direction bit of all channels on the specified Session.
1019  *
1020  * @param session     The pointer of the session in the session list.
1021  * @param isInitiator Whether it is the initiator. true: initiator, false: non-initiator.
1022  */
RfcommUpdateChannelDirectionBit(const RfcommSessionInfo * session,bool isInitiator)1023 void RfcommUpdateChannelDirectionBit(const RfcommSessionInfo *session, bool isInitiator)
1024 {
1025     LOG_INFO("%{public}s", __func__);
1026 
1027     RfcommChannelInfo *channel = NULL;
1028     ListNode *node = NULL;
1029 
1030     node = ListGetFirstNode(g_channelList);
1031     while (node != NULL) {
1032         channel = ListGetNodeData(node);
1033         node = ListGetNextNode(node);
1034         if (channel->session == session) {
1035             channel->dlci = isInitiator ? (channel->scn << 1) : ((channel->scn << 1) + 1);
1036         }
1037     }
1038 }
1039