OSDN Git Service

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