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