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 typedef int (*ChannelActionFunc)(RfcommChannelInfo *channel, const void *data);
19 typedef struct {
20     RfcommChannelEvent eventId;
21     ChannelActionFunc fn;
22 } RfcommChannelEvtAction;
23 
24 static int RfcommOpenChannel(RfcommChannelInfo *channel, const void *data);
25 static int RfcommCloseChannel(RfcommChannelInfo *channel, const void *data);
26 static int RfcommRecvSecurityRslt(RfcommChannelInfo *channel, const void *data);
27 static int RfcommRecvSabm(RfcommChannelInfo *channel, const void *data);
28 static int RfcommRecvDisc(RfcommChannelInfo *channel, const void *data);
29 static int RfcommRecvUa(RfcommChannelInfo *channel, const void *data);
30 static int RfcommRecvDm(RfcommChannelInfo *channel, const void *data);
31 static int RfcommRecvPnReq(RfcommChannelInfo *channel, const void *data);
32 static int RfcommRecvPnRsp(RfcommChannelInfo *channel, const void *data);
33 static int RfcommRecvRpnCmd(RfcommChannelInfo *channel, const void *data);
34 static int RfcommRecvRpnReq(RfcommChannelInfo *channel, const void *data);
35 static int RfcommRecvRpnRsp(RfcommChannelInfo *channel, const void *data);
36 static int RfcommRecvMscReq(RfcommChannelInfo *channel, const void *data);
37 static int RfcommRecvMscRsp(RfcommChannelInfo *channel, const void *data);
38 static int RfcommRecvRlsReq(RfcommChannelInfo *channel, const void *data);
39 static int RfcommRecvRlsRsp(RfcommChannelInfo *channel, const void *data);
40 static int RfcommRecvAcceptRsp(RfcommChannelInfo *channel, const void *data);
41 static int RfcommRecvRejectRsp(RfcommChannelInfo *channel, const void *data);
42 static int RfcommRecvRevData(RfcommChannelInfo *channel, const void *data);
43 static int RfcommSendRpnCmd(RfcommChannelInfo *channel, const void *data);
44 static int RfcommSendRpnReq(RfcommChannelInfo *channel, const void *data);
45 static int RfcommSendRlsReq(RfcommChannelInfo *channel, const void *data);
46 static int RfcommSendMscReq(RfcommChannelInfo *channel, const void *data);
47 static int RfcommWriteData(RfcommChannelInfo *channel, const void *data);
48 static int RfcommTimeOut(RfcommChannelInfo *channel, const void *data);
49 static void RfcommSetUihPnParameter(
50     RfcommFlowControlType fcType, uint8_t reqCl, RfcommPnCmdKind cmdKind, uint8_t *cl, uint8_t *credits);
51 
52 static RfcommChannelEvtAction g_channelEvtActTbl[EV_CHANNEL_EV_MAX] = {
53     {EV_CHANNEL_SEND_OPEN_REQ, RfcommOpenChannel},
54     {EV_CHANNEL_SEND_CLOSE_REQ, RfcommCloseChannel},
55     {EV_CHANNEL_RECV_SECURITY_RESULT, RfcommRecvSecurityRslt},
56     {EV_CHANNEL_RECV_SABM, RfcommRecvSabm},
57     {EV_CHANNEL_RECV_DISC, RfcommRecvDisc},
58     {EV_CHANNEL_RECV_UA, RfcommRecvUa},
59     {EV_CHANNEL_RECV_DM, RfcommRecvDm},
60     {EV_CHANNEL_RECV_PN_REQ, RfcommRecvPnReq},
61     {EV_CHANNEL_RECV_PN_RSP, RfcommRecvPnRsp},
62     {EV_CHANNEL_RECV_MSC_REQ, RfcommRecvMscReq},
63     {EV_CHANNEL_RECV_MSC_RSP, RfcommRecvMscRsp},
64     {EV_CHANNEL_RECV_RPN_CMD, RfcommRecvRpnCmd},
65     {EV_CHANNEL_RECV_RPN_REQ, RfcommRecvRpnReq},
66     {EV_CHANNEL_RECV_RPN_RSP, RfcommRecvRpnRsp},
67     {EV_CHANNEL_RECV_RLS_REQ, RfcommRecvRlsReq},
68     {EV_CHANNEL_RECV_RLS_RSP, RfcommRecvRlsRsp},
69     {EV_CHANNEL_ACCEPT, RfcommRecvAcceptRsp},
70     {EV_CHANNEL_REJECT, RfcommRecvRejectRsp},
71     {EV_CHANNEL_RECV_DATA, RfcommRecvRevData},
72     {EV_CHANNEL_WRITE_DATA, RfcommWriteData},
73     {EV_CHANNEL_SEND_RPN_CMD, RfcommSendRpnCmd},
74     {EV_CHANNEL_SEND_RPN_REQ, RfcommSendRpnReq},
75     {EV_CHANNEL_SEND_RLS_REQ, RfcommSendRlsReq},
76     {EV_CHANNEL_SEND_MSC_REQ, RfcommSendMscReq},
77     {EV_CHANNEL_TIMEOUT, RfcommTimeOut}
78 };
79 
80 /**
81  * @brief State machine for handling events related to data link connection.
82  *
83  * @param channel The pointer of the channel in the channel list.
84  * @param event   The event id.
85  * @param data    Data related to the event.
86  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
87  */
RfcommChannelEvtFsm(RfcommChannelInfo * channel,RfcommChannelEvent event,const void * data)88 int RfcommChannelEvtFsm(RfcommChannelInfo *channel, RfcommChannelEvent event, const void *data)
89 {
90     LOG_INFO("%{public}s event:%{public}d", __func__, event);
91 
92     int ret = 0;
93 
94     for (int cnt = 0; cnt < EV_CHANNEL_EV_MAX; cnt++) {
95         if (g_channelEvtActTbl[cnt].eventId == event) {
96             ret = g_channelEvtActTbl[cnt].fn(channel, data);
97             break;
98         }
99     }
100 
101     return ret;
102 }
103 
104 /**
105  * @brief Processing after receiving connect req event from upper.
106  *
107  * @param channel The pointer of the channel in the channel list.
108  * @param data    Data related to the event.
109  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
110  */
RfcommOpenChannel(RfcommChannelInfo * channel,const void * data)111 int RfcommOpenChannel(RfcommChannelInfo *channel, const void *data)
112 {
113     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
114 
115     (void)data;
116     int ret = 0;
117     uint8_t credits = 0;
118     uint8_t cl = 0;
119     uint8_t scn = channel->scn;
120     RfcommSessionInfo *session = channel->session;
121 
122     switch (channel->channelState) {
123         case ST_CHANNEL_CLOSED:
124             // If session is not connected, connect the session.
125             if (session->sessionState != ST_SESSION_CONNECTED) {
126                 ret = RfcommSessionEvtFsm(session, EV_SESSION_SEND_OPEN_REQ, &scn);
127                 break;
128             }
129             // If session is connected, prepare to connect the DLC.Process PN negotiation firstly.
130             RfcommSetUihPnParameter(session->fcType, 0, PN_REQ, &cl, &credits);
131             channel->localCredit = credits;
132 
133             RfcommSendPnInfo pnInfo;
134             pnInfo.cl = cl;
135             pnInfo.credits = credits;
136             pnInfo.mtu = channel->localMtu;
137             pnInfo.priority = 0;
138             ret = RfcommSendUihPn(session, channel->dlci, true, &pnInfo);
139             channel->channelState = ST_CHANNEL_WAIT_PN_RSP;
140             RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
141             break;
142         case ST_CHANNEL_DISC_REQ_WAIT_UA:
143             channel->channelState = ST_CHANNEL_WAIT_RESTART;
144             break;
145         case ST_CHANNEL_CONNECTED:
146             LOG_DEBUG("%{public}s:DLC is connected.", __func__);
147             break;
148         default:
149             break;
150     }
151 
152     return ret;
153 }
154 
155 /**
156  * @brief Processing after receiving the security check result from GAP.
157  *
158  * @param channel The pointer of the channel in the channel list.
159  * @param data    Data related to the event.
160  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
161  */
RfcommRecvSecurityRslt(RfcommChannelInfo * channel,const void * data)162 int RfcommRecvSecurityRslt(RfcommChannelInfo *channel, const void *data)
163 {
164     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
165 
166     if (data == NULL) {
167         return RFCOMM_ERR_PARAM;
168     }
169 
170     int ret = 0;
171     uint16_t result = *(uint16_t *)data;
172     RfcommSessionInfo *session = channel->session;
173     RfcommConnectedInfo connectedInfo;
174 
175     switch (channel->channelState) {
176         case ST_CHANNEL_CLIENT_WAIT_SECURITY_RESULT:
177             if (result != GAP_SUCCESS) {
178                 channel->channelState = ST_CHANNEL_CLOSED;
179                 RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_FAIL, NULL);
180                 // Release channelinfo.
181                 RfcommRemoveChannel(channel);
182                 // If the last channel on the session is closed, close the session.
183                 RfcommCloseInvalidSession(session);
184                 break;
185             }
186             ret = RfcommSendSabm(session, channel->dlci);
187             channel->channelState = ST_CHANNEL_SABM_REQ_WAIT_UA;
188             RfcommStartChannelTimer(channel, T1_SABM_OPEN_DLC);
189             break;
190         case ST_CHANNEL_SERVER_WAIT_SECURITY_RESULT:
191             // If the security check result is not successful,
192             // then return a connection rejection response to the peer.
193             if (result != GAP_SUCCESS) {
194                 ret = RfcommSendDm(session, channel->dlci, true);
195                 channel->channelState = ST_CHANNEL_CLOSED;
196                 RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_FAIL, NULL);
197                 // Release channelinfo.
198                 RfcommRemoveChannel(channel);
199                 // If the last channel on the session is closed, close the session.
200                 RfcommCloseInvalidSession(session);
201                 break;
202             }
203             // If the result of the security check is successful,
204             // the connection acceptance response is returned to the peer.
205             ret = RfcommSendUa(session, channel->dlci);
206             channel->channelState = ST_CHANNEL_CONNECTED;
207             // After DLC is established, determine the mtu size of the opposite end.
208             RfcommDeterminePeerMtu(channel);
209             (void)memset_s(&connectedInfo, sizeof(RfcommConnectedInfo), 0x00, sizeof(RfcommConnectedInfo));
210             connectedInfo.sendMTU = channel->peerMtu;
211             connectedInfo.recvMTU = channel->localMtu;
212             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_SUCCESS, &connectedInfo);
213             break;
214         default:
215             break;
216     }
217 
218     return ret;
219 }
220 
221 /**
222  * @brief Processing after receiving the UA response from peer.
223  *
224  * @param channel The pointer of the channel in the channel list.
225  * @param data    Data related to the event.
226  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
227  */
RfcommRecvUa(RfcommChannelInfo * channel,const void * data)228 int RfcommRecvUa(RfcommChannelInfo *channel, const void *data)
229 {
230     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
231 
232     (void)data;
233     int ret = 0;
234     uint8_t credits = 0;
235     uint8_t cl = 0;
236     RfcommSessionInfo *session = channel->session;
237     RfcommConnectedInfo connectedInfo;
238     RfcommModemStatusInfo modemStatus;
239     (void)memset_s(&modemStatus, sizeof(modemStatus), 0x00, sizeof(modemStatus));
240 
241     switch (channel->channelState) {
242         case ST_CHANNEL_SABM_REQ_WAIT_UA:
243             // Stop timer.
244             RfcommStopChannelTimer(channel);
245             channel->channelState = ST_CHANNEL_CONNECTED;
246             // After DLC is established, determine the mtu size of the opposite end.
247             RfcommDeterminePeerMtu(channel);
248             // Notify the upper layer that the connection is successful.
249             (void)memset_s(&connectedInfo, sizeof(RfcommConnectedInfo), 0x00, sizeof(RfcommConnectedInfo));
250             connectedInfo.sendMTU = channel->peerMtu;
251             connectedInfo.recvMTU = channel->localMtu;
252             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_SUCCESS, &connectedInfo);
253             // Send MSC command.
254             // In any case MSC commands and responses must be exchanged before
255             // the data transfer may start.Ref-RFCOMM_SPEC_V12(6.3)
256             modemStatus.signals = MSC_RTC | MSC_RTR | MSC_DV;
257             ret = RfcommSendUihMsc(session, channel->dlci, true, &modemStatus);
258             channel->transferReady |= MSC_CMD_SEND;
259             // Start timer.
260             RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
261             break;
262         case ST_CHANNEL_DISC_REQ_WAIT_UA:
263             // Stop timer.
264             RfcommStopChannelTimer(channel);
265             channel->channelState = ST_CHANNEL_CLOSED;
266             // Notify the upper layer that the disconnection is successful.
267             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECT_SUCCESS, NULL);
268             // Release channelinfo.
269             RfcommRemoveChannel(channel);
270             // If the last channel on the session is closed, close the session.
271             RfcommCloseInvalidSession(session);
272             break;
273         case ST_CHANNEL_WAIT_RESTART:
274             RfcommResetChannelInfo(channel);
275             // If session is connected, prepare to connect the DLC.Process PN negotiation first.
276             RfcommSetUihPnParameter(session->fcType, 0, PN_REQ, &cl, &credits);
277             channel->localCredit = credits;
278 
279             RfcommSendPnInfo pnInfo;
280             pnInfo.cl = cl;
281             pnInfo.credits = credits;
282             pnInfo.mtu = channel->localMtu;
283             pnInfo.priority = 0;
284             ret = RfcommSendUihPn(session, channel->dlci, true, &pnInfo);
285             channel->channelState = ST_CHANNEL_WAIT_PN_RSP;
286             RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
287             break;
288         default:
289             break;
290     }
291 
292     return ret;
293 }
294 
295 /**
296  * @brief Processing after receiving the DM response from peer.
297  *
298  * @param channel The pointer of the channel in the channel list.
299  * @param data    Data related to the event.
300  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
301  */
RfcommRecvDm(RfcommChannelInfo * channel,const void * data)302 int RfcommRecvDm(RfcommChannelInfo *channel, const void *data)
303 {
304     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
305 
306     (void)data;
307     RfcommSessionInfo *session = channel->session;
308 
309     if (channel->channelState == ST_CHANNEL_CLOSED) {
310         LOG_DEBUG("%{public}s Channel is restarting.", __func__);
311         return RFCOMM_SUCCESS;
312     }
313 
314     switch (channel->channelState) {
315         case ST_CHANNEL_WAIT_PN_RSP:
316         // fall-through
317         case ST_CHANNEL_SABM_REQ_WAIT_UA:
318             // Stop timer.
319             RfcommStopChannelTimer(channel);
320             channel->channelState = ST_CHANNEL_CLOSED;
321             // Notify the upper layer that the connection is fail.
322             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_FAIL, NULL);
323             break;
324         case ST_CHANNEL_DISC_REQ_WAIT_UA:
325             // Stop timer.
326             RfcommStopChannelTimer(channel);
327             channel->channelState = ST_CHANNEL_CLOSED;
328             // Notify the upper layer that the disconnection is successful.
329             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECT_SUCCESS, NULL);
330             break;
331         case ST_CHANNEL_CONNECTED:
332             // Stop timer.
333             RfcommStopChannelTimer(channel);
334             channel->channelState = ST_CHANNEL_CLOSED;
335             // Notify the upper layer that the channel is disconnected.
336             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECTED, NULL);
337             break;
338         default:
339             break;
340     }
341 
342     // Release channelinfo.
343     RfcommRemoveChannel(channel);
344     // If the last channel on the session is closed, close the session.
345     RfcommCloseInvalidSession(session);
346 
347     return RFCOMM_SUCCESS;
348 }
349 
350 /**
351  * @brief Processing after receiving the RPN commad from peer.
352  *
353  * @param channel The pointer of the channel in the channel list.
354  * @param data    Data related to the event.
355  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
356  */
RfcommRecvRpnCmd(RfcommChannelInfo * channel,const void * data)357 int RfcommRecvRpnCmd(RfcommChannelInfo *channel, const void *data)
358 {
359     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
360 
361     if (data == NULL) {
362         return RFCOMM_ERR_PARAM;
363     }
364 
365     RfcommUihInfo info;
366     (void)memcpy_s(&info, sizeof(RfcommUihInfo), data, sizeof(RfcommUihInfo));
367 
368     channel->portConfig.baudrate = info.rpn.rpnInfo.baudrate;
369     channel->portConfig.data_bits = info.rpn.rpnInfo.data_bits;
370     channel->portConfig.fc = info.rpn.rpnInfo.fc;
371     channel->portConfig.parity = info.rpn.rpnInfo.parity;
372     channel->portConfig.parity_type = info.rpn.rpnInfo.parity_type;
373     channel->portConfig.stop_bit = info.rpn.rpnInfo.stop_bit;
374     channel->portConfig.xoff_char = info.rpn.rpnInfo.xoff_char;
375     channel->portConfig.xon_char = info.rpn.rpnInfo.xon_char;
376     channel->portConfig.parameter_mask1 = info.rpn.rpnInfo.parameter_mask1;
377     channel->portConfig.parameter_mask2 = info.rpn.rpnInfo.parameter_mask2;
378 
379     RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_REMOTE_PORT_CONFIG, &channel->portConfig);
380 
381     return RfcommSendUihRpn(channel->session, channel->dlci, false, &channel->portConfig);
382 }
383 
384 /**
385  * @brief Processing after receiving the RPN request from peer.
386  *
387  * @param channel The pointer of the channel in the channel list.
388  * @param data    Data related to the event.
389  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
390  */
RfcommRecvRpnReq(RfcommChannelInfo * channel,const void * data)391 int RfcommRecvRpnReq(RfcommChannelInfo *channel, const void *data)
392 {
393     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
394 
395     (void)data;
396     RfcommRemotePortConfig portConfig;
397 
398     (void)memcpy_s(&portConfig, sizeof(RfcommRemotePortConfig), &channel->portConfig, sizeof(RfcommRemotePortConfig));
399     portConfig.parameter_mask1 = 0;
400     portConfig.parameter_mask2 = 0;
401 
402     return RfcommSendUihRpn(channel->session, channel->dlci, false, &portConfig);
403 }
404 
405 /**
406  * @brief Processing after receiving the PN request from peer.
407  *
408  * @param channel The pointer of the channel in the channel list.
409  * @param data    Data related to the event.
410  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
411  */
RfcommRecvPnReq(RfcommChannelInfo * channel,const void * data)412 int RfcommRecvPnReq(RfcommChannelInfo *channel, const void *data)
413 {
414     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
415 
416     if (data == NULL) {
417         return RFCOMM_ERR_PARAM;
418     }
419 
420     int ret;
421     uint8_t credits = 0;
422     uint8_t cl = 0;
423     RfcommSessionInfo *session = channel->session;
424     RfcommUihInfo info;
425     (void)memcpy_s(&info, sizeof(RfcommUihInfo), data, sizeof(RfcommUihInfo));
426     RfcommSendPnInfo pnInfo;
427     (void)memset_s(&pnInfo, sizeof(RfcommSendPnInfo), 0x00, sizeof(RfcommSendPnInfo));
428 
429     switch (channel->channelState) {
430         case ST_CHANNEL_CLOSED:
431             // Set flow control type.
432             RfcommSetFlowControlType(session, true, info.pn.cl);
433             // If it is credit-based flow control, then set the initial credits of the peer.
434             if ((session->fcType == FC_TYPE_CREDIT) && (info.pn.cl == CL_REQ_SUPPORT_CREDIT)) {
435                 channel->peerCredit = info.pn.k;
436             }
437             RfcommSetUihPnParameter(session->fcType, info.pn.cl, PN_RSP_BEFORE_CREATE, &cl, &credits);
438             // For a PN command with N1 value of N1c (c for command),
439             // a PN response shall have an N1 value N1r (r for response) where N1r <= N1c.
440             channel->localMtu = (channel->localMtu < info.pn.mtu) ? channel->localMtu : info.pn.mtu;
441             channel->peerMtu = channel->localMtu;
442             // Send PN response to peer.
443             channel->localCredit = credits;
444 
445             pnInfo.cl = cl;
446             pnInfo.credits = credits;
447             pnInfo.mtu = channel->localMtu;
448             pnInfo.priority = info.pn.priority;
449             ret = RfcommSendUihPn(session, channel->dlci, false, &pnInfo);
450             // Waiting peer to send sabm request.
451             channel->channelState = ST_CHANNEL_WAIT_SABM;
452             break;
453         case ST_CHANNEL_DISC_REQ_WAIT_UA:
454             ret = RfcommSendDm(session, channel->dlci, false);
455             break;
456         default:
457             // When DLC is connected or connecting, PN req is received, only return Pn rsp to Peer.
458             RfcommSetUihPnParameter(session->fcType, info.pn.cl, PN_RSP_AFTER_CREATE, &cl, &credits);
459 
460             pnInfo.cl = cl;
461             pnInfo.credits = credits;
462             pnInfo.mtu = channel->localMtu;
463             pnInfo.priority = info.pn.priority;
464             // Send PN response to peer.
465             ret = RfcommSendUihPn(session, channel->dlci, false, &pnInfo);
466             break;
467     }
468 
469     return ret;
470 }
471 
472 /**
473  * @brief Processing after receiving PN response from peer.
474  *
475  * @param channel The pointer of the channel in the channel list.
476  * @param data    Data related to the event.
477  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
478  */
RfcommRecvPnRsp(RfcommChannelInfo * channel,const void * data)479 int RfcommRecvPnRsp(RfcommChannelInfo *channel, const void *data)
480 {
481     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
482 
483     if (data == NULL) {
484         return RFCOMM_ERR_PARAM;
485     }
486 
487     RfcommUihInfo info;
488     (void)memcpy_s(&info, sizeof(RfcommUihInfo), data, sizeof(RfcommUihInfo));
489 
490     if (channel->channelState != ST_CHANNEL_WAIT_PN_RSP) {
491         LOG_DEBUG("%{public}s:State is not WAIT_RSP.", __func__);
492         return RFCOMM_FAILED;
493     }
494 
495     // Stop timer.
496     RfcommStopChannelTimer(channel);
497 
498     // Set flow control type.
499     RfcommSetFlowControlType(channel->session, false, info.pn.cl);
500     // If flow control type is based credit, then set amount of credits issued to the peer.
501     if (channel->session->fcType == FC_TYPE_CREDIT) {
502         channel->peerCredit = info.pn.k;
503     }
504     // A device receiving a PN response may accept N1r and use this value as the
505     // maximum frame data size.If this connection is established,
506     // neither side may send a frame with more than N1r bytes of data
507     channel->localMtu = (channel->localMtu < info.pn.mtu) ? channel->localMtu : info.pn.mtu;
508     channel->peerMtu = channel->localMtu;
509 
510     // Perform security checks before initiating a connection request.
511     channel->channelState = ST_CHANNEL_CLIENT_WAIT_SECURITY_RESULT;
512 
513     return RfcommCheckChannelSecurity(channel, false);
514 }
515 
516 /**
517  * @brief Processing after receiving the SABM request from peer.
518  *
519  * @param channel The pointer of the channel in the channel list.
520  * @param data    Data related to the event.
521  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
522  */
RfcommRecvSabm(RfcommChannelInfo * channel,const void * data)523 int RfcommRecvSabm(RfcommChannelInfo *channel, const void *data)
524 {
525     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
526 
527     (void)data;
528     RfcommIncomingInfo eventInfo;
529     (void)memset_s(&eventInfo, sizeof(eventInfo), 0x00, sizeof(eventInfo));
530 
531     switch (channel->channelState) {
532         case ST_CHANNEL_CLOSED:
533         // fall-through
534         case ST_CHANNEL_WAIT_SABM:
535             (void)memcpy_s(&eventInfo.addr, sizeof(BtAddr), &(channel->session->btAddr), sizeof(BtAddr));
536             eventInfo.scn = channel->dlci >> RFCOMM_DLCI_SHIFT_SCN;
537             // After receiving the connection request from the peer, notify the request to the upper layer,
538             // and wait for the upper layer to accept or reject the connection request response.
539             channel->channelState = ST_CHANNEL_WAIT_UPPER_RESPONSE;
540             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_INCOMING, &eventInfo);
541             break;
542         default:
543             break;
544     }
545 
546     return RFCOMM_SUCCESS;
547 }
548 
549 /**
550  * @brief Processing after receiving the DISC request from peer.
551  *
552  * @param channel The pointer of the channel in the channel list.
553  * @param data    Data related to the event.
554  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
555  */
RfcommRecvDisc(RfcommChannelInfo * channel,const void * data)556 int RfcommRecvDisc(RfcommChannelInfo *channel, const void *data)
557 {
558     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
559 
560     (void)data;
561     int ret = 0;
562     RfcommSessionInfo *session = channel->session;
563 
564     switch (channel->channelState) {
565         case ST_CHANNEL_CLOSED:
566             ret = RfcommSendDm(session, channel->dlci, true);
567             break;
568         case ST_CHANNEL_WAIT_PN_RSP:
569             // Stop timer.
570             RfcommStopChannelTimer(channel);
571             ret = RfcommSendDm(session, channel->dlci, true);
572             channel->channelState = ST_CHANNEL_CLOSED;
573             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_FAIL, NULL);
574             break;
575         case ST_CHANNEL_SABM_REQ_WAIT_UA:
576             // Stop timer.
577             RfcommStopChannelTimer(channel);
578             ret = RfcommSendUa(session, channel->dlci);
579             channel->channelState = ST_CHANNEL_CLOSED;
580             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_CONNECT_FAIL, NULL);
581             break;
582         case ST_CHANNEL_DISC_REQ_WAIT_UA:
583             // Stop timer.
584             RfcommStopChannelTimer(channel);
585             ret = RfcommSendDm(session, channel->dlci, true);
586             channel->channelState = ST_CHANNEL_CLOSED;
587             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECT_SUCCESS, NULL);
588             // Release channelinfo.
589             RfcommRemoveChannel(channel);
590             // If the last channel on the session is closed, close the session.
591             RfcommCloseInvalidSession(session);
592             return ret;
593         case ST_CHANNEL_WAIT_UPPER_RESPONSE:
594         // fall-through
595         case ST_CHANNEL_SERVER_WAIT_SECURITY_RESULT:
596         // fall-through
597         case ST_CHANNEL_CONNECTED:
598             ret = RfcommSendUa(session, channel->dlci);
599             channel->channelState = ST_CHANNEL_CLOSED;
600             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECTED, NULL);
601             break;
602         default:
603             break;
604     }
605 
606     // Release channel resource.
607     RfcommRemoveChannel(channel);
608 
609     return ret;
610 }
611 
612 /**
613  * @brief Processing after receiving the acception response of the connection request from upper.
614  *
615  * @param channel The pointer of the channel in the channel list.
616  * @param data    Data related to the event.
617  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
618  */
RfcommRecvAcceptRsp(RfcommChannelInfo * channel,const void * data)619 int RfcommRecvAcceptRsp(RfcommChannelInfo *channel, const void *data)
620 {
621     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
622 
623     (void)data;
624 
625     if (channel->channelState != ST_CHANNEL_WAIT_UPPER_RESPONSE) {
626         LOG_DEBUG("%{public}s:State is not WAIT_UPPER_RSP.", __func__);
627         return RFCOMM_FAILED;
628     }
629 
630     // Before returning a response to the connection request, perform security check processing.
631     channel->channelState = ST_CHANNEL_SERVER_WAIT_SECURITY_RESULT;
632 
633     return RfcommCheckChannelSecurity(channel, true);
634 }
635 
636 /**
637  * @brief Processing after receiving the rejection response of the connection request from upper.
638  *
639  * @param channel The pointer of the channel in the channel list.
640  * @param data    Data related to the event.
641  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
642  */
RfcommRecvRejectRsp(RfcommChannelInfo * channel,const void * data)643 int RfcommRecvRejectRsp(RfcommChannelInfo *channel, const void *data)
644 {
645     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
646 
647     (void)data;
648     int ret = 0;
649     RfcommSessionInfo *session = channel->session;
650 
651     if (channel->channelState != ST_CHANNEL_WAIT_UPPER_RESPONSE) {
652         LOG_DEBUG("%{public}s:State is not WAIT_UPPER_RSP.", __func__);
653         return ret;
654     }
655     ret = RfcommSendDm(session, channel->dlci, true);
656     // Release channelinfo.
657     RfcommRemoveChannel(channel);
658     // If the last channel on the session is closed, close the session.
659     RfcommCloseInvalidSession(session);
660 
661     return ret;
662 }
663 
664 /**
665  * @brief Processing after receiving the disconnect channel request from upper.
666  *
667  * @param channel The pointer of the channel in the channel list.
668  * @param data    Data related to the event.
669  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
670  */
RfcommCloseChannel(RfcommChannelInfo * channel,const void * data)671 int RfcommCloseChannel(RfcommChannelInfo *channel, const void *data)
672 {
673     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
674 
675     (void)data;
676     int ret = 0;
677     RfcommSessionInfo *session = channel->session;
678 
679     switch (channel->channelState) {
680         case ST_CHANNEL_WAIT_PN_RSP:
681             // Stop timer.
682             RfcommStopChannelTimer(channel);
683             // fall-through
684         case ST_CHANNEL_CLOSED:
685             // fall-through
686         case ST_CHANNEL_CLIENT_WAIT_SECURITY_RESULT:
687             channel->channelState = ST_CHANNEL_CLOSED;
688             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECT_SUCCESS, NULL);
689             // Release channelinfo.
690             RfcommRemoveChannel(channel);
691             // If the last channel on the session is closed, close the session.
692             RfcommCloseInvalidSession(session);
693             break;
694         case ST_CHANNEL_WAIT_UPPER_RESPONSE:
695         // fall-through
696         case ST_CHANNEL_SERVER_WAIT_SECURITY_RESULT:
697             ret = RfcommSendDm(session, channel->dlci, true);
698             channel->channelState = ST_CHANNEL_CLOSED;
699             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_DISCONNECT_SUCCESS, NULL);
700             // Release channelinfo.
701             RfcommRemoveChannel(channel);
702             // If the last channel on the session is closed, close the session.
703             RfcommCloseInvalidSession(session);
704             break;
705         case ST_CHANNEL_DISC_REQ_WAIT_UA:
706             LOG_DEBUG("%{public}s:DLCI(%hhu) is Disconnecting.", __func__, channel->dlci);
707             break;
708         case ST_CHANNEL_SABM_REQ_WAIT_UA:
709             // Stop timer.
710             RfcommStopChannelTimer(channel);
711             // fall-through
712         case ST_CHANNEL_CONNECTED:
713             ret = RfcommSendDisc(session, channel->dlci);
714             channel->channelState = ST_CHANNEL_DISC_REQ_WAIT_UA;
715             RfcommStartChannelTimer(channel, T1_SABM_DISC);
716             break;
717         default:
718             break;
719     }
720     return ret;
721 }
722 
723 /**
724  * @brief Processing after receiving the timeout notification.
725  *
726  * @param channel The pointer of the channel in the channel list.
727  * @param data    Data related to the event.
728  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
729  */
RfcommTimeOut(RfcommChannelInfo * channel,const void * data)730 int RfcommTimeOut(RfcommChannelInfo *channel, const void *data)
731 {
732     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
733 
734     (void)data;
735     uint32_t eventId = 0;
736     RfcommSessionInfo *session = channel->session;
737 
738     switch (channel->channelState) {
739         case ST_CHANNEL_WAIT_PN_RSP:
740         // fall-through
741         case ST_CHANNEL_SABM_REQ_WAIT_UA:
742             eventId = RFCOMM_CHANNEL_EV_CONNECT_FAIL;
743             break;
744         case ST_CHANNEL_DISC_REQ_WAIT_UA:
745             eventId = RFCOMM_CHANNEL_EV_DISCONNECT_SUCCESS;
746             break;
747         case ST_CHANNEL_CONNECTED:
748             eventId = RFCOMM_CHANNEL_EV_DISCONNECTED;
749             break;
750         default:
751             return RFCOMM_SUCCESS;
752     }
753 
754     channel->channelState = ST_CHANNEL_CLOSED;
755     RfcommNotifyEvtToUpper(channel, eventId, NULL);
756     RfcommRemoveChannel(channel);
757 
758     return RfcommSessionEvtFsm(session, EV_SESSION_TIMEOUT, NULL);
759 }
760 
761 /**
762  * @brief Processing after receiving the MSC request from peer.
763  *
764  * @param channel The pointer of the channel in the channel list.
765  * @param data    Data related to the event.
766  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
767  */
RfcommRecvMscReq(RfcommChannelInfo * channel,const void * data)768 int RfcommRecvMscReq(RfcommChannelInfo *channel, const void *data)
769 {
770     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
771 
772     if (data == NULL) {
773         return RFCOMM_ERR_PARAM;
774     }
775 
776     RfcommUihInfo info;
777     RfcommModemStatusInfo modemSts;
778     (void)memset_s(&modemSts, sizeof(modemSts), 0x00, sizeof(modemSts));
779 
780     (void)memcpy_s(&info, sizeof(RfcommUihInfo), data, sizeof(RfcommUihInfo));
781     modemSts.signals = info.msc.signal;
782     modemSts.breakSignal = info.msc.breakSignal;
783     // Send MSC response to the peer.
784     int ret = RfcommSendUihMsc(channel->session, channel->dlci, false, &modemSts);
785 
786     uint8_t oldSt = channel->transferReady;
787     channel->transferReady |= MSC_CMD_RECV;
788     LOG_DEBUG("%{public}s:transferReady State is (%hhu).", __func__, channel->transferReady);
789 
790     // Set peer's modem status.
791     RfcommSetPeerModemStatus(channel, &modemSts);
792     // If MSC cmd has not been sent, send it.
793     // In any case MSC commands and responses must be exchanged before
794     // the data transfer may start.Ref-RFCOMM_SPEC_V12(6.3)
795     if (!(channel->transferReady & MSC_CMD_SEND)) {
796         (void)memset_s(&modemSts, sizeof(modemSts), 0x00, sizeof(modemSts));
797         modemSts.signals = MSC_RTC | MSC_RTR | MSC_DV;
798         ret = RfcommSendUihMsc(channel->session, channel->dlci, true, &modemSts);
799         channel->transferReady |= MSC_CMD_SEND;
800         // Start timer.
801         RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
802     } else if (oldSt == (MSC_CMD_SEND | MSC_RSP_RECV)) {
803         // If the MSC commnd and response have been exchanged,
804         // check whether there is data in the sending buffer queue,
805         // and if there is buffered data, send the data.
806         RfcommSendCachePkt(channel);
807         RfcommSetFlcToUpper(channel);
808     }
809 
810     return ret;
811 }
812 
813 /**
814  * @brief Processing after receiving the MSC response from peer.
815  *
816  * @param channel The pointer of the channel in the channel list.
817  * @param data    Data related to the event.
818  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
819  */
RfcommRecvMscRsp(RfcommChannelInfo * channel,const void * data)820 int RfcommRecvMscRsp(RfcommChannelInfo *channel, const void *data)
821 {
822     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
823 
824     (void)data;
825 
826     if (channel->channelState != ST_CHANNEL_CONNECTED) {
827         LOG_DEBUG("%{public}s:State is not connected.", __func__);
828         return RFCOMM_ERR_NOT_CONNECTED;
829     }
830 
831     // Stop timer.
832     RfcommStopChannelTimer(channel);
833 
834     uint8_t oldSt = channel->transferReady;
835     channel->transferReady |= MSC_RSP_RECV;
836 
837     LOG_DEBUG("%{public}s:transferReady State is (%hhu).", __func__, channel->transferReady);
838 
839     // If the MSC commnd and response have been exchanged,
840     // check whether there is data in the sending buffer queue,
841     // and if there is buffered data, send the data.
842     if (oldSt == (MSC_CMD_SEND | MSC_CMD_RECV)) {
843         RfcommSendCachePkt(channel);
844         RfcommSetFlcToUpper(channel);
845     }
846 
847     return RFCOMM_SUCCESS;
848 }
849 
850 /**
851  * @brief Processing after receiving the RPN response from peer.
852  *
853  * @param channel The pointer of the channel in the channel list.
854  * @param data    Data related to the event.
855  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
856  */
RfcommRecvRpnRsp(RfcommChannelInfo * channel,const void * data)857 int RfcommRecvRpnRsp(RfcommChannelInfo *channel, const void *data)
858 {
859     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
860 
861     (void)data;
862 
863     RfcommStopChannelTimer(channel);
864 
865     return RFCOMM_SUCCESS;
866 }
867 
868 /**
869  * @brief Processing after receiving the RLS request from peer.
870  *
871  * @param channel The pointer of the channel in the channel list.
872  * @param data    Data related to the event.
873  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
874  */
RfcommRecvRlsReq(RfcommChannelInfo * channel,const void * data)875 int RfcommRecvRlsReq(RfcommChannelInfo *channel, const void *data)
876 {
877     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
878 
879     if (data == NULL) {
880         return RFCOMM_ERR_PARAM;
881     }
882 
883     RfcommUihInfo info;
884     RfcommRemoteLineStatus lineStatus;
885     (void)memcpy_s(&info, sizeof(RfcommUihInfo), data, sizeof(RfcommUihInfo));
886     (void)memset_s(&lineStatus, sizeof(RfcommRemoteLineStatus), 0x00, sizeof(RfcommRemoteLineStatus));
887 
888     lineStatus.overrunErr = info.rls.lineStatus >> RFCOMM_RLS_SHIFT_OVERRUN;
889     lineStatus.parityErr = info.rls.lineStatus >> RFCOMM_RLS_SHIFT_PARITY;
890     lineStatus.frameErr = info.rls.lineStatus >> RFCOMM_RLS_SHIFT_FRAMING;
891 
892     RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_REMOTE_LINE_STATUS, &lineStatus);
893 
894     return RfcommSendUihRls(channel->session, channel->dlci, false, info.rls.lineStatus);
895 }
896 
897 /**
898  * @brief Processing after receiving the RLS response from peer.
899  *
900  * @param channel The pointer of the channel in the channel list.
901  * @param data    Data related to the event.
902  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
903  */
RfcommRecvRlsRsp(RfcommChannelInfo * channel,const void * data)904 int RfcommRecvRlsRsp(RfcommChannelInfo *channel, const void *data)
905 {
906     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
907 
908     (void)data;
909 
910     RfcommStopChannelTimer(channel);
911 
912     return RFCOMM_SUCCESS;
913 }
914 
915 /**
916  * @brief Processing after receiving the transmit information from peer.
917  *
918  * @param channel The pointer of the channel in the channel list.
919  * @param data    Data related to the event.
920  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
921  */
RfcommRecvRevData(RfcommChannelInfo * channel,const void * data)922 int RfcommRecvRevData(RfcommChannelInfo *channel, const void *data)
923 {
924     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
925 
926     if (data == NULL) {
927         return RFCOMM_ERR_PARAM;
928     }
929 
930     Packet *pkt = NULL;
931     RfcommUihInfo info;
932     (void)memcpy_s(&info, sizeof(RfcommUihInfo), data, sizeof(RfcommUihInfo));
933 
934     if (channel->channelState != ST_CHANNEL_CONNECTED) {
935         LOG_DEBUG("%{public}s Channel is not connected.", __func__);
936         return RfcommSendDm(channel->session, channel->dlci, false);
937     }
938 
939     if (info.data.size > 0) {
940         RfcommReadLock();
941         uint8_t count = (uint8_t)ListGetSize(channel->recvQueue);
942         if (count < MAX_QUEUE_COUNT) {
943             pkt = PacketRefMalloc(info.data.payload);
944             ListAddLast(channel->recvQueue, pkt);
945             RfcommReadUnlock();
946 
947             RfcommNotifyEvtToUpper(channel, RFCOMM_CHANNEL_EV_REV_DATA, NULL);
948             RfcommSetFlcToPeer(channel, false);
949         } else {
950             RfcommReadUnlock();
951         }
952     }
953 
954     if (info.data.credits > 0) {
955         channel->peerCredit += info.data.credits;
956         RfcommSendCachePkt(channel);
957         RfcommSetFlcToUpper(channel);
958     }
959 
960     return RFCOMM_SUCCESS;
961 }
962 
963 /**
964  * @brief Processing after receiving the write transmit information from upper.
965  *
966  * @param channel The pointer of the channel in the channel list.
967  * @param data    Data related to the event.
968  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
969  */
RfcommWriteData(RfcommChannelInfo * channel,const void * data)970 int RfcommWriteData(RfcommChannelInfo *channel, const void *data)
971 {
972     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
973 
974     uint8_t newCredits = 0;
975     Packet *refpkt = NULL;
976     RfcommSessionInfo *session = channel->session;
977 
978     // If it is currently in the process of disconnection, no data will be sent.
979     if (channel->channelState == ST_CHANNEL_DISC_REQ_WAIT_UA || channel->channelState == ST_CHANNEL_CLOSED) {
980         return RFCOMM_ERR_NOT_CONNECTED;
981     }
982     // Determine whether the peer can receive the data. If the peer cannot receive the data,
983     // save the data in the queue to be sent.
984     if (((session->fcType == FC_TYPE_CREDIT) && (channel->peerCredit == 0)) ||
985         (channel->transferReady != TRANSFER_READY) || channel->peerChannelFc || (session->peerSessionFc)) {
986         // Get send list's count
987         uint8_t count = (uint8_t)ListGetSize(channel->sendQueue);
988         if (count < MAX_QUEUE_COUNT) {
989             refpkt = PacketRefMalloc((Packet *)data);
990             ListAddLast(channel->sendQueue, (void *)refpkt);
991             return RFCOMM_SUCCESS;
992         }
993         channel->localFcToUpper = true;
994         return RFCOMM_QUEUE_FULL;
995     }
996     if (session->fcType == FC_TYPE_CREDIT) {
997         // The value of the credit octet (0 - 255) signifies a number of frames,
998         // for which the sender now has buffer space available to receive on the DLC.
999         newCredits = channel->localCreditMax - channel->localCredit;
1000         channel->localCredit += newCredits;
1001     }
1002 
1003     // Add transmite data bytes value.
1004     channel->transmittedBytes += PacketPayloadSize((Packet *)data);
1005     // Send data to peer.
1006     int ret = RfcommSendUihData(session, channel->dlci, newCredits, (Packet *)data);
1007     // Decrease credit count.
1008     if ((session->fcType == FC_TYPE_CREDIT) && (ret == RFCOMM_SUCCESS)) {
1009         if (channel->peerCredit > 0) {
1010             channel->peerCredit--;
1011         }
1012     }
1013     return ret;
1014 }
1015 
1016 /**
1017  * @brief Send rpn command to peer.
1018  *
1019  * @param channel The pointer of the channel in the channel list.
1020  * @param data    Data related to the event.
1021  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
1022  */
RfcommSendRpnCmd(RfcommChannelInfo * channel,const void * data)1023 int RfcommSendRpnCmd(RfcommChannelInfo *channel, const void *data)
1024 {
1025     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
1026 
1027     if (data == NULL) {
1028         return RFCOMM_ERR_PARAM;
1029     }
1030 
1031     int ret = RfcommSendUihRpn(channel->session, channel->dlci, true, (RfcommRemotePortConfig *)data);
1032 
1033     // Start timer.
1034     RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
1035 
1036     return ret;
1037 }
1038 
1039 /**
1040  * @brief Send rpn request to peer.
1041  *
1042  * @param channel The pointer of the channel in the channel list.
1043  * @param data    Data related to the event.
1044  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
1045  */
RfcommSendRpnReq(RfcommChannelInfo * channel,const void * data)1046 int RfcommSendRpnReq(RfcommChannelInfo *channel, const void *data)
1047 {
1048     LOG_INFO("%{public}s channel state is:%{public}d.", __func__, channel->channelState);
1049 
1050     (void)data;
1051 
1052     int ret = RfcommSendUihRpn(channel->session, channel->dlci, true, NULL);
1053 
1054     // Start timer.
1055     RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
1056 
1057     return ret;
1058 }
1059 
1060 /**
1061  * @brief Send rls request to peer.
1062  *
1063  * @param channel The pointer of the channel in the channel list.
1064  * @param data    Data related to the event.
1065  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
1066  */
RfcommSendRlsReq(RfcommChannelInfo * channel,const void * data)1067 int RfcommSendRlsReq(RfcommChannelInfo *channel, const void *data)
1068 {
1069     LOG_INFO("%{public}s", __func__);
1070 
1071     if (data == NULL) {
1072         return RFCOMM_ERR_PARAM;
1073     }
1074 
1075     RfcommRemoteLineStatus *lineStatus = (RfcommRemoteLineStatus *)data;
1076 
1077     uint8_t status = lineStatus->overrunErr ? OVERRUN_ERROR : 0;
1078     status |= lineStatus->parityErr ? PARITY_ERROR : 0;
1079     status |= lineStatus->frameErr ? FRAMING_ERROR : 0;
1080 
1081     if (status) {
1082         status = (status << 1) | 0x01;
1083     }
1084 
1085     int ret = RfcommSendUihRls(channel->session, channel->dlci, true, status);
1086 
1087     // Start timer.
1088     RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
1089 
1090     return ret;
1091 }
1092 
1093 /**
1094  * @brief Send modem status request.
1095  *
1096  * @param channel The pointer of the channel in the channel list.
1097  * @param data    Data related to the event.
1098  * @return Returns <b>RFCOMM_SUCCESS</b> if the operation is successful, otherwise the operation fails.
1099  */
RfcommSendMscReq(RfcommChannelInfo * channel,const void * data)1100 int RfcommSendMscReq(RfcommChannelInfo *channel, const void *data)
1101 {
1102     LOG_INFO("%{public}s", __func__);
1103 
1104     if (data == NULL) {
1105         return RFCOMM_ERR_PARAM;
1106     }
1107 
1108     RfcommModemStatus *modemSts = (RfcommModemStatus *)data;
1109     RfcommModemStatusInfo status;
1110     (void)memset_s(&status, sizeof(RfcommModemStatusInfo), 0x00, sizeof(RfcommModemStatusInfo));
1111 
1112     status.signals = modemSts->fc ? MSC_FC : 0;
1113     status.signals |= modemSts->rtc ? MSC_RTC : 0;
1114     status.signals |= modemSts->rtr ? MSC_RTR : 0;
1115     status.signals |= modemSts->ic ? MSC_IC : 0;
1116     status.signals |= modemSts->dv ? MSC_DV : 0;
1117 
1118     status.breakSignal = modemSts->break_signal ? MSC_BREAK : 0;
1119     status.breakSignal |= modemSts->break_length << RFCOMM_MSC_SHIFT_BREAKLEN;
1120 
1121     int ret = RfcommSendUihMsc(channel->session, channel->dlci, true, &status);
1122     channel->transferReady |= MSC_CMD_SEND;
1123 
1124     // Start timer.
1125     RfcommStartChannelTimer(channel, T2_UIH_DLCI0);
1126 
1127     return ret;
1128 }
1129 
1130 /**
1131  * @brief Set UIH PN request or response parameter.
1132  *
1133  * @param fcType  Flow control type.
1134  * @param reqCl   The cl value of the pn request.
1135  * @param cmdKind Pn command kind.
1136  * @param cl      The cl value that will be sent to peer.
1137  * @param credits The initial credits that will be sent to peer.
1138  */
RfcommSetUihPnParameter(RfcommFlowControlType fcType,uint8_t reqCl,RfcommPnCmdKind cmdKind,uint8_t * cl,uint8_t * credits)1139 void RfcommSetUihPnParameter(
1140     RfcommFlowControlType fcType, uint8_t reqCl, RfcommPnCmdKind cmdKind, uint8_t *cl, uint8_t *credits)
1141 {
1142     LOG_INFO("%{public}s fcType:%{public}d, req_cl:%hhu, cmdKind:%{public}d.", __func__, fcType, reqCl, cmdKind);
1143 
1144     switch (cmdKind) {
1145         case PN_REQ:
1146             // If the flow control type is not set, the credit-based flow control type is supported by default.
1147             // The initiator has to try to turn on the use of credit based flow control.
1148             if ((fcType == FC_TYPE_UNKNOWN) || (fcType == FC_TYPE_CREDIT)) {
1149                 *cl = CL_REQ_SUPPORT_CREDIT;
1150                 *credits = DEFAULT_CREDITS_VALUE;
1151             } else {
1152                 *cl = CL_REQ_UNSUPPORTED_CREDIT;
1153                 *credits = 0;
1154             }
1155             break;
1156         case PN_RSP_BEFORE_CREATE:
1157             // A responding implementation shall set this field in the PN response to 14 (0xE),
1158             // if (and only if) the value in the PN request was 15.
1159             if ((fcType == FC_TYPE_CREDIT) && (reqCl == CL_REQ_SUPPORT_CREDIT)) {
1160                 *cl = CL_RSP_SUPPORT_CREDIT;
1161                 *credits = DEFAULT_CREDITS_VALUE;
1162             } else {
1163                 *cl = CL_RSP_UNSUPPORTED_CREDIT;
1164                 *credits = 0;
1165             }
1166             break;
1167         case PN_RSP_AFTER_CREATE:
1168             // After the DLC is established, the responder of a PN request may
1169             // refuse to change any parameters.
1170             // it is not possible to “set initial credits” more than once per DLC activation.
1171             *credits = 0;
1172             if (reqCl == CL_REQ_SUPPORT_CREDIT) {
1173                 LOG_DEBUG("%{public}s:Peer's cl value is wrong.", __func__);
1174                 *cl = CL_RSP_SUPPORT_CREDIT;
1175             } else {
1176                 *cl = CL_RSP_UNSUPPORTED_CREDIT;
1177             }
1178             break;
1179         default:
1180             LOG_ERROR("%{public}s:Error cmd kind.", __func__);
1181             break;
1182     }
1183 }