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