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