1 /******************************************************************************
3 * Copyright (C) 1999-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains functions to send TS 07.10 frames
23 ******************************************************************************/
26 #include "bt_target.h"
27 #include "bt_common.h"
35 /*******************************************************************************
37 ** Function rfc_send_sabme
39 ** Description This function sends SABME frame.
41 *******************************************************************************/
42 void rfc_send_sabme (tRFC_MCB *p_mcb, UINT8 dlci)
45 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
46 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
48 p_buf->offset = L2CAP_MIN_OFFSET;
49 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
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;
56 *p_data = RFCOMM_SABME_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
60 rfc_check_send_cmd(p_mcb, p_buf);
64 /*******************************************************************************
66 ** Function rfc_send_ua
68 ** Description This function sends UA frame.
70 *******************************************************************************/
71 void rfc_send_ua (tRFC_MCB *p_mcb, UINT8 dlci)
74 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, FALSE);
75 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
77 p_buf->offset = L2CAP_MIN_OFFSET;
78 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
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;
85 *p_data = RFCOMM_UA_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
89 rfc_check_send_cmd(p_mcb, p_buf);
93 /*******************************************************************************
95 ** Function rfc_send_dm
97 ** Description This function sends DM frame.
99 *******************************************************************************/
100 void rfc_send_dm (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN pf)
103 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, FALSE);
104 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
106 p_buf->offset = L2CAP_MIN_OFFSET;
107 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
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;
114 *p_data = RFCOMM_DM_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
118 rfc_check_send_cmd(p_mcb, p_buf);
122 /*******************************************************************************
124 ** Function rfc_send_disc
126 ** Description This function sends DISC frame.
128 *******************************************************************************/
129 void rfc_send_disc (tRFC_MCB *p_mcb, UINT8 dlci)
132 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
133 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
135 p_buf->offset = L2CAP_MIN_OFFSET;
136 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
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;
143 *p_data = RFCOMM_DISC_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
147 rfc_check_send_cmd(p_mcb, p_buf);
151 /*******************************************************************************
153 ** Function rfc_send_buf_uih
155 ** Description This function sends UIH frame.
157 *******************************************************************************/
158 void rfc_send_buf_uih (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
161 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
164 p_buf->offset -= RFCOMM_CTRL_FRAME_LEN;
165 if (p_buf->len > 127)
169 credits = (UINT8)p_buf->layer_specific;
176 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
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)
183 *p_data++ = RFCOMM_EA | (p_buf->len << 1);
188 *p_data++ = (p_buf->len & 0x7f) << 1;
189 *p_data++ = p_buf->len >> RFCOMM_SHIFT_LENGTH2;
199 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len++;
201 *p_data = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci);
203 if (dlci == RFCOMM_MX_DLCI)
205 rfc_check_send_cmd(p_mcb, p_buf);
209 L2CA_DataWrite (p_mcb->lcid, p_buf);
214 /*******************************************************************************
216 ** Function rfc_send_pn
218 ** Description This function sends DLC Parameters Negotiation Frame.
220 *******************************************************************************/
221 void rfc_send_pn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT16 mtu, UINT8 cl, UINT8 k)
224 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
226 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
227 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
229 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_PN;
230 *p_data++ = RFCOMM_EA | (RFCOMM_MX_PN_LEN << 1);
233 *p_data++ = RFCOMM_PN_FRAM_TYPE_UIH | cl;
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.
239 *p_data++ = RFCOMM_PN_PRIORITY_0;
241 *p_data++ = rfc_cb.rfc.rx_frame.u.pn.priority;
243 *p_data++ = RFCOMM_T1_DSEC;
244 *p_data++ = mtu & 0xFF;
245 *p_data++ = mtu >> 8;
246 *p_data++ = RFCOMM_N2;
249 /* Total length is sizeof PN data + mx header 2 */
250 p_buf->len = RFCOMM_MX_PN_LEN + 2;
252 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
256 /*******************************************************************************
258 ** Function rfc_send_fcon
260 ** Description This function sends Flow Control On Command.
262 *******************************************************************************/
263 void rfc_send_fcon (tRFC_MCB *p_mcb, BOOLEAN is_command)
266 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
268 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
269 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
271 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCON;
272 *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCON_LEN << 1);
274 /* Total length is sizeof FCON data + mx header 2 */
275 p_buf->len = RFCOMM_MX_FCON_LEN + 2;
277 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
281 /*******************************************************************************
283 ** Function rfc_send_fcoff
285 ** Description This function sends Flow Control Off Command.
287 *******************************************************************************/
288 void rfc_send_fcoff (tRFC_MCB *p_mcb, BOOLEAN is_command)
291 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
293 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
294 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
296 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCOFF;
297 *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCOFF_LEN << 1);
299 /* Total length is sizeof FCOFF data + mx header 2 */
300 p_buf->len = RFCOMM_MX_FCOFF_LEN + 2;
302 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
306 /*******************************************************************************
308 ** Function rfc_send_msc
310 ** Description This function sends Modem Status Command Frame.
312 *******************************************************************************/
313 void rfc_send_msc (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command,
318 UINT8 break_duration;
320 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
322 signals = p_pars->modem_signal;
323 break_duration = p_pars->break_signal;
325 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
326 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
329 len = RFCOMM_MX_MSC_LEN_WITH_BREAK;
331 len = RFCOMM_MX_MSC_LEN_NO_BREAK;
333 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_MSC;
334 *p_data++ = RFCOMM_EA | (len << 1);
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);
346 *p_data++ = RFCOMM_EA | RFCOMM_MSC_BREAK_PRESENT_MASK |
347 (break_duration << RFCOMM_MSC_SHIFT_BREAK);
350 /* Total length is sizeof MSC data + mx header 2 */
351 p_buf->len = len + 2;
353 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
357 /*******************************************************************************
359 ** Function rfc_send_rls
361 ** Description This function sends Remote Line Status Command Frame.
363 *******************************************************************************/
364 void rfc_send_rls (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT8 status)
367 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
369 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
370 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
372 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RLS;
373 *p_data++ = RFCOMM_EA | (RFCOMM_MX_RLS_LEN << 1);
375 *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
376 *p_data++ = RFCOMM_RLS_ERROR | status;
378 /* Total length is sizeof RLS data + mx header 2 */
379 p_buf->len = RFCOMM_MX_RLS_LEN + 2;
381 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
385 /*******************************************************************************
387 ** Function rfc_send_nsc
389 ** Description This function sends Non Supported Command Response.
391 *******************************************************************************/
392 void rfc_send_nsc (tRFC_MCB *p_mcb)
395 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
397 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
398 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
400 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(FALSE) | RFCOMM_MX_NSC;
401 *p_data++ = RFCOMM_EA | (RFCOMM_MX_NSC_LEN << 1);
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;
407 /* Total length is sizeof NSC data + mx header 2 */
408 p_buf->len = RFCOMM_MX_NSC_LEN + 2;
410 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
414 /*******************************************************************************
416 ** Function rfc_send_rpn
418 ** Description This function sends Remote Port Negotiation Command
420 *******************************************************************************/
421 void rfc_send_rpn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command,
422 tPORT_STATE *p_pars, UINT16 mask)
425 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
427 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
428 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
430 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RPN;
434 *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_REQ_LEN << 1);
436 *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
438 p_buf->len = RFCOMM_MX_RPN_REQ_LEN + 2;
442 *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_LEN << 1);
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);
456 /* Total length is sizeof RPN data + mx header 2 */
457 p_buf->len = RFCOMM_MX_RPN_LEN + 2;
460 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
464 /*******************************************************************************
466 ** Function rfc_send_test
468 ** Description This function sends Test frame.
470 *******************************************************************************/
471 void rfc_send_test (tRFC_MCB *p_mcb, BOOLEAN is_command, BT_HDR *p_buf)
473 /* Shift buffer to give space for header */
474 if (p_buf->offset < (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2))
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));
480 p_new_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
481 p_new_buf->len = p_buf->len;
483 UINT8 *p_dest = (UINT8 *) (p_new_buf + 1) + p_new_buf->offset + p_new_buf->len - 1;
485 for (UINT16 xx = 0; xx < p_buf->len; xx++)
486 *p_dest-- = *p_src--;
492 /* Adjust offset by number of bytes we are going to fill */
494 UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
496 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_TEST;
497 *p_data++ = RFCOMM_EA | (p_buf->len << 1);
501 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
504 /*******************************************************************************
506 ** Function rfc_send_credit
508 ** Description This function sends a flow control credit in UIH frame.
510 *******************************************************************************/
511 void rfc_send_credit(tRFC_MCB *p_mcb, UINT8 dlci, UINT8 credit)
514 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
515 BT_HDR *p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE);
517 p_buf->offset = L2CAP_MIN_OFFSET;
518 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
520 *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
521 *p_data++ = RFCOMM_UIH | RFCOMM_PF;
522 *p_data++ = RFCOMM_EA | 0;
524 *p_data = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci);
528 rfc_check_send_cmd(p_mcb, p_buf);
532 /*******************************************************************************
534 ** Function rfc_parse_data
536 ** Description This function processes data packet received from L2CAP
538 *******************************************************************************/
539 UINT8 rfc_parse_data (tRFC_MCB *p_mcb, MX_FRAME *p_frame, BT_HDR *p_buf)
542 UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
543 UINT8 *p_start = p_data;
546 if (p_buf->len < RFCOMM_CTRL_FRAME_LEN)
548 RFCOMM_TRACE_ERROR ("Bad Length1: %d", p_buf->len);
549 return (RFC_EVENT_BAD_FRAME);
552 RFCOMM_PARSE_CTRL_FIELD (ead, p_frame->cr, p_frame->dlci, p_data);
555 RFCOMM_TRACE_ERROR ("Bad Address(EA must be 1)");
556 return (RFC_EVENT_BAD_FRAME);
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;
569 p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */
570 p_buf->offset += (3 + !ead + !eal);
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))
576 p_frame->credit = *p_data++;
583 if (p_buf->len != len)
585 RFCOMM_TRACE_ERROR ("Bad Length2 %d %d", p_buf->len, len);
586 return (RFC_EVENT_BAD_FRAME);
589 fcs = *(p_data + len);
591 /* All control frames that we are sending are sent with P=1, expect */
593 /* According to TS 07.10 spec ivalid frames are discarded without */
594 /* notification to the sender */
595 switch (p_frame->type)
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))
602 RFCOMM_TRACE_ERROR ("Bad SABME");
603 return (RFC_EVENT_BAD_FRAME);
606 return (RFC_EVENT_SABME);
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))
613 RFCOMM_TRACE_ERROR ("Bad UA");
614 return (RFC_EVENT_BAD_FRAME);
617 return (RFC_EVENT_UA);
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))
624 RFCOMM_TRACE_ERROR ("Bad DM");
625 return (RFC_EVENT_BAD_FRAME);
628 return (RFC_EVENT_DM);
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))
635 RFCOMM_TRACE_ERROR ("Bad DISC");
636 return (RFC_EVENT_BAD_FRAME);
639 return (RFC_EVENT_DISC);
642 if (!RFCOMM_VALID_DLCI(p_frame->dlci))
644 RFCOMM_TRACE_ERROR ("Bad UIH - invalid DLCI");
645 return (RFC_EVENT_BAD_FRAME);
647 else if (!rfc_check_fcs (2, p_start, fcs))
649 RFCOMM_TRACE_ERROR ("Bad UIH - FCS");
650 return (RFC_EVENT_BAD_FRAME);
652 else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr))
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);
659 return (RFC_EVENT_UIH);
662 return (RFC_EVENT_BAD_FRAME);
666 /*******************************************************************************
668 ** Function rfc_process_mx_message
670 ** Description This function processes UIH frames received on the
671 ** multiplexer control channel.
673 *******************************************************************************/
674 void rfc_process_mx_message (tRFC_MCB *p_mcb, BT_HDR *p_buf)
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;
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);
686 if (!p_rx_frame->ea || !length)
688 RFCOMM_TRACE_ERROR ("Illegal MX Frame ea:%d len:%d", p_rx_frame->ea, length);
695 is_command = p_rx_frame->cr;
697 ea = *p_data & RFCOMM_EA;
699 mx_len = *p_data++ >> RFCOMM_SHIFT_LENGTH1;
704 mx_len += *p_data++ << RFCOMM_SHIFT_LENGTH2;
708 if (mx_len != length)
710 RFCOMM_TRACE_ERROR ("Bad MX frame");
715 switch (p_rx_frame->type)
718 if (length != RFCOMM_MX_PN_LEN)
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);
728 p_rx_frame->u.pn.n2 = *p_data++;
729 p_rx_frame->u.pn.k = *p_data++ & RFCOMM_PN_K_MASK;
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))
736 RFCOMM_TRACE_ERROR ("Bad PN frame");
742 rfc_process_pn (p_mcb, is_command, p_rx_frame);
749 p_rx_frame->u.test.p_data = p_data;
750 p_rx_frame->u.test.data_len = length;
756 rfc_send_test (p_mcb, FALSE, p_buf);
758 rfc_process_test_rsp (p_mcb, p_buf);
762 if (length != RFCOMM_MX_FCON_LEN)
767 rfc_process_fcon (p_mcb, is_command);
770 case RFCOMM_MX_FCOFF:
771 if (length != RFCOMM_MX_FCOFF_LEN)
776 rfc_process_fcoff (p_mcb, is_command);
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;
785 if (!ea || !cr || !p_rx_frame->dlci
786 || !RFCOMM_VALID_DLCI (p_rx_frame->dlci))
788 RFCOMM_TRACE_ERROR ("Bad MSC frame");
792 p_rx_frame->u.msc.signals = *p_data++;
794 if (mx_len == RFCOMM_MX_MSC_LEN_WITH_BREAK)
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;
801 p_rx_frame->u.msc.break_present = FALSE;
802 p_rx_frame->u.msc.break_duration = 0;
806 rfc_process_msc (p_mcb, is_command, p_rx_frame);
810 if ((length != RFCOMM_MX_NSC_LEN) || !is_command)
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;
819 rfc_process_nsc (p_mcb, p_rx_frame);
823 if ((length != RFCOMM_MX_RPN_REQ_LEN) && (length != RFCOMM_MX_RPN_LEN))
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;
830 if (!ea || !cr || !p_rx_frame->dlci
831 || !RFCOMM_VALID_DLCI (p_rx_frame->dlci))
833 RFCOMM_TRACE_ERROR ("Bad RPN frame");
837 p_rx_frame->u.rpn.is_request = (length == RFCOMM_MX_RPN_REQ_LEN);
839 if (!p_rx_frame->u.rpn.is_request)
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;
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;
854 rfc_process_rpn (p_mcb, is_command, p_rx_frame->u.rpn.is_request, p_rx_frame);
858 if (length != RFCOMM_MX_RLS_LEN)
861 ea = *p_data & RFCOMM_EA;
862 cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
864 p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
865 p_rx_frame->u.rls.line_status = (*p_data & ~0x01);
867 if (!ea || !cr || !p_rx_frame->dlci
868 || !RFCOMM_VALID_DLCI (p_rx_frame->dlci))
870 RFCOMM_TRACE_ERROR ("Bad RPN frame");
876 rfc_process_rls (p_mcb, is_command, p_rx_frame);
883 rfc_send_nsc (p_mcb);