| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- /******************************************************************************
- *
- * Copyright (C) 1999-2012 Broadcom Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
- /*****************************************************************************
- *
- * This file contains functions callable by an application
- * running on top of RFCOMM
- *
- *****************************************************************************/
- #include <string.h>
- #include "common/bt_target.h"
- #include "stack/rfcdefs.h"
- #include "stack/port_api.h"
- #include "stack/l2c_api.h"
- #include "port_int.h"
- #include "rfc_int.h"
- #include "common/bt_defs.h"
- #if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
- #if RFC_DYNAMIC_MEMORY == FALSE
- tRFC_CB rfc_cb;
- #else
- tRFC_CB *rfc_cb_ptr;
- #endif
- /*******************************************************************************
- **
- ** Function RFCOMM_StartReq
- **
- ** Description This function handles Start Request from the upper layer.
- ** If RFCOMM multiplexer channel can not be allocated
- ** send start not accepted confirmation. Otherwise dispatch
- ** start event to the state machine.
- **
- *******************************************************************************/
- void RFCOMM_StartReq (tRFC_MCB *p_mcb)
- {
- rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_REQ, NULL);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_StartRsp
- **
- ** Description This function handles Start Response from the upper layer.
- ** Save upper layer handle and result of the Start Indication
- ** in the control block and dispatch event to the FSM.
- **
- *******************************************************************************/
- void RFCOMM_StartRsp (tRFC_MCB *p_mcb, UINT16 result)
- {
- rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_RSP, &result);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_DlcEstablishReq
- **
- ** Description This function is called by the user app to establish
- ** connection with the specific dlci on a specific bd device.
- ** It will allocate RFCOMM connection control block if not
- ** allocated before and dispatch open event to the state
- ** machine.
- **
- *******************************************************************************/
- void RFCOMM_DlcEstablishReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
- {
- UNUSED(mtu);
- if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
- PORT_DlcEstablishCnf (p_mcb, dlci, 0, RFCOMM_ERROR);
- return;
- }
- tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
- if (p_port == NULL) {
- RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
- dlci);
- return;
- }
- rfc_port_sm_execute(p_port, RFC_EVENT_OPEN, NULL);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_DlcEstablishRsp
- **
- ** Description This function is called by the port emulation entity
- ** acks Establish Indication.
- **
- *******************************************************************************/
- void RFCOMM_DlcEstablishRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
- {
- UNUSED(mtu);
- if ((p_mcb->state != RFC_MX_STATE_CONNECTED) && (result == RFCOMM_SUCCESS)) {
- PORT_DlcReleaseInd (p_mcb, dlci);
- return;
- }
- tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
- if (p_port == NULL) {
- RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
- dlci);
- return;
- }
- rfc_port_sm_execute(p_port, RFC_EVENT_ESTABLISH_RSP, &result);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_ParNegReq
- **
- ** Description This function is called by the user app to start
- ** DLC parameter negotiation. Port emulation can send this
- ** request before actually establishing the DLC. In this
- ** case the function will allocate RFCOMM connection control
- ** block.
- **
- *******************************************************************************/
- void RFCOMM_ParNegReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
- {
- UINT8 flow;
- UINT8 cl;
- UINT8 k;
- tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
- if (p_port == NULL) {
- RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
- dlci);
- return;
- }
- if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
- p_port->error = PORT_PAR_NEG_FAILED;
- return;
- }
- /* Negotiate the flow control mechanism. If flow control mechanism for */
- /* mux has not been set yet, use our default value. If it has been set, */
- /* use that value. */
- flow = (p_mcb->flow == PORT_FC_UNDEFINED) ? PORT_FC_DEFAULT : p_mcb->flow;
- /* Set convergence layer and number of credits (k) */
- if (flow == PORT_FC_CREDIT) {
- cl = RFCOMM_PN_CONV_LAYER_CBFC_I;
- k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max : RFCOMM_K_MAX;
- p_port->credit_rx = k;
- } else {
- cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
- k = 0;
- }
- /* Send Parameter Negotiation Command UIH frame */
- p_port->rfc.expected_rsp |= RFC_RSP_PN;
- rfc_send_pn (p_mcb, dlci, TRUE, mtu, cl, k);
- rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_ParNegRsp
- **
- ** Description This function is called by the user app to acknowledge
- ** DLC parameter negotiation.
- **
- *******************************************************************************/
- void RFCOMM_ParNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
- {
- if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
- return;
- }
- /* Send Parameter Negotiation Response UIH frame */
- rfc_send_pn (p_mcb, dlci, FALSE, mtu, cl, k);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_PortNegReq
- **
- ** Description This function is called by the user app to start
- ** Remote Port parameter negotiation. Port emulation can
- ** send this request before actually establishing the DLC.
- ** In this case the function will allocate RFCOMM connection
- ** control block.
- **
- *******************************************************************************/
- void RFCOMM_PortNegReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars)
- {
- if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
- PORT_PortNegCnf (p_mcb, dlci, NULL, RFCOMM_ERROR);
- return;
- }
- tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
- if (p_port == NULL) {
- RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
- dlci);
- return;
- }
- /* Send Parameter Negotiation Command UIH frame */
- if (!p_pars) {
- p_port->rfc.expected_rsp |= RFC_RSP_RPN_REPLY;
- } else {
- p_port->rfc.expected_rsp |= RFC_RSP_RPN;
- }
- rfc_send_rpn (p_mcb, dlci, TRUE, p_pars, RFCOMM_RPN_PM_MASK);
- rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_PortNegRsp
- **
- ** Description This function is called by the user app to acknowledge
- ** Port parameters negotiation.
- **
- *******************************************************************************/
- void RFCOMM_PortNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars,
- UINT16 param_mask)
- {
- if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
- return;
- }
- rfc_send_rpn (p_mcb, dlci, FALSE, p_pars, param_mask);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_ControlReq
- **
- ** Description This function is called by the port entity to send control
- ** parameters to remote port emulation entity.
- **
- *******************************************************************************/
- void RFCOMM_ControlReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars)
- {
- tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
- if (p_port == NULL) {
- RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
- dlci);
- return;
- }
- if ((p_port->state != PORT_STATE_OPENED)
- || (p_port->rfc.state != RFC_STATE_OPENED)) {
- return;
- }
- p_port->port_ctrl |= PORT_CTRL_REQ_SENT;
- p_port->rfc.expected_rsp |= RFC_RSP_MSC;
- rfc_send_msc (p_mcb, dlci, TRUE, p_pars);
- rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_FlowReq
- **
- ** Description This function is called by the port entity when flow
- ** control state has changed. Enable flag passed shows if
- ** port can accept more data.
- **
- *******************************************************************************/
- void RFCOMM_FlowReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 enable)
- {
- tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
- if (p_port == NULL) {
- RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
- dlci);
- return;
- }
- if ((p_port->state != PORT_STATE_OPENED)
- || (p_port->rfc.state != RFC_STATE_OPENED)) {
- return;
- }
- p_port->local_ctrl.fc = !enable;
- p_port->rfc.expected_rsp |= RFC_RSP_MSC;
- rfc_send_msc (p_mcb, dlci, TRUE, &p_port->local_ctrl);
- rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_LineStatusReq
- **
- ** Description This function is called by the port entity when line
- ** status should be delivered to the peer.
- **
- *******************************************************************************/
- void RFCOMM_LineStatusReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 status)
- {
- tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
- if (p_port == NULL) {
- RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
- dlci);
- return;
- }
- if ((p_port->state != PORT_STATE_OPENED)
- || (p_port->rfc.state != RFC_STATE_OPENED)) {
- return;
- }
- p_port->rfc.expected_rsp |= RFC_RSP_RLS;
- rfc_send_rls (p_mcb, dlci, TRUE, status);
- rfc_port_timer_start (p_port, RFC_T2_TIMEOUT);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_DlcReleaseReq
- **
- ** Description This function is called by the PORT unit to close DLC
- **
- *******************************************************************************/
- void RFCOMM_DlcReleaseReq (tRFC_MCB *p_mcb, UINT8 dlci)
- {
- rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, 0);
- }
- /*******************************************************************************
- **
- ** Function RFCOMM_DataReq
- **
- ** Description This function is called by the user app to send data buffer
- **
- *******************************************************************************/
- void RFCOMM_DataReq (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
- {
- rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_DATA, p_buf);
- }
- #endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
|