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