1/****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/***************************************************************************** 20 * 21 * This file contains functions callable by an application 22 * running on top of RFCOMM 23 * 24 *****************************************************************************/ 25 26#include <string.h> 27#include "bt_target.h" 28#include "gki.h" 29#include "rfcdefs.h" 30#include "port_api.h" 31#include "l2c_api.h" 32#include "port_int.h" 33#include "rfc_int.h" 34 35 36#if RFC_DYNAMIC_MEMORY == FALSE 37tRFC_CB rfc_cb; 38#endif 39 40/******************************************************************************* 41** 42** Function RFCOMM_StartReq 43** 44** Description This function handles Start Request from the upper layer. 45** If RFCOMM multiplexer channel can not be allocated 46** send start not accepted confirmation. Otherwise dispatch 47** start event to the state machine. 48** 49*******************************************************************************/ 50void RFCOMM_StartReq (tRFC_MCB *p_mcb) 51{ 52 rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_REQ, NULL); 53} 54 55 56/******************************************************************************* 57** 58** Function RFCOMM_StartRsp 59** 60** Description This function handles Start Response from the upper layer. 61** Save upper layer handle and result of the Start Indication 62** in the control block and dispatch event to the FSM. 63** 64*******************************************************************************/ 65void RFCOMM_StartRsp (tRFC_MCB *p_mcb, UINT16 result) 66{ 67 rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_RSP, &result); 68} 69 70 71/******************************************************************************* 72** 73** Function RFCOMM_DlcEstablishReq 74** 75** Description This function is called by the user app to establish 76** connection with the specific dlci on a specific bd device. 77** It will allocate RFCOMM connection control block if not 78** allocated before and dispatch open event to the state 79** machine. 80** 81*******************************************************************************/ 82void RFCOMM_DlcEstablishReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) 83{ 84 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); 85 86 if (p_mcb->state != RFC_MX_STATE_CONNECTED) 87 { 88 PORT_DlcEstablishCnf (p_mcb, dlci, 0, RFCOMM_ERROR); 89 return; 90 } 91 92 rfc_port_sm_execute(p_port, RFC_EVENT_OPEN, NULL); 93} 94 95 96/******************************************************************************* 97** 98** Function RFCOMM_DlcEstablishRsp 99** 100** Description This function is called by the port emulation entity 101** acks Establish Indication. 102** 103*******************************************************************************/ 104void RFCOMM_DlcEstablishRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result) 105{ 106 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); 107 108 if ((p_mcb->state != RFC_MX_STATE_CONNECTED) && (result == RFCOMM_SUCCESS)) 109 { 110 PORT_DlcReleaseInd (p_mcb, dlci); 111 return; 112 } 113 114 rfc_port_sm_execute(p_port, RFC_EVENT_ESTABLISH_RSP, &result); 115} 116 117 118/******************************************************************************* 119** 120** Function RFCOMM_ParNegReq 121** 122** Description This function is called by the user app to start 123** DLC parameter negotiation. Port emulation can send this 124** request before actually establishing the DLC. In this 125** case the function will allocate RFCOMM connection control 126** block. 127** 128*******************************************************************************/ 129void RFCOMM_ParNegReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) 130{ 131 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); 132 UINT8 flow; 133 UINT8 cl; 134 UINT8 k; 135 136 if (p_mcb->state != RFC_MX_STATE_CONNECTED) 137 { 138 p_port->error = PORT_PAR_NEG_FAILED; 139 return; 140 } 141 142 /* Negotiate the flow control mechanism. If flow control mechanism for */ 143 /* mux has not been set yet, use our default value. If it has been set, */ 144 /* use that value. */ 145 flow = (p_mcb->flow == PORT_FC_UNDEFINED) ? PORT_FC_DEFAULT : p_mcb->flow; 146 147 /* Set convergence layer and number of credits (k) */ 148 if (flow == PORT_FC_CREDIT) 149 { 150 cl = RFCOMM_PN_CONV_LAYER_CBFC_I; 151 k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max : RFCOMM_K_MAX; 152 p_port->credit_rx = k; 153 } 154 else 155 { 156 cl = RFCOMM_PN_CONV_LAYER_TYPE_1; 157 k = 0; 158 } 159 160 /* Send Parameter Negotiation Command UIH frame */ 161 p_port->rfc.expected_rsp |= RFC_RSP_PN; 162 163 rfc_send_pn (p_mcb, dlci, TRUE, mtu, cl, k); 164 165 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ; 166} 167 168 169/******************************************************************************* 170** 171** Function RFCOMM_ParNegRsp 172** 173** Description This function is called by the user app to acknowledge 174** DLC parameter negotiation. 175** 176*******************************************************************************/ 177void RFCOMM_ParNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k) 178{ 179 if (p_mcb->state != RFC_MX_STATE_CONNECTED) 180 return; 181 182 /* Send Parameter Negotiation Response UIH frame */ 183 rfc_send_pn (p_mcb, dlci, FALSE, mtu, cl, k); 184} 185 186 187/******************************************************************************* 188** 189** Function RFCOMM_PortNegReq 190** 191** Description This function is called by the user app to start 192** Remote Port parameter negotiation. Port emulation can 193** send this request before actually establishing the DLC. 194** In this case the function will allocate RFCOMM connection 195** control block. 196** 197*******************************************************************************/ 198void RFCOMM_PortNegReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars) 199{ 200 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); 201 202 if (p_mcb->state != RFC_MX_STATE_CONNECTED) 203 { 204 PORT_PortNegCnf (p_mcb, dlci, NULL, RFCOMM_ERROR); 205 return; 206 } 207 208 /* Send Parameter Negotiation Command UIH frame */ 209 if (!p_pars) 210 p_port->rfc.expected_rsp |= RFC_RSP_RPN_REPLY; 211 else 212 p_port->rfc.expected_rsp |= RFC_RSP_RPN; 213 214 rfc_send_rpn (p_mcb, dlci, TRUE, p_pars, RFCOMM_RPN_PM_MASK); 215 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ; 216 217} 218 219 220/******************************************************************************* 221** 222** Function RFCOMM_PortNegRsp 223** 224** Description This function is called by the user app to acknowledge 225** Port parameters negotiation. 226** 227*******************************************************************************/ 228void RFCOMM_PortNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars, 229 UINT16 param_mask) 230{ 231 if (p_mcb->state != RFC_MX_STATE_CONNECTED) 232 return; 233 234 rfc_send_rpn (p_mcb, dlci, FALSE, p_pars, param_mask); 235} 236 237 238/******************************************************************************* 239** 240** Function RFCOMM_ControlReq 241** 242** Description This function is called by the port entity to send control 243** parameters to remote port emulation entity. 244** 245*******************************************************************************/ 246void RFCOMM_ControlReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars) 247{ 248 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); 249 250 if ((p_port->state != PORT_STATE_OPENED) 251 || (p_port->rfc.state != RFC_STATE_OPENED)) 252 return; 253 254 p_port->port_ctrl |= PORT_CTRL_REQ_SENT; 255 256 p_port->rfc.expected_rsp |= RFC_RSP_MSC; 257 258 rfc_send_msc (p_mcb, dlci, TRUE, p_pars); 259 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ; 260 261} 262 263 264/******************************************************************************* 265** 266** Function RFCOMM_FlowReq 267** 268** Description This function is called by the port entity when flow 269** control state has changed. Enable flag passed shows if 270** port can accept more data. 271** 272*******************************************************************************/ 273void RFCOMM_FlowReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 enable) 274{ 275 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); 276 277 if ((p_port->state != PORT_STATE_OPENED) 278 || (p_port->rfc.state != RFC_STATE_OPENED)) 279 return; 280 281 p_port->local_ctrl.fc = !enable; 282 283 p_port->rfc.expected_rsp |= RFC_RSP_MSC; 284 285 rfc_send_msc (p_mcb, dlci, TRUE, &p_port->local_ctrl); 286 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ; 287 288} 289 290 291/******************************************************************************* 292** 293** Function RFCOMM_LineStatusReq 294** 295** Description This function is called by the port entity when line 296** status should be delivered to the peer. 297** 298*******************************************************************************/ 299void RFCOMM_LineStatusReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 status) 300{ 301 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); 302 303 if ((p_port->state != PORT_STATE_OPENED) 304 || (p_port->rfc.state != RFC_STATE_OPENED)) 305 return; 306 307 p_port->rfc.expected_rsp |= RFC_RSP_RLS; 308 309 rfc_send_rls (p_mcb, dlci, TRUE, status); 310 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT); 311} 312 313 314/******************************************************************************* 315** 316** Function RFCOMM_DlcReleaseReq 317** 318** Description This function is called by the PORT unit to close DLC 319** 320*******************************************************************************/ 321void RFCOMM_DlcReleaseReq (tRFC_MCB *p_mcb, UINT8 dlci) 322{ 323 rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, 0); 324} 325 326 327/******************************************************************************* 328** 329** Function RFCOMM_DataReq 330** 331** Description This function is called by the user app to send data buffer 332** 333*******************************************************************************/ 334void RFCOMM_DataReq (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf) 335{ 336 rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_DATA, p_buf); 337} 338 339 340