1 /******************************************************************************
2  *
3  *  Copyright 1999-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains functions to send TS 07.10 frames
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "rfcomm"
26 
27 #include <bluetooth/log.h>
28 
29 #include <cstdint>
30 
31 #include "os/logging/log_adapter.h"
32 #include "osi/include/allocator.h"
33 #include "stack/include/bt_hdr.h"
34 #include "stack/include/rfcdefs.h"
35 #include "stack/rfcomm/port_int.h"
36 #include "stack/rfcomm/rfc_int.h"
37 
38 using namespace bluetooth;
39 
40 /*******************************************************************************
41  *
42  * Function         rfc_send_sabme
43  *
44  * Description      This function sends SABME frame.
45  *
46  ******************************************************************************/
rfc_send_sabme(tRFC_MCB * p_mcb,uint8_t dlci)47 void rfc_send_sabme(tRFC_MCB* p_mcb, uint8_t dlci) {
48   uint8_t* p_data;
49   uint8_t cr = RFCOMM_CR(p_mcb->is_initiator, true);
50   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
51 
52   p_buf->offset = L2CAP_MIN_OFFSET;
53   p_data = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
54 
55   /* SABME frame, command, PF = 1, dlci */
56   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
57   *p_data++ = RFCOMM_SABME | RFCOMM_PF;
58   *p_data++ = RFCOMM_EA | 0;
59 
60   *p_data = RFCOMM_SABME_FCS((uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
61 
62   p_buf->len = 4;
63 
64   rfc_check_send_cmd(p_mcb, p_buf);
65 }
66 
67 /*******************************************************************************
68  *
69  * Function         rfc_send_ua
70  *
71  * Description      This function sends UA frame.
72  *
73  ******************************************************************************/
rfc_send_ua(tRFC_MCB * p_mcb,uint8_t dlci)74 void rfc_send_ua(tRFC_MCB* p_mcb, uint8_t dlci) {
75   uint8_t* p_data;
76   uint8_t cr = RFCOMM_CR(p_mcb->is_initiator, false);
77   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
78 
79   p_buf->offset = L2CAP_MIN_OFFSET;
80   p_data = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
81 
82   /* ua frame, response, PF = 1, dlci */
83   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
84   *p_data++ = RFCOMM_UA | RFCOMM_PF;
85   *p_data++ = RFCOMM_EA | 0;
86 
87   *p_data = RFCOMM_UA_FCS((uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
88 
89   p_buf->len = 4;
90 
91   rfc_check_send_cmd(p_mcb, p_buf);
92 }
93 
94 /*******************************************************************************
95  *
96  * Function         rfc_send_dm
97  *
98  * Description      This function sends DM frame.
99  *
100  ******************************************************************************/
rfc_send_dm(tRFC_MCB * p_mcb,uint8_t dlci,bool pf)101 void rfc_send_dm(tRFC_MCB* p_mcb, uint8_t dlci, bool pf) {
102   uint8_t* p_data;
103   uint8_t cr = RFCOMM_CR(p_mcb->is_initiator, false);
104   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
105 
106   p_buf->offset = L2CAP_MIN_OFFSET;
107   p_data = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
108 
109   /* DM frame, response, PF = 1, dlci */
110   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
111   *p_data++ = RFCOMM_DM | ((pf) ? RFCOMM_PF : 0);
112   *p_data++ = RFCOMM_EA | 0;
113 
114   *p_data = RFCOMM_DM_FCS((uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
115 
116   p_buf->len = 4;
117 
118   rfc_check_send_cmd(p_mcb, p_buf);
119 }
120 
121 /*******************************************************************************
122  *
123  * Function         rfc_send_disc
124  *
125  * Description      This function sends DISC frame.
126  *
127  ******************************************************************************/
rfc_send_disc(tRFC_MCB * p_mcb,uint8_t dlci)128 void rfc_send_disc(tRFC_MCB* p_mcb, uint8_t dlci) {
129   uint8_t* p_data;
130   uint8_t cr = RFCOMM_CR(p_mcb->is_initiator, true);
131   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
132 
133   p_buf->offset = L2CAP_MIN_OFFSET;
134   p_data = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
135 
136   /* DISC frame, command, PF = 1, dlci */
137   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
138   *p_data++ = RFCOMM_DISC | RFCOMM_PF;
139   *p_data++ = RFCOMM_EA | 0;
140 
141   *p_data = RFCOMM_DISC_FCS((uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
142 
143   p_buf->len = 4;
144 
145   rfc_check_send_cmd(p_mcb, p_buf);
146 }
147 
148 /*******************************************************************************
149  *
150  * Function         rfc_send_buf_uih
151  *
152  * Description      This function sends UIH frame.
153  *
154  ******************************************************************************/
rfc_send_buf_uih(tRFC_MCB * p_mcb,uint8_t dlci,BT_HDR * p_buf)155 void rfc_send_buf_uih(tRFC_MCB* p_mcb, uint8_t dlci, BT_HDR* p_buf) {
156   uint8_t* p_data;
157   uint8_t cr = RFCOMM_CR(p_mcb->is_initiator, true);
158   uint8_t credits;
159 
160   p_buf->offset -= RFCOMM_CTRL_FRAME_LEN;
161   if (p_buf->len > 127) {
162     p_buf->offset--;
163   }
164 
165   if (dlci) {
166     credits = (uint8_t)p_buf->layer_specific;
167   } else {
168     credits = 0;
169   }
170 
171   if (credits) {
172     p_buf->offset--;
173   }
174 
175   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
176 
177   /* UIH frame, command, PF = 0, dlci */
178   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
179   *p_data++ = RFCOMM_UIH | ((credits) ? RFCOMM_PF : 0);
180   if (p_buf->len <= 127) {
181     *p_data++ = RFCOMM_EA | (p_buf->len << 1);
182     p_buf->len += 3;
183   } else {
184     *p_data++ = (p_buf->len & 0x7f) << 1;
185     *p_data++ = p_buf->len >> RFCOMM_SHIFT_LENGTH2;
186     p_buf->len += 4;
187   }
188 
189   if (credits) {
190     *p_data++ = credits;
191     p_buf->len++;
192   }
193 
194   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len++;
195 
196   *p_data = RFCOMM_UIH_FCS((uint8_t*)(p_buf + 1) + p_buf->offset, dlci);
197 
198   if (dlci == RFCOMM_MX_DLCI) {
199     rfc_check_send_cmd(p_mcb, p_buf);
200   } else {
201     uint16_t len = p_buf->len;
202     if (stack::l2cap::get_interface().L2CA_DataWrite(p_mcb->lcid, p_buf) !=
203         tL2CAP_DW_RESULT::SUCCESS) {
204       log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_mcb->bd_addr, p_mcb->lcid,
205                 len);
206     }
207   }
208 }
209 
210 /*******************************************************************************
211  *
212  * Function         rfc_send_pn
213  *
214  * Description      This function sends DLC Parameters Negotiation Frame.
215  *
216  ******************************************************************************/
rfc_send_pn(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,uint16_t mtu,uint8_t cl,uint8_t k)217 void rfc_send_pn(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command, uint16_t mtu, uint8_t cl,
218                  uint8_t k) {
219   uint8_t* p_data;
220   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
221 
222   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
223   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
224 
225   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_PN;
226   *p_data++ = RFCOMM_EA | (RFCOMM_MX_PN_LEN << 1);
227 
228   *p_data++ = dlci;
229   *p_data++ = RFCOMM_PN_FRAM_TYPE_UIH | cl;
230 
231   /* It appeared that we need to reply with the same priority bits as we
232    *received.
233    ** We will use the fact that we reply in the same context so rx_frame can
234    *still be used.
235    */
236   if (is_command) {
237     *p_data++ = RFCOMM_PN_PRIORITY_0;
238   } else {
239     *p_data++ = rfc_cb.rfc.rx_frame.u.pn.priority;
240   }
241   *p_data++ = RFCOMM_T1_DSEC;
242   *p_data++ = mtu & 0xFF;
243   *p_data++ = mtu >> 8;
244   *p_data++ = RFCOMM_N2;
245   *p_data = k;
246 
247   /* Total length is sizeof PN data + mx header 2 */
248   p_buf->len = RFCOMM_MX_PN_LEN + 2;
249 
250   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
251 }
252 
253 /*******************************************************************************
254  *
255  * Function         rfc_send_fcon
256  *
257  * Description      This function sends Flow Control On Command.
258  *
259  ******************************************************************************/
rfc_send_fcon(tRFC_MCB * p_mcb,bool is_command)260 void rfc_send_fcon(tRFC_MCB* p_mcb, bool is_command) {
261   uint8_t* p_data;
262   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
263 
264   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
265   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
266 
267   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCON;
268   *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCON_LEN << 1);
269 
270   /* Total length is sizeof FCON data + mx header 2 */
271   p_buf->len = RFCOMM_MX_FCON_LEN + 2;
272 
273   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
274 }
275 
276 /*******************************************************************************
277  *
278  * Function         rfc_send_fcoff
279  *
280  * Description      This function sends Flow Control Off Command.
281  *
282  ******************************************************************************/
rfc_send_fcoff(tRFC_MCB * p_mcb,bool is_command)283 void rfc_send_fcoff(tRFC_MCB* p_mcb, bool is_command) {
284   uint8_t* p_data;
285   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
286 
287   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
288   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
289 
290   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCOFF;
291   *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCOFF_LEN << 1);
292 
293   /* Total length is sizeof FCOFF data + mx header 2 */
294   p_buf->len = RFCOMM_MX_FCOFF_LEN + 2;
295 
296   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
297 }
298 
299 /*******************************************************************************
300  *
301  * Function         rfc_send_msc
302  *
303  * Description      This function sends Modem Status Command Frame.
304  *
305  ******************************************************************************/
rfc_send_msc(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,tPORT_CTRL * p_pars)306 void rfc_send_msc(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command, tPORT_CTRL* p_pars) {
307   uint8_t* p_data;
308   uint8_t signals;
309   uint8_t break_duration;
310   uint8_t len;
311   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
312 
313   signals = p_pars->modem_signal;
314   break_duration = p_pars->break_signal;
315 
316   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
317   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
318 
319   if (break_duration) {
320     len = RFCOMM_MX_MSC_LEN_WITH_BREAK;
321   } else {
322     len = RFCOMM_MX_MSC_LEN_NO_BREAK;
323   }
324 
325   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_MSC;
326   *p_data++ = RFCOMM_EA | (len << 1);
327 
328   *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
329   *p_data++ = RFCOMM_EA | ((p_pars->fc) ? RFCOMM_MSC_FC : 0) |
330               ((signals & MODEM_SIGNAL_DTRDSR) ? RFCOMM_MSC_RTC : 0) |
331               ((signals & MODEM_SIGNAL_RTSCTS) ? RFCOMM_MSC_RTR : 0) |
332               ((signals & MODEM_SIGNAL_RI) ? RFCOMM_MSC_IC : 0) |
333               ((signals & MODEM_SIGNAL_DCD) ? RFCOMM_MSC_DV : 0);
334 
335   if (break_duration) {
336     *p_data++ =
337             RFCOMM_EA | RFCOMM_MSC_BREAK_PRESENT_MASK | (break_duration << RFCOMM_MSC_SHIFT_BREAK);
338   }
339 
340   /* Total length is sizeof MSC data + mx header 2 */
341   p_buf->len = len + 2;
342 
343   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
344 }
345 
346 /*******************************************************************************
347  *
348  * Function         rfc_send_rls
349  *
350  * Description      This function sends Remote Line Status Command Frame.
351  *
352  ******************************************************************************/
rfc_send_rls(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,uint8_t status)353 void rfc_send_rls(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command, uint8_t status) {
354   uint8_t* p_data;
355   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
356 
357   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
358   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
359 
360   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RLS;
361   *p_data++ = RFCOMM_EA | (RFCOMM_MX_RLS_LEN << 1);
362 
363   *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
364   *p_data++ = RFCOMM_RLS_ERROR | status;
365 
366   /* Total length is sizeof RLS data + mx header 2 */
367   p_buf->len = RFCOMM_MX_RLS_LEN + 2;
368 
369   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
370 }
371 
372 /*******************************************************************************
373  *
374  * Function         rfc_send_nsc
375  *
376  * Description      This function sends Non Supported Command Response.
377  *
378  ******************************************************************************/
rfc_send_nsc(tRFC_MCB * p_mcb)379 static void rfc_send_nsc(tRFC_MCB* p_mcb) {
380   uint8_t* p_data;
381   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
382 
383   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
384   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
385 
386   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(false) | RFCOMM_MX_NSC;
387   *p_data++ = RFCOMM_EA | (RFCOMM_MX_NSC_LEN << 1);
388 
389   *p_data++ = rfc_cb.rfc.rx_frame.ea | (rfc_cb.rfc.rx_frame.cr << RFCOMM_SHIFT_CR) |
390               rfc_cb.rfc.rx_frame.type;
391 
392   /* Total length is sizeof NSC data + mx header 2 */
393   p_buf->len = RFCOMM_MX_NSC_LEN + 2;
394 
395   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
396 }
397 
398 /*******************************************************************************
399  *
400  * Function         rfc_send_rpn
401  *
402  * Description      This function sends Remote Port Negotiation Command
403  *
404  ******************************************************************************/
rfc_send_rpn(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,PortSettings * p_settings,uint16_t mask)405 void rfc_send_rpn(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command, PortSettings* p_settings,
406                   uint16_t mask) {
407   uint8_t* p_data;
408   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
409 
410   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
411   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
412 
413   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RPN;
414 
415   if (!p_settings) {
416     *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_REQ_LEN << 1);
417 
418     *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
419 
420     p_buf->len = RFCOMM_MX_RPN_REQ_LEN + 2;
421   } else {
422     *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_LEN << 1);
423 
424     *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
425     *p_data++ = p_settings->baud_rate;
426     *p_data++ = (p_settings->byte_size << RFCOMM_RPN_BITS_SHIFT) |
427                 (p_settings->stop_bits << RFCOMM_RPN_STOP_BITS_SHIFT) |
428                 (p_settings->parity << RFCOMM_RPN_PARITY_SHIFT) |
429                 (p_settings->parity_type << RFCOMM_RPN_PARITY_TYPE_SHIFT);
430     *p_data++ = p_settings->fc_type;
431     *p_data++ = p_settings->xon_char;
432     *p_data++ = p_settings->xoff_char;
433     *p_data++ = (mask & 0xFF);
434     *p_data++ = (mask >> 8);
435 
436     /* Total length is sizeof RPN data + mx header 2 */
437     p_buf->len = RFCOMM_MX_RPN_LEN + 2;
438   }
439 
440   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
441 }
442 
443 /*******************************************************************************
444  *
445  * Function         rfc_send_test
446  *
447  * Description      This function sends Test frame.
448  *
449  ******************************************************************************/
rfc_send_test(tRFC_MCB * p_mcb,bool is_command,BT_HDR * p_buf)450 void rfc_send_test(tRFC_MCB* p_mcb, bool is_command, BT_HDR* p_buf) {
451   /* Shift buffer to give space for header */
452   if (p_buf->offset < (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2)) {
453     uint8_t* p_src = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len - 1;
454     BT_HDR* p_new_buf = (BT_HDR*)osi_malloc(
455             p_buf->len + (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2 + sizeof(BT_HDR) + 1));
456 
457     p_new_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
458     p_new_buf->len = p_buf->len;
459 
460     uint8_t* p_dest = (uint8_t*)(p_new_buf + 1) + p_new_buf->offset + p_new_buf->len - 1;
461 
462     for (uint16_t xx = 0; xx < p_buf->len; xx++) {
463       *p_dest-- = *p_src--;
464     }
465 
466     osi_free(p_buf);
467     p_buf = p_new_buf;
468   }
469 
470   /* Adjust offset by number of bytes we are going to fill */
471   p_buf->offset -= 2;
472   uint8_t* p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
473 
474   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_TEST;
475   *p_data++ = RFCOMM_EA | (p_buf->len << 1);
476 
477   p_buf->len += 2;
478 
479   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
480 }
481 
482 /*******************************************************************************
483  *
484  * Function         rfc_send_credit
485  *
486  * Description      This function sends a flow control credit in UIH frame.
487  *
488  ******************************************************************************/
rfc_send_credit(tRFC_MCB * p_mcb,uint8_t dlci,uint8_t credit)489 void rfc_send_credit(tRFC_MCB* p_mcb, uint8_t dlci, uint8_t credit) {
490   uint8_t* p_data;
491   uint8_t cr = RFCOMM_CR(p_mcb->is_initiator, true);
492   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
493 
494   p_buf->offset = L2CAP_MIN_OFFSET;
495   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
496 
497   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
498   *p_data++ = RFCOMM_UIH | RFCOMM_PF;
499   *p_data++ = RFCOMM_EA | 0;
500   *p_data++ = credit;
501   *p_data = RFCOMM_UIH_FCS((uint8_t*)(p_buf + 1) + p_buf->offset, dlci);
502 
503   p_buf->len = 5;
504 
505   rfc_check_send_cmd(p_mcb, p_buf);
506 }
507 
508 /*******************************************************************************
509  *
510  * Function         rfc_parse_data
511  *
512  * Description      This function processes data packet received from L2CAP
513  *
514  ******************************************************************************/
rfc_parse_data(tRFC_MCB * p_mcb,MX_FRAME * p_frame,BT_HDR * p_buf)515 tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) {
516   uint8_t ead, eal, fcs;
517   uint8_t* p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
518   uint8_t* p_start = p_data;
519   uint16_t len;
520 
521   if (p_buf->len < RFCOMM_CTRL_FRAME_LEN) {
522     log::error("Bad Length1: {}", p_buf->len);
523     return RFC_EVENT_BAD_FRAME;
524   }
525 
526   RFCOMM_PARSE_CTRL_FIELD(ead, p_frame->cr, p_frame->dlci, p_data);
527   if (!ead) {
528     log::error("Bad Address(EA must be 1)");
529     return RFC_EVENT_BAD_FRAME;
530   }
531   RFCOMM_PARSE_TYPE_FIELD(p_frame->type, p_frame->pf, p_data);
532 
533   eal = *(p_data)&RFCOMM_EA;
534   len = *(p_data)++ >> RFCOMM_SHIFT_LENGTH1;
535   if (eal == 0 && p_buf->len > RFCOMM_CTRL_FRAME_LEN) {
536     len += (*(p_data)++ << RFCOMM_SHIFT_LENGTH2);
537   } else if (eal == 0) {
538     log::error("Bad Length when EAL = 0: {}", p_buf->len);
539     return RFC_EVENT_BAD_FRAME;
540   }
541 
542   if (p_buf->len < (3 + !ead + !eal + 1)) {
543     log::error("Bad Length: {}", p_buf->len);
544     return RFC_EVENT_BAD_FRAME;
545   }
546   p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */
547   p_buf->offset += (3 + !ead + !eal);
548 
549   /* handle credit if credit based flow control */
550   if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) &&
551       (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1)) {
552     if (p_buf->len < sizeof(uint8_t)) {
553       log::error("Bad Length in flow control: {}", p_buf->len);
554       return RFC_EVENT_BAD_FRAME;
555     }
556     p_frame->credit = *p_data++;
557     p_buf->len--;
558     p_buf->offset++;
559   } else {
560     p_frame->credit = 0;
561   }
562 
563   if (p_buf->len != len) {
564     log::error("Bad Length2 {} {}", p_buf->len, len);
565     return RFC_EVENT_BAD_FRAME;
566   }
567 
568   fcs = *(p_data + len);
569 
570   /* All control frames that we are sending are sent with P=1, expect */
571   /* reply with F=1 */
572   /* According to TS 07.10 spec ivalid frames are discarded without */
573   /* notification to the sender */
574   switch (p_frame->type) {
575     case RFCOMM_SABME:
576       if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) || !p_frame->pf || len ||
577           !RFCOMM_VALID_DLCI(p_frame->dlci) ||
578           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
579         log::error("Bad SABME");
580         return RFC_EVENT_BAD_FRAME;
581       } else {
582         return RFC_EVENT_SABME;
583       }
584 
585     case RFCOMM_UA:
586       if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) || !p_frame->pf || len ||
587           !RFCOMM_VALID_DLCI(p_frame->dlci) ||
588           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
589         log::error("Bad UA");
590         return RFC_EVENT_BAD_FRAME;
591       } else {
592         return RFC_EVENT_UA;
593       }
594 
595     case RFCOMM_DM:
596       if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) || len ||
597           !RFCOMM_VALID_DLCI(p_frame->dlci) ||
598           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
599         log::error("Bad DM");
600         return RFC_EVENT_BAD_FRAME;
601       } else {
602         return RFC_EVENT_DM;
603       }
604 
605     case RFCOMM_DISC:
606       if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) || !p_frame->pf || len ||
607           !RFCOMM_VALID_DLCI(p_frame->dlci) ||
608           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
609         log::error("Bad DISC");
610         return RFC_EVENT_BAD_FRAME;
611       } else {
612         return RFC_EVENT_DISC;
613       }
614 
615     case RFCOMM_UIH:
616       if (!RFCOMM_VALID_DLCI(p_frame->dlci)) {
617         log::error("Bad UIH - invalid DLCI");
618         return RFC_EVENT_BAD_FRAME;
619       } else if (!rfc_check_fcs(2, p_start, fcs)) {
620         log::error("Bad UIH - FCS");
621         return RFC_EVENT_BAD_FRAME;
622       } else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)) {
623         /* we assume that this is ok to allow bad implementations to work */
624         log::error("Bad UIH - response");
625         return RFC_EVENT_UIH;
626       } else {
627         return RFC_EVENT_UIH;
628       }
629   }
630 
631   return RFC_EVENT_BAD_FRAME;
632 }
633 
634 /*******************************************************************************
635  *
636  * Function         rfc_process_mx_message
637  *
638  * Description      This function processes UIH frames received on the
639  *                  multiplexer control channel.
640  *
641  ******************************************************************************/
rfc_process_mx_message(tRFC_MCB * p_mcb,BT_HDR * p_buf)642 void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) {
643   uint8_t* p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
644   MX_FRAME* p_rx_frame = &rfc_cb.rfc.rx_frame;
645   uint16_t length = p_buf->len;
646   uint8_t ea, cr, mx_len;
647 
648   if (length < 2) {
649     log::error("Illegal MX Frame len when reading EA, C/R. len:{} < 2", length);
650     osi_free(p_buf);
651     return;
652   }
653   p_rx_frame->ea = *p_data & RFCOMM_EA;
654   p_rx_frame->cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
655   p_rx_frame->type = *p_data++ & ~(RFCOMM_CR_MASK | RFCOMM_EA_MASK);
656 
657   if (!p_rx_frame->ea || !length) {
658     log::error("Invalid MX frame ea={}, len={}, bd_addr={}", p_rx_frame->ea, length,
659                p_mcb->bd_addr);
660     osi_free(p_buf);
661     return;
662   }
663 
664   length--;
665 
666   bool is_command = p_rx_frame->cr;
667 
668   ea = *p_data & RFCOMM_EA;
669 
670   mx_len = *p_data++ >> RFCOMM_SHIFT_LENGTH1;
671   length--;
672 
673   if (!ea) {
674     if (length < 1) {
675       log::error("Illegal MX Frame when EA = 0. len:{} < 1", length);
676       osi_free(p_buf);
677       return;
678     }
679     mx_len += *p_data++ << RFCOMM_SHIFT_LENGTH2;
680     length--;
681   }
682 
683   if (mx_len != length) {
684     log::error("Bad MX frame, p_mcb={}, bd_addr={}", std::format_ptr(p_mcb), p_mcb->bd_addr);
685     osi_free(p_buf);
686     return;
687   }
688 
689   log::verbose("type=0x{:02x}, bd_addr={}", p_rx_frame->type, p_mcb->bd_addr);
690   switch (p_rx_frame->type) {
691     case RFCOMM_MX_PN:
692       if (length != RFCOMM_MX_PN_LEN) {
693         log::error("Invalid PN length, p_mcb={}, bd_addr={}", std::format_ptr(p_mcb),
694                    p_mcb->bd_addr);
695         break;
696       }
697 
698       p_rx_frame->dlci = *p_data++ & RFCOMM_PN_DLCI_MASK;
699       p_rx_frame->u.pn.frame_type = *p_data & RFCOMM_PN_FRAME_TYPE_MASK;
700       p_rx_frame->u.pn.conv_layer = *p_data++ & RFCOMM_PN_CONV_LAYER_MASK;
701       p_rx_frame->u.pn.priority = *p_data++ & RFCOMM_PN_PRIORITY_MASK;
702       p_rx_frame->u.pn.t1 = *p_data++;
703       p_rx_frame->u.pn.mtu = *p_data + (*(p_data + 1) << 8);
704       p_data += 2;
705       p_rx_frame->u.pn.n2 = *p_data++;
706       p_rx_frame->u.pn.k = *p_data++ & RFCOMM_PN_K_MASK;
707 
708       if (!p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci) ||
709           (p_rx_frame->u.pn.mtu < RFCOMM_MIN_MTU) || (p_rx_frame->u.pn.mtu > RFCOMM_MAX_MTU)) {
710         log::error("Bad PN frame, p_mcb={}, bd_addr={}", std::format_ptr(p_mcb), p_mcb->bd_addr);
711         break;
712       }
713 
714       osi_free(p_buf);
715 
716       rfc_process_pn(p_mcb, is_command, p_rx_frame);
717       return;
718 
719     case RFCOMM_MX_TEST:
720       if (!length) {
721         break;
722       }
723 
724       p_rx_frame->u.test.p_data = p_data;
725       p_rx_frame->u.test.data_len = length;
726 
727       p_buf->offset += 2;
728       p_buf->len -= 2;
729 
730       if (is_command) {
731         rfc_send_test(p_mcb, false, p_buf);
732       } else {
733         rfc_process_test_rsp(p_mcb, p_buf);
734       }
735       return;
736 
737     case RFCOMM_MX_FCON:
738       if (length != RFCOMM_MX_FCON_LEN) {
739         break;
740       }
741 
742       osi_free(p_buf);
743 
744       rfc_process_fcon(p_mcb, is_command);
745       return;
746 
747     case RFCOMM_MX_FCOFF:
748       if (length != RFCOMM_MX_FCOFF_LEN) {
749         break;
750       }
751 
752       osi_free(p_buf);
753 
754       rfc_process_fcoff(p_mcb, is_command);
755       return;
756 
757     case RFCOMM_MX_MSC:
758       if (length != RFCOMM_MX_MSC_LEN_WITH_BREAK && length != RFCOMM_MX_MSC_LEN_NO_BREAK) {
759         log::error("Illegal MX MSC Frame len:{}", length);
760         osi_free(p_buf);
761         return;
762       }
763       ea = *p_data & RFCOMM_EA;
764       cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
765       p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
766 
767       if (!ea || !cr || !p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci)) {
768         log::error("Bad MSC frame");
769         break;
770       }
771 
772       p_rx_frame->u.msc.signals = *p_data++;
773 
774       if (mx_len == RFCOMM_MX_MSC_LEN_WITH_BREAK) {
775         p_rx_frame->u.msc.break_present = *p_data & RFCOMM_MSC_BREAK_PRESENT_MASK;
776         p_rx_frame->u.msc.break_duration =
777                 (*p_data & RFCOMM_MSC_BREAK_MASK) >> RFCOMM_MSC_SHIFT_BREAK;
778       } else {
779         p_rx_frame->u.msc.break_present = false;
780         p_rx_frame->u.msc.break_duration = 0;
781       }
782       osi_free(p_buf);
783 
784       rfc_process_msc(p_mcb, is_command, p_rx_frame);
785       return;
786 
787     case RFCOMM_MX_NSC:
788       if ((length != RFCOMM_MX_NSC_LEN) || !is_command) {
789         break;
790       }
791 
792       p_rx_frame->u.nsc.ea = *p_data & RFCOMM_EA;
793       p_rx_frame->u.nsc.cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
794       p_rx_frame->u.nsc.type = *p_data++ >> RFCOMM_SHIFT_DLCI;
795 
796       osi_free(p_buf);
797 
798       rfc_process_nsc(p_mcb, p_rx_frame);
799       return;
800 
801     case RFCOMM_MX_RPN:
802       if ((length != RFCOMM_MX_RPN_REQ_LEN) && (length != RFCOMM_MX_RPN_LEN)) {
803         break;
804       }
805 
806       ea = *p_data & RFCOMM_EA;
807       cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
808       p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
809 
810       if (!ea || !cr || !p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci)) {
811         log::error("Bad RPN frame");
812         break;
813       }
814 
815       p_rx_frame->u.rpn.is_request = (length == RFCOMM_MX_RPN_REQ_LEN);
816 
817       if (!p_rx_frame->u.rpn.is_request) {
818         p_rx_frame->u.rpn.baud_rate = *p_data++;
819         p_rx_frame->u.rpn.byte_size = (*p_data >> RFCOMM_RPN_BITS_SHIFT) & RFCOMM_RPN_BITS_MASK;
820         p_rx_frame->u.rpn.stop_bits =
821                 (*p_data >> RFCOMM_RPN_STOP_BITS_SHIFT) & RFCOMM_RPN_STOP_BITS_MASK;
822         p_rx_frame->u.rpn.parity = (*p_data >> RFCOMM_RPN_PARITY_SHIFT) & RFCOMM_RPN_PARITY_MASK;
823         p_rx_frame->u.rpn.parity_type =
824                 (*p_data++ >> RFCOMM_RPN_PARITY_TYPE_SHIFT) & RFCOMM_RPN_PARITY_TYPE_MASK;
825 
826         p_rx_frame->u.rpn.fc_type = *p_data++ & RFCOMM_FC_MASK;
827         p_rx_frame->u.rpn.xon_char = *p_data++;
828         p_rx_frame->u.rpn.xoff_char = *p_data++;
829         p_rx_frame->u.rpn.param_mask = (*p_data + (*(p_data + 1) << 8)) & RFCOMM_RPN_PM_MASK;
830       }
831       osi_free(p_buf);
832 
833       rfc_process_rpn(p_mcb, is_command, p_rx_frame->u.rpn.is_request, p_rx_frame);
834       return;
835 
836     case RFCOMM_MX_RLS:
837       if (length != RFCOMM_MX_RLS_LEN) {
838         break;
839       }
840 
841       ea = *p_data & RFCOMM_EA;
842       cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
843 
844       p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
845       p_rx_frame->u.rls.line_status = (*p_data & ~0x01);
846 
847       if (!ea || !cr || !p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci)) {
848         log::error("Bad RPN frame");
849         break;
850       }
851 
852       osi_free(p_buf);
853 
854       rfc_process_rls(p_mcb, is_command, p_rx_frame);
855       return;
856   }
857 
858   osi_free(p_buf);
859 
860   if (is_command) {
861     rfc_send_nsc(p_mcb);
862   }
863 }
864