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
39static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
40static 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
43static 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);
46static void bta_gatts_send_request_cback (UINT16 conn_id,
47                                          UINT32 trans_id,
48                                          tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
49static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
50
51static 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
62tGATT_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*******************************************************************************/
78static 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*******************************************************************************/
94static 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*******************************************************************************/
112void 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*******************************************************************************/
154void 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*******************************************************************************/
185void 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*******************************************************************************/
277void 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*******************************************************************************/
300void 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*******************************************************************************/
345void 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*******************************************************************************/
412void 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*******************************************************************************/
446void 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*******************************************************************************/
484void 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*******************************************************************************/
523void 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*******************************************************************************/
556void 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*******************************************************************************/
589void 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*******************************************************************************/
614void 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*******************************************************************************/
636void 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*******************************************************************************/
706void 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*******************************************************************************/
746void 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*******************************************************************************/
781void 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*******************************************************************************/
827void 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*******************************************************************************/
863static 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*******************************************************************************/
916static 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*******************************************************************************/
964static 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