• 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) {
158     p_buf->offset--;
159   }
160 
161   if (dlci) {
162     credits = (uint8_t)p_buf->layer_specific;
163   } else {
164     credits = 0;
165   }
166 
167   if (credits) {
168     p_buf->offset--;
169   }
170 
171   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
172 
173   /* UIH frame, command, PF = 0, dlci */
174   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
175   *p_data++ = RFCOMM_UIH | ((credits) ? RFCOMM_PF : 0);
176   if (p_buf->len <= 127) {
177     *p_data++ = RFCOMM_EA | (p_buf->len << 1);
178     p_buf->len += 3;
179   } else {
180     *p_data++ = (p_buf->len & 0x7f) << 1;
181     *p_data++ = p_buf->len >> RFCOMM_SHIFT_LENGTH2;
182     p_buf->len += 4;
183   }
184 
185   if (credits) {
186     *p_data++ = credits;
187     p_buf->len++;
188   }
189 
190   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len++;
191 
192   *p_data = RFCOMM_UIH_FCS((uint8_t*)(p_buf + 1) + p_buf->offset, dlci);
193 
194   if (dlci == RFCOMM_MX_DLCI) {
195     rfc_check_send_cmd(p_mcb, p_buf);
196   } else {
197     L2CA_DataWrite(p_mcb->lcid, p_buf);
198   }
199 }
200 
201 /*******************************************************************************
202  *
203  * Function         rfc_send_pn
204  *
205  * Description      This function sends DLC Parameters Negotiation Frame.
206  *
207  ******************************************************************************/
rfc_send_pn(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,uint16_t mtu,uint8_t cl,uint8_t k)208 void rfc_send_pn(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command, uint16_t mtu,
209                  uint8_t cl, uint8_t k) {
210   uint8_t* p_data;
211   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
212 
213   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
214   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
215 
216   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_PN;
217   *p_data++ = RFCOMM_EA | (RFCOMM_MX_PN_LEN << 1);
218 
219   *p_data++ = dlci;
220   *p_data++ = RFCOMM_PN_FRAM_TYPE_UIH | cl;
221 
222   /* It appeared that we need to reply with the same priority bits as we
223   *received.
224   ** We will use the fact that we reply in the same context so rx_frame can
225   *still be used.
226   */
227   if (is_command) {
228     *p_data++ = RFCOMM_PN_PRIORITY_0;
229   } else {
230     *p_data++ = rfc_cb.rfc.rx_frame.u.pn.priority;
231   }
232   *p_data++ = RFCOMM_T1_DSEC;
233   *p_data++ = mtu & 0xFF;
234   *p_data++ = mtu >> 8;
235   *p_data++ = RFCOMM_N2;
236   *p_data = k;
237 
238   /* Total length is sizeof PN data + mx header 2 */
239   p_buf->len = RFCOMM_MX_PN_LEN + 2;
240 
241   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
242 }
243 
244 /*******************************************************************************
245  *
246  * Function         rfc_send_fcon
247  *
248  * Description      This function sends Flow Control On Command.
249  *
250  ******************************************************************************/
rfc_send_fcon(tRFC_MCB * p_mcb,bool is_command)251 void rfc_send_fcon(tRFC_MCB* p_mcb, bool is_command) {
252   uint8_t* p_data;
253   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
254 
255   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
256   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
257 
258   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCON;
259   *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCON_LEN << 1);
260 
261   /* Total length is sizeof FCON data + mx header 2 */
262   p_buf->len = RFCOMM_MX_FCON_LEN + 2;
263 
264   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
265 }
266 
267 /*******************************************************************************
268  *
269  * Function         rfc_send_fcoff
270  *
271  * Description      This function sends Flow Control Off Command.
272  *
273  ******************************************************************************/
rfc_send_fcoff(tRFC_MCB * p_mcb,bool is_command)274 void rfc_send_fcoff(tRFC_MCB* p_mcb, bool is_command) {
275   uint8_t* p_data;
276   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
277 
278   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
279   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
280 
281   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCOFF;
282   *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCOFF_LEN << 1);
283 
284   /* Total length is sizeof FCOFF data + mx header 2 */
285   p_buf->len = RFCOMM_MX_FCOFF_LEN + 2;
286 
287   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
288 }
289 
290 /*******************************************************************************
291  *
292  * Function         rfc_send_msc
293  *
294  * Description      This function sends Modem Status Command Frame.
295  *
296  ******************************************************************************/
rfc_send_msc(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,tPORT_CTRL * p_pars)297 void rfc_send_msc(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command,
298                   tPORT_CTRL* p_pars) {
299   uint8_t* p_data;
300   uint8_t signals;
301   uint8_t break_duration;
302   uint8_t len;
303   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
304 
305   signals = p_pars->modem_signal;
306   break_duration = p_pars->break_signal;
307 
308   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
309   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
310 
311   if (break_duration)
312     len = RFCOMM_MX_MSC_LEN_WITH_BREAK;
313   else
314     len = RFCOMM_MX_MSC_LEN_NO_BREAK;
315 
316   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_MSC;
317   *p_data++ = RFCOMM_EA | (len << 1);
318 
319   *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
320   *p_data++ = RFCOMM_EA | ((p_pars->fc) ? RFCOMM_MSC_FC : 0) |
321               ((signals & MODEM_SIGNAL_DTRDSR) ? RFCOMM_MSC_RTC : 0) |
322               ((signals & MODEM_SIGNAL_RTSCTS) ? RFCOMM_MSC_RTR : 0) |
323               ((signals & MODEM_SIGNAL_RI) ? RFCOMM_MSC_IC : 0) |
324               ((signals & MODEM_SIGNAL_DCD) ? RFCOMM_MSC_DV : 0);
325 
326   if (break_duration) {
327     *p_data++ = RFCOMM_EA | RFCOMM_MSC_BREAK_PRESENT_MASK |
328                 (break_duration << RFCOMM_MSC_SHIFT_BREAK);
329   }
330 
331   /* Total length is sizeof MSC data + mx header 2 */
332   p_buf->len = len + 2;
333 
334   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
335 }
336 
337 /*******************************************************************************
338  *
339  * Function         rfc_send_rls
340  *
341  * Description      This function sends Remote Line Status Command Frame.
342  *
343  ******************************************************************************/
rfc_send_rls(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,uint8_t status)344 void rfc_send_rls(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command,
345                   uint8_t status) {
346   uint8_t* p_data;
347   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
348 
349   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
350   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
351 
352   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RLS;
353   *p_data++ = RFCOMM_EA | (RFCOMM_MX_RLS_LEN << 1);
354 
355   *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
356   *p_data++ = RFCOMM_RLS_ERROR | status;
357 
358   /* Total length is sizeof RLS data + mx header 2 */
359   p_buf->len = RFCOMM_MX_RLS_LEN + 2;
360 
361   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
362 }
363 
364 /*******************************************************************************
365  *
366  * Function         rfc_send_nsc
367  *
368  * Description      This function sends Non Supported Command Response.
369  *
370  ******************************************************************************/
rfc_send_nsc(tRFC_MCB * p_mcb)371 void rfc_send_nsc(tRFC_MCB* p_mcb) {
372   uint8_t* p_data;
373   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
374 
375   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
376   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
377 
378   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(false) | RFCOMM_MX_NSC;
379   *p_data++ = RFCOMM_EA | (RFCOMM_MX_NSC_LEN << 1);
380 
381   *p_data++ = rfc_cb.rfc.rx_frame.ea |
382               (rfc_cb.rfc.rx_frame.cr << RFCOMM_SHIFT_CR) |
383               rfc_cb.rfc.rx_frame.type;
384 
385   /* Total length is sizeof NSC data + mx header 2 */
386   p_buf->len = RFCOMM_MX_NSC_LEN + 2;
387 
388   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
389 }
390 
391 /*******************************************************************************
392  *
393  * Function         rfc_send_rpn
394  *
395  * Description      This function sends Remote Port Negotiation Command
396  *
397  ******************************************************************************/
rfc_send_rpn(tRFC_MCB * p_mcb,uint8_t dlci,bool is_command,tPORT_STATE * p_pars,uint16_t mask)398 void rfc_send_rpn(tRFC_MCB* p_mcb, uint8_t dlci, bool is_command,
399                   tPORT_STATE* p_pars, uint16_t mask) {
400   uint8_t* p_data;
401   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
402 
403   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
404   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
405 
406   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RPN;
407 
408   if (!p_pars) {
409     *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_REQ_LEN << 1);
410 
411     *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
412 
413     p_buf->len = RFCOMM_MX_RPN_REQ_LEN + 2;
414   } else {
415     *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_LEN << 1);
416 
417     *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
418     *p_data++ = p_pars->baud_rate;
419     *p_data++ = (p_pars->byte_size << RFCOMM_RPN_BITS_SHIFT) |
420                 (p_pars->stop_bits << RFCOMM_RPN_STOP_BITS_SHIFT) |
421                 (p_pars->parity << RFCOMM_RPN_PARITY_SHIFT) |
422                 (p_pars->parity_type << RFCOMM_RPN_PARITY_TYPE_SHIFT);
423     *p_data++ = p_pars->fc_type;
424     *p_data++ = p_pars->xon_char;
425     *p_data++ = p_pars->xoff_char;
426     *p_data++ = (mask & 0xFF);
427     *p_data++ = (mask >> 8);
428 
429     /* Total length is sizeof RPN data + mx header 2 */
430     p_buf->len = RFCOMM_MX_RPN_LEN + 2;
431   }
432 
433   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
434 }
435 
436 /*******************************************************************************
437  *
438  * Function         rfc_send_test
439  *
440  * Description      This function sends Test frame.
441  *
442  ******************************************************************************/
rfc_send_test(tRFC_MCB * p_mcb,bool is_command,BT_HDR * p_buf)443 void rfc_send_test(tRFC_MCB* p_mcb, bool is_command, BT_HDR* p_buf) {
444   /* Shift buffer to give space for header */
445   if (p_buf->offset < (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2)) {
446     uint8_t* p_src = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len - 1;
447     BT_HDR* p_new_buf =
448         (BT_HDR*)osi_malloc(p_buf->len + (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET +
449                                           2 + sizeof(BT_HDR) + 1));
450 
451     p_new_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
452     p_new_buf->len = p_buf->len;
453 
454     uint8_t* p_dest =
455         (uint8_t*)(p_new_buf + 1) + p_new_buf->offset + p_new_buf->len - 1;
456 
457     for (uint16_t xx = 0; xx < p_buf->len; xx++) *p_dest-- = *p_src--;
458 
459     osi_free(p_buf);
460     p_buf = p_new_buf;
461   }
462 
463   /* Adjust offset by number of bytes we are going to fill */
464   p_buf->offset -= 2;
465   uint8_t* p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
466 
467   *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_TEST;
468   *p_data++ = RFCOMM_EA | (p_buf->len << 1);
469 
470   p_buf->len += 2;
471 
472   rfc_send_buf_uih(p_mcb, RFCOMM_MX_DLCI, p_buf);
473 }
474 
475 /*******************************************************************************
476  *
477  * Function         rfc_send_credit
478  *
479  * Description      This function sends a flow control credit in UIH frame.
480  *
481  ******************************************************************************/
rfc_send_credit(tRFC_MCB * p_mcb,uint8_t dlci,uint8_t credit)482 void rfc_send_credit(tRFC_MCB* p_mcb, uint8_t dlci, uint8_t credit) {
483   uint8_t* p_data;
484   uint8_t cr = RFCOMM_CR(p_mcb->is_initiator, true);
485   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
486 
487   p_buf->offset = L2CAP_MIN_OFFSET;
488   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
489 
490   *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
491   *p_data++ = RFCOMM_UIH | RFCOMM_PF;
492   *p_data++ = RFCOMM_EA | 0;
493   *p_data++ = credit;
494   *p_data = RFCOMM_UIH_FCS((uint8_t*)(p_buf + 1) + p_buf->offset, dlci);
495 
496   p_buf->len = 5;
497 
498   rfc_check_send_cmd(p_mcb, p_buf);
499 }
500 
501 /*******************************************************************************
502  *
503  * Function         rfc_parse_data
504  *
505  * Description      This function processes data packet received from L2CAP
506  *
507  ******************************************************************************/
rfc_parse_data(tRFC_MCB * p_mcb,MX_FRAME * p_frame,BT_HDR * p_buf)508 uint8_t rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) {
509   uint8_t ead, eal, fcs;
510   uint8_t* p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
511   uint8_t* p_start = p_data;
512   uint16_t len;
513 
514   if (p_buf->len < RFCOMM_CTRL_FRAME_LEN) {
515     RFCOMM_TRACE_ERROR("Bad Length1: %d", p_buf->len);
516     return (RFC_EVENT_BAD_FRAME);
517   }
518 
519   RFCOMM_PARSE_CTRL_FIELD(ead, p_frame->cr, p_frame->dlci, p_data);
520   if (!ead) {
521     RFCOMM_TRACE_ERROR("Bad Address(EA must be 1)");
522     return (RFC_EVENT_BAD_FRAME);
523   }
524   RFCOMM_PARSE_TYPE_FIELD(p_frame->type, p_frame->pf, p_data);
525 
526   eal = *(p_data)&RFCOMM_EA;
527   len = *(p_data)++ >> RFCOMM_SHIFT_LENGTH1;
528   if (eal == 0 && p_buf->len > RFCOMM_CTRL_FRAME_LEN) {
529     len += (*(p_data)++ << RFCOMM_SHIFT_LENGTH2);
530   } else if (eal == 0) {
531     RFCOMM_TRACE_ERROR("Bad Length when EAL = 0: %d", p_buf->len);
532     android_errorWriteLog(0x534e4554, "78288018");
533     return RFC_EVENT_BAD_FRAME;
534   }
535 
536   if (p_buf->len < (3 + !ead + !eal + 1)) {
537     android_errorWriteLog(0x534e4554, "120255805");
538     RFCOMM_TRACE_ERROR("Bad Length: %d", p_buf->len);
539     return RFC_EVENT_BAD_FRAME;
540   }
541   p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */
542   p_buf->offset += (3 + !ead + !eal);
543 
544   /* handle credit if credit based flow control */
545   if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) &&
546       (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1)) {
547     if (p_buf->len < sizeof(uint8_t)) {
548       RFCOMM_TRACE_ERROR("Bad Length in flow control: %d", p_buf->len);
549       return RFC_EVENT_BAD_FRAME;
550     }
551     p_frame->credit = *p_data++;
552     p_buf->len--;
553     p_buf->offset++;
554   } else {
555     p_frame->credit = 0;
556   }
557 
558   if (p_buf->len != len) {
559     RFCOMM_TRACE_ERROR("Bad Length2 %d %d", p_buf->len, len);
560     return (RFC_EVENT_BAD_FRAME);
561   }
562 
563   fcs = *(p_data + len);
564 
565   /* All control frames that we are sending are sent with P=1, expect */
566   /* reply with F=1 */
567   /* According to TS 07.10 spec ivalid frames are discarded without */
568   /* notification to the sender */
569   switch (p_frame->type) {
570     case RFCOMM_SABME:
571       if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) ||
572           !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) ||
573           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
574         RFCOMM_TRACE_ERROR("Bad SABME");
575         return (RFC_EVENT_BAD_FRAME);
576       } else
577         return (RFC_EVENT_SABME);
578 
579     case RFCOMM_UA:
580       if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) ||
581           !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) ||
582           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
583         RFCOMM_TRACE_ERROR("Bad UA");
584         return (RFC_EVENT_BAD_FRAME);
585       } else
586         return (RFC_EVENT_UA);
587 
588     case RFCOMM_DM:
589       if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) || len ||
590           !RFCOMM_VALID_DLCI(p_frame->dlci) ||
591           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
592         RFCOMM_TRACE_ERROR("Bad DM");
593         return (RFC_EVENT_BAD_FRAME);
594       } else
595         return (RFC_EVENT_DM);
596 
597     case RFCOMM_DISC:
598       if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) ||
599           !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) ||
600           !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
601         RFCOMM_TRACE_ERROR("Bad DISC");
602         return (RFC_EVENT_BAD_FRAME);
603       } else
604         return (RFC_EVENT_DISC);
605 
606     case RFCOMM_UIH:
607       if (!RFCOMM_VALID_DLCI(p_frame->dlci)) {
608         RFCOMM_TRACE_ERROR("Bad UIH - invalid DLCI");
609         return (RFC_EVENT_BAD_FRAME);
610       } else if (!rfc_check_fcs(2, p_start, fcs)) {
611         RFCOMM_TRACE_ERROR("Bad UIH - FCS");
612         return (RFC_EVENT_BAD_FRAME);
613       } else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)) {
614         /* we assume that this is ok to allow bad implementations to work */
615         RFCOMM_TRACE_ERROR("Bad UIH - response");
616         return (RFC_EVENT_UIH);
617       } else {
618         return (RFC_EVENT_UIH);
619       }
620   }
621 
622   return (RFC_EVENT_BAD_FRAME);
623 }
624 
625 /*******************************************************************************
626  *
627  * Function         rfc_process_mx_message
628  *
629  * Description      This function processes UIH frames received on the
630  *                  multiplexer control channel.
631  *
632  ******************************************************************************/
rfc_process_mx_message(tRFC_MCB * p_mcb,BT_HDR * p_buf)633 void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) {
634   uint8_t* p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
635   MX_FRAME* p_rx_frame = &rfc_cb.rfc.rx_frame;
636   uint16_t length = p_buf->len;
637   uint8_t ea, cr, mx_len;
638 
639   if (length < 2) {
640     RFCOMM_TRACE_ERROR(
641         "%s: Illegal MX Frame len when reading EA, C/R. len:%d < 2", __func__,
642         length);
643     android_errorWriteLog(0x534e4554, "111937065");
644     osi_free(p_buf);
645     return;
646   }
647   p_rx_frame->ea = *p_data & RFCOMM_EA;
648   p_rx_frame->cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
649   p_rx_frame->type = *p_data++ & ~(RFCOMM_CR_MASK | RFCOMM_EA_MASK);
650 
651   if (!p_rx_frame->ea || !length) {
652     LOG(ERROR) << __func__
653                << ": Invalid MX frame ea=" << std::to_string(p_rx_frame->ea)
654                << ", len=" << length << ", bd_addr=" << p_mcb->bd_addr;
655     osi_free(p_buf);
656     return;
657   }
658 
659   length--;
660 
661   bool is_command = p_rx_frame->cr;
662 
663   ea = *p_data & RFCOMM_EA;
664 
665   mx_len = *p_data++ >> RFCOMM_SHIFT_LENGTH1;
666   length--;
667 
668   if (!ea) {
669     if (length < 1) {
670       RFCOMM_TRACE_ERROR("%s: Illegal MX Frame when EA = 0. len:%d < 1",
671                          __func__, length);
672       android_errorWriteLog(0x534e4554, "111937065");
673       osi_free(p_buf);
674       return;
675     }
676     mx_len += *p_data++ << RFCOMM_SHIFT_LENGTH2;
677     length--;
678   }
679 
680   if (mx_len != length) {
681     LOG(ERROR) << __func__ << ": Bad MX frame, p_mcb=" << p_mcb
682                << ", bd_addr=" << p_mcb->bd_addr;
683     osi_free(p_buf);
684     return;
685   }
686 
687   RFCOMM_TRACE_DEBUG("%s: type=0x%02x, bd_addr=%s", __func__, p_rx_frame->type,
688                      p_mcb->bd_addr.ToString().c_str());
689   switch (p_rx_frame->type) {
690     case RFCOMM_MX_PN:
691       if (length != RFCOMM_MX_PN_LEN) {
692         LOG(ERROR) << __func__ << ": Invalid PN length, p_mcb=" << p_mcb
693                    << ", bd_addr=" << p_mcb->bd_addr;
694         break;
695       }
696 
697       p_rx_frame->dlci = *p_data++ & RFCOMM_PN_DLCI_MASK;
698       p_rx_frame->u.pn.frame_type = *p_data & RFCOMM_PN_FRAME_TYPE_MASK;
699       p_rx_frame->u.pn.conv_layer = *p_data++ & RFCOMM_PN_CONV_LAYER_MASK;
700       p_rx_frame->u.pn.priority = *p_data++ & RFCOMM_PN_PRIORITY_MASK;
701       p_rx_frame->u.pn.t1 = *p_data++;
702       p_rx_frame->u.pn.mtu = *p_data + (*(p_data + 1) << 8);
703       p_data += 2;
704       p_rx_frame->u.pn.n2 = *p_data++;
705       p_rx_frame->u.pn.k = *p_data++ & RFCOMM_PN_K_MASK;
706 
707       if (!p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci) ||
708           (p_rx_frame->u.pn.mtu < RFCOMM_MIN_MTU) ||
709           (p_rx_frame->u.pn.mtu > RFCOMM_MAX_MTU)) {
710         LOG(ERROR) << __func__ << ": Bad PN frame, p_mcb=" << p_mcb
711                    << ", bd_addr=" << p_mcb->bd_addr;
712         break;
713       }
714 
715       osi_free(p_buf);
716 
717       rfc_process_pn(p_mcb, is_command, p_rx_frame);
718       return;
719 
720     case RFCOMM_MX_TEST:
721       if (!length) break;
722 
723       p_rx_frame->u.test.p_data = p_data;
724       p_rx_frame->u.test.data_len = length;
725 
726       p_buf->offset += 2;
727       p_buf->len -= 2;
728 
729       if (is_command)
730         rfc_send_test(p_mcb, false, p_buf);
731       else
732         rfc_process_test_rsp(p_mcb, p_buf);
733       return;
734 
735     case RFCOMM_MX_FCON:
736       if (length != RFCOMM_MX_FCON_LEN) break;
737 
738       osi_free(p_buf);
739 
740       rfc_process_fcon(p_mcb, is_command);
741       return;
742 
743     case RFCOMM_MX_FCOFF:
744       if (length != RFCOMM_MX_FCOFF_LEN) break;
745 
746       osi_free(p_buf);
747 
748       rfc_process_fcoff(p_mcb, is_command);
749       return;
750 
751     case RFCOMM_MX_MSC:
752       if (length != RFCOMM_MX_MSC_LEN_WITH_BREAK &&
753           length != RFCOMM_MX_MSC_LEN_NO_BREAK) {
754         RFCOMM_TRACE_ERROR("%s: Illegal MX MSC Frame len:%d", __func__, length);
755         android_errorWriteLog(0x534e4554, "111937065");
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