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