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