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