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