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