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