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