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*******************************************************************************/
42void 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*******************************************************************************/
74void 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*******************************************************************************/
106void 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*******************************************************************************/
138void 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*******************************************************************************/
170void 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*******************************************************************************/
235void 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*******************************************************************************/
280void 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*******************************************************************************/
308void 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*******************************************************************************/
336void 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*******************************************************************************/
390void 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*******************************************************************************/
421void 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*******************************************************************************/
453void 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*******************************************************************************/
506void 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*******************************************************************************/
543void 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*******************************************************************************/
574UINT8 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*******************************************************************************/
701void 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