15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 1999-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  This file contains functions to send TS 07.10 frames
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.h"
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "rfcdefs.h"
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "port_api.h"
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "port_int.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "rfc_int.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_sabme
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends SABME frame.
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_sabme (tRFC_MCB *p_mcb, UINT8 dlci)
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET;
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* SABME frame, command, PF = 1, dlci */
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_SABME | RFCOMM_PF;
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | 0;
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data   = RFCOMM_SABME_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = 4;
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_check_send_cmd(p_mcb, p_buf);
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_ua
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends UA frame.
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_ua (tRFC_MCB *p_mcb, UINT8 dlci)
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   cr = RFCOMM_CR(p_mcb->is_initiator, FALSE);
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET;
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* ua frame, response, PF = 1, dlci */
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_UA | RFCOMM_PF;
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | 0;
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data   = RFCOMM_UA_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = 4;
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_check_send_cmd(p_mcb, p_buf);
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_dm
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends DM frame.
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_dm (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN pf)
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   cr = RFCOMM_CR(p_mcb->is_initiator, FALSE);
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET;
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* DM frame, response, PF = 1, dlci */
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_DM | ((pf) ? RFCOMM_PF : 0);
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | 0;
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data   = RFCOMM_DM_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = 4;
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_check_send_cmd(p_mcb, p_buf);
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_disc
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends DISC frame.
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_disc (tRFC_MCB *p_mcb, UINT8 dlci)
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET;
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* DISC frame, command, PF = 1, dlci */
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_DISC | RFCOMM_PF;
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | 0;
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data   = RFCOMM_DISC_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = 4;
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_check_send_cmd(p_mcb, p_buf);
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_buf_uih
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends UIH frame.
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_buf_uih (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   credits;
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset -= RFCOMM_CTRL_FRAME_LEN;
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_buf->len > 127)
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset--;
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (dlci)
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        credits = (UINT8)p_buf->layer_specific;
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        credits = 0;
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (credits)
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset--;
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* UIH frame, command, PF = 0, dlci */
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_UIH | ((credits) ? RFCOMM_PF : 0);
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_buf->len <= 127)
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++   = RFCOMM_EA | (p_buf->len << 1);
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len += 3;
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++   = (p_buf->len & 0x7f) << 1;
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++   = p_buf->len >> RFCOMM_SHIFT_LENGTH2;
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len += 4;
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (credits)
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = credits;
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len++;
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data  = (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len++;
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci);
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (dlci == RFCOMM_MX_DLCI)
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_check_send_cmd(p_mcb, p_buf);
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CA_DataWrite (p_mcb->lcid, p_buf);
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_pn
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends DLC Parameters Negotiation Frame.
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_pn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT16 mtu, UINT8 cl, UINT8 k)
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR   *p_buf;
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    *p_data;
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_PN;
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | (RFCOMM_MX_PN_LEN << 1);
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = dlci;
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_PN_FRAM_TYPE_UIH | cl;
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* It appeared that we need to reply with the same priority bits as we received.
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    ** We will use the fact that we reply in the same context so rx_frame can still be used.
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (is_command)
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = RFCOMM_PN_PRIORITY_0;
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = rfc_cb.rfc.rx_frame.u.pn.priority;
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_T1_DSEC;
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = mtu & 0xFF;
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = mtu >> 8;
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_N2;
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data   = k;
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Total length is sizeof PN data + mx header 2 */
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = RFCOMM_MX_PN_LEN + 2;
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_fcon
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends Flow Control On Command.
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_fcon (tRFC_MCB *p_mcb, BOOLEAN is_command)
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCON;
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCON_LEN << 1);
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Total length is sizeof FCON data + mx header 2 */
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = RFCOMM_MX_FCON_LEN + 2;
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_fcoff
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends Flow Control Off Command.
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_fcoff (tRFC_MCB *p_mcb, BOOLEAN is_command)
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCOFF;
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCOFF_LEN << 1);
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Total length is sizeof FCOFF data + mx header 2 */
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = RFCOMM_MX_FCOFF_LEN + 2;
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_msc
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends Modem Status Command Frame.
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_msc (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command,
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   tPORT_CTRL *p_pars)
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   signals;
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   break_duration;
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   len;
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    signals        = p_pars->modem_signal;
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    break_duration = p_pars->break_signal;
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (break_duration)
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len = RFCOMM_MX_MSC_LEN_WITH_BREAK;
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len = RFCOMM_MX_MSC_LEN_NO_BREAK;
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_MSC;
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | (len << 1);
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA |
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ((p_pars->fc)                    ? RFCOMM_MSC_FC : 0)  |
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ((signals & MODEM_SIGNAL_DTRDSR) ? RFCOMM_MSC_RTC : 0) |
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ((signals & MODEM_SIGNAL_RTSCTS) ? RFCOMM_MSC_RTR : 0) |
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ((signals & MODEM_SIGNAL_RI)     ? RFCOMM_MSC_IC : 0)  |
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ((signals & MODEM_SIGNAL_DCD)    ? RFCOMM_MSC_DV : 0);
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (break_duration)
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = RFCOMM_EA | RFCOMM_MSC_BREAK_PRESENT_MASK |
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    (break_duration << RFCOMM_MSC_SHIFT_BREAK);
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Total length is sizeof MSC data + mx header 2 */
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = len + 2;
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_rls
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends Remote Line Status Command Frame.
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_rls (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT8 status)
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RLS;
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | (RFCOMM_MX_RLS_LEN << 1);
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_RLS_ERROR | status;
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Total length is sizeof RLS data + mx header 2 */
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = RFCOMM_MX_RLS_LEN + 2;
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_nsc
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends Non Supported Command Response.
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_nsc (tRFC_MCB *p_mcb)
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(FALSE) | RFCOMM_MX_NSC;
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | (RFCOMM_MX_NSC_LEN << 1);
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ =  rfc_cb.rfc.rx_frame.ea |
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (rfc_cb.rfc.rx_frame.cr << RFCOMM_SHIFT_CR) |
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                 rfc_cb.rfc.rx_frame.type;
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Total length is sizeof NSC data + mx header 2 */
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = RFCOMM_MX_NSC_LEN + 2;
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_rpn
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends Remote Port Negotiation Command
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_rpn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command,
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   tPORT_STATE *p_pars, UINT16 mask)
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR   *p_buf;
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    *p_data;
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RPN;
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_pars)
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_REQ_LEN << 1);
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len = RFCOMM_MX_RPN_REQ_LEN + 2;
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_LEN << 1);
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = p_pars->baud_rate;
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ =  (p_pars->byte_size << RFCOMM_RPN_BITS_SHIFT)
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   | (p_pars->stop_bits << RFCOMM_RPN_STOP_BITS_SHIFT)
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   | (p_pars->parity << RFCOMM_RPN_PARITY_SHIFT)
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   | (p_pars->parity_type << RFCOMM_RPN_PARITY_TYPE_SHIFT);
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = p_pars->fc_type;
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = p_pars->xon_char;
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = p_pars->xoff_char;
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = (mask & 0xFF);
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++ = (mask >> 8);
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Total length is sizeof RPN data + mx header 2 */
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len = RFCOMM_MX_RPN_LEN + 2;
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_test
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends Test frame.
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_test (tRFC_MCB *p_mcb, BOOLEAN is_command, BT_HDR *p_buf)
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    *p_data;
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16   xx;
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    *p_src, *p_dest;
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Shift buffer to give space for header */
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_buf->offset < (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2))
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_src  = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len - 1;
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_dest = (UINT8 *) (p_buf + 1) + L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2 + p_buf->len - 1;
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (xx = 0; xx < p_buf->len; xx++)
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_dest-- = *p_src--;
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Adjust offset by number of bytes we are going to fill */
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset -= 2;
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_TEST;
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | (p_buf->len << 1);
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len += 2;
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_send_credit
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sends a flow control credit in UIH frame.
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_send_credit(tRFC_MCB *p_mcb, UINT8 dlci, UINT8 credit)
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR   *p_buf;
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    *p_data;
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL)
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_MIN_OFFSET;
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_UIH | RFCOMM_PF;
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = RFCOMM_EA | 0;
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data++ = credit;
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data   = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci);
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = 5;
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_check_send_cmd(p_mcb, p_buf);
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_parse_data
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function processes data packet received from L2CAP
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 rfc_parse_data (tRFC_MCB *p_mcb, MX_FRAME *p_frame, BT_HDR *p_buf)
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8     ead, eal, fcs;
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8     *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8     *p_start = p_data;
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16    len;
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_buf->len < RFCOMM_CTRL_FRAME_LEN)
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
579d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati        RFCOMM_TRACE_ERROR ("Bad Length1: %d", p_buf->len);
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (RFC_EVENT_BAD_FRAME);
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_PARSE_CTRL_FIELD (ead, p_frame->cr, p_frame->dlci, p_data);
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( !ead )
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
586d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati        RFCOMM_TRACE_ERROR ("Bad Address(EA must be 1)");
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (RFC_EVENT_BAD_FRAME);
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_PARSE_TYPE_FIELD (p_frame->type, p_frame->pf, p_data);
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_PARSE_LEN_FIELD (eal, len, p_data);
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len      -= (3 + !ead + !eal + 1);  /* Additional 1 for FCS */
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset   += (3 + !ead + !eal);
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* handle credit if credit based flow control */
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) &&
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1))
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_frame->credit = *p_data++;
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len--;
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset++;
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_frame->credit = 0;
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_buf->len != len)
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
608d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati        RFCOMM_TRACE_ERROR ("Bad Length2 %d %d", p_buf->len, len);
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (RFC_EVENT_BAD_FRAME);
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    fcs = *(p_data + len);
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* All control frames that we are sending are sent with P=1, expect */
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* reply with F=1 */
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* According to TS 07.10 spec ivalid frames are discarded without */
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* notification to the sender */
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (p_frame->type)
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_SABME:
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || !p_frame->pf || len || !RFCOMM_VALID_DLCI (p_frame->dlci)
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs))
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
625d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad SABME");
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_BAD_FRAME);
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_SABME);
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_UA:
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr)
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project          || !p_frame->pf || len || !RFCOMM_VALID_DLCI (p_frame->dlci)
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project          || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs))
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
636d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad UA");
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_BAD_FRAME);
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_UA);
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_DM:
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr)
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || len || !RFCOMM_VALID_DLCI(p_frame->dlci)
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs))
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
647d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad DM");
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_BAD_FRAME);
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_DM);
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_DISC:
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project          || !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci)
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project          || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs))
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
658d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad DISC");
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_BAD_FRAME);
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_DISC);
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_UIH:
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!RFCOMM_VALID_DLCI(p_frame->dlci))
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
667d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad UIH - invalid DLCI");
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_BAD_FRAME);
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (!rfc_check_fcs (2, p_start, fcs))
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
672d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad UIH - FCS");
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_BAD_FRAME);
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr))
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* we assume that this is ok to allow bad implementations to work */
678d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad UIH - response");
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_UIH);
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (RFC_EVENT_UIH);
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (RFC_EVENT_BAD_FRAME);
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         rfc_process_mx_message
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function processes UIH frames received on the
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  multiplexer control channel.
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid rfc_process_mx_message (tRFC_MCB *p_mcb, BT_HDR *p_buf)
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    MX_FRAME    *p_rx_frame = &rfc_cb.rfc.rx_frame;
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16       length  = p_buf->len;
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8        ea, cr, mx_len;
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN      is_command;
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rx_frame->ea   = *p_data & RFCOMM_EA;
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rx_frame->cr   = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rx_frame->type = *p_data++ & ~(RFCOMM_CR_MASK | RFCOMM_EA_MASK);
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_rx_frame->ea || !length)
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
711d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati        RFCOMM_TRACE_ERROR ("Illegal MX Frame ea:%d len:%d", p_rx_frame->ea, length);
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    length--;
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    is_command = p_rx_frame->cr;
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    ea = *p_data & RFCOMM_EA;
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    mx_len = *p_data++ >> RFCOMM_SHIFT_LENGTH1;
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    length--;
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!ea)
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        mx_len += *p_data++ << RFCOMM_SHIFT_LENGTH2;
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        length --;
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (mx_len != length)
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
733d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati        RFCOMM_TRACE_ERROR ("Bad MX frame");
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (p_rx_frame->type)
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_PN:
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (length != RFCOMM_MX_PN_LEN)
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->dlci            = *p_data++ & RFCOMM_PN_DLCI_MASK;
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.pn.frame_type = *p_data & RFCOMM_PN_FRAME_TYPE_MASK;
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.pn.conv_layer = *p_data++ & RFCOMM_PN_CONV_LAYER_MASK;
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.pn.priority   = *p_data++ & RFCOMM_PN_PRIORITY_MASK;
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.pn.t1         = *p_data++;
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.pn.mtu        = *p_data + (*(p_data + 1) << 8);
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data += 2;
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.pn.n2         = *p_data++;
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.pn.k          = *p_data++ & RFCOMM_PN_K_MASK;
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_rx_frame->dlci
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || (p_rx_frame->u.pn.mtu < RFCOMM_MIN_MTU)
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || (p_rx_frame->u.pn.mtu > RFCOMM_MAX_MTU))
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
759d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad PN frame");
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_process_pn (p_mcb, is_command, p_rx_frame);
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_TEST:
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!length)
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.test.p_data   = p_data;
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.test.data_len = length;
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset += 2;
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len    -= 2;
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (is_command)
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rfc_send_test (p_mcb, FALSE, p_buf);
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rfc_process_test_rsp (p_mcb, p_buf);
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_FCON:
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (length != RFCOMM_MX_FCON_LEN)
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_process_fcon (p_mcb, is_command);
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_FCOFF:
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (length != RFCOMM_MX_FCOFF_LEN)
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_process_fcoff (p_mcb, is_command);
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_MSC:
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ea                   = *p_data & RFCOMM_EA;
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cr                   = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!ea || !cr || !p_rx_frame->dlci
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || !RFCOMM_VALID_DLCI (p_rx_frame->dlci))
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
811d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad MSC frame");
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.msc.signals        = *p_data++;
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mx_len == RFCOMM_MX_MSC_LEN_WITH_BREAK)
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.msc.break_present  = *p_data & RFCOMM_MSC_BREAK_PRESENT_MASK;
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.msc.break_duration = (*p_data & RFCOMM_MSC_BREAK_MASK) >> RFCOMM_MSC_SHIFT_BREAK;
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.msc.break_present  = FALSE;
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.msc.break_duration = 0;
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_process_msc (p_mcb, is_command, p_rx_frame);
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_NSC:
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((length != RFCOMM_MX_NSC_LEN) || !is_command)
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.nsc.ea   = *p_data & RFCOMM_EA;
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.nsc.cr   = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.nsc.type = *p_data++ >> RFCOMM_SHIFT_DLCI;
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_process_nsc (p_mcb, p_rx_frame);
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_RPN:
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((length != RFCOMM_MX_RPN_REQ_LEN) && (length != RFCOMM_MX_RPN_LEN))
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ea                   = *p_data & RFCOMM_EA;
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cr                   = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!ea || !cr || !p_rx_frame->dlci
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || !RFCOMM_VALID_DLCI (p_rx_frame->dlci))
8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
856d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad RPN frame");
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.rpn.is_request  = (length == RFCOMM_MX_RPN_REQ_LEN);
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_rx_frame->u.rpn.is_request)
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.baud_rate   = *p_data++;
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.byte_size   = (*p_data >> RFCOMM_RPN_BITS_SHIFT) & RFCOMM_RPN_BITS_MASK;
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.stop_bits   = (*p_data >> RFCOMM_RPN_STOP_BITS_SHIFT) & RFCOMM_RPN_STOP_BITS_MASK;
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.parity      = (*p_data >> RFCOMM_RPN_PARITY_SHIFT) & RFCOMM_RPN_PARITY_MASK;
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.parity_type = (*p_data++ >> RFCOMM_RPN_PARITY_TYPE_SHIFT) & RFCOMM_RPN_PARITY_TYPE_MASK;
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.fc_type     = *p_data++ & RFCOMM_FC_MASK;
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.xon_char    = *p_data++;
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.xoff_char   = *p_data++;
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rx_frame->u.rpn.param_mask  = (*p_data + (*(p_data + 1) << 8)) & RFCOMM_RPN_PM_MASK;
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_process_rpn (p_mcb, is_command, p_rx_frame->u.rpn.is_request, p_rx_frame);
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case RFCOMM_MX_RLS:
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (length != RFCOMM_MX_RLS_LEN)
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ea = *p_data & RFCOMM_EA;
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->dlci              = *p_data++ >> RFCOMM_SHIFT_DLCI;
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rx_frame->u.rls.line_status = (*p_data & ~0x01);
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!ea || !cr || !p_rx_frame->dlci
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || !RFCOMM_VALID_DLCI (p_rx_frame->dlci))
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
893d5bba906b0704cd60e824613bd2e438935ba5d89Sharvil Nanavati            RFCOMM_TRACE_ERROR ("Bad RPN frame");
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_process_rls (p_mcb, is_command, p_rx_frame);
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_freebuf (p_buf);
9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (is_command)
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_send_nsc (p_mcb);
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
909