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