blob: 4c73b5a4fd88422b72408b1be5e3b0f9f92a1621 [file] [log] [blame]
Hemant Gupta3fe1b492014-04-29 16:23:59 +05301/******************************************************************************
2 *
Hemant Gupta10256872013-08-19 18:33:01 +05303 * Copyright (c) 2014 The Android Open Source Project
Hemant Gupta3fe1b492014-04-29 16:23:59 +05304 * Copyright (C) 2004-2012 Broadcom Corporation
5 *
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:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
18 ******************************************************************************/
19
20/******************************************************************************
21 *
22 * This file contains the audio gateway functions controlling the RFCOMM
23 * connections.
24 *
25 ******************************************************************************/
26
27#include <string.h>
28#include "bta_api.h"
Hemant Gupta10256872013-08-19 18:33:01 +053029#include "bta_hf_client_int.h"
Hemant Gupta3fe1b492014-04-29 16:23:59 +053030#include "port_api.h"
Hemant Gupta3fe1b492014-04-29 16:23:59 +053031#include "bd.h"
Hemant Gupta10256872013-08-19 18:33:01 +053032#include "bt_utils.h"
Hemant Gupta3fe1b492014-04-29 16:23:59 +053033
34/*******************************************************************************
35**
Hemant Gupta10256872013-08-19 18:33:01 +053036** Function bta_hf_client_port_cback
Hemant Gupta3fe1b492014-04-29 16:23:59 +053037**
38** Description RFCOMM Port callback
39**
40**
41** Returns void
42**
43*******************************************************************************/
Hemant Gupta10256872013-08-19 18:33:01 +053044static void bta_hf_client_port_cback(UINT32 code, UINT16 port_handle)
Hemant Gupta3fe1b492014-04-29 16:23:59 +053045{
46 BT_HDR *p_buf;
Hemant Gupta3fe1b492014-04-29 16:23:59 +053047 UNUSED(code);
48
Hemant Gupta10256872013-08-19 18:33:01 +053049 /* ignore port events for port handles other than connected handle */
50 if (port_handle != bta_hf_client_cb.scb.conn_handle)
Hemant Gupta3fe1b492014-04-29 16:23:59 +053051 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070052 APPL_TRACE_DEBUG("bta_hf_client_port_cback ignoring handle:%d conn_handle = %d",
Hemant Gupta10256872013-08-19 18:33:01 +053053 port_handle, bta_hf_client_cb.scb.conn_handle);
54 return;
55 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +053056
Hemant Gupta10256872013-08-19 18:33:01 +053057 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
58 {
59 p_buf->event = BTA_HF_CLIENT_RFC_DATA_EVT;
60 bta_sys_sendmsg(p_buf);
Hemant Gupta3fe1b492014-04-29 16:23:59 +053061 }
62}
63
64/*******************************************************************************
65**
Hemant Gupta10256872013-08-19 18:33:01 +053066** Function bta_hf_client_mgmt_cback
Hemant Gupta3fe1b492014-04-29 16:23:59 +053067**
68** Description RFCOMM management callback
69**
70**
71** Returns void
72**
73*******************************************************************************/
Hemant Gupta10256872013-08-19 18:33:01 +053074static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle)
Hemant Gupta3fe1b492014-04-29 16:23:59 +053075{
Hemant Gupta10256872013-08-19 18:33:01 +053076 tBTA_HF_CLIENT_RFC *p_buf;
77 UINT16 event;
Hemant Gupta3fe1b492014-04-29 16:23:59 +053078
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070079 APPL_TRACE_DEBUG("bta_hf_client_mgmt_cback : code = %d, port_handle = %d, conn_handle = %d, serv_handle = %d",
Hemant Gupta10256872013-08-19 18:33:01 +053080 code, port_handle, bta_hf_client_cb.scb.conn_handle, bta_hf_client_cb.scb.serv_handle);
Hemant Gupta3fe1b492014-04-29 16:23:59 +053081
Hemant Gupta10256872013-08-19 18:33:01 +053082 /* ignore close event for port handles other than connected handle */
83 if ((code != PORT_SUCCESS) && (port_handle != bta_hf_client_cb.scb.conn_handle))
Hemant Gupta3fe1b492014-04-29 16:23:59 +053084 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070085 APPL_TRACE_DEBUG("bta_hf_client_mgmt_cback ignoring handle:%d", port_handle);
Hemant Gupta10256872013-08-19 18:33:01 +053086 return;
87 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +053088
Hemant Gupta10256872013-08-19 18:33:01 +053089 if (code == PORT_SUCCESS)
90 {
91 if ((bta_hf_client_cb.scb.conn_handle && (port_handle == bta_hf_client_cb.scb.conn_handle)) || /* outgoing connection */
92 (port_handle == bta_hf_client_cb.scb.serv_handle)) /* incoming connection */
Hemant Gupta3fe1b492014-04-29 16:23:59 +053093 {
Hemant Gupta10256872013-08-19 18:33:01 +053094 event = BTA_HF_CLIENT_RFC_OPEN_EVT;
Hemant Gupta3fe1b492014-04-29 16:23:59 +053095 }
96 else
97 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070098 APPL_TRACE_ERROR ("bta_hf_client_mgmt_cback: PORT_SUCCESS, ignoring handle = %d", port_handle);
Hemant Gupta10256872013-08-19 18:33:01 +053099 return;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530100 }
101 }
Hemant Gupta10256872013-08-19 18:33:01 +0530102 /* distinguish server close events */
103 else if (port_handle == bta_hf_client_cb.scb.conn_handle)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530104 {
Hemant Gupta10256872013-08-19 18:33:01 +0530105 event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
106 }
107 else
108 {
109 event = BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530110 }
111
Hemant Gupta10256872013-08-19 18:33:01 +0530112 if ((p_buf = (tBTA_HF_CLIENT_RFC *) GKI_getbuf(sizeof(tBTA_HF_CLIENT_RFC))) != NULL)
113 {
114 p_buf->hdr.event = event;
115 p_buf->port_handle = port_handle;
116 bta_sys_sendmsg(p_buf);
117 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530118}
119
120/*******************************************************************************
121**
Hemant Gupta10256872013-08-19 18:33:01 +0530122** Function bta_hf_client_setup_port
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530123**
Hemant Gupta10256872013-08-19 18:33:01 +0530124** Description Setup RFCOMM port for use by HF Client.
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530125**
126**
127** Returns void
128**
129*******************************************************************************/
Hemant Gupta10256872013-08-19 18:33:01 +0530130void bta_hf_client_setup_port(UINT16 handle)
131{
132 PORT_SetEventMask(handle, PORT_EV_RXCHAR);
133 PORT_SetEventCallback(handle, bta_hf_client_port_cback);
134}
135
136/*******************************************************************************
137**
138** Function bta_hf_client_start_server
139**
140** Description Setup RFCOMM server for use by HF Client.
141**
142**
143** Returns void
144**
145*******************************************************************************/
146void bta_hf_client_start_server(void)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530147{
148 int i;
Hemant Gupta10256872013-08-19 18:33:01 +0530149 int port_status;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530150
Hemant Gupta10256872013-08-19 18:33:01 +0530151 if (bta_hf_client_cb.scb.serv_handle > 0)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530152 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700153 APPL_TRACE_DEBUG("%s already started, handle: %d", __FUNCTION__, bta_hf_client_cb.scb.serv_handle);
Hemant Gupta10256872013-08-19 18:33:01 +0530154 return;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530155 }
Hemant Gupta10256872013-08-19 18:33:01 +0530156
157 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_HF_HANDSFREE, bta_hf_client_cb.scb.serv_sec_mask,
158 BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, bta_hf_client_cb.scn);
159
160 port_status = RFCOMM_CreateConnection(UUID_SERVCLASS_HF_HANDSFREE, bta_hf_client_cb.scn,
161 TRUE, BTA_HF_CLIENT_MTU, (UINT8 *) bd_addr_any, &(bta_hf_client_cb.scb.serv_handle),
162 bta_hf_client_mgmt_cback);
163
164 if (port_status == PORT_SUCCESS)
165 {
166 bta_hf_client_setup_port(bta_hf_client_cb.scb.serv_handle);
167 }
168 else
169 {
170 /* TODO: can we handle this better? */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700171 APPL_TRACE_DEBUG("bta_hf_client_start_server: RFCOMM_CreateConnection returned error:%d", port_status);
Hemant Gupta10256872013-08-19 18:33:01 +0530172 }
173
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700174 APPL_TRACE_DEBUG("bta_hf_client_start_server handle: %d", bta_hf_client_cb.scb.serv_handle);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530175}
176
177/*******************************************************************************
178**
Hemant Gupta10256872013-08-19 18:33:01 +0530179** Function bta_hf_client_close_server
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530180**
Hemant Gupta10256872013-08-19 18:33:01 +0530181** Description Close RFCOMM server port for use by HF Client.
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530182**
183**
184** Returns void
185**
186*******************************************************************************/
Hemant Gupta10256872013-08-19 18:33:01 +0530187void bta_hf_client_close_server(void)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530188{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700189 APPL_TRACE_DEBUG("%s %d", __FUNCTION__, bta_hf_client_cb.scb.serv_handle);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530190
Hemant Gupta10256872013-08-19 18:33:01 +0530191 if (bta_hf_client_cb.scb.serv_handle == 0)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530192 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700193 APPL_TRACE_DEBUG("%s already stopped", __FUNCTION__);
Hemant Gupta10256872013-08-19 18:33:01 +0530194 return;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530195 }
Hemant Gupta10256872013-08-19 18:33:01 +0530196
197 RFCOMM_RemoveServer(bta_hf_client_cb.scb.serv_handle);
198 bta_hf_client_cb.scb.serv_handle = 0;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530199}
200
201/*******************************************************************************
202**
Hemant Gupta10256872013-08-19 18:33:01 +0530203** Function bta_hf_client_rfc_do_open
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530204**
205** Description Open an RFCOMM connection to the peer device.
206**
207**
208** Returns void
209**
210*******************************************************************************/
Hemant Gupta10256872013-08-19 18:33:01 +0530211void bta_hf_client_rfc_do_open(tBTA_HF_CLIENT_DATA *p_data)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530212{
Hemant Gupta10256872013-08-19 18:33:01 +0530213 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_HF_HANDSFREE,
214 bta_hf_client_cb.scb.cli_sec_mask, BT_PSM_RFCOMM,
215 BTM_SEC_PROTO_RFCOMM, bta_hf_client_cb.scb.peer_scn);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530216
Hemant Gupta10256872013-08-19 18:33:01 +0530217 if (RFCOMM_CreateConnection(UUID_SERVCLASS_HF_HANDSFREE, bta_hf_client_cb.scb.peer_scn,
218 FALSE, BTA_HF_CLIENT_MTU, bta_hf_client_cb.scb.peer_addr, &(bta_hf_client_cb.scb.conn_handle),
219 bta_hf_client_mgmt_cback) == PORT_SUCCESS)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530220 {
Hemant Gupta10256872013-08-19 18:33:01 +0530221 bta_hf_client_setup_port(bta_hf_client_cb.scb.conn_handle);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700222 APPL_TRACE_DEBUG("bta_hf_client_rfc_do_open : conn_handle = %d", bta_hf_client_cb.scb.conn_handle);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530223 }
224 /* RFCOMM create connection failed; send ourselves RFCOMM close event */
225 else
226 {
Hemant Gupta10256872013-08-19 18:33:01 +0530227 bta_hf_client_sm_execute(BTA_HF_CLIENT_RFC_CLOSE_EVT, p_data);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530228 }
229}
230
231/*******************************************************************************
232**
Hemant Gupta10256872013-08-19 18:33:01 +0530233** Function bta_hf_client_rfc_do_close
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530234**
235** Description Close RFCOMM connection.
236**
237**
238** Returns void
239**
240*******************************************************************************/
Hemant Gupta10256872013-08-19 18:33:01 +0530241void bta_hf_client_rfc_do_close(tBTA_HF_CLIENT_DATA *p_data)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530242{
Hemant Gupta10256872013-08-19 18:33:01 +0530243 tBTA_HF_CLIENT_RFC *p_buf;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530244 UNUSED(p_data);
245
Hemant Gupta10256872013-08-19 18:33:01 +0530246 if (bta_hf_client_cb.scb.conn_handle)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530247 {
Hemant Gupta10256872013-08-19 18:33:01 +0530248 RFCOMM_RemoveConnection(bta_hf_client_cb.scb.conn_handle);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530249 }
250 else
251 {
Hemant Gupta10256872013-08-19 18:33:01 +0530252 /* Close API was called while HF Client is in Opening state. */
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530253 /* Need to trigger the state machine to send callback to the app */
254 /* and move back to INIT state. */
Hemant Gupta10256872013-08-19 18:33:01 +0530255 if ((p_buf = (tBTA_HF_CLIENT_RFC *) GKI_getbuf(sizeof(tBTA_HF_CLIENT_RFC))) != NULL)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530256 {
Hemant Gupta10256872013-08-19 18:33:01 +0530257 p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530258 bta_sys_sendmsg(p_buf);
259 }
260
261 /* Cancel SDP if it had been started. */
Hemant Gupta10256872013-08-19 18:33:01 +0530262 if(bta_hf_client_cb.scb.p_disc_db)
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530263 {
Hemant Gupta10256872013-08-19 18:33:01 +0530264 (void)SDP_CancelServiceSearch (bta_hf_client_cb.scb.p_disc_db);
265 bta_hf_client_free_db(NULL);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530266 }
267 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530268}