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