1 /******************************************************************************
2 *
3 * Copyright (C) 2004-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 the audio gateway functions controlling the RFCOMM
22 * connections.
23 *
24 ******************************************************************************/
25
26 #include <string.h>
27
28 #include "bt_common.h"
29 #include "bta_ag_api.h"
30 #include "bta_ag_co.h"
31 #include "bta_ag_int.h"
32 #include "bta_api.h"
33 #include "bta_sys.h"
34 #include "btm_api.h"
35 #include "osi/include/osi.h"
36 #include "port_api.h"
37 #include "rfcdefs.h"
38 #include "utl.h"
39
40 /* Event mask for RfCOMM port callback */
41 #define BTA_AG_PORT_EV_MASK PORT_EV_RXCHAR
42
43 /* each scb has its own rfcomm callbacks */
44 void bta_ag_port_cback_1(uint32_t code, uint16_t port_handle);
45 void bta_ag_port_cback_2(uint32_t code, uint16_t port_handle);
46 void bta_ag_port_cback_3(uint32_t code, uint16_t port_handle);
47
48 void bta_ag_mgmt_cback_1(uint32_t code, uint16_t port_handle);
49 void bta_ag_mgmt_cback_2(uint32_t code, uint16_t port_handle);
50 void bta_ag_mgmt_cback_3(uint32_t code, uint16_t port_handle);
51
52 int bta_ag_data_cback_1(uint16_t port_handle, void* p_data, uint16_t len);
53 int bta_ag_data_cback_2(uint16_t port_handle, void* p_data, uint16_t len);
54 int bta_ag_data_cback_3(uint16_t port_handle, void* p_data, uint16_t len);
55
56 /* rfcomm callback function tables */
57 typedef tPORT_CALLBACK* tBTA_AG_PORT_CBACK;
58 const tBTA_AG_PORT_CBACK bta_ag_port_cback_tbl[] = {
59 bta_ag_port_cback_1, bta_ag_port_cback_2, bta_ag_port_cback_3};
60
61 const tBTA_AG_PORT_CBACK bta_ag_mgmt_cback_tbl[] = {
62 bta_ag_mgmt_cback_1, bta_ag_mgmt_cback_2, bta_ag_mgmt_cback_3};
63
64 typedef tPORT_DATA_CALLBACK* tBTA_AG_DATA_CBACK;
65 const tBTA_AG_DATA_CBACK bta_ag_data_cback_tbl[] = {
66 bta_ag_data_cback_1, bta_ag_data_cback_2, bta_ag_data_cback_3};
67
68 /*******************************************************************************
69 *
70 * Function bta_ag_port_cback
71 *
72 * Description RFCOMM Port callback
73 *
74 *
75 * Returns void
76 *
77 ******************************************************************************/
bta_ag_port_cback(UNUSED_ATTR uint32_t code,uint16_t port_handle,uint16_t handle)78 static void bta_ag_port_cback(UNUSED_ATTR uint32_t code, uint16_t port_handle,
79 uint16_t handle) {
80 tBTA_AG_SCB* p_scb;
81
82 p_scb = bta_ag_scb_by_idx(handle);
83 if (p_scb != NULL) {
84 /* ignore port events for port handles other than connected handle */
85 if (port_handle != p_scb->conn_handle) {
86 APPL_TRACE_DEBUG(
87 "ag_port_cback ignoring handle:%d conn_handle = %d other handle = %d",
88 port_handle, p_scb->conn_handle, handle);
89 return;
90 }
91
92 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR));
93 p_buf->event = BTA_AG_RFC_DATA_EVT;
94 p_buf->layer_specific = handle;
95 bta_sys_sendmsg(p_buf);
96 }
97 }
98
99 /*******************************************************************************
100 *
101 * Function bta_ag_mgmt_cback
102 *
103 * Description RFCOMM management callback
104 *
105 *
106 * Returns void
107 *
108 ******************************************************************************/
bta_ag_mgmt_cback(uint32_t code,uint16_t port_handle,uint16_t handle)109 static void bta_ag_mgmt_cback(uint32_t code, uint16_t port_handle,
110 uint16_t handle) {
111 tBTA_AG_SCB* p_scb;
112 uint16_t event;
113 uint8_t i;
114 bool found_handle = false;
115
116 APPL_TRACE_DEBUG("ag_mgmt_cback : code = %d, port_handle = %d, handle = %d",
117 code, port_handle, handle);
118
119 p_scb = bta_ag_scb_by_idx(handle);
120 if (p_scb != NULL) {
121 /* ignore close event for port handles other than connected handle */
122 if ((code != PORT_SUCCESS) && (port_handle != p_scb->conn_handle)) {
123 APPL_TRACE_DEBUG("ag_mgmt_cback ignoring handle:%d", port_handle);
124 return;
125 }
126
127 if (code == PORT_SUCCESS) {
128 if (p_scb->conn_handle) /* Outgoing connection */
129 {
130 if (port_handle == p_scb->conn_handle) found_handle = true;
131 } else /* Incoming connection */
132 {
133 for (i = 0; i < BTA_AG_NUM_IDX; i++) {
134 if (port_handle == p_scb->serv_handle[i]) found_handle = true;
135 }
136 }
137
138 if (!found_handle) {
139 APPL_TRACE_ERROR(
140 "bta_ag_mgmt_cback: PORT_SUCCESS, ignoring handle = %d",
141 port_handle);
142 return;
143 }
144
145 event = BTA_AG_RFC_OPEN_EVT;
146 }
147 /* distinguish server close events */
148 else if (port_handle == p_scb->conn_handle) {
149 event = BTA_AG_RFC_CLOSE_EVT;
150 } else {
151 event = BTA_AG_RFC_SRV_CLOSE_EVT;
152 }
153
154 tBTA_AG_RFC* p_buf = (tBTA_AG_RFC*)osi_malloc(sizeof(tBTA_AG_RFC));
155 p_buf->hdr.event = event;
156 p_buf->hdr.layer_specific = handle;
157 p_buf->port_handle = port_handle;
158 bta_sys_sendmsg(p_buf);
159 }
160 }
161
162 /*******************************************************************************
163 *
164 * Function bta_ag_data_cback
165 *
166 * Description RFCOMM data callback
167 *
168 *
169 * Returns void
170 *
171 ******************************************************************************/
bta_ag_data_cback(UNUSED_ATTR uint16_t port_handle,void * p_data,uint16_t len,uint16_t handle)172 static int bta_ag_data_cback(UNUSED_ATTR uint16_t port_handle, void* p_data,
173 uint16_t len, uint16_t handle) {
174 /* call data call-out directly */
175 bta_ag_co_tx_write(handle, (uint8_t*)p_data, len);
176 return 0;
177 }
178
179 /*******************************************************************************
180 *
181 * Function bta_ag_port_cback_1 to 3
182 * bta_ag_mgmt_cback_1 to 3
183 *
184 * Description RFCOMM callback functions. This is an easy way to
185 * distinguish scb from the callback.
186 *
187 *
188 * Returns void
189 *
190 ******************************************************************************/
bta_ag_mgmt_cback_1(uint32_t code,uint16_t handle)191 void bta_ag_mgmt_cback_1(uint32_t code, uint16_t handle) {
192 bta_ag_mgmt_cback(code, handle, 1);
193 }
bta_ag_mgmt_cback_2(uint32_t code,uint16_t handle)194 void bta_ag_mgmt_cback_2(uint32_t code, uint16_t handle) {
195 bta_ag_mgmt_cback(code, handle, 2);
196 }
bta_ag_mgmt_cback_3(uint32_t code,uint16_t handle)197 void bta_ag_mgmt_cback_3(uint32_t code, uint16_t handle) {
198 bta_ag_mgmt_cback(code, handle, 3);
199 }
bta_ag_port_cback_1(uint32_t code,uint16_t handle)200 void bta_ag_port_cback_1(uint32_t code, uint16_t handle) {
201 bta_ag_port_cback(code, handle, 1);
202 }
bta_ag_port_cback_2(uint32_t code,uint16_t handle)203 void bta_ag_port_cback_2(uint32_t code, uint16_t handle) {
204 bta_ag_port_cback(code, handle, 2);
205 }
bta_ag_port_cback_3(uint32_t code,uint16_t handle)206 void bta_ag_port_cback_3(uint32_t code, uint16_t handle) {
207 bta_ag_port_cback(code, handle, 3);
208 }
209
210 /*******************************************************************************
211 *
212 * Function bta_ag_data_cback_1 to 3
213 *
214 * Description RFCOMM data callback functions. This is an easy way to
215 * distinguish scb from the callback.
216 *
217 *
218 * Returns void
219 *
220 ******************************************************************************/
bta_ag_data_cback_1(uint16_t port_handle,void * p_data,uint16_t len)221 int bta_ag_data_cback_1(uint16_t port_handle, void* p_data, uint16_t len) {
222 return bta_ag_data_cback(port_handle, p_data, len, 1);
223 }
bta_ag_data_cback_2(uint16_t port_handle,void * p_data,uint16_t len)224 int bta_ag_data_cback_2(uint16_t port_handle, void* p_data, uint16_t len) {
225 return bta_ag_data_cback(port_handle, p_data, len, 2);
226 }
bta_ag_data_cback_3(uint16_t port_handle,void * p_data,uint16_t len)227 int bta_ag_data_cback_3(uint16_t port_handle, void* p_data, uint16_t len) {
228 return bta_ag_data_cback(port_handle, p_data, len, 3);
229 }
230
231 /*******************************************************************************
232 *
233 * Function bta_ag_setup_port
234 *
235 * Description Setup RFCOMM port for use by AG.
236 *
237 *
238 * Returns void
239 *
240 ******************************************************************************/
bta_ag_setup_port(tBTA_AG_SCB * p_scb,uint16_t handle)241 void bta_ag_setup_port(tBTA_AG_SCB* p_scb, uint16_t handle) {
242 uint16_t i = bta_ag_scb_to_idx(p_scb) - 1;
243
244 /* set up data callback if using pass through mode */
245 if (bta_ag_cb.parse_mode == BTA_AG_PASS_THROUGH) {
246 PORT_SetDataCallback(handle, bta_ag_data_cback_tbl[i]);
247 }
248
249 PORT_SetEventMask(handle, BTA_AG_PORT_EV_MASK);
250 PORT_SetEventCallback(handle, bta_ag_port_cback_tbl[i]);
251 }
252
253 /*******************************************************************************
254 *
255 * Function bta_ag_start_servers
256 *
257 * Description Setup RFCOMM servers for use by AG.
258 *
259 *
260 * Returns void
261 *
262 ******************************************************************************/
bta_ag_start_servers(tBTA_AG_SCB * p_scb,tBTA_SERVICE_MASK services)263 void bta_ag_start_servers(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK services) {
264 int i;
265 int bta_ag_port_status;
266
267 services >>= BTA_HSP_SERVICE_ID;
268 for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
269 /* if service is set in mask */
270 if (services & 1) {
271 BTM_SetSecurityLevel(false, "", bta_ag_sec_id[i], p_scb->serv_sec_mask,
272 BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM,
273 bta_ag_cb.profile[i].scn);
274
275 bta_ag_port_status = RFCOMM_CreateConnection(
276 bta_ag_uuid[i], bta_ag_cb.profile[i].scn, true, BTA_AG_MTU,
277 (uint8_t*)bd_addr_any, &(p_scb->serv_handle[i]),
278 bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]);
279
280 if (bta_ag_port_status == PORT_SUCCESS) {
281 bta_ag_setup_port(p_scb, p_scb->serv_handle[i]);
282 } else {
283 /* TODO: CR#137125 to handle to error properly */
284 APPL_TRACE_DEBUG(
285 "bta_ag_start_servers: RFCOMM_CreateConnection returned error:%d",
286 bta_ag_port_status);
287 }
288 }
289 }
290 }
291
292 /*******************************************************************************
293 *
294 * Function bta_ag_close_servers
295 *
296 * Description Close RFCOMM servers port for use by AG.
297 *
298 *
299 * Returns void
300 *
301 ******************************************************************************/
bta_ag_close_servers(tBTA_AG_SCB * p_scb,tBTA_SERVICE_MASK services)302 void bta_ag_close_servers(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK services) {
303 int i;
304
305 services >>= BTA_HSP_SERVICE_ID;
306 for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
307 /* if service is set in mask */
308 if (services & 1) {
309 RFCOMM_RemoveServer(p_scb->serv_handle[i]);
310 p_scb->serv_handle[i] = 0;
311 }
312 }
313 }
314
315 /*******************************************************************************
316 *
317 * Function bta_ag_is_server_closed
318 *
319 * Description Returns true if all servers are closed.
320 *
321 *
322 * Returns true if all servers are closed, false otherwise
323 *
324 ******************************************************************************/
bta_ag_is_server_closed(tBTA_AG_SCB * p_scb)325 bool bta_ag_is_server_closed(tBTA_AG_SCB* p_scb) {
326 uint8_t xx;
327 bool is_closed = true;
328
329 for (xx = 0; xx < BTA_AG_NUM_IDX; xx++) {
330 if (p_scb->serv_handle[xx] != 0) is_closed = false;
331 }
332
333 return is_closed;
334 }
335
336 /*******************************************************************************
337 *
338 * Function bta_ag_rfc_do_open
339 *
340 * Description Open an RFCOMM connection to the peer device.
341 *
342 *
343 * Returns void
344 *
345 ******************************************************************************/
bta_ag_rfc_do_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)346 void bta_ag_rfc_do_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) {
347 BTM_SetSecurityLevel(true, "", bta_ag_sec_id[p_scb->conn_service],
348 p_scb->cli_sec_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM,
349 p_scb->peer_scn);
350
351 if (RFCOMM_CreateConnection(
352 bta_ag_uuid[p_scb->conn_service], p_scb->peer_scn, false, BTA_AG_MTU,
353 p_scb->peer_addr, &(p_scb->conn_handle),
354 bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]) ==
355 PORT_SUCCESS) {
356 bta_ag_setup_port(p_scb, p_scb->conn_handle);
357 APPL_TRACE_DEBUG("bta_ag_rfc_do_open : conn_handle = %d",
358 p_scb->conn_handle);
359 }
360 /* RFCOMM create connection failed; send ourselves RFCOMM close event */
361 else {
362 bta_ag_sm_execute(p_scb, BTA_AG_RFC_CLOSE_EVT, p_data);
363 }
364 }
365
366 /*******************************************************************************
367 *
368 * Function bta_ag_rfc_do_close
369 *
370 * Description Close RFCOMM connection.
371 *
372 *
373 * Returns void
374 *
375 ******************************************************************************/
bta_ag_rfc_do_close(tBTA_AG_SCB * p_scb,UNUSED_ATTR tBTA_AG_DATA * p_data)376 void bta_ag_rfc_do_close(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) {
377 if (p_scb->conn_handle) {
378 RFCOMM_RemoveConnection(p_scb->conn_handle);
379 } else {
380 /* Close API was called while AG is in Opening state. */
381 /* Need to trigger the state machine to send callback to the app */
382 /* and move back to INIT state. */
383 tBTA_AG_RFC* p_buf = (tBTA_AG_RFC*)osi_malloc(sizeof(tBTA_AG_RFC));
384 p_buf->hdr.event = BTA_AG_RFC_CLOSE_EVT;
385 p_buf->hdr.layer_specific = bta_ag_scb_to_idx(p_scb);
386 bta_sys_sendmsg(p_buf);
387
388 /* Cancel SDP if it had been started. */
389 /*
390 if(p_scb->p_disc_db)
391 {
392 (void)SDP_CancelServiceSearch (p_scb->p_disc_db);
393 }
394 */
395 }
396 }
397