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 }