1 /******************************************************************************
3 * Copyright (c) 2014 The Android Open Source Project
4 * Copyright (C) 2004-2012 Broadcom Corporation
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 ******************************************************************************/
20 /******************************************************************************
22 * This file contains the audio gateway functions controlling the RFCOMM
25 ******************************************************************************/
29 #include "bta_hf_client_int.h"
33 /*******************************************************************************
35 ** Function bta_hf_client_port_cback
37 ** Description RFCOMM Port callback
42 *******************************************************************************/
43 static void bta_hf_client_port_cback(UINT32 code, UINT16 port_handle)
48 /* ignore port events for port handles other than connected handle */
49 if (port_handle != bta_hf_client_cb.scb.conn_handle)
51 APPL_TRACE_DEBUG("bta_hf_client_port_cback ignoring handle:%d conn_handle = %d",
52 port_handle, bta_hf_client_cb.scb.conn_handle);
56 if ((p_buf = (BT_HDR *) osi_getbuf(sizeof(BT_HDR))) != NULL)
58 p_buf->event = BTA_HF_CLIENT_RFC_DATA_EVT;
59 bta_sys_sendmsg(p_buf);
63 /*******************************************************************************
65 ** Function bta_hf_client_mgmt_cback
67 ** Description RFCOMM management callback
72 *******************************************************************************/
73 static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle)
75 tBTA_HF_CLIENT_RFC *p_buf;
78 APPL_TRACE_DEBUG("bta_hf_client_mgmt_cback : code = %d, port_handle = %d, conn_handle = %d, serv_handle = %d",
79 code, port_handle, bta_hf_client_cb.scb.conn_handle, bta_hf_client_cb.scb.serv_handle);
81 /* ignore close event for port handles other than connected handle */
82 if ((code != PORT_SUCCESS) && (port_handle != bta_hf_client_cb.scb.conn_handle))
84 APPL_TRACE_DEBUG("bta_hf_client_mgmt_cback ignoring handle:%d", port_handle);
88 if (code == PORT_SUCCESS)
90 if ((bta_hf_client_cb.scb.conn_handle && (port_handle == bta_hf_client_cb.scb.conn_handle)) || /* outgoing connection */
91 (port_handle == bta_hf_client_cb.scb.serv_handle)) /* incoming connection */
93 event = BTA_HF_CLIENT_RFC_OPEN_EVT;
97 APPL_TRACE_ERROR ("bta_hf_client_mgmt_cback: PORT_SUCCESS, ignoring handle = %d", port_handle);
101 /* distinguish server close events */
102 else if (port_handle == bta_hf_client_cb.scb.conn_handle)
104 event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
108 event = BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT;
111 if ((p_buf = (tBTA_HF_CLIENT_RFC *) osi_getbuf(sizeof(tBTA_HF_CLIENT_RFC))) != NULL)
113 p_buf->hdr.event = event;
114 p_buf->port_handle = port_handle;
115 bta_sys_sendmsg(p_buf);
119 /*******************************************************************************
121 ** Function bta_hf_client_setup_port
123 ** Description Setup RFCOMM port for use by HF Client.
128 *******************************************************************************/
129 void bta_hf_client_setup_port(UINT16 handle)
131 PORT_SetEventMask(handle, PORT_EV_RXCHAR);
132 PORT_SetEventCallback(handle, bta_hf_client_port_cback);
135 /*******************************************************************************
137 ** Function bta_hf_client_start_server
139 ** Description Setup RFCOMM server for use by HF Client.
144 *******************************************************************************/
145 void bta_hf_client_start_server(void)
149 if (bta_hf_client_cb.scb.serv_handle > 0)
151 APPL_TRACE_DEBUG("%s already started, handle: %d", __FUNCTION__, bta_hf_client_cb.scb.serv_handle);
155 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_HF_HANDSFREE, bta_hf_client_cb.scb.serv_sec_mask,
156 BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, bta_hf_client_cb.scn);
158 port_status = RFCOMM_CreateConnection(UUID_SERVCLASS_HF_HANDSFREE, bta_hf_client_cb.scn,
159 TRUE, BTA_HF_CLIENT_MTU, (UINT8 *) bd_addr_any, &(bta_hf_client_cb.scb.serv_handle),
160 bta_hf_client_mgmt_cback);
162 if (port_status == PORT_SUCCESS)
164 bta_hf_client_setup_port(bta_hf_client_cb.scb.serv_handle);
168 /* TODO: can we handle this better? */
169 APPL_TRACE_DEBUG("bta_hf_client_start_server: RFCOMM_CreateConnection returned error:%d", port_status);
172 APPL_TRACE_DEBUG("bta_hf_client_start_server handle: %d", bta_hf_client_cb.scb.serv_handle);
175 /*******************************************************************************
177 ** Function bta_hf_client_close_server
179 ** Description Close RFCOMM server port for use by HF Client.
184 *******************************************************************************/
185 void bta_hf_client_close_server(void)
187 APPL_TRACE_DEBUG("%s %d", __FUNCTION__, bta_hf_client_cb.scb.serv_handle);
189 if (bta_hf_client_cb.scb.serv_handle == 0)
191 APPL_TRACE_DEBUG("%s already stopped", __FUNCTION__);
195 RFCOMM_RemoveServer(bta_hf_client_cb.scb.serv_handle);
196 bta_hf_client_cb.scb.serv_handle = 0;
199 /*******************************************************************************
201 ** Function bta_hf_client_rfc_do_open
203 ** Description Open an RFCOMM connection to the peer device.
208 *******************************************************************************/
209 void bta_hf_client_rfc_do_open(tBTA_HF_CLIENT_DATA *p_data)
211 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_HF_HANDSFREE,
212 bta_hf_client_cb.scb.cli_sec_mask, BT_PSM_RFCOMM,
213 BTM_SEC_PROTO_RFCOMM, bta_hf_client_cb.scb.peer_scn);
215 if (RFCOMM_CreateConnection(UUID_SERVCLASS_HF_HANDSFREE, bta_hf_client_cb.scb.peer_scn,
216 FALSE, BTA_HF_CLIENT_MTU, bta_hf_client_cb.scb.peer_addr, &(bta_hf_client_cb.scb.conn_handle),
217 bta_hf_client_mgmt_cback) == PORT_SUCCESS)
219 bta_hf_client_setup_port(bta_hf_client_cb.scb.conn_handle);
220 APPL_TRACE_DEBUG("bta_hf_client_rfc_do_open : conn_handle = %d", bta_hf_client_cb.scb.conn_handle);
222 /* RFCOMM create connection failed; send ourselves RFCOMM close event */
225 bta_hf_client_sm_execute(BTA_HF_CLIENT_RFC_CLOSE_EVT, p_data);
229 /*******************************************************************************
231 ** Function bta_hf_client_rfc_do_close
233 ** Description Close RFCOMM connection.
238 *******************************************************************************/
239 void bta_hf_client_rfc_do_close(tBTA_HF_CLIENT_DATA *p_data)
241 tBTA_HF_CLIENT_RFC *p_buf;
244 if (bta_hf_client_cb.scb.conn_handle)
246 RFCOMM_RemoveConnection(bta_hf_client_cb.scb.conn_handle);
250 /* Close API was called while HF Client is in Opening state. */
251 /* Need to trigger the state machine to send callback to the app */
252 /* and move back to INIT state. */
253 if ((p_buf = (tBTA_HF_CLIENT_RFC *) osi_getbuf(sizeof(tBTA_HF_CLIENT_RFC))) != NULL)
255 p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
256 bta_sys_sendmsg(p_buf);
259 /* Cancel SDP if it had been started. */
260 if(bta_hf_client_cb.scb.p_disc_db)
262 (void)SDP_CancelServiceSearch (bta_hf_client_cb.scb.p_disc_db);
263 bta_hf_client_free_db(NULL);