• 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 Server action functions for the state
22  *  machine.
23  *
24  ******************************************************************************/
25 
26 
27 #include "bt_target.h"
28 
29 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
30 
31 #include "utl.h"
32 #include "gki.h"
33 #include "bta_sys.h"
34 #include "bta_gatts_int.h"
35 #include "bta_gatts_co.h"
36 #include "btm_ble_api.h"
37 #include <string.h>
38 
39 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
40 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
41                                                 tGATTS_SRV_CHG_RSP *p_rsp);
42 
43 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
44                                       BOOLEAN connected, tGATT_DISCONN_REASON reason,
45                                       tGATT_TRANSPORT transport);
46 static void bta_gatts_send_request_cback (UINT16 conn_id,
47                                           UINT32 trans_id,
48                                           tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
49 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
50 
51 static tGATT_CBACK bta_gatts_cback =
52 {
53     bta_gatts_conn_cback,
54     NULL,
55     NULL,
56     NULL,
57     bta_gatts_send_request_cback,
58     NULL,
59     bta_gatts_cong_cback
60 };
61 
62 tGATT_APPL_INFO bta_gatts_nv_cback =
63 {
64     bta_gatts_nv_save_cback,
65     bta_gatts_nv_srv_chg_cback
66 };
67 
68 /*******************************************************************************
69 **
70 ** Function         bta_gatts_nv_save_cback
71 **
72 ** Description      NV save callback function.
73 **
74 ** Parameter        is_add: true is to add a handle range; otherwise is to delete.
75 ** Returns          none.
76 **
77 *******************************************************************************/
bta_gatts_nv_save_cback(BOOLEAN is_add,tGATTS_HNDL_RANGE * p_hndl_range)78 static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range)
79 {
80     bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range);
81 }
82 
83 
84 /*******************************************************************************
85 **
86 ** Function         bta_gatts_nv_srv_chg_cback
87 **
88 ** Description      NV save callback function.
89 **
90 ** Parameter        is_add: true is to add a handle range; otherwise is to delete.
91 ** Returns          none.
92 **
93 *******************************************************************************/
bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,tGATTS_SRV_CHG_REQ * p_req,tGATTS_SRV_CHG_RSP * p_rsp)94 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
95                                               tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
96 {
97     return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
98                                 (tBTA_GATTS_SRV_CHG_REQ *) p_req,
99                                 (tBTA_GATTS_SRV_CHG_RSP *) p_rsp);
100 }
101 
102 
103 /*******************************************************************************
104 **
105 ** Function         bta_gatts_enable
106 **
107 ** Description      enable BTA GATTS module.
108 **
109 ** Returns          none.
110 **
111 *******************************************************************************/
bta_gatts_enable(tBTA_GATTS_CB * p_cb)112 void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
113 {
114     UINT8 index=0;
115     tBTA_GATTS_HNDL_RANGE handle_range;
116     tBTA_GATT_STATUS    status = BTA_GATT_OK;
117 
118     if (p_cb->enabled)
119     {
120         APPL_TRACE_DEBUG("GATTS already enabled.");
121     }
122     else
123     {
124         memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
125 
126         p_cb->enabled = TRUE;
127 
128         while ( bta_gatts_co_load_handle_range(index, &handle_range))
129         {
130             GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
131             memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
132             index++;
133         }
134 
135         APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
136 
137         if (!GATTS_NVRegister(&bta_gatts_nv_cback))
138         {
139             APPL_TRACE_ERROR("BTA GATTS NV register failed.");
140             status = BTA_GATT_ERROR;
141         }
142     }
143 }
144 
145 /*******************************************************************************
146 **
147 ** Function         bta_gatts_api_disable
148 **
149 ** Description      disable BTA GATTS module.
150 **
151 ** Returns          none.
152 **
153 *******************************************************************************/
bta_gatts_api_disable(tBTA_GATTS_CB * p_cb)154 void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
155 {
156     UINT8 i;
157     tBTA_GATT_STATUS    status = BTA_GATT_OK;
158 
159     if (p_cb->enabled)
160     {
161         for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
162         {
163             if (p_cb->rcb[i].in_use)
164             {
165                 GATT_Deregister(p_cb->rcb[i].gatt_if);
166             }
167         }
168         memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
169     }
170     else
171     {
172         APPL_TRACE_ERROR("GATTS not enabled");
173     }
174 }
175 
176 /*******************************************************************************
177 **
178 ** Function         bta_gatts_register
179 **
180 ** Description      register an application.
181 **
182 ** Returns          none.
183 **
184 *******************************************************************************/
bta_gatts_register(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)185 void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
186 {
187     tBTA_GATTS_INT_START_IF  *p_buf;
188     tBTA_GATTS               cb_data;
189     tBTA_GATT_STATUS         status = BTA_GATT_OK;
190     UINT8                    i, first_unuse = 0xff;
191 
192     if (p_cb->enabled == FALSE)
193     {
194         bta_gatts_enable(p_cb);
195     }
196 
197     for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
198     {
199         if (p_cb->rcb[i].in_use)
200         {
201             if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid))
202             {
203                 APPL_TRACE_ERROR("application already registered.");
204                 status = BTA_GATT_DUP_REG;
205                 break;
206             }
207         }
208     }
209 
210     if (status == BTA_GATT_OK)
211     {
212         for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
213         {
214             if (first_unuse == 0xff && !p_cb->rcb[i].in_use)
215             {
216                 first_unuse = i;
217                 break;
218             }
219         }
220 
221         cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
222 // btla-specific ++
223         memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
224 // btla-specific --
225         if (first_unuse != 0xff)
226         {
227             APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse);
228 
229             p_cb->rcb[first_unuse].in_use = TRUE;
230             p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
231             memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
232             cb_data.reg_oper.server_if      =
233             p_cb->rcb[first_unuse].gatt_if  =
234             GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
235             if ( !p_cb->rcb[first_unuse].gatt_if)
236             {
237                 status = BTA_GATT_NO_RESOURCES;
238             }
239             else
240             {
241                 if ((p_buf =
242                   (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
243                 {
244                     p_buf->hdr.event    = BTA_GATTS_INT_START_IF_EVT;
245                     p_buf->server_if    = p_cb->rcb[first_unuse].gatt_if;
246 
247                     bta_sys_sendmsg(p_buf);
248                 }
249                 else
250                 {
251                     status = BTA_GATT_NO_RESOURCES;
252                     memset( &p_cb->rcb[first_unuse], 0 , sizeof(tBTA_GATTS_RCB));
253                 }
254             }
255         }
256         else
257         {
258             status = BTA_GATT_NO_RESOURCES;
259         }
260 
261     }
262     cb_data.reg_oper.status = status;
263     if (p_msg->api_reg.p_cback)
264         (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
265 }
266 
267 
268 /*******************************************************************************
269 **
270 ** Function         bta_gatts_start_if
271 **
272 ** Description      start an application interface.
273 **
274 ** Returns          none.
275 **
276 *******************************************************************************/
bta_gatts_start_if(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)277 void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
278 {
279     UNUSED(p_cb);
280 
281     if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if))
282     {
283         GATT_StartIf(p_msg->int_start_if.server_if);
284     }
285     else
286     {
287         APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
288             p_msg->int_start_if.server_if );
289     }
290 }
291 /*******************************************************************************
292 **
293 ** Function         bta_gatts_deregister
294 **
295 ** Description      deregister an application.
296 **
297 ** Returns          none.
298 **
299 *******************************************************************************/
bta_gatts_deregister(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)300 void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
301 {
302     tBTA_GATT_STATUS    status = BTA_GATT_ERROR;
303     tBTA_GATTS_CBACK    *p_cback = NULL;
304     UINT8               i;
305     tBTA_GATTS          cb_data;
306 
307     cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
308     cb_data.reg_oper.status = status;
309 
310     for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
311     {
312         if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if)
313         {
314             p_cback = p_cb->rcb[i].p_cback;
315             status = BTA_GATT_OK;
316 
317             /* deregister the app */
318             GATT_Deregister(p_cb->rcb[i].gatt_if);
319 
320             /* reset cb */
321             memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
322             cb_data.reg_oper.status = status;
323             break;
324         }
325     }
326 
327     if (p_cback)
328     {
329         (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
330     }
331     else
332     {
333         APPL_TRACE_ERROR("application not registered.");
334     }
335 }
336 /*******************************************************************************
337 **
338 ** Function         bta_gatts_create_srvc
339 **
340 ** Description      action function to create a service.
341 **
342 ** Returns          none.
343 **
344 *******************************************************************************/
bta_gatts_create_srvc(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)345 void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
346 {
347     UINT8               rcb_idx;
348     tBTA_GATTS          cb_data;
349     UINT8               srvc_idx;
350     UINT16              service_id = 0;
351 
352     cb_data.create.status = BTA_GATT_ERROR;
353 
354     rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
355 
356     APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx);
357 
358     if (rcb_idx != BTA_GATTS_INVALID_APP)
359     {
360         if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP)
361         {
362             /* create the service now */
363             service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
364                                               &p_msg->api_create_svc.service_uuid,
365                                               p_msg->api_create_svc.inst,
366                                               p_msg->api_create_svc.num_handle,
367                                               p_msg->api_create_svc.is_pri);
368 
369             if (service_id != 0)
370             {
371                 memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
372                     &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
373                 p_cb->srvc_cb[srvc_idx].service_id   = service_id;
374                 p_cb->srvc_cb[srvc_idx].inst_num     = p_msg->api_create_svc.inst;
375                 p_cb->srvc_cb[srvc_idx].idx          = srvc_idx;
376 
377                 cb_data.create.status      = BTA_GATT_OK;
378                 cb_data.create.service_id  = service_id;
379 // btla-specific ++
380                 cb_data.create.is_primary  = p_msg->api_create_svc.is_pri;
381 // btla-specific --
382                 cb_data.create.server_if   = p_cb->rcb[rcb_idx].gatt_if;
383             }
384             else
385             {
386                 cb_data.status  = BTA_GATT_ERROR;
387                 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
388                 APPL_TRACE_ERROR("service creation failed.");
389             }
390 // btla-specific ++
391             memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
392             cb_data.create.svc_instance= p_msg->api_create_svc.inst;
393 // btla-specific --
394         }
395         if (p_cb->rcb[rcb_idx].p_cback)
396             (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
397     }
398     else /* application not registered */
399     {
400         APPL_TRACE_ERROR("Application not registered");
401     }
402 }
403 /*******************************************************************************
404 **
405 ** Function         bta_gatts_add_include_srvc
406 **
407 ** Description      action function to add an included service.
408 **
409 ** Returns          none.
410 **
411 *******************************************************************************/
bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)412 void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg)
413 {
414     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
415     UINT16          attr_id = 0;
416     tBTA_GATTS      cb_data;
417 
418     attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
419                                       p_msg->api_add_incl_srvc.included_service_id);
420 
421     cb_data.add_result.server_if = p_rcb->gatt_if;
422     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
423     cb_data.add_result.attr_id = attr_id;
424 
425     if (attr_id)
426     {
427         cb_data.add_result.status = BTA_GATT_OK;
428     }
429     else
430     {
431         cb_data.add_result.status = BTA_GATT_ERROR;
432     }
433 
434     if (p_rcb->p_cback)
435         (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
436 }
437 /*******************************************************************************
438 **
439 ** Function         bta_gatts_add_char
440 **
441 ** Description      action function to add characteristic.
442 **
443 ** Returns          none.
444 **
445 *******************************************************************************/
bta_gatts_add_char(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)446 void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
447 {
448     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
449     UINT16          attr_id = 0;
450     tBTA_GATTS      cb_data;
451 
452     attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
453                                       &p_msg->api_add_char.char_uuid,
454                                       p_msg->api_add_char.perm,
455                                       p_msg->api_add_char.property);
456     cb_data.add_result.server_if = p_rcb->gatt_if;
457     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
458     cb_data.add_result.attr_id = attr_id;
459 // btla-specific ++
460     memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));
461 // btla-specific --
462 
463     if (attr_id)
464     {
465         cb_data.add_result.status = BTA_GATT_OK;
466     }
467     else
468     {
469         cb_data.add_result.status = BTA_GATT_ERROR;
470     }
471 
472     if (p_rcb->p_cback)
473         (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
474 }
475 /*******************************************************************************
476 **
477 ** Function         bta_gatts_add_char_descr
478 **
479 ** Description      action function to add characteristic descriptor.
480 **
481 ** Returns          none.
482 **
483 *******************************************************************************/
bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)484 void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
485 {
486     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
487     UINT16          attr_id = 0;
488     tBTA_GATTS      cb_data;
489 
490     attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
491                                        p_msg->api_add_char_descr.perm,
492                                        &p_msg->api_add_char_descr.descr_uuid);
493 
494     cb_data.add_result.server_if = p_rcb->gatt_if;
495     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
496     cb_data.add_result.attr_id = attr_id;
497 // btla-specific ++
498     memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));
499 // btla-specific --
500 
501     if (attr_id)
502     {
503         cb_data.add_result.status = BTA_GATT_OK;
504     }
505     else
506     {
507         cb_data.add_result.status = BTA_GATT_ERROR;
508     }
509 
510     if (p_rcb->p_cback)
511         (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
512 
513 }
514 /*******************************************************************************
515 **
516 ** Function         bta_gatts_delete_service
517 **
518 ** Description      action function to delete a service.
519 **
520 ** Returns          none.
521 **
522 *******************************************************************************/
bta_gatts_delete_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)523 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
524 {
525     tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
526     tBTA_GATTS      cb_data;
527 
528     cb_data.srvc_oper.server_if = p_rcb->gatt_if;
529     cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
530 
531     if (GATTS_DeleteService(p_rcb->gatt_if,
532                             &p_srvc_cb->service_uuid,
533                             p_srvc_cb->inst_num))
534     {
535         cb_data.srvc_oper.status = BTA_GATT_OK;
536         memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
537     }
538     else
539     {
540         cb_data.srvc_oper.status = BTA_GATT_ERROR;
541     }
542 
543     if (p_rcb->p_cback)
544         (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
545 
546 }
547 /*******************************************************************************
548 **
549 ** Function         bta_gatts_start_service
550 **
551 ** Description      action function to start a service.
552 **
553 ** Returns          none.
554 **
555 *******************************************************************************/
bta_gatts_start_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)556 void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
557 {
558     tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
559     tBTA_GATTS      cb_data;
560 
561     cb_data.srvc_oper.server_if = p_rcb->gatt_if;
562     cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
563 
564     if (GATTS_StartService(p_rcb->gatt_if,
565                            p_srvc_cb->service_id,
566                            p_msg->api_start.transport) ==  GATT_SUCCESS)
567     {
568         APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
569         cb_data.srvc_oper.status = BTA_GATT_OK;
570     }
571     else
572     {
573         cb_data.srvc_oper.status = BTA_GATT_ERROR;
574     }
575 
576     if (p_rcb->p_cback)
577         (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);
578 
579 }
580 /*******************************************************************************
581 **
582 ** Function         bta_gatts_stop_service
583 **
584 ** Description      action function to stop a service.
585 **
586 ** Returns          none.
587 **
588 *******************************************************************************/
bta_gatts_stop_service(tBTA_GATTS_SRVC_CB * p_srvc_cb,tBTA_GATTS_DATA * p_msg)589 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
590 {
591     tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
592     tBTA_GATTS      cb_data;
593     UNUSED(p_msg);
594 
595     GATTS_StopService(p_srvc_cb->service_id);
596     cb_data.srvc_oper.server_if = p_rcb->gatt_if;
597     cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
598     cb_data.srvc_oper.status = BTA_GATT_OK;
599     APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
600 
601     if (p_rcb->p_cback)
602         (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
603 
604 }
605 /*******************************************************************************
606 **
607 ** Function         bta_gatts_send_rsp
608 **
609 ** Description      GATTS send response.
610 **
611 ** Returns          none.
612 **
613 *******************************************************************************/
bta_gatts_send_rsp(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)614 void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
615 {
616     UNUSED(p_cb);
617 
618     if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
619                         p_msg->api_rsp.trans_id,
620                         p_msg->api_rsp.status,
621                         (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
622     {
623         APPL_TRACE_ERROR("Sending response failed");
624     }
625 
626 }
627 /*******************************************************************************
628 **
629 ** Function         bta_gatts_indicate_handle
630 **
631 ** Description      GATTS send handle value indication or notification.
632 **
633 ** Returns          none.
634 **
635 *******************************************************************************/
bta_gatts_indicate_handle(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)636 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
637 {
638     tBTA_GATTS_SRVC_CB  *p_srvc_cb;
639     tBTA_GATTS_RCB      *p_rcb = NULL;
640     tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
641     tGATT_IF            gatt_if;
642     BD_ADDR             remote_bda;
643     tBTA_TRANSPORT transport;
644     tBTA_GATTS          cb_data;
645 
646     p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
647 
648     if (p_srvc_cb )
649     {
650         if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
651             &gatt_if, remote_bda, &transport))
652         {
653             p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
654 
655             if (p_msg->api_indicate.need_confirm)
656 
657                 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
658                                                       p_msg->api_indicate.attr_id,
659                                                       p_msg->api_indicate.len,
660                                                       p_msg->api_indicate.value);
661             else
662                 status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
663                                                         p_msg->api_indicate.attr_id,
664                                                         p_msg->api_indicate.len,
665                                                         p_msg->api_indicate.value);
666 
667             /* if over BR_EDR, inform PM for mode change */
668             if (transport == BTA_TRANSPORT_BR_EDR)
669             {
670                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
671                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
672             }
673         }
674         else
675         {
676             APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
677                               p_msg->api_indicate.hdr.layer_specific);
678         }
679 
680         if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
681             p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
682         {
683             cb_data.req_data.status = status;
684             cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
685 
686             (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
687         }
688     }
689     else
690     {
691         APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
692                           p_msg->api_indicate.attr_id);
693     }
694 }
695 
696 
697 /*******************************************************************************
698 **
699 ** Function         bta_gatts_open
700 **
701 ** Description
702 **
703 ** Returns          none.
704 **
705 *******************************************************************************/
bta_gatts_open(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)706 void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
707 {
708     tBTA_GATTS_RCB      *p_rcb=NULL;
709     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
710     UINT16              conn_id;
711     UNUSED(p_cb);
712 
713     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
714     {
715         /* should always get the connection ID */
716         if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
717                         p_msg->api_open.is_direct, p_msg->api_open.transport))
718         {
719             status = BTA_GATT_OK;
720 
721             if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
722                                             &conn_id, p_msg->api_open.transport))
723             {
724                 status = BTA_GATT_ALREADY_OPEN;
725             }
726         }
727     }
728     else
729     {
730         APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
731     }
732 
733     if (p_rcb && p_rcb->p_cback)
734         (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT,  (tBTA_GATTS *)&status);
735 
736 }
737 /*******************************************************************************
738 **
739 ** Function         bta_gatts_cancel_open
740 **
741 ** Description
742 **
743 ** Returns          none.
744 **
745 *******************************************************************************/
bta_gatts_cancel_open(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)746 void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
747 {
748     tBTA_GATTS_RCB      *p_rcb;
749     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
750     UNUSED(p_cb);
751 
752     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
753     {
754         if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
755                                 p_msg->api_cancel_open.is_direct))
756         {
757             APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
758         }
759         else
760         {
761             status= BTA_GATT_OK;
762         }
763     }
764     else
765     {
766         APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
767     }
768 
769     if (p_rcb && p_rcb->p_cback)
770         (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT,  (tBTA_GATTS *)&status);
771 }
772 /*******************************************************************************
773 **
774 ** Function         bta_gatts_close
775 **
776 ** Description
777 **
778 ** Returns          none.
779 **
780 *******************************************************************************/
bta_gatts_close(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)781 void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
782 {
783     tBTA_GATTS_RCB     *p_rcb;
784     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
785     tGATT_IF            gatt_if;
786     BD_ADDR             remote_bda;
787     tBTA_GATT_TRANSPORT transport;
788 
789     UNUSED(p_cb);
790 
791     if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
792     {
793         if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
794         {
795             APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
796         }
797         else
798         {
799             status= BTA_GATT_OK;
800         }
801 
802         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
803 
804         if (p_rcb && p_rcb->p_cback)
805         {
806             if (transport == BTA_TRANSPORT_BR_EDR)
807                 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
808 
809             (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT,  (tBTA_GATTS *)&status);
810         }
811     }
812     else
813     {
814         APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
815     }
816 
817 }
818 /*******************************************************************************
819 **
820 ** Function         bta_gatts_listen
821 **
822 ** Description      Start or stop listening for LE connection on a GATT server
823 **
824 ** Returns          none.
825 **
826 *******************************************************************************/
bta_gatts_listen(tBTA_GATTS_CB * p_cb,tBTA_GATTS_DATA * p_msg)827 void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
828 {
829     tBTA_GATTS_RCB     *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
830     tBTA_GATTS          cb_data;
831     UNUSED(p_cb);
832 
833     cb_data.reg_oper.status = BTA_GATT_OK;
834     cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
835 
836     if (p_rcb == NULL)
837     {
838         APPL_TRACE_ERROR("Unknown GATTS application");
839         return;
840     }
841 
842     if (!GATT_Listen(p_msg->api_listen.server_if,
843                      p_msg->api_listen.start,
844                      p_msg->api_listen.remote_bda))
845     {
846         cb_data.status = BTA_GATT_ERROR;
847         APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
848     }
849 
850     if (p_rcb->p_cback)
851         (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
852 }
853 
854 /*******************************************************************************
855 **
856 ** Function         bta_gatts_request_cback
857 **
858 ** Description      GATTS attribute request callback.
859 **
860 ** Returns          none.
861 **
862 *******************************************************************************/
bta_gatts_send_request_cback(UINT16 conn_id,UINT32 trans_id,tGATTS_REQ_TYPE req_type,tGATTS_DATA * p_data)863 static void bta_gatts_send_request_cback (UINT16 conn_id,
864                                           UINT32 trans_id,
865                                           tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
866 {
867     tBTA_GATTS          cb_data;
868     tBTA_GATTS_RCB     *p_rcb;
869     tGATT_IF            gatt_if;
870     tBTA_GATT_TRANSPORT transport;
871 
872     memset(&cb_data, 0 , sizeof(tBTA_GATTS));
873 
874     if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
875     {
876         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
877 
878         APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
879                             conn_id, trans_id, req_type);
880 
881         if (p_rcb && p_rcb->p_cback)
882         {
883             /* if over BR_EDR, inform PM for mode change */
884             if (transport == BTA_TRANSPORT_BR_EDR)
885             {
886                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
887                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
888             }
889 
890             cb_data.req_data.conn_id    = conn_id;
891             cb_data.req_data.trans_id   = trans_id;
892             cb_data.req_data.p_data     = (tBTA_GATTS_REQ_DATA *)p_data;
893 
894             (*p_rcb->p_cback)(req_type,  &cb_data);
895         }
896         else
897         {
898             APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
899         }
900     }
901     else
902     {
903         APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
904     }
905 }
906 
907 /*******************************************************************************
908 **
909 ** Function         bta_gatts_conn_cback
910 **
911 ** Description      connection callback.
912 **
913 ** Returns          none.
914 **
915 *******************************************************************************/
bta_gatts_conn_cback(tGATT_IF gatt_if,BD_ADDR bda,UINT16 conn_id,BOOLEAN connected,tGATT_DISCONN_REASON reason,tGATT_TRANSPORT transport)916 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
917                                   BOOLEAN connected, tGATT_DISCONN_REASON reason,
918                                   tGATT_TRANSPORT transport)
919 {
920     tBTA_GATTS      cb_data;
921     UINT8           evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
922     tBTA_GATTS_RCB  *p_reg;
923 
924     APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
925                         gatt_if, conn_id, connected, reason);
926     APPL_TRACE_DEBUG("bta_gatts_conn_cback  bda :%02x-%02x-%02x-%02x-%02x-%02x ",
927                       bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
928 
929     p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
930 
931     if (p_reg && p_reg->p_cback)
932     {
933         /* there is no RM for GATT */
934         if (transport == BTA_TRANSPORT_BR_EDR)
935         {
936             if (connected)
937                 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
938             else
939                 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda);
940         }
941 
942         cb_data.conn.conn_id = conn_id;
943         cb_data.conn.server_if = gatt_if;
944         cb_data.conn.reason = reason;
945         cb_data.conn.transport = transport;
946         memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
947         (*p_reg->p_cback)(evt, &cb_data);
948     }
949     else
950     {
951         APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if);
952     }
953 }
954 
955 /*******************************************************************************
956 **
957 ** Function         bta_gatts_cong_cback
958 **
959 ** Description      congestion callback.
960 **
961 ** Returns          none.
962 **
963 *******************************************************************************/
bta_gatts_cong_cback(UINT16 conn_id,BOOLEAN congested)964 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
965 {
966     tBTA_GATTS_RCB *p_rcb;
967     tGATT_IF gatt_if;
968     tBTA_GATT_TRANSPORT transport;
969     tBTA_GATTS cb_data;
970 
971     if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
972     {
973         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
974 
975         if (p_rcb && p_rcb->p_cback)
976         {
977             cb_data.congest.conn_id = conn_id;
978             cb_data.congest.congested = congested;
979 
980             (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
981         }
982     }
983 }
984 #endif /* BTA_GATT_INCLUDED */
985