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
26 #include "bt_target.h"
27
28 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
29
30
31 #include "utl.h"
32 #include "gki.h"
33 #include "bd.h"
34 #include "bta_sys.h"
35
36 #include "bta_gattc_int.h"
37 #include "l2c_api.h"
38
39
40 #include <string.h>
41
42 /*****************************************************************************
43 ** Constants
44 *****************************************************************************/
45 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
46 BOOLEAN connected, tGATT_DISCONN_REASON reason);
47
48 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
49 tGATT_CL_COMPLETE *p_data);
50
51 static tGATT_CBACK bta_gattc_cl_cback =
52 {
53 bta_gattc_conn_cback,
54 bta_gattc_cmpl_cback,
55 bta_gattc_disc_res_cback,
56 bta_gattc_disc_cmpl_cback,
57 NULL
58 };
59
60 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
61 static UINT16 bta_gattc_opcode_to_int_evt[] =
62 {
63 BTA_GATTC_API_READ_EVT,
64 BTA_GATTC_API_WRITE_EVT,
65 BTA_GATTC_API_EXEC_EVT
66 };
67
68 #if (BT_TRACE_VERBOSE == TRUE)
69 static const char *bta_gattc_op_code_name[] =
70 {
71 "Unknown",
72 "Discovery",
73 "Read",
74 "Write",
75 "Exec",
76 "Config",
77 "Notification",
78 "Indication"
79 };
80 #endif
81 /*****************************************************************************
82 ** Action Functions
83 *****************************************************************************/
84
85 /*******************************************************************************
86 **
87 ** Function bta_gattc_register
88 **
89 ** Description Register a GATT client application with BTA.
90 **
91 ** Returns void
92 **
93 *******************************************************************************/
bta_gattc_register(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_data)94 void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
95 {
96 tBTA_GATTC cb_data;
97 UINT8 i;
98 tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid;
99 tBTA_GATTC_INT_START_IF *p_buf;
100
101
102 /* todo need to check duplicate uuid */
103 for (i = 0; i < BTA_GATTC_CL_MAX; i ++)
104 {
105 if (!p_cb->cl_rcb[i].in_use)
106 {
107 if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0)
108 {
109 APPL_TRACE_ERROR0("Register with GATT stack failed.");
110 cb_data.reg_oper.status = BTA_GATT_ERROR;
111 }
112 else
113
114 {
115 p_cb->cl_rcb[i].in_use = TRUE;
116 p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
117 memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
118
119 /* BTA use the same client interface as BTE GATT statck */
120 cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
121 // btla-specific ++
122 memcpy(&(cb_data.reg_oper.app_uuid),p_app_uuid,sizeof(tBT_UUID));
123 // btla-specific --
124
125 cb_data.reg_oper.status = BTA_GATT_OK;
126
127 if ((p_buf = (tBTA_GATTC_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTC_INT_START_IF))) != NULL)
128 {
129 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
130 p_buf->client_if = p_cb->cl_rcb[i].client_if;
131
132 bta_sys_sendmsg(p_buf);
133 }
134 else
135 {
136 cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
137 memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
138 }
139 break;
140 }
141 }
142 }
143 /* callback with register event */
144 if (p_data->api_reg.p_cback)
145 {
146 (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data);
147 }
148 }
149 /*******************************************************************************
150 **
151 ** Function bta_gattc_start_if
152 **
153 ** Description start an application interface.
154 **
155 ** Returns none.
156 **
157 *******************************************************************************/
bta_gattc_start_if(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)158 void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
159 {
160 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) !=NULL )
161 {
162 GATT_StartIf(p_msg->int_start_if.client_if);
163 }
164 else
165 {
166 APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.client_if );
167 }
168 }
169 /*******************************************************************************
170 **
171 ** Function bta_gattc_deregister_cmpl
172 **
173 ** Description De-Register a GATT client application with BTA completed.
174 **
175 ** Returns void
176 **
177 *******************************************************************************/
bta_gattc_int_deregister_cmpl(tBTA_GATTC_RCB * p_clreg,tBTA_GATTC_IF client_if)178 void bta_gattc_int_deregister_cmpl(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_IF client_if)
179 {
180 tBTA_GATTC_CBACK *p_cback = p_clreg->p_cback;
181 tBTA_GATTC cb_data;
182
183
184 APPL_TRACE_DEBUG1("bta_gattc_int_deregister_cmpl client_if=%d", client_if );
185
186 GATT_Deregister(p_clreg->client_if);
187 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
188
189 cb_data.reg_oper.client_if = client_if;
190 cb_data.reg_oper.status = BTA_GATT_OK;
191
192 if (p_cback)
193 /* callback with de-register event */
194 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
195 }
196
197
198 /*******************************************************************************
199 **
200 ** Function bta_gattc_deregister_cmpl
201 **
202 ** Description De-Register a GATT client application with BTA completed.
203 **
204 ** Returns void
205 **
206 *******************************************************************************/
bta_gattc_deregister_cmpl(tBTA_GATTC_RCB * p_clreg,tBTA_GATTC_IF client_if)207 void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_IF client_if)
208 {
209 tBTA_GATTC_INT_DEREG *p_buf;
210
211 APPL_TRACE_DEBUG1("bta_gattc_deregister_cmpl client_if=%d", client_if );
212
213 if ((p_buf = (tBTA_GATTC_INT_DEREG *) GKI_getbuf(sizeof(tBTA_GATTC_INT_DEREG))) != NULL)
214 {
215 p_buf->hdr.event = BTA_GATTC_INT_DEREG_EVT;
216 p_buf->client_if = client_if;
217 bta_sys_sendmsg(p_buf);
218 }
219 else
220 {
221 APPL_TRACE_ERROR1("bta_gattc_deregister_cmpl unable to allocate buffer to complete dereg=%d", client_if);
222 }
223
224 }
225 /*******************************************************************************
226 **
227 ** Function bta_gattc_deregister
228 **
229 ** Description De-Register a GATT client application with BTA.
230 **
231 ** Returns void
232 **
233 *******************************************************************************/
bta_gattc_int_deregister(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_data)234 void bta_gattc_int_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
235 {
236
237 tBTA_GATTC_IF client_if = p_data->int_dereg.client_if;
238 tBTA_GATTC_CBACK *p_cback;
239 tBTA_GATTC cb_data;
240 tBTA_GATTC_RCB *p_clreg;
241
242
243 APPL_TRACE_DEBUG1("bta_gattc_int_deregister_cmpl client_if=%d", client_if );
244
245 if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
246 {
247 p_cback = p_clreg->p_cback;
248 GATT_Deregister(client_if);
249 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
250 cb_data.reg_oper.client_if = client_if;
251 cb_data.reg_oper.status = BTA_GATT_OK;
252
253 if (p_cback)
254 /* callback with de-register event */
255 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC *)&cb_data);
256 }
257 else
258 {
259 APPL_TRACE_ERROR1("bta_gattc_int_deregister Deregister Failed, unknown client_if: %d", p_data->int_dereg.client_if);
260 }
261 }
262 /*******************************************************************************
263 **
264 ** Function bta_gattc_deregister
265 **
266 ** Description De-Register a GATT client application with BTA.
267 **
268 ** Returns void
269 **
270 *******************************************************************************/
bta_gattc_deregister(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_data)271 void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
272 {
273 tBTA_GATTC_RCB *p_clreg;
274 UINT8 i;
275 BT_HDR buf;
276
277 if ((p_clreg = bta_gattc_cl_get_regcb(p_data->api_dereg.client_if)) != NULL)
278 {
279 if (p_clreg->num_clcb > 0)
280 {
281 /* close all CLCB related to this app */
282 for (i= 0; i < BTA_GATTC_CLCB_MAX; i ++)
283 {
284 if (p_cb->clcb[i].in_use && (p_cb->clcb[i].p_rcb == p_clreg))
285 {
286 p_clreg->dereg_pending = TRUE;
287
288 buf.event = BTA_GATTC_API_CLOSE_EVT;
289 buf.layer_specific = p_cb->clcb[i].bta_conn_id;
290 bta_gattc_close(&p_cb->clcb[i], (tBTA_GATTC_DATA *)&buf) ;
291 }
292 }
293 }
294 else
295 bta_gattc_deregister_cmpl(p_clreg, p_clreg->client_if);
296 }
297 else
298 {
299 APPL_TRACE_ERROR1("bta_gattc_deregister Deregister Failed, unknown client_if: %d", p_data->api_dereg.client_if);
300 }
301 }
302 /*******************************************************************************
303 **
304 ** Function bta_gattc_process_api_open
305 **
306 ** Description process connect API request.
307 **
308 ** Returns void
309 **
310 *******************************************************************************/
bta_gattc_process_api_open(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)311 void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
312 {
313 UINT16 event = ((BT_HDR *)p_msg)->event;
314 tBTA_GATTC_CLCB *p_clcb = NULL;
315 tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
316
317 if (p_clreg != NULL)
318 {
319 if (p_msg->api_conn.is_direct)
320 {
321 if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
322 p_msg->api_conn.remote_bda)) != NULL)
323 {
324 bta_gattc_sm_execute(p_clcb, event, p_msg);
325 }
326 else
327 {
328 APPL_TRACE_ERROR0("No resources to open a new connection.");
329
330 bta_gattc_send_open_cback(p_clreg,
331 BTA_GATT_NO_RESOURCES,
332 p_msg->api_conn.remote_bda,
333 BTA_GATT_INVALID_CONN_ID);
334 }
335 }
336 else
337 {
338 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
339 }
340 }
341 else
342 {
343 APPL_TRACE_ERROR1("bta_gattc_process_api_open Failed, unknown client_if: %d",
344 p_msg->api_conn.client_if);
345 }
346 }
347 /*******************************************************************************
348 **
349 ** Function bta_gattc_process_api_open_cancel
350 **
351 ** Description process connect API request.
352 **
353 ** Returns void
354 **
355 *******************************************************************************/
bta_gattc_process_api_open_cancel(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)356 void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
357 {
358 UINT16 event = ((BT_HDR *)p_msg)->event;
359 tBTA_GATTC_CLCB *p_clcb = NULL;
360 tBTA_GATTC_RCB *p_clreg;
361 tBTA_GATTC cb_data;
362
363 if (p_msg->api_cancel_conn.is_direct)
364 {
365 if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
366 p_msg->api_cancel_conn.remote_bda)) != NULL)
367 {
368 bta_gattc_sm_execute(p_clcb, event, p_msg);
369 }
370 else
371 {
372 APPL_TRACE_ERROR0("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 {
378 cb_data.status = BTA_GATT_ERROR;
379 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
380 }
381 }
382 }
383 else
384 {
385 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
386
387 }
388 }
389 /*******************************************************************************
390 **
391 ** Function bta_gattc_cancel_open_error
392 **
393 ** Description
394 **
395 ** Returns void
396 **
397 *******************************************************************************/
bta_gattc_cancel_open_error(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)398 void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
399 {
400 tBTA_GATTC cb_data;
401 cb_data.status=BTA_GATT_ERROR;
402
403 if ( p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback )
404 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
405 }
406
407 /*******************************************************************************
408 **
409 ** Function bta_gattc_open_error
410 **
411 ** Description
412 **
413 ** Returns void
414 **
415 *******************************************************************************/
bta_gattc_open_error(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)416 void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
417 {
418 APPL_TRACE_ERROR0("Connection already opened. wrong state");
419
420 bta_gattc_send_open_cback(p_clcb->p_rcb,
421 BTA_GATT_ALREADY_OPEN,
422 p_clcb->bda,
423 p_clcb->bta_conn_id);
424 }
425 /*******************************************************************************
426 **
427 ** Function bta_gattc_open_fail
428 **
429 ** Description
430 **
431 ** Returns void
432 **
433 *******************************************************************************/
bta_gattc_open_fail(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)434 void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
435 {
436 bta_gattc_open_error(p_clcb, p_data);
437 /* open failure, remove clcb */
438 bta_gattc_clcb_dealloc(p_clcb);
439 }
440
441 /*******************************************************************************
442 **
443 ** Function bta_gattc_open
444 **
445 ** Description Process API connection function.
446 **
447 ** Returns void
448 **
449 *******************************************************************************/
bta_gattc_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)450 void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
451 {
452 tBTA_GATTC_DATA gattc_data;
453
454 /* open/hold a connection */
455 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, TRUE))
456 {
457 APPL_TRACE_ERROR0("Connection open failure");
458
459 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
460 }
461 else
462 {
463 /* a connected remote device */
464 if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
465 p_data->api_conn.remote_bda,
466 &p_clcb->bta_conn_id))
467 {
468 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id;
469
470 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
471 }
472 /* else wait for the callback event */
473 }
474 }
475 /*******************************************************************************
476 **
477 ** Function bta_gattc_init_bk_conn
478 **
479 ** Description Process API Open for a background connection
480 **
481 ** Returns void
482 **
483 *******************************************************************************/
bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN * p_data,tBTA_GATTC_RCB * p_clreg)484 void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg)
485 {
486 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
487 UINT16 conn_id;
488 tBTA_GATTC_CLCB *p_clcb;
489 tBTA_GATTC_DATA gattc_data;
490
491 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))
492 {
493 /* alwaya call open to hold a connection */
494 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE))
495 {
496 status = BTA_GATT_ERROR;
497 APPL_TRACE_ERROR0("bta_gattc_init_bk_conn failed");
498 }
499 else
500 {
501 status = BTA_GATT_OK;
502
503 /* if is a connected remote device */
504 if (GATT_GetConnIdIfConnected(p_data->client_if,
505 p_data->remote_bda,
506 &conn_id))
507 {
508 if ((p_clcb = bta_gattc_clcb_alloc(p_data->client_if, p_data->remote_bda)) != NULL)
509 {
510 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
511
512 /* open connection */
513 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
514 status = BTA_GATT_OK;
515 }
516 }
517 }
518 }
519
520 /* open failure, report OPEN_EVT */
521 if (status != BTA_GATT_OK)
522 {
523 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, BTA_GATT_INVALID_CONN_ID);
524 }
525 }
526 /*******************************************************************************
527 **
528 ** Function bta_gattc_cancel_bk_conn
529 **
530 ** Description Process API Cancel Open for a background connection
531 **
532 ** Returns void
533 **
534 *******************************************************************************/
bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN * p_data)535 void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data)
536 {
537 tBTA_GATTC_RCB *p_clreg;
538 tBTA_GATTC cb_data;
539 cb_data.status = BTA_GATT_ERROR;
540
541 /* remove the device from the bg connection mask */
542 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, FALSE, FALSE))
543 {
544 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, FALSE))
545 {
546 cb_data.status = BTA_GATT_OK;
547 }
548 else
549 {
550 APPL_TRACE_ERROR0("bta_gattc_cancel_bk_conn failed");
551 }
552 }
553 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
554
555 if (p_clreg && p_clreg->p_cback)
556 {
557 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
558 }
559
560 }
561 /*******************************************************************************
562 **
563 ** Function bta_gattc_int_cancel_open_ok
564 **
565 ** Description
566 **
567 ** Returns void
568 **
569 *******************************************************************************/
bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)570 void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
571 {
572 tBTA_GATTC cb_data;
573
574 if ( p_clcb->p_rcb->p_cback )
575 {
576 cb_data.status = BTA_GATT_OK;
577 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
578 }
579
580 bta_gattc_clcb_dealloc(p_clcb);
581 }
582 /*******************************************************************************
583 **
584 ** Function bta_gattc_cancel_open
585 **
586 ** Description
587 **
588 ** Returns void
589 **
590 *******************************************************************************/
bta_gattc_cancel_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)591 void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
592 {
593 tBTA_GATTC cb_data;
594
595 if (GATT_CancelConnect(p_clcb->p_rcb->client_if, p_data->api_cancel_conn.remote_bda, TRUE))
596 {
597 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
598 }
599 else
600 {
601 if ( p_clcb->p_rcb->p_cback )
602 {
603 cb_data.status = BTA_GATT_ERROR;
604 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
605 }
606 }
607 }
608 /*******************************************************************************
609 **
610 ** Function bta_gattc_conn
611 **
612 ** Description receive connection callback from stack
613 **
614 ** Returns void
615 **
616 *******************************************************************************/
bta_gattc_conn(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)617 void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
618 {
619 tBTA_GATTC_IF gatt_if;
620 APPL_TRACE_DEBUG1("bta_gattc_conn server cache state=%d",p_clcb->p_srcb->state);
621
622 if (p_data != NULL)
623 {
624 APPL_TRACE_DEBUG1("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific);
625
626 p_clcb->p_srcb->connected = TRUE;
627 p_clcb->bta_conn_id = p_data->hdr.layer_specific;
628 GATT_GetConnectionInfor(p_data->hdr.layer_specific, &gatt_if, p_clcb->bda);
629
630 /* start database cache if needed */
631 if (p_clcb->p_srcb->p_srvc_cache == NULL ||
632 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE)
633 {
634 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
635 {
636 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
637 bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, p_data);
638 }
639 else /* cache is building */
640 p_clcb->state = BTA_GATTC_DISCOVER_ST;
641 }
642
643 else
644 {
645 /* a pending service handle change indication */
646 if (p_clcb->p_srcb->srvc_hdl_chg)
647 {
648 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
649 /* start discovery */
650 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
651 }
652 }
653
654 if (p_clcb->p_rcb)
655 {
656 bta_gattc_send_open_cback(p_clcb->p_rcb,
657 BTA_GATT_OK,
658 p_clcb->bda,
659 p_clcb->bta_conn_id);
660 }
661 }
662 }
663 /*******************************************************************************
664 **
665 ** Function bta_gattc_close_fail
666 **
667 ** Description close a connection.
668 **
669 ** Returns void
670 **
671 *******************************************************************************/
bta_gattc_close_fail(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)672 void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
673 {
674 tBTA_GATTC cb_data;
675
676 if ( p_clcb->p_rcb->p_cback )
677 {
678 memset(&cb_data, 0, sizeof(tBTA_GATTC));
679 cb_data.close.client_if = p_clcb->p_rcb->client_if;
680 cb_data.close.conn_id = p_data->hdr.layer_specific;
681 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
682 cb_data.close.status = BTA_GATT_ERROR;
683 cb_data.close.reason = BTA_GATT_CONN_NONE;
684
685
686 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
687 }
688 }
689 /*******************************************************************************
690 **
691 ** Function bta_gattc_api_close
692 **
693 ** Description close a GATTC connection.
694 **
695 ** Returns void
696 **
697 *******************************************************************************/
bta_gattc_close(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)698 void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
699 {
700 tBTA_GATTC_CBACK *p_cback = p_clcb->p_rcb->p_cback;
701 tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
702 tBTA_GATTC cb_data;
703
704 APPL_TRACE_DEBUG1("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id);
705
706 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT)
707 p_clcb->status = GATT_Disconnect(p_clcb->bta_conn_id);
708
709 cb_data.close.client_if = p_clcb->p_rcb->client_if;
710 cb_data.close.conn_id = p_clcb->bta_conn_id;
711 cb_data.close.status = p_clcb->status;
712 cb_data.close.reason = p_clcb->reason;
713 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
714
715 bta_gattc_clcb_dealloc(p_clcb);
716
717 ( * p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
718
719 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending)
720 {
721 bta_gattc_deregister_cmpl(p_clreg, p_clreg->client_if);
722 }
723 }
724 /*******************************************************************************
725 **
726 ** Function bta_gattc_reset_discover_st
727 **
728 ** Description when a SRCB finished discovery, tell all related clcb.
729 **
730 ** Returns None.
731 **
732 *******************************************************************************/
bta_gattc_reset_discover_st(tBTA_GATTC_SERV * p_srcb,tBTA_GATT_STATUS status)733 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS status)
734 {
735 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
736 UINT8 i;
737
738 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++)
739 {
740 if (p_cb->clcb[i].p_srcb == p_srcb)
741 {
742 p_cb->clcb[i].status = status;
743 bta_gattc_sm_execute(&p_cb->clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
744 }
745 }
746 }
747 /*******************************************************************************
748 **
749 ** Function bta_gattc_disc_close
750 **
751 ** Description close a GATTC connection while in discovery state.
752 **
753 ** Returns void
754 **
755 *******************************************************************************/
bta_gattc_disc_close(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)756 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
757 {
758 APPL_TRACE_DEBUG1("Discovery cancel conn_id=%d",p_clcb->bta_conn_id);
759
760 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
761 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_CLOSE_EVT, p_data);
762 }
763 /*******************************************************************************
764 **
765 ** Function bta_gattc_set_discover_st
766 **
767 ** Description when a SRCB start discovery, tell all related clcb and set
768 ** the state.
769 **
770 ** Returns None.
771 **
772 *******************************************************************************/
bta_gattc_set_discover_st(tBTA_GATTC_SERV * p_srcb)773 void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
774 {
775 tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
776 UINT8 i;
777
778 #if BLE_INCLUDED == TRUE
779 L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, FALSE);
780 #endif
781 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++)
782 {
783 if (p_cb->clcb[i].p_srcb == p_srcb)
784 {
785 p_cb->clcb[i].status = BTA_GATT_OK;
786 p_cb->clcb[i].state = BTA_GATTC_DISCOVER_ST;
787 }
788 }
789 }
790 /*******************************************************************************
791 **
792 ** Function bta_gattc_restart_discover
793 **
794 ** Description process service change in discovery state, mark up the auto
795 ** update flag and set status to be discovery cancel for current
796 ** discovery.
797 **
798 ** Returns None.
799 **
800 *******************************************************************************/
bta_gattc_restart_discover(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)801 void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
802 {
803 p_clcb->status = BTA_GATT_CANCEL;
804 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
805 }
806 /*******************************************************************************
807 **
808 ** Function bta_gattc_start_discover
809 **
810 ** Description Start a discovery on server.
811 **
812 ** Returns None.
813 **
814 *******************************************************************************/
bta_gattc_start_discover(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)815 void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
816 {
817
818 APPL_TRACE_DEBUG2("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
819 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
820
821 if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
822 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
823 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC)
824 /* no pending operation, start discovery right away */
825 {
826 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
827
828 if (p_clcb->p_srcb != NULL)
829 {
830 /* clear the service change mask */
831 p_clcb->p_srcb->srvc_hdl_chg = FALSE;
832 p_clcb->p_srcb->update_count = 0;
833 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
834
835 /* set all srcb related clcb into discovery ST */
836 bta_gattc_set_discover_st(p_clcb->p_srcb);
837
838 if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK)
839 {
840 p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
841 }
842 if (p_clcb->status != BTA_GATT_OK)
843 {
844 APPL_TRACE_ERROR0("discovery on server failed");
845 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
846 }
847 }
848 else
849 {
850 APPL_TRACE_ERROR0("unknown device, can not start discovery");
851 }
852 }
853 /* pending operation, wait until it finishes */
854 else
855 {
856 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
857
858 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
859 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
860 }
861
862 }
863 /*******************************************************************************
864 **
865 ** Function bta_gattc_disc_cmpl
866 **
867 ** Description discovery on server is finished
868 **
869 ** Returns None.
870 **
871 *******************************************************************************/
bta_gattc_disc_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)872 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
873 {
874 tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
875 APPL_TRACE_DEBUG1("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id);
876
877 #if BLE_INCLUDED == TRUE
878 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
879 #endif
880 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
881
882 if (p_clcb->status != GATT_SUCCESS)
883 {
884 /* clean up cache */
885 if(p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache)
886 {
887 while (p_clcb->p_srcb->cache_buffer.p_first)
888 {
889 GKI_freebuf (GKI_dequeue (&p_clcb->p_srcb->cache_buffer));
890 }
891 p_clcb->p_srcb->p_srvc_cache = NULL;
892 }
893
894 /* used to reset cache in application */
895 bta_gattc_co_cache_reset(p_clcb->p_srcb->server_bda);
896 }
897 /* release pending attribute list buffer */
898 utl_freebuf((void **)&p_clcb->p_srcb->p_srvc_list);
899
900 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
901 {
902 /* start discovery again */
903 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
904 }
905 /* get any queued command to proceed */
906 else if (p_q_cmd != NULL)
907 {
908 p_clcb->p_q_cmd = NULL;
909
910 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
911
912 utl_freebuf((void **)&p_q_cmd);
913
914 }
915 }
916 /*******************************************************************************
917 **
918 ** Function bta_gattc_read
919 **
920 ** Description Read an attribute
921 **
922 ** Returns None.
923 **
924 *******************************************************************************/
bta_gattc_read(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)925 void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
926 {
927 UINT16 handle = 0;
928 tGATT_READ_PARAM read_param;
929 tBTA_GATTC_OP_CMPL op_cmpl;
930
931 memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
932 memset (&op_cmpl, 0 ,sizeof(tBTA_GATTC_OP_CMPL));
933
934 if (bta_gattc_enqueue(p_clcb, p_data))
935 {
936 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
937 &p_data->api_read.srvc_id,
938 &p_data->api_read.char_id,
939 p_data->api_read.descr_type)) == 0)
940 {
941 op_cmpl.status = BTA_GATT_ERROR;
942 }
943 else
944 {
945 read_param.by_handle.handle = handle;
946 read_param.by_handle.auth_req = p_data->api_read.auth_req;
947
948 op_cmpl.status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
949 }
950
951 /* read fail */
952 if (op_cmpl.status != BTA_GATT_OK)
953 {
954 op_cmpl.op_code = GATTC_OPTYPE_READ;
955 op_cmpl.p_cmpl = NULL;
956
957 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
958 }
959 }
960 }
961 /*******************************************************************************
962 **
963 ** Function bta_gattc_read_multi
964 **
965 ** Description read multiple
966 **
967 ** Returns None.
968 *********************************************************************************/
bta_gattc_read_multi(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)969 void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
970 {
971 UINT16 i, handle;
972 tBTA_GATT_STATUS status = BTA_GATT_OK;
973 tGATT_READ_PARAM read_param;
974 tBTA_GATTC_OP_CMPL op_cmpl;
975 tBTA_GATTC_ATTR_ID *p_id;
976 tBT_UUID dummy_uuid;
977
978 if (bta_gattc_enqueue(p_clcb, p_data))
979 {
980 memset(&dummy_uuid, 0, sizeof(tBT_UUID));
981 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
982
983 p_id = p_data->api_read_multi.p_id_list;
984
985 for (i = 0; i < p_data->api_read_multi.num_attr && p_id; i ++, p_id ++)
986 {
987 handle = 0;
988
989 if (p_id->id_type == BTA_GATT_TYPE_CHAR)
990 {
991 handle = bta_gattc_id2handle(p_clcb->p_srcb,
992 &p_id->id_value.char_id.srvc_id,
993 &p_id->id_value.char_id.char_id,
994 dummy_uuid);
995 }
996 else if (p_id->id_type == BTA_GATT_TYPE_CHAR_DESCR)
997 {
998 handle = bta_gattc_id2handle(p_clcb->p_srcb,
999 &p_id->id_value.char_descr_id.char_id.srvc_id,
1000 &p_id->id_value.char_descr_id.char_id.char_id,
1001 p_id->id_value.char_descr_id.descr_type);
1002 }
1003 else
1004 {
1005 APPL_TRACE_ERROR1("invalud ID type: %d", p_id->id_type);
1006 }
1007
1008 if (handle == 0)
1009 {
1010 status = BTA_GATT_ERROR;
1011 break;
1012 }
1013 }
1014 if (status == BTA_GATT_OK)
1015 {
1016 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
1017 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
1018
1019 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
1020 }
1021
1022 /* read fail */
1023 if (status != BTA_GATT_OK)
1024 {
1025 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
1026
1027 op_cmpl.status = status;
1028 op_cmpl.op_code = GATTC_OPTYPE_READ;
1029 op_cmpl.p_cmpl = NULL;
1030
1031 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
1032 }
1033 }
1034 }
1035 /*******************************************************************************
1036 **
1037 ** Function bta_gattc_write
1038 **
1039 ** Description Write an attribute
1040 **
1041 ** Returns None.
1042 **
1043 *******************************************************************************/
bta_gattc_write(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1044 void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1045 {
1046 UINT16 handle = 0;
1047 tGATT_VALUE attr = {0};
1048 tBTA_GATTC_OP_CMPL op_cmpl;
1049 tBTA_GATT_STATUS status = BTA_GATT_OK;
1050
1051 if (bta_gattc_enqueue(p_clcb, p_data))
1052 {
1053 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1054 &p_data->api_write.srvc_id,
1055 &p_data->api_write.char_id,
1056 p_data->api_write.descr_type)) == 0)
1057 {
1058 status = BTA_GATT_ERROR;
1059 }
1060 else
1061 {
1062 attr.handle= handle;
1063 attr.offset = p_data->api_write.offset;
1064 attr.len = p_data->api_write.len;
1065 attr.auth_req = p_data->api_write.auth_req;
1066
1067 if (p_data->api_write.p_value)
1068 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1069
1070 status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1071 }
1072
1073 /* write fail */
1074 if (status != BTA_GATT_OK)
1075 {
1076 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
1077
1078 op_cmpl.status = status;
1079 op_cmpl.op_code = GATTC_OPTYPE_WRITE;
1080 op_cmpl.p_cmpl = NULL;
1081
1082 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
1083 }
1084 }
1085 }
1086 /*******************************************************************************
1087 **
1088 ** Function bta_gattc_execute
1089 **
1090 ** Description send execute write
1091 **
1092 ** Returns None.
1093 *********************************************************************************/
bta_gattc_execute(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1094 void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1095 {
1096 tBTA_GATTC_OP_CMPL op_cmpl;
1097 tBTA_GATT_STATUS status;
1098
1099 if (bta_gattc_enqueue(p_clcb, p_data))
1100 {
1101 status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1102
1103 if (status != BTA_GATT_OK)
1104 {
1105 memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
1106
1107 op_cmpl.status = status;
1108 op_cmpl.op_code = GATTC_OPTYPE_EXE_WRITE;
1109 op_cmpl.p_cmpl = NULL;
1110
1111 bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
1112 }
1113 }
1114 }
1115 /*******************************************************************************
1116 **
1117 ** Function bta_gattc_confirm
1118 **
1119 ** Description send handle value confirmation
1120 **
1121 ** Returns None.
1122 **
1123 *******************************************************************************/
bta_gattc_confirm(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1124 void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1125 {
1126 UINT16 handle;
1127 tBT_UUID null_uuid = {0};
1128
1129 if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
1130 &p_data->api_confirm.srvc_id,
1131 &p_data->api_confirm.char_id,
1132 null_uuid)) == 0)
1133 {
1134 APPL_TRACE_ERROR0("Can not map service/char ID into valid handle");
1135 }
1136 else
1137 {
1138 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
1139 != GATT_SUCCESS)
1140 {
1141 APPL_TRACE_ERROR1("bta_gattc_confirm to handle [0x%04x] failed", handle);
1142 }
1143 }
1144 }
1145 /*******************************************************************************
1146 **
1147 ** Function bta_gattc_read_cmpl
1148 **
1149 ** Description read complete
1150 **
1151 ** Returns None.
1152 **
1153 *******************************************************************************/
bta_gattc_read_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1154 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1155 {
1156 UINT8 event;
1157 tBTA_GATTC cb_data;
1158 tBTA_GATT_READ_VAL read_value;
1159
1160 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1161 memset(&read_value, 0, sizeof(tBTA_GATT_READ_VAL));
1162
1163 cb_data.read.status = p_data->status;
1164
1165 if (p_data->p_cmpl != NULL && p_data->status == BTA_GATT_OK)
1166 {
1167 if (bta_gattc_handle2id(p_clcb->p_srcb,
1168 p_data->p_cmpl->att_value.handle,
1169 &cb_data.read.srvc_id,
1170 &cb_data.read.char_id,
1171 &cb_data.read.descr_type) == FALSE)
1172 {
1173 cb_data.read.status = BTA_GATT_INTERNAL_ERROR;
1174 APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", p_data->p_cmpl->att_value.handle);
1175 }
1176 else
1177 {
1178 cb_data.read.status = bta_gattc_pack_read_cb_data(p_clcb->p_srcb,
1179 cb_data.read.descr_type,
1180 &p_data->p_cmpl->att_value,
1181 &read_value);
1182 cb_data.read.p_value = &read_value;
1183 }
1184 }
1185 else
1186 {
1187 cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id;
1188 cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id;
1189 cb_data.read.descr_type = p_clcb->p_q_cmd->api_read.descr_type;
1190 }
1191
1192 event = (p_clcb->p_q_cmd->api_read.descr_type.len == 0) ? BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
1193 cb_data.read.conn_id = p_clcb->bta_conn_id;
1194
1195 utl_freebuf((void **)&p_clcb->p_q_cmd);
1196 /* read complete, callback */
1197 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1198
1199 }
1200 /*******************************************************************************
1201 **
1202 ** Function bta_gattc_write_cmpl
1203 **
1204 ** Description read complete
1205 **
1206 ** Returns None.
1207 **
1208 *******************************************************************************/
bta_gattc_write_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1209 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1210 {
1211 tBTA_GATTC cb_data = {0};
1212 UINT8 event;
1213
1214 cb_data.write.status = p_data->status;
1215
1216 if (p_data->p_cmpl != NULL)
1217 {
1218 bta_gattc_handle2id(p_clcb->p_srcb, p_data->p_cmpl->handle,
1219 &cb_data.write.srvc_id, &cb_data.write.char_id,
1220 &cb_data.write.descr_type);
1221 }
1222 else
1223 {
1224 cb_data.write.srvc_id = p_clcb->p_q_cmd->api_write.srvc_id;
1225 cb_data.write.char_id = p_clcb->p_q_cmd->api_write.char_id;
1226 cb_data.write.descr_type = p_clcb->p_q_cmd->api_write.descr_type;
1227 }
1228
1229 if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
1230 p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE)
1231
1232 event = BTA_GATTC_PREP_WRITE_EVT;
1233
1234 else if (p_clcb->p_q_cmd->api_write.descr_type.len == 0)
1235
1236 event = BTA_GATTC_WRITE_CHAR_EVT;
1237
1238 else
1239 event = BTA_GATTC_WRITE_DESCR_EVT;
1240
1241 utl_freebuf((void **)&p_clcb->p_q_cmd);
1242 cb_data.write.conn_id = p_clcb->bta_conn_id;
1243 /* write complete, callback */
1244 ( *p_clcb->p_rcb->p_cback)(event, (tBTA_GATTC *)&cb_data);
1245
1246 }
1247 /*******************************************************************************
1248 **
1249 ** Function bta_gattc_exec_cmpl
1250 **
1251 ** Description execute write complete
1252 **
1253 ** Returns None.
1254 **
1255 *******************************************************************************/
bta_gattc_exec_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1256 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
1257 {
1258 tBTA_GATTC cb_data;
1259
1260 utl_freebuf((void **)&p_clcb->p_q_cmd);
1261
1262 p_clcb->status = BTA_GATT_OK;
1263
1264 /* execute complete, callback */
1265 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1266 cb_data.exec_cmpl.status = p_data->status;
1267
1268 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1269
1270 }
1271 /*******************************************************************************
1272 **
1273 ** Function bta_gattc_op_cmpl
1274 **
1275 ** Description operation completed.
1276 **
1277 ** Returns None.
1278 **
1279 *******************************************************************************/
bta_gattc_op_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1280 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1281 {
1282 UINT8 op = (UINT8)p_data->op_cmpl.op_code;
1283 UINT8 mapped_op = 0;
1284
1285 APPL_TRACE_DEBUG1("bta_gattc_op_cmpl op = %d", op);
1286
1287 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION)
1288 {
1289 APPL_TRACE_ERROR0("unexpected operation, ignored");
1290 }
1291 else if (op >= GATTC_OPTYPE_READ)
1292 {
1293 if (p_clcb->p_q_cmd == NULL)
1294 {
1295 APPL_TRACE_ERROR0("No pending command");
1296 return;
1297 }
1298 if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ])
1299 {
1300 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;
1301 if ( mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0;
1302
1303 #if (BT_TRACE_VERBOSE == TRUE)
1304 APPL_TRACE_ERROR3("expect op:(%s :0x%04x), receive unexpected operation (%s).",
1305 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
1306 bta_gattc_op_code_name[op]);
1307 #else
1308 APPL_TRACE_ERROR3("expect op:(%u :0x%04x), receive unexpected operation (%u).",
1309 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
1310 #endif
1311 return;
1312 }
1313
1314 /* service handle change void the response, discard it */
1315 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
1316 {
1317 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1318 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1319 }
1320 else if (op == GATTC_OPTYPE_READ)
1321 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1322
1323 else if (op == GATTC_OPTYPE_WRITE)
1324 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1325
1326 else if (op == GATTC_OPTYPE_EXE_WRITE)
1327 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1328 /*
1329 else if (op == GATTC_OPTYPE_CONFIG) // API to be added
1330 {
1331 }
1332 */
1333 }
1334 }
1335 /*******************************************************************************
1336 **
1337 ** Function bta_gattc_op_cmpl
1338 **
1339 ** Description operation completed.
1340 **
1341 ** Returns None.
1342 **
1343 *******************************************************************************/
bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1344 void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1345 {
1346 /* receive op complete when discovery is started, ignore the response,
1347 and wait for discovery finish and resent */
1348 APPL_TRACE_DEBUG1("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
1349
1350 }
1351 /*******************************************************************************
1352 **
1353 ** Function bta_gattc_search
1354 **
1355 ** Description start a search in the local server cache
1356 **
1357 ** Returns None.
1358 **
1359 *******************************************************************************/
bta_gattc_search(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1360 void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1361 {
1362 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1363 tBTA_GATTC cb_data;
1364 APPL_TRACE_DEBUG1("bta_gattc_search conn_id=%d",p_clcb->bta_conn_id);
1365 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache)
1366 {
1367 status = BTA_GATT_OK;
1368 /* search the local cache of a server device */
1369 bta_gattc_search_service(p_clcb, p_data->api_search.srvc_uuid);
1370 }
1371 cb_data.search_cmpl.status = status;
1372 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1373
1374 /* end of search or no server cache available */
1375 ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1376 }
1377 /*******************************************************************************
1378 **
1379 ** Function bta_gattc_q_cmd
1380 **
1381 ** Description enqueue a command into control block, usually because discovery
1382 ** operation is busy.
1383 **
1384 ** Returns None.
1385 **
1386 *******************************************************************************/
bta_gattc_q_cmd(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1387 void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1388 {
1389 bta_gattc_enqueue(p_clcb, p_data);
1390 }
1391 /*******************************************************************************
1392 **
1393 ** Function bta_gattc_cache_open
1394 **
1395 ** Description open a NV cache for loading
1396 **
1397 ** Returns void
1398 **
1399 *******************************************************************************/
bta_gattc_cache_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1400 void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1401 {
1402 bta_gattc_set_discover_st(p_clcb->p_srcb);
1403
1404 APPL_TRACE_DEBUG1("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id);
1405 bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT,
1406 p_clcb->bta_conn_id, FALSE);
1407 }
1408 /*******************************************************************************
1409 **
1410 ** Function bta_gattc_start_load
1411 **
1412 ** Description start cache loading by sending callout open cache
1413 **
1414 ** Returns None.
1415 **
1416 *******************************************************************************/
bta_gattc_ci_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1417 void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1418 {
1419 APPL_TRACE_DEBUG2("bta_gattc_ci_open conn_id=%d server state=%d" ,
1420 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
1421 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD)
1422 {
1423 if (p_data->ci_open.status == BTA_GATT_OK)
1424 {
1425 p_clcb->p_srcb->attr_index = 0;
1426 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
1427 BTA_GATTC_CI_CACHE_LOAD_EVT,
1428 p_clcb->p_srcb->attr_index,
1429 p_clcb->bta_conn_id);
1430 }
1431 else
1432 {
1433 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
1434 /* cache open failure, start discovery */
1435 bta_gattc_start_discover(p_clcb, NULL);
1436 }
1437 }
1438 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_SAVE)
1439 {
1440 if (p_data->ci_open.status == BTA_GATT_OK)
1441 {
1442 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id))
1443 {
1444 p_data->ci_open.status = BTA_GATT_ERROR;
1445 }
1446 }
1447 if (p_data->ci_open.status != BTA_GATT_OK)
1448 {
1449 p_clcb->p_srcb->attr_index = 0;
1450 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, p_clcb->bta_conn_id);
1451 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
1452
1453 }
1454 }
1455 }
1456 /*******************************************************************************
1457 **
1458 ** Function bta_gattc_ci_load
1459 **
1460 ** Description cache loading received.
1461 **
1462 ** Returns None.
1463 **
1464 *******************************************************************************/
bta_gattc_ci_load(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1465 void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1466 {
1467
1468 APPL_TRACE_DEBUG2("bta_gattc_ci_load conn_id=%d load status=%d" ,
1469 p_clcb->bta_conn_id, p_data->ci_load.status );
1470 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1471
1472 if ((p_data->ci_load.status == BTA_GATT_OK ||
1473 p_data->ci_load.status == BTA_GATT_MORE) &&
1474 p_data->ci_load.num_attr > 0)
1475 {
1476 bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
1477
1478 if (p_data->ci_load.status == BTA_GATT_OK)
1479 {
1480 p_clcb->p_srcb->attr_index = 0;
1481 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
1482
1483 }
1484 else /* load more */
1485 {
1486 p_clcb->p_srcb->attr_index += p_data->ci_load.num_attr;
1487
1488 bta_gattc_co_cache_load(p_clcb->p_srcb->server_bda,
1489 BTA_GATTC_CI_CACHE_LOAD_EVT,
1490 p_clcb->p_srcb->attr_index,
1491 p_clcb->bta_conn_id);
1492 }
1493 }
1494 else
1495 {
1496 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
1497 p_clcb->p_srcb->attr_index = 0;
1498 /* cache open failure, start discovery */
1499 bta_gattc_start_discover(p_clcb, NULL);
1500 }
1501 }
1502 /*******************************************************************************
1503 **
1504 ** Function bta_gattc_ci_load
1505 **
1506 ** Description cache loading received.
1507 **
1508 ** Returns None.
1509 **
1510 *******************************************************************************/
bta_gattc_ci_save(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1511 void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1512 {
1513 APPL_TRACE_DEBUG1("bta_gattc_ci_save conn_id=%d " ,
1514 p_clcb->bta_conn_id );
1515
1516 if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id))
1517 {
1518 p_clcb->p_srcb->attr_index = 0;
1519 bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
1520 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
1521 }
1522 }
1523 /*******************************************************************************
1524 **
1525 ** Function bta_gattc_fail
1526 **
1527 ** Description report API call failure back to apps
1528 **
1529 ** Returns None.
1530 **
1531 *******************************************************************************/
bta_gattc_fail(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1532 void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
1533 {
1534 if (p_clcb->status == BTA_GATT_OK)
1535 {
1536 APPL_TRACE_ERROR1("operation not supported at current state [%d]", p_clcb->state);
1537 }
1538 }
1539 /*******************************************************************************
1540 **
1541 ** Function bta_gattc_conn_cback
1542 ** bta_gattc_cmpl_cback
1543 **
1544 ** Description callback functions to GATT client stack.
1545 **
1546 ** Returns void
1547 **
1548 *******************************************************************************/
bta_gattc_conn_cback(tGATT_IF gattc_if,BD_ADDR bda,UINT16 conn_id,BOOLEAN connected,tGATT_DISCONN_REASON reason)1549 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
1550 BOOLEAN connected, tGATT_DISCONN_REASON reason)
1551 {
1552 BT_HDR *p_buf;
1553 tBTA_GATTC_CLCB *p_clcb = NULL;
1554 #if BLE_INCLUDED == TRUE
1555 UINT8 role ;
1556 #endif
1557 APPL_TRACE_DEBUG4("bta_gattc_conn_cback: cif = %d connected = %d conn_id = %d reaosn = 0x%04x",
1558 gattc_if, connected, conn_id, reason);
1559
1560 if (connected)
1561 {
1562 #if BLE_INCLUDED == TRUE
1563 role = L2CA_GetBleConnRole(bda);
1564
1565 if (role == HCI_ROLE_SLAVE)
1566 bta_gattc_conn_find_alloc(bda);
1567 #endif
1568
1569 /* outgoing connection : locate a logic channel */
1570 if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
1571 {
1572 #if BLE_INCLUDED == TRUE
1573 /* for a background connection or listening connection */
1574 if (/* L2CA_GetBleConnRole(bda)== HCI_ROLE_MASTER && */
1575 bta_gattc_check_bg_conn(gattc_if, bda, role))
1576 {
1577 /* allocate a new channel */
1578 p_clcb = bta_gattc_clcb_alloc(gattc_if, bda);
1579 }
1580 #endif
1581 }
1582 if (p_clcb != NULL)
1583 {
1584 p_clcb->bta_conn_id = conn_id;
1585
1586 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
1587 {
1588 p_buf->event = BTA_GATTC_INT_CONN_EVT;
1589 p_buf->layer_specific = conn_id;
1590
1591 bta_sys_sendmsg(p_buf);
1592 }
1593 }
1594 }
1595 else
1596 {
1597 #if BLE_INCLUDED == TRUE
1598 bta_gattc_conn_dealloc(bda);
1599 #endif
1600 /* connection attempt timeout, send connection callback event */
1601 if (reason == GATT_CONN_CANCEL )
1602 {
1603 p_clcb = bta_gattc_find_alloc_clcb(gattc_if, bda);
1604 p_clcb->bta_conn_id = conn_id;
1605 }
1606 if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL)
1607 {
1608 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
1609 {
1610 p_buf->event = BTA_GATTC_INT_DISCONN_EVT;
1611 p_buf->layer_specific = conn_id;
1612 p_clcb->reason = reason;
1613
1614 bta_sys_sendmsg(p_buf);
1615 }
1616 }
1617 else
1618 {
1619 APPL_TRACE_DEBUG1(" connection ID: [%d] not used by BTA", conn_id);
1620 }
1621 }
1622 }
1623 /*******************************************************************************
1624 **
1625 ** Function bta_gattc_process_api_refresh
1626 **
1627 ** Description process refresh API to delete cache and start a new discovery
1628 ** if currently connected.
1629 **
1630 ** Returns None.
1631 **
1632 *******************************************************************************/
bta_gattc_process_api_refresh(tBTA_GATTC_CB * p_cb,tBTA_GATTC_DATA * p_msg)1633 void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
1634 {
1635 tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1636 tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
1637 BOOLEAN found = FALSE;
1638 UINT8 i;
1639
1640 if (p_srvc_cb != NULL)
1641 {
1642 /* try to find a CLCB */
1643 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0)
1644 {
1645 for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++)
1646 {
1647 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb)
1648 {
1649 found = TRUE;
1650 break;
1651 }
1652 }
1653 if (found)
1654 {
1655 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1656 return;
1657 }
1658 }
1659 /* in all other cases, mark it and delete the cache */
1660 if (p_srvc_cb->p_srvc_cache != NULL)
1661 {
1662 while (p_srvc_cb->cache_buffer.p_first)
1663 GKI_freebuf (GKI_dequeue (&p_srvc_cb->cache_buffer));
1664
1665 p_srvc_cb->p_srvc_cache = NULL;
1666 }
1667 }
1668 /* used to reset cache in application */
1669 bta_gattc_co_cache_reset(p_msg->api_conn.remote_bda);
1670
1671 }
1672 /*******************************************************************************
1673 **
1674 ** Function bta_gattc_process_srvc_chg_ind
1675 **
1676 ** Description process service change indication.
1677 **
1678 ** Returns None.
1679 **
1680 *******************************************************************************/
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,UINT16 handle)1681 BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
1682 tBTA_GATTC_RCB *p_clrcb,
1683 tBTA_GATTC_SERV *p_srcb,
1684 tBTA_GATTC_CLCB *p_clcb,
1685 tBTA_GATTC_NOTIFY *p_notify,
1686 UINT16 handle)
1687 {
1688 tBT_UUID gattp_uuid, srvc_chg_uuid;
1689 BOOLEAN processed = FALSE;
1690 UINT8 i;
1691
1692 gattp_uuid.len = 2;
1693 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1694
1695 srvc_chg_uuid.len = 2;
1696 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1697
1698 if (bta_gattc_uuid_compare(p_notify->char_id.srvc_id.id.uuid, gattp_uuid, TRUE) &&
1699 bta_gattc_uuid_compare(p_notify->char_id.char_id.uuid, srvc_chg_uuid, TRUE))
1700 {
1701 processed = TRUE;
1702 /* mark service handle change pending */
1703 p_srcb->srvc_hdl_chg = TRUE;
1704 /* clear up all notification/indication registration */
1705 bta_gattc_clear_notif_registration(conn_id);
1706 /* service change indication all received, do discovery update */
1707 if ( ++ p_srcb->update_count == bta_gattc_num_reg_app())
1708 {
1709 /* not an opened connection; or connection busy */
1710 /* search for first available clcb and start discovery */
1711 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL))
1712 {
1713 for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++)
1714 {
1715 if (bta_gattc_cb.clcb[i].in_use &&
1716 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1717 bta_gattc_cb.clcb[i].p_q_cmd == NULL)
1718 {
1719 p_clcb = &bta_gattc_cb.clcb[i];
1720 break;
1721 }
1722 }
1723 }
1724 /* send confirmation here if this is an indication, it should always be */
1725 GATTC_SendHandleValueConfirm(conn_id, handle);
1726
1727 /* if connection available, refresh cache by doing discovery now */
1728 if (p_clcb != NULL)
1729 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1730 }
1731 /* notify applicationf or service change */
1732 if (p_clrcb->p_cback != NULL)
1733 {
1734 (* p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC *)p_srcb->server_bda);
1735 }
1736
1737 }
1738
1739 return processed;
1740
1741 }
1742 /*******************************************************************************
1743 **
1744 ** Function bta_gattc_proc_other_indication
1745 **
1746 ** Description process all non-service change indication/notification.
1747 **
1748 ** Returns None.
1749 **
1750 *******************************************************************************/
bta_gattc_proc_other_indication(tBTA_GATTC_CLCB * p_clcb,UINT8 op,tGATT_CL_COMPLETE * p_data,tBTA_GATTC_NOTIFY * p_notify)1751 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB *p_clcb, UINT8 op,
1752 tGATT_CL_COMPLETE *p_data,
1753 tBTA_GATTC_NOTIFY *p_notify)
1754 {
1755 APPL_TRACE_DEBUG2("bta_gattc_proc_other_indication check \
1756 p_data->att_value.handle=%d p_data->handle=%d",
1757 p_data->att_value.handle, p_data->handle);
1758 APPL_TRACE_DEBUG1("is_notify", p_notify->is_notify);
1759
1760 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
1761 p_notify->len = p_data->att_value.len;
1762 bdcpy(p_notify->bda, p_clcb->bda);
1763 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
1764 p_notify->conn_id = p_clcb->bta_conn_id;
1765
1766 if (p_clcb->p_rcb->p_cback)
1767 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC *)p_notify);
1768
1769 }
1770 /*******************************************************************************
1771 **
1772 ** Function bta_gattc_process_indicate
1773 **
1774 ** Description process indication/notification.
1775 **
1776 ** Returns None.
1777 **
1778 *******************************************************************************/
bta_gattc_process_indicate(UINT16 conn_id,tGATTC_OPTYPE op,tGATT_CL_COMPLETE * p_data)1779 void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data)
1780 {
1781 UINT16 handle = p_data->att_value.handle;
1782 tBTA_GATTC_CLCB *p_clcb ;
1783 tBTA_GATTC_RCB *p_clrcb = NULL;
1784 tBTA_GATTC_SERV *p_srcb = NULL;
1785 tBTA_GATTC_NOTIFY notify;
1786 BD_ADDR remote_bda;
1787 tBTA_GATTC_IF gatt_if;
1788
1789 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
1790 {
1791 APPL_TRACE_ERROR0("indication/notif for unknown app");
1792 return;
1793 }
1794
1795 if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL)
1796 {
1797 APPL_TRACE_ERROR0("indication/notif for unregistered app");
1798 return;
1799 }
1800
1801 if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL)
1802 {
1803 APPL_TRACE_ERROR0("indication/notif for unknown device, ignore");
1804 return;
1805 }
1806
1807 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1808
1809 if (bta_gattc_handle2id(p_srcb, handle,
1810 ¬ify.char_id.srvc_id,
1811 ¬ify.char_id.char_id,
1812 ¬ify.descr_type))
1813 {
1814 /* if non-service change indication/notification, forward to application */
1815 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, handle))
1816 {
1817 /* if app registered for the notification */
1818 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify))
1819 {
1820 /* connection not open yet */
1821 if (p_clcb == NULL)
1822 {
1823 if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda)) != NULL)
1824 {
1825 p_clcb->bta_conn_id = conn_id;
1826
1827 /* send connection event */
1828 bta_gattc_send_open_cback(p_clrcb,
1829 BTA_GATT_OK,
1830 remote_bda,
1831 conn_id);
1832 }
1833 else
1834 {
1835 APPL_TRACE_ERROR0("No resources");
1836 }
1837 }
1838
1839 if (p_clcb != NULL)
1840 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
1841 }
1842 /* no one intersted and need ack? */
1843 else if (op == GATTC_OPTYPE_INDICATION)
1844 {
1845 APPL_TRACE_DEBUG0("no one interested, ack now");
1846 GATTC_SendHandleValueConfirm(conn_id, handle);
1847 }
1848 }
1849 }
1850 else
1851 {
1852 APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", handle);
1853 }
1854 }
1855 /*******************************************************************************
1856 **
1857 ** Function bta_gattc_cmpl_cback
1858 **
1859 ** Description client operation complete callback register with BTE GATT.
1860 **
1861 ** Returns None.
1862 **
1863 *******************************************************************************/
bta_gattc_cmpl_cback(UINT16 conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)1864 static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
1865 tGATT_CL_COMPLETE *p_data)
1866 {
1867 tBTA_GATTC_CLCB *p_clcb ;
1868 tBTA_GATTC_OP_CMPL *p_buf;
1869 UINT16 len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
1870
1871 APPL_TRACE_DEBUG3("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
1872 conn_id, op, status);
1873
1874 /* notification and indication processed right away */
1875 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION)
1876 {
1877 bta_gattc_process_indicate(conn_id, op, p_data);
1878 return;
1879 }
1880 /* for all other operation, not expected if w/o connection */
1881 else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL)
1882 {
1883 APPL_TRACE_ERROR1("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
1884 return;
1885 }
1886
1887
1888 if ((p_buf = (tBTA_GATTC_OP_CMPL *) GKI_getbuf(len)) != NULL)
1889 {
1890 memset(p_buf, 0, len);
1891 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
1892 p_buf->hdr.layer_specific = conn_id;
1893 p_buf->status = status;
1894 p_buf->op_code = op;
1895
1896 if (p_data != NULL)
1897 {
1898 p_buf->p_cmpl = (tGATT_CL_COMPLETE *)(p_buf + 1);
1899 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
1900 }
1901
1902 bta_sys_sendmsg(p_buf);
1903 }
1904
1905 return;
1906 }
1907 #if BLE_INCLUDED == TRUE
1908 /*******************************************************************************
1909 **
1910 ** Function bta_gattc_init_clcb_conn
1911 **
1912 ** Description Initaite a BTA CLCB connection
1913 **
1914 ** Returns void
1915 **
1916 ********************************************************************************/
bta_gattc_init_clcb_conn(UINT8 cif,BD_ADDR remote_bda)1917 void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
1918 {
1919 tBTA_GATTC_CLCB *p_clcb = NULL;
1920 tBTA_GATTC_DATA gattc_data;
1921 UINT16 conn_id;
1922
1923 /* should always get the connection ID */
1924 if (GATT_GetConnIdIfConnected(cif, remote_bda,&conn_id) == FALSE)
1925 {
1926 APPL_TRACE_ERROR0("bta_gattc_init_clcb_conn ERROR: not a connected device");
1927 return;
1928 }
1929
1930 /* initaite a new connection here */
1931 if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda)) != NULL)
1932 {
1933 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
1934
1935 gattc_data.api_conn.client_if = cif;
1936 memcpy(gattc_data.api_conn.remote_bda, remote_bda, BD_ADDR_LEN);
1937 gattc_data.api_conn.is_direct = TRUE;
1938
1939 bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_OPEN_EVT, &gattc_data);
1940 }
1941 else
1942 {
1943 APPL_TRACE_ERROR0("No resources");
1944 }
1945 }
1946
1947 #endif /* #if BLE_INCLUDED == TRUE */
1948 #endif /* BTA_GATT_INCLUDED */
1949