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