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