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