1 /******************************************************************************
2 *
3 * Copyright (C) 2003-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 GATT client action functions for the state
22 * machine.
23 *
24 ******************************************************************************/
25 #define LOG_TAG "bt_bta_gattc"
26
27 #include "common/bt_target.h"
28
29 #include "bta/utl.h"
30 #include "bta/bta_sys.h"
31
32 #include "bta_gattc_int.h"
33 #include "stack/l2c_api.h"
34 #include "l2c_int.h"
35 #include "gatt_int.h"
36 #include "osi/allocator.h"
37 #include "osi/mutex.h"
38 #include "bta_hh_int.h"
39 #include "btm_int.h"
40
41 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
42 #include "bta_hh_int.h"
43 #endif
44
45 // #include "btif/include/btif_debug_conn.h"
46
47 #include <string.h>
48
49 // #include "osi/include/log.h"
50
51 #if GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE
52
53 /*****************************************************************************
54 ** Constants
55 *****************************************************************************/
56 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
57 BOOLEAN connected, tGATT_DISCONN_REASON reason,
58 tBT_TRANSPORT transport);
59
60 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
61 tGATT_CL_COMPLETE *p_data);
62 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
63 tBTA_GATT_STATUS status,
64 tGATT_CL_COMPLETE *p_data);
65 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb);
66
67 void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
68 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
69 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
70 static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
71 static tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda);
72
73 extern void btc_gattc_congest_callback(tBTA_GATTC *param);
74 extern uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
75
76 static const tGATT_CBACK bta_gattc_cl_cback = {
77 bta_gattc_conn_cback,
78 bta_gattc_cmpl_cback,
79 bta_gattc_disc_res_cback,
80 bta_gattc_disc_cmpl_cback,
81 bta_gattc_req_cback,
82 bta_gattc_enc_cmpl_cback,
83 bta_gattc_cong_cback
84 };
85
86 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
87 static const UINT16 bta_gattc_opcode_to_int_evt[] = {
88 BTA_GATTC_API_READ_EVT,
89 BTA_GATTC_API_WRITE_EVT,
90 BTA_GATTC_API_EXEC_EVT,
91 BTA_GATTC_API_CFG_MTU_EVT,
92 BTA_GATTC_API_READ_MULTI_EVT
93 };
94
95 #if (BT_TRACE_VERBOSE == TRUE)
96 static const char *bta_gattc_op_code_name[] = {
97 "Unknown",
98 "Discovery",
99 "Read",
100 "Write",
101 "Exec",
102 "Config",
103 "Notification",
104 "Indication"
105 };
106 #endif
107 /*****************************************************************************
108 ** Action Functions
109 *****************************************************************************/
110
111
112 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status);
113
114 /*******************************************************************************
115 **
116 ** Function bta_gattc_enable
117 **
118 ** Description Enables GATTC module
119 **
120 **
121 ** Returns void
122 **
123 *******************************************************************************/
bta_gattc_enable(tBTA_GATTC_CB * p_cb)124 static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
125 {
126 APPL_TRACE_DEBUG("bta_gattc_enable");
127 /* This is a workaround because the task priority of btc (BTA_GATTC_CLOSE_EVT
128 in that task) is lower than the priority of the btu task.
129 Consequently, the p_cb->state fails to be restored to BTA_GATTC_STATE_DISABLED
130 and remains in the BTA_GATTC_STATE_DISABLING state. */
131 if (p_cb->state == BTA_GATTC_STATE_DISABLED || p_cb->state == BTA_GATTC_STATE_DISABLING) {
132 /* initialize control block */
133 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
134 bta_gattc_cb.auto_disc = true;
135 p_cb->state = BTA_GATTC_STATE_ENABLED;
136 } else {
137 APPL_TRACE_DEBUG("GATTC is already enabled");
138 }
139 }
140
141
142 /*******************************************************************************
143 **
144 ** Function bta_gattc_disable
145 **
146 ** Description Disable GATTC module by cleaning up all active connections
147 ** and deregister all application.
148 **
149 ** Returns void
150 **
151 *******************************************************************************/
bta_gattc_disable(tBTA_GATTC_CB * p_cb)152 void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
153 {
154 UINT8 i;
155
156 APPL_TRACE_DEBUG("bta_gattc_disable");
157
158 if (p_cb->state != BTA_GATTC_STATE_ENABLED) {
159 APPL_TRACE_ERROR("not enabled or disable in progress");
160 return;
161 }
162
163 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
164 if (p_cb->cl_rcb[i].in_use) {
165 p_cb->state = BTA_GATTC_STATE_DISABLING;
166 /* don't deregister HH GATT IF */
167 /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
168 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
169 if (!bta_hh_le_is_hh_gatt_if(p_cb->cl_rcb[i].client_if)) {
170 #endif
171 bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]);
172 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
173 }
174 #endif
175 }
176 }
177
178 /* no registered apps, indicate disable completed */
179 if (p_cb->state != BTA_GATTC_STATE_DISABLING) {
180 p_cb->state = BTA_GATTC_STATE_DISABLED;
181 memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
182 }
183 }
184
185 /*******************************************************************************
186 **
187 ** Function bta_gattc_register
188 **
189 ** Description Register a GATT client application with BTA.
190 **
191 ** Returns void
192 **
193 *******************************************************************************/
bta_gattc_register(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_data)194 void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
195 {
196 tBTA_GATTC cb_data;
197 UINT8 i;
198 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid;
199 tBTA_GATTC_INT_START_IF *p_buf;
200 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
201
202
203 APPL_TRACE_DEBUG("bta_gattc_register state %d\n", p_cb->state);
204 memset(&cb_data, 0, sizeof(cb_data));
205 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
206
207 /* check if GATTC module is already enabled . Else enable */
208 /* This is a workaround because the task priority of btc (BTA_GATTC_CLOSE_EVT
209 in that task) is lower than the priority of the btu task.
210 Consequently, the p_cb->state fails to be restored to BTA_GATTC_STATE_DISABLED
211 and remains in the BTA_GATTC_STATE_DISABLING state. */
212 if (p_cb->state == BTA_GATTC_STATE_DISABLED || p_cb->state == BTA_GATTC_STATE_DISABLING) {
213 bta_gattc_enable (p_cb);
214 }
215 /* todo need to check duplicate uuid */
216 for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
217 if (!p_cb->cl_rcb[i].in_use) {
218 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) {
219 APPL_TRACE_ERROR("Register with GATT stack failed.\n");
220 status = BTA_GATT_ERROR;
221 } else {
222 p_cb->cl_rcb[i].in_use = TRUE;
223 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
224 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
225
226 /* BTA use the same client interface as BTE GATT statck */
227 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
228
229 if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) {
230 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
231 p_buf->client_if = p_cb->cl_rcb[i].client_if;
232 APPL_TRACE_DEBUG("GATTC getbuf success.\n");
233 bta_sys_sendmsg(p_buf);
234 status = BTA_GATT_OK;
235 } else {
236 GATT_Deregister(p_cb->cl_rcb[i].client_if);
237
238 status = BTA_GATT_NO_RESOURCES;
239 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
240 }
241 break;
242 }
243 }
244 }
245
246 /* callback with register event */
247 if (p_data->api_reg.p_cback) {
248 if (p_app_uuid != NULL) {
249 memcpy(&(cb_data.reg_oper.app_uuid), p_app_uuid, sizeof(tBT_UUID));
250 }
251 cb_data.reg_oper.status = status;
252 (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data);
253 }
254 }
255 /*******************************************************************************
256 **
257 ** Function bta_gattc_start_if
258 **
259 ** Description start an application interface.
260 **
261 ** Returns none.
262 **
263 *******************************************************************************/
bta_gattc_start_if(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)264 void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
265 {
266 UNUSED(p_cb);
267
268 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) != NULL ) {
269 GATT_StartIf(p_msg->int_start_if.client_if);
270 } else {
271 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d", p_msg->int_start_if.client_if );
272 }
273 }
274
275 /*******************************************************************************
276 **
277 ** Function bta_gattc_deregister
278 **
279 ** Description De-Register a GATT client application with BTA.
280 **
281 ** Returns void
282 **
283 *******************************************************************************/
bta_gattc_deregister(tBTA_GATTC_CB * p_cb,tBTA_GATTC_RCB * p_clreg)284 void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg)
285 {
286 UINT8 i;
287 BT_HDR buf;
288
289 if (p_clreg != NULL) {
290 /* remove bg connection associated with this rcb */
291 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++) {
292 if (p_cb->bg_track[i].in_use) {
293 if (p_cb->bg_track[i].cif_mask & (1 << (p_clreg->client_if - 1))) {
294 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, FALSE);
295 GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE);
296 }
297 if (p_cb->bg_track[i].cif_adv_mask & (1 << (p_clreg->client_if - 1))) {
298 bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE);
299 }
300 }
301 }
302
303 if (p_clreg->num_clcb > 0) {
304 /* close all CLCB related to this app */
305 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
306 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg)) {
307 p_clreg->dereg_pending = TRUE;
308
309 buf.event = BTA_GATTC_API_CLOSE_EVT;
310 buf.layer_specific = p_cb->clcb[i].bta_conn_id;
311 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ;
312 }
313 }
314 } else {
315 bta_gattc_deregister_cmpl(p_clreg);
316 }
317 } else {
318 APPL_TRACE_ERROR("Deregister Failed unknown client cif");
319 #if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
320 bta_hh_cleanup_disable(BTA_HH_OK);
321 #endif
322 }
323 }
324 /*******************************************************************************
325 **
326 ** Function bta_gattc_process_api_open
327 **
328 ** Description process connect API request.
329 **
330 ** Returns void
331 **
332 *******************************************************************************/
bta_gattc_process_api_open(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)333 void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
334 {
335 UINT16 event = ((BT_HDR *)p_msg)->event;
336 tBTA_GATTC_CLCB *p_clcb = NULL;
337 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
338 UNUSED(p_cb);
339
340 if (p_clreg != NULL) {
341 if (p_msg->api_conn.own_addr_type <= BLE_ADDR_TYPE_MAX) {
342 // update own address type for creating connection
343 BTM_BleUpdateOwnType(&p_msg->api_conn.own_addr_type, NULL);
344 }
345 if (p_msg->api_conn.is_direct) {
346 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
347 p_msg->api_conn.remote_bda,
348 p_msg->api_conn.transport)) != NULL) {
349 bta_gattc_sm_execute(p_clcb, event, p_msg);
350 } else {
351 APPL_TRACE_ERROR("No resources to open a new connection.");
352
353 bta_gattc_send_open_cback(p_clreg,
354 BTA_GATT_NO_RESOURCES,
355 p_msg->api_conn.remote_bda,
356 BTA_GATT_INVALID_CONN_ID,
357 p_msg->api_conn.transport, 0);
358 }
359 } else {
360 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
361 }
362 } else {
363 APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
364 p_msg->api_conn.client_if);
365 }
366 }
367 /*******************************************************************************
368 **
369 ** Function bta_gattc_process_api_open_cancel
370 **
371 ** Description process connect API request.
372 **
373 ** Returns void
374 **
375 *******************************************************************************/
bta_gattc_process_api_open_cancel(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)376 void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
377 {
378 UINT16 event = ((BT_HDR *)p_msg)->event;
379 tBTA_GATTC_CLCB *p_clcb = NULL;
380 tBTA_GATTC_RCB *p_clreg;
381 tBTA_GATTC cb_data;
382 UNUSED(p_cb);
383
384 if (p_msg->api_cancel_conn.is_direct) {
385 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
386 p_msg->api_cancel_conn.remote_bda,
387 BTA_GATT_TRANSPORT_LE)) != NULL) {
388 bta_gattc_sm_execute(p_clcb, event, p_msg);
389 } else {
390 APPL_TRACE_ERROR("No such connection need to be cancelled");
391
392 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
393
394 if (p_clreg && p_clreg->p_cback) {
395 cb_data.status = BTA_GATT_ERROR;
396 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
397 }
398 }
399 } else {
400 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
401
402 }
403 }
404
405 /*******************************************************************************
406 **
407 ** Function bta_gattc_process_enc_cmpl
408 **
409 ** Description process encryption complete message.
410 **
411 ** Returns void
412 **
413 *******************************************************************************/
bta_gattc_process_enc_cmpl(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)414 void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
415 {
416 tBTA_GATTC_RCB *p_clreg;
417 tBTA_GATTC cb_data;
418 UNUSED(p_cb);
419
420 p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
421
422 if (p_clreg && p_clreg->p_cback) {
423 memset(&cb_data, 0, sizeof(tBTA_GATTC));
424
425 cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
426 bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
427
428 (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
429 }
430 }
431
432 /*******************************************************************************
433 **
434 ** Function bta_gattc_cancel_open_error
435 **
436 ** Description
437 **
438 ** Returns void
439 **
440 *******************************************************************************/
bta_gattc_cancel_open_error(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)441 void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
442 {
443 tBTA_GATTC cb_data;
444 UNUSED(p_data);
445
446 cb_data.status = BTA_GATT_ERROR;
447
448 if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback ) {
449 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
450 }
451 }
452
453 /*******************************************************************************
454 **
455 ** Function bta_gattc_open_error
456 **
457 ** Description
458 **
459 ** Returns void
460 **
461 *******************************************************************************/
bta_gattc_open_error(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)462 void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
463 {
464 UNUSED(p_data);
465
466 APPL_TRACE_ERROR("Connection already opened. wrong state");
467
468 bta_gattc_send_open_cback(p_clcb->p_rcb,
469 BTA_GATT_OK,
470 p_clcb->bda,
471 p_clcb->bta_conn_id,
472 p_clcb->transport,
473 0);
474 }
475 /*******************************************************************************
476 **
477 ** Function bta_gattc_open_fail
478 **
479 ** Description
480 **
481 ** Returns void
482 **
483 *******************************************************************************/
bta_gattc_open_fail(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)484 void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
485 {
486 UNUSED(p_data);
487
488 bta_gattc_send_open_cback(p_clcb->p_rcb,
489 BTA_GATT_ERROR,
490 p_clcb->bda,
491 p_clcb->bta_conn_id,
492 p_clcb->transport,
493 0);
494 /* open failure, remove clcb */
495 bta_gattc_clcb_dealloc(p_clcb);
496 }
497
498 /*******************************************************************************
499 **
500 ** Function bta_gattc_open
501 **
502 ** Description Process API connection function.
503 **
504 ** Returns void
505 **
506 *******************************************************************************/
bta_gattc_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)507 void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
508 {
509 tBTA_GATTC_DATA gattc_data;
510 BOOLEAN found_app = FALSE;
511 tGATT_TCB *p_tcb;
512 tBTM_SEC_DEV_REC *p_dev_rec = NULL;
513
514 if (!p_clcb || !p_data) {
515 return;
516 }
517
518 p_tcb = gatt_find_tcb_by_addr(p_data->api_conn.remote_bda, BT_TRANSPORT_LE);
519 if(p_tcb) {
520 found_app = gatt_find_specific_app_in_hold_link(p_tcb, p_clcb->p_rcb->client_if);
521 }
522
523 if (p_data->api_conn.phy_mask) {
524 p_dev_rec = btm_find_or_alloc_dev(p_data->api_conn.remote_bda);
525 if (p_dev_rec) {
526 if (p_data->api_conn.is_aux) {
527 #if (BLE_50_FEATURE_SUPPORT == TRUE)
528 p_dev_rec->ext_conn_params.phy_mask = p_data->api_conn.phy_mask;
529 if (p_data->api_conn.phy_mask & BTA_BLE_PHY_1M_MASK) {
530 memcpy(&p_dev_rec->ext_conn_params.phy_1m_conn_params, &p_data->api_conn.phy_1m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
531 }
532 if (p_data->api_conn.phy_mask & BTA_BLE_PHY_2M_MASK) {
533 memcpy(&p_dev_rec->ext_conn_params.phy_2m_conn_params, &p_data->api_conn.phy_2m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
534 }
535 if (p_data->api_conn.phy_mask & BTA_BLE_PHY_CODED_MASK) {
536 memcpy(&p_dev_rec->ext_conn_params.phy_coded_conn_params, &p_data->api_conn.phy_coded_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
537 }
538 #endif
539 } else {
540 if (p_data->api_conn.phy_mask & BTA_BLE_PHY_1M_MASK) {
541 memcpy(&p_dev_rec->conn_params, &p_data->api_conn.phy_1m_conn_params, sizeof(tBTA_BLE_CONN_PARAMS));
542 }
543 }
544 } else {
545 APPL_TRACE_ERROR("Unknown Device, setting rejected");
546 }
547 }
548
549 /* open/hold a connection */
550 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, p_data->api_conn.remote_addr_type,
551 TRUE, p_data->api_conn.transport, p_data->api_conn.is_aux)) {
552 APPL_TRACE_ERROR("Connection open failure");
553
554 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
555 } else {
556 /* a connected remote device */
557 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
558 p_data->api_conn.remote_bda,
559 &p_clcb->bta_conn_id,
560 p_data->api_conn.transport)) {
561 gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
562 gattc_data.int_conn.already_connect = found_app;
563 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
564 }
565 /* else wait for the callback event */
566 }
567 }
568 /*******************************************************************************
569 **
570 ** Function bta_gattc_init_bk_conn
571 **
572 ** Description Process API Open for a background connection
573 **
574 ** Returns void
575 **
576 *******************************************************************************/
bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN * p_data,tBTA_GATTC_RCB * p_clreg)577 void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg)
578 {
579 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
580 UINT16 conn_id;
581 tBTA_GATTC_CLCB *p_clcb;
582 tBTA_GATTC_DATA gattc_data;
583
584 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE)) {
585 /* always call open to hold a connection */
586 if (!GATT_Connect(p_data->client_if, p_data->remote_bda,
587 p_data->remote_addr_type, FALSE,
588 p_data->transport, p_data->is_aux)) {
589 #if (!CONFIG_BT_STACK_NO_LOG)
590 uint8_t *bda = (uint8_t *)p_data->remote_bda;
591 #endif
592 status = BTA_GATT_ERROR;
593 APPL_TRACE_ERROR("%s unable to connect to remote bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
594 __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
595
596 } else {
597 status = BTA_GATT_OK;
598
599 /* if is a connected remote device */
600 if (GATT_GetConnIdIfConnected(p_data->client_if,
601 p_data->remote_bda,
602 &conn_id,
603 p_data->transport)) {
604 if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
605 BTA_GATT_TRANSPORT_LE)) != NULL) {
606 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
607
608 /* open connection */
609 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
610 status = BTA_GATT_OK;
611 }
612 }
613 }
614 }
615
616 /* open failure, report OPEN_EVT */
617 if (status != BTA_GATT_OK) {
618 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
619 BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
620 }
621 }
622 /*******************************************************************************
623 **
624 ** Function bta_gattc_cancel_bk_conn
625 **
626 ** Description Process API Cancel Open for a background connection
627 **
628 ** Returns void
629 **
630 *******************************************************************************/
bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN * p_data)631 void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data)
632 {
633 tBTA_GATTC_RCB *p_clreg;
634 tBTA_GATTC cb_data;
635 cb_data.status = BTA_GATT_ERROR;
636
637 /* remove the device from the bg connection mask */
638 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE)) {
639 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE)) {
640 cb_data.status = BTA_GATT_OK;
641 } else {
642 APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
643 }
644 }
645 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
646
647 if (p_clreg && p_clreg->p_cback) {
648 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
649 }
650
651 }
652 /*******************************************************************************
653 **
654 ** Function bta_gattc_int_cancel_open_ok
655 **
656 ** Description
657 **
658 ** Returns void
659 **
660 *******************************************************************************/
bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)661 void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
662 {
663 tBTA_GATTC cb_data;
664 UNUSED(p_data);
665
666 if ( p_clcb->p_rcb->p_cback ) {
667 cb_data.status = BTA_GATT_OK;
668 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
669 }
670
671 bta_gattc_clcb_dealloc(p_clcb);
672 }
673 /*******************************************************************************
674 **
675 ** Function bta_gattc_cancel_open
676 **
677 ** Description
678 **
679 ** Returns void
680 **
681 *******************************************************************************/
bta_gattc_cancel_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)682 void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
683 {
684 tBTA_GATTC cb_data;
685
686 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE)) {
687 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
688 } else {
689 if ( p_clcb->p_rcb->p_cback ) {
690 cb_data.status = BTA_GATT_ERROR;
691 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
692 }
693 }
694 }
695 /*******************************************************************************
696 **
697 ** Function bta_gattc_conn
698 **
699 ** Description receive connection callback from stack
700 **
701 ** Returns void
702 **
703 *******************************************************************************/
bta_gattc_conn(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)704 void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
705 {
706 tBTA_GATTC_IF gatt_if;
707 APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d", p_clcb->p_srcb->state);
708
709 if (p_data != NULL) {
710 APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d", p_data->hdr.layer_specific);
711 p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
712
713 GATT_GetConnectionInfor(p_data->hdr.layer_specific,
714 &gatt_if, p_clcb->bda, &p_clcb->transport);
715 }
716
717 p_clcb->p_srcb->connected = TRUE;
718
719 if (p_clcb->p_srcb->mtu == 0) {
720 p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
721 }
722
723 /* start database cache if needed */
724 if (p_clcb->p_srcb->p_srvc_cache == NULL ||
725 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
726 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
727 #if (GATTC_CACHE_NVS == TRUE)
728 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
729 if (bta_gattc_cache_load(p_clcb)) {
730 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
731 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
732 //register service change
733 bta_gattc_register_service_change_notify(p_clcb->bta_conn_id, p_clcb->bda);
734 } else
735 #endif
736 { /* cache is building */
737 if (bta_gattc_cb.auto_disc) {
738 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
739 /* cache load failure, start discovery */
740 bta_gattc_start_discover(p_clcb, NULL);
741 }
742 }
743 } else { /* cache is building */
744 p_clcb->state = BTA_GATTC_DISCOVER_ST;
745 }
746 } else {
747 /* a pending service handle change indication */
748 if (p_clcb->p_srcb->srvc_hdl_chg) {
749 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
750 /* start discovery */
751 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
752 }
753 }
754
755 if (p_clcb->p_rcb) {
756 /* there is no RM for GATT */
757 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
758 bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
759 }
760 tBTA_GATT_STATUS status = BTA_GATT_OK;
761 if (p_data && p_data->int_conn.already_connect) {
762 //clear already_connect
763 p_data->int_conn.already_connect = FALSE;
764 status = BTA_GATT_ALREADY_OPEN;
765 }
766 bta_gattc_send_open_cback(p_clcb->p_rcb,
767 status,
768 p_clcb->bda,
769 p_clcb->bta_conn_id,
770 p_clcb->transport,
771 p_clcb->p_srcb->mtu);
772
773 }
774 }
775 /*******************************************************************************
776 **
777 ** Function bta_gattc_conncback
778 **
779 ** Description receive connection callback from stack
780 **
781 ** Returns void
782 **
783 *******************************************************************************/
bta_gattc_conncback(tBTA_GATTC_RCB * p_rcb,tBTA_GATTC_DATA * p_data)784 void bta_gattc_conncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
785 {
786 if (p_rcb) {
787 bta_gattc_send_connect_cback(p_rcb,
788 p_data->int_conn.remote_bda,
789 p_data->int_conn.hdr.layer_specific, p_data->int_conn.conn_params, p_data->int_conn.role,
790 p_data->int_conn.ble_addr_type, p_data->int_conn.conn_handle);
791
792 }
793 }
794 /*******************************************************************************
795 **
796 ** Function bta_gattc_disconncback
797 **
798 ** Description receive disconnection callback from stack
799 **
800 ** Returns void
801 **
802 *******************************************************************************/
bta_gattc_disconncback(tBTA_GATTC_RCB * p_rcb,tBTA_GATTC_DATA * p_data)803 void bta_gattc_disconncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
804 {
805 if (p_rcb) {
806 // Clear up the notification registration information by BD_ADDR
807 bta_gattc_clear_notif_registration_by_bda(p_rcb, p_data->int_conn.remote_bda);
808 bta_gattc_send_disconnect_cback(p_rcb,
809 p_data->int_conn.reason,
810 p_data->int_conn.remote_bda,
811 p_data->int_conn.hdr.layer_specific);
812
813 }
814 }
815 /*******************************************************************************
816 **
817 ** Function bta_gattc_close_fail
818 **
819 ** Description close a connection.
820 **
821 ** Returns void
822 **
823 *******************************************************************************/
bta_gattc_close_fail(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)824 void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
825 {
826 tBTA_GATTC cb_data;
827
828 if ( p_clcb->p_rcb->p_cback ) {
829 memset(&cb_data, 0, sizeof(tBTA_GATTC));
830 cb_data.close.client_if = p_clcb->p_rcb->client_if;
831 cb_data.close.conn_id = p_data->hdr.layer_specific;
832 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
833 cb_data.close.status = BTA_GATT_ERROR;
834 cb_data.close.reason = BTA_GATT_CONN_NONE;
835
836
837 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
838 }
839 }
840 /*******************************************************************************
841 **
842 ** Function bta_gattc_api_close
843 **
844 ** Description close a GATTC connection.
845 **
846 ** Returns void
847 **
848 *******************************************************************************/
bta_gattc_close(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)849 void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
850 {
851 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback;
852 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
853 tBTA_GATTC cb_data;
854
855 APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d", p_clcb->bta_conn_id);
856
857 cb_data.close.client_if = p_clcb->p_rcb->client_if;
858 cb_data.close.conn_id = p_clcb->bta_conn_id;
859 cb_data.close.reason = p_clcb->reason;
860 cb_data.close.status = p_clcb->status;
861 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
862
863 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
864 bta_sys_conn_close( BTA_ID_GATTC , BTA_ALL_APP_ID, p_clcb->bda);
865 }
866
867 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) {
868 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
869 } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) {
870 cb_data.close.status = BTA_GATT_OK;
871 cb_data.close.reason = p_data->int_conn.reason;
872 }
873
874 if (p_cback) {
875 (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
876 }
877
878 // Please note that BTA_GATTC_CLOSE_EVT will run in the BTC task.
879 // because bta_gattc_deregister_cmpl did not execute as expected(this is a known issue),
880 // we will run it again in bta_gattc_clcb_dealloc_by_conn_id.
881 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
882 bta_gattc_deregister_cmpl(p_clreg);
883 }
884 }
885 /*******************************************************************************
886 **
887 ** Function bta_gattc_reset_discover_st
888 **
889 ** Description when a SRCB finished discovery, tell all related clcb.
890 **
891 ** Returns None.
892 **
893 *******************************************************************************/
bta_gattc_reset_discover_st(tBTA_GATTC_SERV * p_srcb,tBTA_GATT_STATUS status)894 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
895 {
896 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
897 UINT8 i;
898
899 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
900 if (p_cb->clcb[i].p_srcb == p_srcb) {
901 p_cb->clcb[i].status = status;
902 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
903 }
904 }
905 }
906 /*******************************************************************************
907 **
908 ** Function bta_gattc_disc_close
909 **
910 ** Description close a GATTC connection while in discovery state.
911 **
912 ** Returns void
913 **
914 *******************************************************************************/
bta_gattc_disc_close(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)915 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
916 {
917 APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
918 p_clcb->bta_conn_id);
919
920 if (p_clcb->disc_active) {
921 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
922 } else {
923 p_clcb->state = BTA_GATTC_CONN_ST;
924 }
925
926 // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
927 // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
928 // connection itself still needs to be closed to resolve the original event.
929 if (p_clcb->state == BTA_GATTC_CONN_ST) {
930 APPL_TRACE_DEBUG("State is back to BTA_GATTC_CONN_ST. "
931 "Trigger connection close");
932 bta_gattc_close(p_clcb, p_data);
933 }
934 }
935 /*******************************************************************************
936 **
937 ** Function bta_gattc_set_discover_st
938 **
939 ** Description when a SRCB start discovery, tell all related clcb and set
940 ** the state.
941 **
942 ** Returns None.
943 **
944 *******************************************************************************/
bta_gattc_set_discover_st(tBTA_GATTC_SERV * p_srcb)945 void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
946 {
947 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
948 UINT8 i;
949
950 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
951 if (p_cb->clcb[i].p_srcb == p_srcb) {
952 p_cb->clcb[i].status = BTA_GATT_OK;
953 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
954 }
955 }
956 }
957 /*******************************************************************************
958 **
959 ** Function bta_gattc_restart_discover
960 **
961 ** Description process service change in discovery state, mark up the auto
962 ** update flag and set status to be discovery cancel for current
963 ** discovery.
964 **
965 ** Returns None.
966 **
967 *******************************************************************************/
bta_gattc_restart_discover(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)968 void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
969 {
970 UNUSED(p_data);
971
972 p_clcb->status = BTA_GATT_CANCEL;
973 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
974 }
975
976 /*******************************************************************************
977 **
978 ** Function bta_gattc_cfg_mtu
979 **
980 ** Description Configure MTU size on the GATT connection.
981 **
982 ** Returns None.
983 **
984 *******************************************************************************/
bta_gattc_cfg_mtu(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)985 void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
986 {
987 tBTA_GATT_STATUS status;
988
989 if (bta_gattc_enqueue(p_clcb, p_data)) {
990 status = GATTC_ConfigureMTU (p_clcb->bta_conn_id);
991
992 /* if failed, return callback here */
993 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) {
994 /* Dequeue the data, if it was enqueued */
995 if (p_clcb->p_q_cmd == p_data) {
996 p_clcb->p_q_cmd = NULL;
997 bta_gattc_pop_command_to_send(p_clcb);
998 }
999
1000 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL);
1001 }
1002 }
1003 }
1004 /*******************************************************************************
1005 **
1006 ** Function bta_gattc_start_discover
1007 **
1008 ** Description Start a discovery send to server.
1009 **
1010 ** Returns None.
1011 **
1012 *******************************************************************************/
bta_gattc_start_discover(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1013 void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1014 {
1015 UNUSED(p_data);
1016
1017 APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
1018 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
1019
1020 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
1021 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
1022 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC) {
1023 /* no pending operation, start discovery right away */
1024 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
1025
1026 if (p_clcb->p_srcb != NULL) {
1027 /* clear the service change mask */
1028 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
1029 p_clcb->p_srcb->update_count = 0;
1030 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
1031 #if (BT_MULTI_CONNECTION_ENBALE == FALSE)
1032 if (p_clcb->transport == BTA_TRANSPORT_LE) {
1033 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
1034 }
1035 #endif
1036
1037 /* set all srcb related clcb into discovery ST */
1038 bta_gattc_set_discover_st(p_clcb->p_srcb);
1039
1040 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK) {
1041 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
1042 p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
1043 }
1044 if (p_clcb->status != BTA_GATT_OK) {
1045 APPL_TRACE_ERROR("discovery on server failed");
1046 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
1047 //discover service complete, trigger callback
1048 tBTA_GATTC cb_data;
1049 cb_data.dis_cmpl.status = p_clcb->status;
1050 cb_data.dis_cmpl.conn_id = p_clcb->bta_conn_id;
1051 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_DIS_SRVC_CMPL_EVT, &cb_data);
1052 } else {
1053 p_clcb->disc_active = TRUE;
1054 }
1055 p_clcb->searched_service_source = BTA_GATTC_SERVICE_INFO_FROM_REMOTE_DEVICE;
1056 } else {
1057 APPL_TRACE_ERROR("unknown device, can not start discovery");
1058 }
1059 }
1060 /* pending operation, wait until it finishes */
1061 else {
1062 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
1063
1064 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
1065 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
1066 }
1067 }
1068
1069 }
1070 /*******************************************************************************
1071 **
1072 ** Function bta_gattc_disc_cmpl
1073 **
1074 ** Description discovery on server is finished
1075 **
1076 ** Returns None.
1077 **
1078 *******************************************************************************/
bta_gattc_disc_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1079 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1080 {
1081 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
1082 UNUSED(p_data);
1083
1084 APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d, status = %d", p_clcb->bta_conn_id, p_clcb->status);
1085
1086 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
1087 p_clcb->disc_active = FALSE;
1088
1089 if (p_clcb->status != GATT_SUCCESS) {
1090 /* clean up cache */
1091 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1092 list_free(p_clcb->p_srcb->p_srvc_cache);
1093 p_clcb->p_srcb->p_srvc_cache = NULL;
1094 }
1095 #if(GATTC_CACHE_NVS == TRUE)
1096 /* used to reset cache in application */
1097 bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
1098 #endif
1099 }
1100 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
1101 /* release pending attribute list buffer */
1102 osi_free(p_clcb->p_srcb->p_srvc_list);
1103 p_clcb->p_srcb->p_srvc_list = NULL;
1104 //osi_free_and_reset((void **)&p_clcb->p_srcb->p_srvc_list);
1105 }
1106
1107 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1108 /* start discovery again */
1109 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1110 }
1111 /* get any queued command to proceed */
1112 else if (p_q_cmd != NULL) {
1113 p_clcb->p_q_cmd = NULL;
1114 /* execute pending operation of link block still present */
1115 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1116 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
1117 }
1118 /* if the command executed requeued the cmd, we don't
1119 * want to free the underlying buffer that's being
1120 * referenced by p_clcb->p_q_cmd
1121 */
1122 if (p_q_cmd != p_clcb->p_q_cmd) {
1123 osi_free(p_q_cmd);
1124 p_q_cmd = NULL;
1125 }
1126 }
1127
1128 //register service change
1129 bta_gattc_register_service_change_notify(p_clcb->bta_conn_id, p_clcb->bda);
1130
1131 }
1132 /*******************************************************************************
1133 **
1134 ** Function bta_gattc_read
1135 **
1136 ** Description Read an attribute
1137 **
1138 ** Returns None.
1139 **
1140 *******************************************************************************/
bta_gattc_read(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1141 void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1142 {
1143 if (!bta_gattc_enqueue(p_clcb, p_data)) {
1144 return;
1145 }
1146
1147 tGATT_READ_PARAM read_param;
1148 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1149 read_param.by_handle.handle = p_data->api_read.handle;
1150 read_param.by_handle.auth_req = p_data->api_read.auth_req;
1151
1152 tBTA_GATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
1153
1154 /* read fail */
1155 if (status != BTA_GATT_OK) {
1156 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1157 }
1158 }
1159 /*******************************************************************************
1160 **
1161 ** Function bta_gattc_read_by_type
1162 **
1163 ** Description Read an attribute
1164 **
1165 ** Returns None.
1166 **
1167 *******************************************************************************/
bta_gattc_read_by_type(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1168 void bta_gattc_read_by_type(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1169 {
1170 if (!bta_gattc_enqueue(p_clcb, p_data)) {
1171 return;
1172 }
1173
1174 tGATT_READ_PARAM read_param;
1175 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
1176 read_param.service.auth_req = p_data->api_read.auth_req;
1177 read_param.service.s_handle = p_data->api_read.s_handle;
1178 read_param.service.e_handle = p_data->api_read.e_handle;
1179 memcpy(&(read_param.service.uuid), &(p_data->api_read.uuid), sizeof(tBT_UUID));
1180
1181 tBTA_GATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_TYPE, &read_param);
1182
1183 /* read fail */
1184 if (status != BTA_GATT_OK) {
1185 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1186 }
1187 }
1188 /*******************************************************************************
1189 **
1190 ** Function bta_gattc_read_multi
1191 **
1192 ** Description read multiple
1193 **
1194 ** Returns None.
1195 *********************************************************************************/
bta_gattc_read_multi(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1196 void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1197 {
1198 tBTA_GATT_STATUS status = BTA_GATT_OK;
1199 tGATT_READ_PARAM read_param;
1200
1201 if (bta_gattc_enqueue(p_clcb, p_data)) {
1202 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1203
1204 if (status == BTA_GATT_OK) {
1205 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1206 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1207 memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
1208 sizeof(UINT16) * p_data->api_read_multi.num_attr);
1209
1210 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1211 }
1212
1213 /* read fail */
1214 if (status != BTA_GATT_OK) {
1215 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1216 }
1217 }
1218 }
1219 /*******************************************************************************
1220 **
1221 ** Function bta_gattc_read_multi_var
1222 **
1223 ** Description read multiple variable
1224 **
1225 ** Returns None.
1226 *********************************************************************************/
bta_gattc_read_multi_var(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1227 void bta_gattc_read_multi_var(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1228 {
1229 tBTA_GATT_STATUS status = BTA_GATT_OK;
1230 tGATT_READ_PARAM read_param;
1231
1232 if (bta_gattc_enqueue(p_clcb, p_data)) {
1233 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
1234
1235 if (status == BTA_GATT_OK) {
1236 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1237 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1238 memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
1239 sizeof(UINT16) * p_data->api_read_multi.num_attr);
1240
1241 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE_VAR, &read_param);
1242 }
1243
1244 /* read fail */
1245 if (status != BTA_GATT_OK) {
1246 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
1247 }
1248 }
1249 }
1250 /*******************************************************************************
1251 **
1252 ** Function bta_gattc_write
1253 **
1254 ** Description Write an attribute
1255 **
1256 ** Returns None.
1257 **
1258 *******************************************************************************/
bta_gattc_write(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1259 void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1260 {
1261 if (!bta_gattc_enqueue(p_clcb, p_data)) {
1262 return;
1263 }
1264
1265 tBTA_GATT_STATUS status = BTA_GATT_OK;
1266
1267 tGATT_CL_COMPLETE cl_data = {0};
1268
1269 cl_data.att_value.conn_id = p_clcb->bta_conn_id;
1270 cl_data.att_value.handle = p_data->api_write.handle;
1271 cl_data.att_value.offset = p_data->api_write.offset;
1272 cl_data.att_value.len = p_data->api_write.len;
1273 cl_data.att_value.auth_req = p_data->api_write.auth_req;
1274
1275 if (p_data->api_write.p_value) {
1276 memcpy(cl_data.att_value.value, p_data->api_write.p_value, p_data->api_write.len);
1277 }
1278
1279 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &cl_data.att_value);
1280
1281 /* write fail */
1282 if (status != BTA_GATT_OK) {
1283 cl_data.handle = p_data->api_write.handle;
1284 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, &cl_data);
1285 }
1286 }
1287 /*******************************************************************************
1288 **
1289 ** Function bta_gattc_execute
1290 **
1291 ** Description send execute write
1292 **
1293 ** Returns None.
1294 *********************************************************************************/
bta_gattc_execute(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1295 void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1296 {
1297 tBTA_GATT_STATUS status;
1298
1299 if (bta_gattc_enqueue(p_clcb, p_data)) {
1300 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1301
1302 if (status != BTA_GATT_OK) {
1303 /* Dequeue the data, if it was enqueued */
1304 if (p_clcb->p_q_cmd == p_data) {
1305 p_clcb->p_q_cmd = NULL;
1306 bta_gattc_pop_command_to_send(p_clcb);
1307 }
1308
1309 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL);
1310 }
1311 }
1312 }
1313 /*******************************************************************************
1314 **
1315 ** Function bta_gattc_confirm
1316 **
1317 ** Description send handle value confirmation
1318 **
1319 ** Returns None.
1320 **
1321 *******************************************************************************/
bta_gattc_confirm(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1322 void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1323 {
1324 UINT16 handle = p_data->api_confirm.handle;
1325
1326 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1327 != GATT_SUCCESS) {
1328 APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1329 } else {
1330 /* if over BR_EDR, inform PM for mode change */
1331 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1332 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1333 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1334 }
1335 }
1336 }
1337 /*******************************************************************************
1338 **
1339 ** Function bta_gattc_read_cmpl
1340 **
1341 ** Description read complete
1342 **
1343 ** Returns None.
1344 **
1345 *******************************************************************************/
bta_gattc_read_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1346 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1347 {
1348 UINT8 event;
1349 tBTA_GATTC cb_data;
1350 tBTA_GATT_UNFMT read_value;
1351
1352 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1353 memset(&read_value, 0, sizeof(tBTA_GATT_UNFMT));
1354
1355 cb_data.read.status = p_data->status;
1356
1357 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK) {
1358 cb_data.read.handle = p_data->p_cmpl->att_value.handle;
1359
1360 read_value.len = p_data->p_cmpl->att_value.len;
1361 read_value.p_value = p_data->p_cmpl->att_value.value;
1362 cb_data.read.p_value = &read_value;
1363 } else {
1364 cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle;
1365 }
1366
1367 if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT &&
1368 p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_VAR_EVT) {
1369 event = p_clcb->p_q_cmd->api_read.cmpl_evt;
1370 } else {
1371 event = p_clcb->p_q_cmd->api_read_multi.cmpl_evt;
1372 }
1373 cb_data.read.conn_id = p_clcb->bta_conn_id;
1374 //free the command data store in the queue.
1375 bta_gattc_free_command_data(p_clcb);
1376 bta_gattc_pop_command_to_send(p_clcb);
1377 /* read complete, callback */
1378 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1379
1380 }
1381 /*******************************************************************************
1382 **
1383 ** Function bta_gattc_write_cmpl
1384 **
1385 ** Description write complete
1386 **
1387 ** Returns None.
1388 **
1389 *******************************************************************************/
bta_gattc_write_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1390 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1391 {
1392 tBTA_GATTC cb_data = {0};
1393 UINT8 event;
1394 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_clcb->bda);
1395
1396 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1397
1398 cb_data.write.status = p_data->status;
1399 cb_data.write.handle = p_data->p_cmpl->att_value.handle;
1400 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1401 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) {
1402 // Should check the value received from the peer device is correct or not.
1403 if (memcmp(p_clcb->p_q_cmd->api_write.p_value, p_data->p_cmpl->att_value.value,
1404 p_data->p_cmpl->att_value.len) != 0) {
1405 cb_data.write.status = BTA_GATT_INVALID_PDU;
1406 }
1407
1408 event = BTA_GATTC_PREP_WRITE_EVT;
1409 } else {
1410 event = p_clcb->p_q_cmd->api_write.cmpl_evt;
1411 }
1412 //free the command data store in the queue.
1413 bta_gattc_free_command_data(p_clcb);
1414 bta_gattc_pop_command_to_send(p_clcb);
1415 cb_data.write.conn_id = p_clcb->bta_conn_id;
1416 if (p_conn && p_conn->svc_change_descr_handle == cb_data.write.handle) {
1417 if(cb_data.write.status != BTA_GATT_OK) {
1418 p_conn->write_remote_svc_change_ccc_done = FALSE;
1419 APPL_TRACE_ERROR("service change write ccc failed");
1420 }
1421 return;
1422 }
1423 /* write complete, callback */
1424 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1425
1426 }
1427 /*******************************************************************************
1428 **
1429 ** Function bta_gattc_exec_cmpl
1430 **
1431 ** Description execute write complete
1432 **
1433 ** Returns None.
1434 **
1435 *******************************************************************************/
bta_gattc_exec_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1436 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1437 {
1438 tBTA_GATTC cb_data;
1439 //free the command data store in the queue.
1440 bta_gattc_free_command_data(p_clcb);
1441 bta_gattc_pop_command_to_send(p_clcb);
1442 p_clcb->status = BTA_GATT_OK;
1443
1444 /* execute complete, callback */
1445 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1446 cb_data.exec_cmpl.status = p_data->status;
1447
1448 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1449
1450 }
1451
1452 /*******************************************************************************
1453 **
1454 ** Function bta_gattc_cfg_mtu_cmpl
1455 **
1456 ** Description configure MTU operation complete
1457 **
1458 ** Returns None.
1459 **
1460 *******************************************************************************/
bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1461 void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1462 {
1463 tBTA_GATTC cb_data;
1464 //free the command data store in the queue.
1465 bta_gattc_free_command_data(p_clcb);
1466 bta_gattc_pop_command_to_send(p_clcb);
1467
1468 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK) {
1469 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
1470 }
1471
1472 /* configure MTU complete, callback */
1473 p_clcb->status = p_data->status;
1474 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1475 cb_data.cfg_mtu.status = p_data->status;
1476 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
1477
1478 (*p_clcb->p_rcb->p_cback) (BTA_GATTC_CFG_MTU_EVT, &cb_data);
1479
1480 }
1481 /*******************************************************************************
1482 **
1483 ** Function bta_gattc_op_cmpl
1484 **
1485 ** Description operation completed.
1486 **
1487 ** Returns None.
1488 **
1489 *******************************************************************************/
bta_gattc_op_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1490 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1491 {
1492 UINT8 op = (UINT8)p_data->op_cmpl.op_code;
1493 UINT8 mapped_op = 0;
1494
1495 APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1496
1497 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) {
1498 APPL_TRACE_ERROR("unexpected operation, ignored");
1499 } else if (op >= GATTC_OPTYPE_READ) {
1500 if (p_clcb->p_q_cmd == NULL) {
1501 APPL_TRACE_ERROR("No pending command");
1502 return;
1503 }
1504 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
1505 if ((p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) &&
1506 (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_BY_TYPE_EVT) &&
1507 (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_VAR_EVT)) {
1508 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1509 if ( mapped_op > GATTC_OPTYPE_INDICATION) {
1510 mapped_op = 0;
1511 }
1512
1513 #if (BT_TRACE_VERBOSE == TRUE)
1514 APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1515 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1516 bta_gattc_op_code_name[op]);
1517 #else
1518 APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1519 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1520 #endif
1521 return;
1522 }
1523 }
1524
1525 /* discard responses if service change indication is received before operation completed */
1526 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg) {
1527 APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
1528 p_data->op_cmpl.status = GATT_ERROR;
1529 }
1530
1531 /* service handle change void the response, discard it */
1532 if (op == GATTC_OPTYPE_READ) {
1533 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1534 }
1535
1536 else if (op == GATTC_OPTYPE_WRITE) {
1537 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1538 }
1539
1540 else if (op == GATTC_OPTYPE_EXE_WRITE) {
1541 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1542 }
1543
1544 else if (op == GATTC_OPTYPE_CONFIG) {
1545 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1546 }
1547
1548 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1549 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1550 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1551 }
1552 }
1553 }
1554 /*******************************************************************************
1555 **
1556 ** Function bta_gattc_op_cmpl
1557 **
1558 ** Description operation completed.
1559 **
1560 ** Returns None.
1561 **
1562 *******************************************************************************/
bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1563 void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1564 {
1565 UNUSED(p_clcb);
1566
1567 /* receive op complete when discovery is started, ignore the response,
1568 and wait for discovery finish and resent */
1569 APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1570
1571 }
1572 /*******************************************************************************
1573 **
1574 ** Function bta_gattc_search
1575 **
1576 ** Description start a search in the local server cache
1577 **
1578 ** Returns None.
1579 **
1580 *******************************************************************************/
bta_gattc_search(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1581 void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1582 {
1583 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1584 tBTA_GATTC cb_data;
1585 APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d", p_clcb->bta_conn_id);
1586 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1587 status = BTA_GATT_OK;
1588 /* search the local cache of a server device */
1589 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1590 }
1591 cb_data.search_cmpl.status = status;
1592 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1593 cb_data.search_cmpl.searched_service_source = p_clcb->searched_service_source;
1594
1595 /* end of search or no server cache available */
1596 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1597 }
1598 /*******************************************************************************
1599 **
1600 ** Function bta_gattc_q_cmd
1601 **
1602 ** Description enqueue a command into control block, usually because discovery
1603 ** operation is busy.
1604 **
1605 ** Returns None.
1606 **
1607 *******************************************************************************/
bta_gattc_q_cmd(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1608 void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1609 {
1610 bta_gattc_enqueue(p_clcb, p_data);
1611 }
1612 /*******************************************************************************
1613 **
1614 ** Function bta_gattc_pop_command_to_send
1615 **
1616 ** Description dequeue a command into control block.
1617 ** Check if there has command pending in the command queue or not,
1618 ** if there has command pending in the command queue, sent it to the state machine to decision
1619 ** should be sent it to the remote device or not.
1620 **
1621 ** Returns None.
1622 **
1623 *******************************************************************************/
bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB * p_clcb)1624 static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb)
1625 {
1626 if (!list_is_empty(p_clcb->p_cmd_list)) {
1627 list_node_t *node = list_begin(p_clcb->p_cmd_list);
1628 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1629 if (p_data != NULL) {
1630 /* execute pending operation of link block still present */
1631 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
1632 // The data to be sent to the gattc state machine for processing
1633 if(bta_gattc_sm_execute(p_clcb, p_data->hdr.event, p_data)) {
1634 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1635 }
1636
1637 if (p_clcb->is_full) {
1638 tBTA_GATTC cb_data = {0};
1639 p_clcb->is_full = FALSE;
1640 cb_data.status = GATT_SUCCESS;
1641 cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
1642 cb_data.queue_full.is_full = FALSE;
1643 if (p_clcb->p_rcb->p_cback != NULL) {
1644 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
1645 }
1646 }
1647 }
1648 }
1649 }
1650 }
1651 /*******************************************************************************
1652 **
1653 ** Function bta_gattc_free_command_data
1654 **
1655 ** Description free the command data into control block.
1656 **
1657 ** Returns None.
1658 **
1659 *******************************************************************************/
bta_gattc_free_command_data(tBTA_GATTC_CLCB * p_clcb)1660 void bta_gattc_free_command_data(tBTA_GATTC_CLCB *p_clcb)
1661 {
1662 assert(p_clcb->p_cmd_list);
1663 //Check the list is empty or not.
1664 if (!list_is_empty(p_clcb->p_cmd_list)) {
1665 /* Traversal the command queue, check the p_q_cmd is point to the queue data or not, if the p_q_cmd point to the
1666 command queue,should remove it from the list */
1667 for (list_node_t *node = list_begin(p_clcb->p_cmd_list); node != list_end(p_clcb->p_cmd_list);
1668 node = list_next(node)) {
1669 tBTA_GATTC_DATA *p_data = (tBTA_GATTC_DATA *)list_node(node);
1670 if (p_data == p_clcb->p_q_cmd) {
1671 list_remove(p_clcb->p_cmd_list, (void *)p_data);
1672 p_clcb->p_q_cmd = NULL;
1673 return;
1674 }
1675 }
1676
1677 osi_free(p_clcb->p_q_cmd);
1678 p_clcb->p_q_cmd = NULL;
1679 } else {
1680 osi_free(p_clcb->p_q_cmd);
1681 p_clcb->p_q_cmd = NULL;
1682 }
1683 }
1684
1685 /*******************************************************************************
1686 **
1687 ** Function bta_gattc_fail
1688 **
1689 ** Description report API call failure back to apps
1690 **
1691 ** Returns None.
1692 **
1693 *******************************************************************************/
bta_gattc_fail(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1694 void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1695 {
1696 UNUSED(p_data);
1697
1698 if (p_clcb->status == BTA_GATT_OK) {
1699 APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
1700 }
1701 }
1702
1703 /*******************************************************************************
1704 **
1705 ** Function bta_gattc_deregister_cmpl
1706 **
1707 ** Description De-Register a GATT client application with BTA completed.
1708 **
1709 ** Returns void
1710 **
1711 *******************************************************************************/
bta_gattc_deregister_cmpl(tBTA_GATTC_RCB * p_clreg)1712 void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
1713 {
1714 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
1715 tBTA_GATTC_IF client_if = p_clreg->client_if;
1716 tBTA_GATTC cb_data;
1717 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback;
1718
1719 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1720
1721 GATT_Deregister(p_clreg->client_if);
1722 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1723
1724 cb_data.reg_oper.client_if = client_if;
1725 cb_data.reg_oper.status = BTA_GATT_OK;
1726
1727 if (p_cback)
1728 /* callback with de-register event */
1729 {
1730 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
1731 }
1732
1733 if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING) {
1734 p_cb->state = BTA_GATTC_STATE_DISABLED;
1735 }
1736 }
1737
1738 /*******************************************************************************
1739 **
1740 ** Function bta_gattc_conn_cback
1741 **
1742 ** Description callback functions to GATT client stack.
1743 **
1744 ** Returns void
1745 **
1746 *******************************************************************************/
bta_gattc_conn_cback(tGATT_IF gattc_if,BD_ADDR bda,UINT16 conn_id,BOOLEAN connected,tGATT_DISCONN_REASON reason,tBT_TRANSPORT transport)1747 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1748 BOOLEAN connected, tGATT_DISCONN_REASON reason,
1749 tBT_TRANSPORT transport)
1750 {
1751 tBTA_GATTC_DATA *p_buf;
1752
1753 if (reason != 0) {
1754 APPL_TRACE_WARNING("gattc_conn_cb: if=%d st=%d id=%d rsn=0x%x", gattc_if, connected, conn_id, reason);
1755 }
1756
1757 bt_bdaddr_t bdaddr;
1758 bdcpy(bdaddr.address, bda);
1759
1760 if ((p_buf = (tBTA_GATTC_DATA *) osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1761 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1762
1763 p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT :
1764 BTA_GATTC_INT_DISCONN_EVT;
1765 if(p_buf->int_conn.hdr.event == BTA_GATTC_INT_CONN_EVT) {
1766 tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
1767 if(p_lcb != NULL) {
1768 p_buf->int_conn.conn_params.interval = p_lcb->current_used_conn_interval;
1769 p_buf->int_conn.conn_params.latency = p_lcb->current_used_conn_latency;
1770 p_buf->int_conn.conn_params.timeout = p_lcb->current_used_conn_timeout;
1771 #if (BLE_INCLUDED == TRUE)
1772 p_buf->int_conn.ble_addr_type = p_lcb->ble_addr_type;
1773 #endif
1774 p_buf->int_conn.conn_handle = p_lcb->handle;
1775
1776 } else {
1777 APPL_TRACE_WARNING("gattc_conn_cb: conn params not found");
1778 }
1779 }
1780 p_buf->int_conn.hdr.layer_specific = conn_id;
1781 p_buf->int_conn.client_if = gattc_if;
1782 p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
1783 p_buf->int_conn.reason = reason;
1784 p_buf->int_conn.transport = transport;
1785 bdcpy(p_buf->int_conn.remote_bda, bda);
1786
1787 bta_sys_sendmsg(p_buf);
1788 }
1789 }
1790
1791 /*******************************************************************************
1792 **
1793 ** Function bta_gattc_enc_cmpl_cback
1794 **
1795 ** Description encryption complete callback function to GATT client stack.
1796 **
1797 ** Returns void
1798 **
1799 *******************************************************************************/
bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if,BD_ADDR bda)1800 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
1801 {
1802 tBTA_GATTC_DATA *p_buf;
1803 tBTA_GATTC_CLCB *p_clcb = NULL;
1804
1805 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL) {
1806 return;
1807 }
1808
1809 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
1810 /* filter this event just for BTA HH LE GATT client,
1811 In the future, if we want to enable encryption complete event
1812 for all GATT clients, we can remove this code */
1813 if (!bta_hh_le_is_hh_gatt_if(gattc_if)) {
1814 return;
1815 }
1816 #endif
1817
1818 APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
1819
1820 if ((p_buf = (tBTA_GATTC_DATA *) osi_calloc(sizeof(tBTA_GATTC_DATA))) != NULL) {
1821 memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
1822
1823 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
1824 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
1825 p_buf->enc_cmpl.client_if = gattc_if;
1826 bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1827
1828 bta_sys_sendmsg(p_buf);
1829 }
1830 }
1831
1832 /*******************************************************************************
1833 **
1834 ** Function bta_gattc_process_api_refresh
1835 **
1836 ** Description process refresh API to delete cache and start a new discovery
1837 ** if currently connected.
1838 **
1839 ** Returns None.
1840 **
1841 *******************************************************************************/
bta_gattc_process_api_refresh(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)1842 void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1843 {
1844 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_refresh.remote_bda);
1845 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
1846 BOOLEAN found = FALSE;
1847 UINT8 i;
1848 UNUSED(p_cb);
1849
1850 if (p_srvc_cb != NULL) {
1851 /* try to find a CLCB */
1852 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
1853 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
1854 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
1855 found = TRUE;
1856 break;
1857 }
1858 }
1859 if (found) {
1860 // If the device is discovering services, return
1861 if(p_clcb->state == BTA_GATTC_CONN_ST) {
1862 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1863 }
1864 return;
1865 }
1866 }
1867 /* in all other cases, mark it and delete the cache */
1868 if (p_srvc_cb->p_srvc_cache != NULL) {
1869 list_free(p_srvc_cb->p_srvc_cache);
1870 p_srvc_cb->p_srvc_cache = NULL;
1871 }
1872 }
1873 }
1874
bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)1875 void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1876 {
1877 tBTA_GATTC gattc_cb = {0};
1878 gattc_cb.set_assoc.client_if = p_msg->api_assoc.client_if;
1879 BOOLEAN state = FALSE;
1880 tBTA_GATTC_CLCB *p_assoc_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_assoc.client_if,
1881 p_msg->api_assoc.assoc_addr, BTA_TRANSPORT_LE);
1882 tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_assoc.client_if);
1883 if (p_assoc_clcb != NULL) {
1884 if (p_assoc_clcb->state == BTA_GATTC_CONN_ST || p_assoc_clcb->state == BTA_GATTC_DISCOVER_ST) {
1885 gattc_cb.set_assoc.status = BTA_GATT_BUSY;
1886 if (p_clrcb != NULL) {
1887 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1888 return;
1889 }
1890 }
1891 }
1892
1893 if (p_msg->api_assoc.is_assoc) {
1894 if ((state = bta_gattc_co_cache_append_assoc_addr(p_msg->api_assoc.src_addr, p_msg->api_assoc.assoc_addr)) == TRUE) {
1895 gattc_cb.set_assoc.status = BTA_GATT_OK;
1896
1897 } else {
1898 gattc_cb.set_assoc.status = BTA_GATT_ERROR;
1899 if (p_clrcb != NULL) {
1900 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1901 return;
1902 }
1903 }
1904 } else {
1905 if (( state = bta_gattc_co_cache_remove_assoc_addr(p_msg->api_assoc.src_addr, p_msg->api_assoc.assoc_addr)) == TRUE) {
1906 gattc_cb.set_assoc.status = BTA_GATT_OK;
1907 } else {
1908 gattc_cb.set_assoc.status = BTA_GATT_ERROR;
1909 if (p_clrcb != NULL) {
1910 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1911 return;
1912 }
1913 }
1914 }
1915
1916 if (p_clrcb != NULL) {
1917 (*p_clrcb->p_cback)(BTA_GATTC_ASSOC_EVT, &gattc_cb);
1918 }
1919
1920 return;
1921
1922 }
bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)1923 void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1924 {
1925 tBTA_GATTC gattc_cb = {0};
1926 tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_get_addr.client_if);
1927 UINT8 num_addr = bta_gattc_co_get_addr_num();
1928 gattc_cb.get_addr_list.client_if = p_msg->api_get_addr.client_if;
1929
1930 if (num_addr != 0) {
1931 gattc_cb.get_addr_list.num_addr = num_addr;
1932 gattc_cb.get_addr_list.bda_list = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR)*num_addr);
1933 if (gattc_cb.get_addr_list.bda_list != NULL) {
1934 bta_gattc_co_get_addr_list(gattc_cb.get_addr_list.bda_list);
1935 gattc_cb.get_addr_list.status = BTA_GATT_OK;
1936 } else {
1937 gattc_cb.get_addr_list.status = BTA_GATT_ERROR;
1938 }
1939 } else {
1940 gattc_cb.get_addr_list.status = BTA_GATT_NOT_FOUND;
1941 }
1942
1943 if (p_clrcb != NULL) {
1944 (* p_clrcb->p_cback)(BTA_GATTC_GET_ADDR_LIST_EVT, &gattc_cb);
1945 }
1946
1947 //release the address list buffer after used.
1948 if (gattc_cb.get_addr_list.bda_list != NULL) {
1949 osi_free((void *)gattc_cb.get_addr_list.bda_list);
1950 }
1951
1952 }
1953
1954 /*******************************************************************************
1955 **
1956 ** Function bta_gattc_process_api_cache_clean
1957 **
1958 ** Description process cache clean API to delete cache
1959 **
1960 ** Returns None.
1961 **
1962 *******************************************************************************/
bta_gattc_process_api_cache_clean(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)1963 void bta_gattc_process_api_cache_clean(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
1964 {
1965 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_clean.remote_bda);
1966 UNUSED(p_cb);
1967
1968 if (p_srvc_cb != NULL && p_srvc_cb->p_srvc_cache != NULL) {
1969 //mark it and delete the cache */
1970 list_free(p_srvc_cb->p_srvc_cache);
1971 p_srvc_cb->p_srvc_cache = NULL;
1972 }
1973 }
1974
1975 /*******************************************************************************
1976 **
1977 ** Function bta_gattc_process_srvc_chg_ind
1978 **
1979 ** Description process service change indication.
1980 **
1981 ** Returns None.
1982 **
1983 *******************************************************************************/
bta_gattc_process_srvc_chg_ind(UINT16 conn_id,tBTA_GATTC_RCB * p_clrcb,tBTA_GATTC_SERV * p_srcb,tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_NOTIFY * p_notify,tGATT_VALUE * att_value)1984 BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1985 tBTA_GATTC_RCB *p_clrcb,
1986 tBTA_GATTC_SERV *p_srcb,
1987 tBTA_GATTC_CLCB *p_clcb,
1988 tBTA_GATTC_NOTIFY *p_notify,
1989 tGATT_VALUE *att_value)
1990 {
1991 tBT_UUID gattp_uuid, srvc_chg_uuid;
1992 BOOLEAN processed = FALSE;
1993 UINT8 i;
1994
1995 gattp_uuid.len = 2;
1996 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1997
1998 srvc_chg_uuid.len = 2;
1999 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
2000
2001 const tBTA_GATTC_CHARACTERISTIC *p_char = bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
2002 if (p_char && bta_gattc_uuid_compare(&p_char->service->uuid, &gattp_uuid, TRUE) &&
2003 bta_gattc_uuid_compare(&p_char->uuid, &srvc_chg_uuid, TRUE)) {
2004 if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
2005 APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
2006 return FALSE;
2007 }
2008
2009 UINT8 *p = att_value->value;
2010 UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
2011 UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
2012
2013 APPL_TRACE_DEBUG("%s: service changed s_handle:0x%04x e_handle:0x%04x",
2014 __func__, s_handle, e_handle);
2015
2016 processed = TRUE;
2017 /* mark service handle change pending */
2018 p_srcb->srvc_hdl_chg = TRUE;
2019 /* clear up all notification/indication registration */
2020 bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
2021 /* service change indication all received, do discovery update */
2022 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) {
2023 /* not an opened connection; or connection busy */
2024 /* search for first available clcb and start discovery */
2025 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
2026 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) {
2027 if (bta_gattc_cb.clcb[i].in_use &&
2028 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
2029 bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
2030 p_clcb = &bta_gattc_cb.clcb[i];
2031 break;
2032 }
2033 }
2034 }
2035 /* send confirmation here if this is an indication, it should always be */
2036 GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
2037
2038 /* if connection available, refresh cache by doing discovery now */
2039 if (p_clcb != NULL) {
2040 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find(p_clcb->bda);
2041 if(p_conn) {
2042 p_conn->write_remote_svc_change_ccc_done = FALSE;
2043 }
2044 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
2045 }
2046 }
2047 /* notify applicationf or service change */
2048 if (p_clrcb->p_cback != NULL) {
2049 tBTA_GATTC_SERVICE_CHANGE srvc_chg= {0};
2050 memcpy(srvc_chg.remote_bda, p_srcb->server_bda, sizeof(BD_ADDR));
2051 srvc_chg.conn_id = conn_id;
2052 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)&srvc_chg);
2053 }
2054
2055 }
2056
2057 return processed;
2058
2059 }
2060 /*******************************************************************************
2061 **
2062 ** Function bta_gattc_proc_other_indication
2063 **
2064 ** Description process all non-service change indication/notification.
2065 **
2066 ** Returns None.
2067 **
2068 *******************************************************************************/
bta_gattc_proc_other_indication(tBTA_GATTC_CLCB * p_clcb,UINT8 op,tGATT_CL_COMPLETE * p_data,tBTA_GATTC_NOTIFY * p_notify)2069 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
2070 tGATT_CL_COMPLETE *p_data,
2071 tBTA_GATTC_NOTIFY *p_notify)
2072 {
2073 APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check p_data->att_value.handle=%d p_data->handle=%d",
2074 p_data->att_value.handle, p_data->handle);
2075 APPL_TRACE_DEBUG("is_notify %d", p_notify->is_notify);
2076
2077 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
2078 p_notify->len = p_data->att_value.len;
2079 bdcpy(p_notify->bda, p_clcb->bda);
2080 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
2081 p_notify->conn_id = p_clcb->bta_conn_id;
2082
2083 if (p_clcb->p_rcb->p_cback) {
2084 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify);
2085 }
2086
2087 }
2088 /*******************************************************************************
2089 **
2090 ** Function bta_gattc_process_indicate
2091 **
2092 ** Description process indication/notification.
2093 **
2094 ** Returns None.
2095 **
2096 *******************************************************************************/
bta_gattc_process_indicate(UINT16 conn_id,tGATTC_OPTYPE op,tGATT_CL_COMPLETE * p_data)2097 void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
2098 {
2099 UINT16 handle = p_data->att_value.handle;
2100 tBTA_GATTC_CLCB *p_clcb ;
2101 tBTA_GATTC_RCB *p_clrcb = NULL;
2102 tBTA_GATTC_SERV *p_srcb = NULL;
2103 tBTA_GATTC_NOTIFY notify;
2104 BD_ADDR remote_bda;
2105 tBTA_GATTC_IF gatt_if;
2106 tBTA_TRANSPORT transport;
2107
2108 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
2109 APPL_TRACE_ERROR("%s indication/notif for unknown app", __func__);
2110 if (op == GATTC_OPTYPE_INDICATION) {
2111 GATTC_SendHandleValueConfirm(conn_id, handle);
2112 }
2113 return;
2114 }
2115
2116 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL) {
2117 APPL_TRACE_ERROR("%s indication/notif for unregistered app", __func__);
2118 if (op == GATTC_OPTYPE_INDICATION) {
2119 GATTC_SendHandleValueConfirm(conn_id, handle);
2120 }
2121 return;
2122 }
2123
2124 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
2125 APPL_TRACE_ERROR("%s indication/notif for unknown device, ignore", __func__);
2126 if (op == GATTC_OPTYPE_INDICATION) {
2127 GATTC_SendHandleValueConfirm(conn_id, handle);
2128 }
2129 return;
2130 }
2131
2132 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
2133
2134 notify.handle = handle;
2135 /* if non-service change indication/notification, forward to application */
2136 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, &p_data->att_value)) {
2137 /* if app registered for the notification */
2138 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) {
2139 /* connection not open yet */
2140 if (p_clcb == NULL) {
2141 p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
2142
2143 if (p_clcb == NULL) {
2144 APPL_TRACE_ERROR("No resources");
2145 return;
2146 }
2147
2148 p_clcb->bta_conn_id = conn_id;
2149 p_clcb->transport = transport;
2150
2151 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
2152 }
2153
2154 if (p_clcb != NULL) {
2155 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
2156 }
2157 } else if (op == GATTC_OPTYPE_INDICATION) {
2158 /* no one interested and need ack? */
2159 APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
2160 GATTC_SendHandleValueConfirm(conn_id, handle);
2161 }
2162 }
2163 }
2164 /*******************************************************************************
2165 **
2166 ** Function bta_gattc_cmpl_cback
2167 **
2168 ** Description client operation complete callback register with BTE GATT.
2169 **
2170 ** Returns None.
2171 **
2172 *******************************************************************************/
bta_gattc_cmpl_cback(UINT16 conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)2173 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
2174 tGATT_CL_COMPLETE *p_data)
2175 {
2176 tBTA_GATTC_CLCB *p_clcb;
2177 APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
2178 conn_id, op, status);
2179
2180 /* notification and indication processed right away */
2181 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) {
2182 bta_gattc_process_indicate(conn_id, op, p_data);
2183 return;
2184 }
2185 /* for all other operation, not expected if w/o connection */
2186 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL) {
2187 APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
2188 return;
2189 }
2190
2191 /* if over BR_EDR, inform PM for mode change */
2192 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
2193 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2194 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
2195 }
2196
2197 bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
2198 }
2199
2200 /*******************************************************************************
2201 **
2202 ** Function bta_gattc_cmpl_sendmsg
2203 **
2204 ** Description client operation complete send message
2205 **
2206 ** Returns None.
2207 **
2208 *******************************************************************************/
bta_gattc_cmpl_sendmsg(UINT16 conn_id,tGATTC_OPTYPE op,tBTA_GATT_STATUS status,tGATT_CL_COMPLETE * p_data)2209 static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
2210 tBTA_GATT_STATUS status,
2211 tGATT_CL_COMPLETE *p_data)
2212 {
2213 const UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
2214 tBTA_GATTC_OP_CMPL *p_buf = (tBTA_GATTC_OP_CMPL *) osi_malloc(len);
2215
2216 if (p_buf != NULL) {
2217 memset(p_buf, 0, len);
2218 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
2219 p_buf->hdr.layer_specific = conn_id;
2220 p_buf->status = status;
2221 p_buf->op_code = op;
2222
2223 if (p_data != NULL) {
2224 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
2225 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
2226 }
2227
2228 bta_sys_sendmsg(p_buf);
2229 }
2230 }
2231
2232 /*******************************************************************************
2233 **
2234 ** Function bta_gattc_cong_cback
2235 **
2236 ** Description congestion callback for BTA GATT client.
2237 **
2238 ** Returns void
2239 **
2240 ********************************************************************************/
bta_gattc_cong_cback(UINT16 conn_id,BOOLEAN congested)2241 static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
2242 {
2243 tBTA_GATTC cb_data;
2244 cb_data.congest.conn_id = conn_id;
2245 cb_data.congest.congested = congested;
2246 btc_gattc_congest_callback(&cb_data);
2247 }
2248
2249 /*******************************************************************************
2250 **
2251 ** Function bta_gattc_req_cback
2252 **
2253 ** Description GATT request command callback for BTA GATT client.
2254 **
2255 ** Returns void
2256 **
2257 ********************************************************************************/
bta_gattc_req_cback(UINT16 conn_id,UINT32 trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)2258 static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data)
2259 {
2260 /* GATTC doesn't need to process the GATT request commands.
2261 * Add this callback here to avoid the warning "Call back not found for application"
2262 * printed in the function gatt_sr_send_req_callback
2263 * */
2264 UNUSED (conn_id);
2265 UNUSED (trans_id) ;
2266 UNUSED (type);
2267 UNUSED (p_data);
2268 }
2269
2270 #if BLE_INCLUDED == TRUE
2271 /*******************************************************************************
2272 **
2273 ** Function bta_gattc_init_clcb_conn
2274 **
2275 ** Description Initiate a BTA CLCB connection
2276 **
2277 ** Returns void
2278 **
2279 ********************************************************************************/
bta_gattc_init_clcb_conn(UINT8 cif,BD_ADDR remote_bda)2280 void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
2281 {
2282 tBTA_GATTC_CLCB *p_clcb = NULL;
2283 tBTA_GATTC_DATA gattc_data;
2284 UINT16 conn_id;
2285
2286 /* should always get the connection ID */
2287 if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE) {
2288 APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
2289 return;
2290 }
2291
2292 /* initiate a new connection here */
2293 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) {
2294 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
2295
2296 gattc_data.api_conn.client_if = cif;
2297 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
2298 gattc_data.api_conn.is_direct = TRUE;
2299
2300 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
2301 } else {
2302 APPL_TRACE_ERROR("No resources");
2303 }
2304 }
2305 /*******************************************************************************
2306 **
2307 ** Function bta_gattc_process_listen_all
2308 **
2309 ** Description process listen all, send open callback to application for all
2310 ** connected slave LE link.
2311 **
2312 ** Returns void
2313 **
2314 ********************************************************************************/
bta_gattc_process_listen_all(UINT8 cif)2315 void bta_gattc_process_listen_all(UINT8 cif)
2316 {
2317 UINT8 i_conn = 0;
2318 tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
2319
2320 for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
2321 if (p_conn->in_use ) {
2322 if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL) {
2323 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
2324 }
2325 /* else already connected */
2326 }
2327 }
2328 }
2329 /*******************************************************************************
2330 **
2331 ** Function bta_gattc_listen
2332 **
2333 ** Description Start or stop a listen for connection
2334 **
2335 ** Returns void
2336 **
2337 ********************************************************************************/
bta_gattc_listen(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)2338 void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2339 {
2340 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2341 tBTA_GATTC cb_data;
2342 UNUSED(p_cb);
2343
2344 cb_data.reg_oper.status = BTA_GATT_ERROR;
2345 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2346
2347 if (p_clreg == NULL) {
2348 APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
2349 p_msg->api_listen.client_if);
2350 return;
2351 }
2352 /* mark bg conn record */
2353 if (bta_gattc_mark_bg_conn(p_msg->api_listen.client_if,
2354 (BD_ADDR_PTR) p_msg->api_listen.remote_bda,
2355 p_msg->api_listen.start,
2356 TRUE)) {
2357 if (!GATT_Listen(p_msg->api_listen.client_if,
2358 p_msg->api_listen.start,
2359 p_msg->api_listen.remote_bda)) {
2360 APPL_TRACE_ERROR("Listen failure");
2361 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2362 } else {
2363 cb_data.status = BTA_GATT_OK;
2364
2365 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2366
2367 if (p_msg->api_listen.start) {
2368 /* if listen to a specific target */
2369 if (p_msg->api_listen.remote_bda != NULL) {
2370
2371 /* if is a connected remote device */
2372 if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
2373 bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
2374 p_msg->api_listen.remote_bda,
2375 BTA_GATT_TRANSPORT_LE) == NULL) {
2376
2377 bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
2378 p_msg->api_listen.remote_bda);
2379 }
2380 }
2381 /* if listen to all */
2382 else {
2383 APPL_TRACE_DEBUG("Listen For All now");
2384 /* go through all connected device and send
2385 callback for all connected slave connection */
2386 bta_gattc_process_listen_all(p_msg->api_listen.client_if);
2387 }
2388 }
2389 }
2390 }
2391 }
2392
2393 /*******************************************************************************
2394 **
2395 ** Function bta_gattc_broadcast
2396 **
2397 ** Description Start or stop broadcasting
2398 **
2399 ** Returns void
2400 **
2401 ********************************************************************************/
bta_gattc_broadcast(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)2402 void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
2403 {
2404 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
2405 tBTA_GATTC cb_data;
2406 UNUSED(p_cb);
2407
2408 cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
2409 cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL);
2410 //TODO need modify callback if used
2411 if (p_clreg && p_clreg->p_cback) {
2412 (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
2413 }
2414 }
2415
2416 /*******************************************************************************
2417 **
2418 ** Function bta_gattc_register_service_change_notify
2419 **
2420 ** Description Find remote device's gatt service change characteristic ccc's handle and write 2 to this
2421 ** this ccc.
2422 **
2423 ** Returns Return result of service change ccc service discovery result
2424 **
2425 *******************************************************************************/
bta_gattc_register_service_change_notify(UINT16 conn_id,BD_ADDR remote_bda)2426 tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_id, BD_ADDR remote_bda)
2427 {
2428 tBTA_GATTC_SERV *p_srcb = NULL;
2429 list_t *p_cache = NULL;
2430 tBTA_GATTC_SERVICE *p_service = NULL;
2431 tBTA_GATTC_CHARACTERISTIC *p_char = NULL;
2432 tBTA_GATTC_DESCRIPTOR *p_desc = NULL;
2433 tBTA_GATTC_FIND_SERVICE_CB result;
2434 BOOLEAN gatt_cache_found = FALSE;
2435 BOOLEAN gatt_service_found = FALSE;
2436 BOOLEAN gatt_service_change_found = FALSE;
2437 BOOLEAN gatt_ccc_found = FALSE;
2438
2439 tBT_UUID gatt_service_uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
2440 tBT_UUID gatt_service_change_uuid = {LEN_UUID_16, {GATT_UUID_GATT_SRV_CHGD}};
2441 tBT_UUID gatt_ccc_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
2442 tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find_alloc(remote_bda);
2443 if(p_conn && p_conn->write_remote_svc_change_ccc_done) {
2444 return SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
2445 }
2446
2447 p_srcb = bta_gattc_find_srcb(remote_bda);
2448 if ((p_srcb != NULL) && (p_srcb->p_srvc_cache != NULL)) {
2449 p_cache = p_srcb->p_srvc_cache;
2450 gatt_cache_found = TRUE;
2451 }
2452 else {
2453 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2454 }
2455 /* start to find gatt service */
2456 if (gatt_cache_found == TRUE) {
2457 for (list_node_t *sn = list_begin(p_cache);
2458 sn != list_end(p_cache); sn = list_next(sn)) {
2459 p_service = list_node(sn);
2460 if (bta_gattc_uuid_compare(&gatt_service_uuid, &p_service->uuid, TRUE)) {
2461 gatt_service_found = TRUE;
2462 break;
2463 }
2464 }
2465 }
2466 else {
2467 result = SERVICE_CHANGE_CACHE_NOT_FOUND;
2468 }
2469
2470 /* start to find gatt service change characteristic */
2471 if (gatt_service_found == TRUE) {
2472 if (p_service->characteristics) {
2473 for (list_node_t *cn = list_begin(p_service->characteristics);
2474 cn != list_end(p_service->characteristics); cn = list_next(cn)) {
2475 p_char = list_node(cn);
2476 if (bta_gattc_uuid_compare(&gatt_service_change_uuid, &p_char->uuid, TRUE)) {
2477 gatt_service_change_found = TRUE;
2478 break;
2479 }
2480 }
2481 }
2482 }
2483 else if (gatt_cache_found == TRUE) {
2484 /* Gatt service not found, start a timer to wait for service discovery */
2485 result = SERVICE_CHANGE_SERVICE_NOT_FOUND;
2486 }
2487 /* start to find gatt service change characteristic ccc */
2488 if (gatt_service_change_found == TRUE) {
2489 if (p_char->descriptors) {
2490 for (list_node_t *dn = list_begin(p_char->descriptors);
2491 dn != list_end(p_char->descriptors); dn = list_next(dn)) {
2492 p_desc = list_node(dn);
2493 if (bta_gattc_uuid_compare(&gatt_ccc_uuid, &p_desc->uuid, TRUE)) {
2494 gatt_ccc_found = TRUE;
2495 break;
2496 }
2497 }
2498 }
2499 }
2500 else if (gatt_service_found ==TRUE) {
2501 /* Gatt service found, but service change char not found,
2502 * Case1: remote device doesn't have service change char, we don't need to start a timer here to
2503 * wait for service discovery
2504 * Case2: remote device exist service change char, we have found gatt service, but have not found
2505 * service change char, we need to start a timer here*/
2506 result = SERVICE_CHANGE_CHAR_NOT_FOUND;
2507 }
2508
2509 if (gatt_ccc_found == TRUE){
2510 if (p_conn) {
2511 p_conn->svc_change_descr_handle = p_desc->handle;
2512 p_conn->write_remote_svc_change_ccc_done = TRUE;
2513 }
2514 result = SERVICE_CHANGE_CCC_WRITTEN_SUCCESS;
2515 uint16_t indicate_value = GATT_CLT_CONFIG_INDICATION;
2516 tBTA_GATT_UNFMT indicate_v;
2517 indicate_v.len = 2;
2518 indicate_v.p_value = (uint8_t *)&indicate_value;
2519 BTA_GATTC_WriteCharDescr (conn_id, p_desc->handle, BTA_GATTC_TYPE_WRITE, &indicate_v, BTA_GATT_AUTH_REQ_NONE);
2520
2521 }
2522 else if (gatt_service_change_found == TRUE) {
2523 /* Gatt service char found, but service change char ccc not found,
2524 * Case1: remote device doesn't have service change char ccc, we don't need to start a timer here to
2525 * wait for service discovery
2526 * Case2: remote device exist service change char ccc, we have found gatt service change char, but have not found
2527 * service change char ccc, we need to start a timer here */
2528 result = SERVICE_CHANGE_CCC_NOT_FOUND;
2529 }
2530
2531 return result;
2532 }
2533
2534 #endif
2535 #endif ///GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE
2536