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