• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                             &notify.char_id.srvc_id,
1811                             &notify.char_id.char_id,
1812                             &notify.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, &notify, handle))
1816         {
1817             /* if app registered for the notification */
1818             if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, &notify))
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, &notify);
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