OSDN Git Service

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