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