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