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