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