1/******************************************************************************
2 *
3 *  Copyright (C) 2010-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 is the implementation of the API for GATT server of BTA.
22 *
23 ******************************************************************************/
24
25#include "bt_target.h"
26
27#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
28
29#include <string.h>
30#include "gki.h"
31#include "bta_sys.h"
32#include "bta_gatt_api.h"
33#include "bta_gatts_int.h"
34
35/*****************************************************************************
36**  Constants
37*****************************************************************************/
38
39static const tBTA_SYS_REG bta_gatts_reg =
40{
41    bta_gatts_hdl_event,
42    BTA_GATTS_Disable
43};
44
45/*******************************************************************************
46**
47** Function         BTA_GATTS_Disable
48**
49** Description      This function is called to disable GATTS module
50**
51** Parameters       None.
52**
53** Returns          None
54**
55*******************************************************************************/
56void BTA_GATTS_Disable(void)
57{
58    BT_HDR  *p_buf;
59
60    if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
61    {
62        APPL_TRACE_WARNING("GATTS Module not enabled/already disabled");
63        return;
64    }
65
66    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
67    {
68        p_buf->event = BTA_GATTS_API_DISABLE_EVT;
69        bta_sys_sendmsg(p_buf);
70    }
71    bta_sys_deregister(BTA_ID_GATTS);
72
73}
74
75/*******************************************************************************
76**
77** Function         BTA_GATTS_AppRegister
78**
79** Description      This function is called to register application callbacks
80**                    with BTA GATTS module.
81**
82** Parameters       p_app_uuid - applicaiton UUID
83**                  p_cback - pointer to the application callback function.
84**
85** Returns          None
86**
87*******************************************************************************/
88void BTA_GATTS_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTS_CBACK *p_cback)
89{
90    tBTA_GATTS_API_REG  *p_buf;
91
92    /* register with BTA system manager */
93    if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
94    {
95        bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
96    }
97
98    if ((p_buf = (tBTA_GATTS_API_REG *) GKI_getbuf(sizeof(tBTA_GATTS_API_REG))) != NULL)
99    {
100        p_buf->hdr.event    = BTA_GATTS_API_REG_EVT;
101
102        if (p_app_uuid != NULL)
103            memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID));
104        p_buf->p_cback      = p_cback;
105
106        bta_sys_sendmsg(p_buf);
107    }
108    return;
109}
110
111
112
113/*******************************************************************************
114**
115** Function         BTA_GATTS_AppDeregister
116**
117** Description      De-register with GATT Server.
118**
119** Parameters       app_id: applicatino ID.
120**
121** Returns          void
122**
123*******************************************************************************/
124void BTA_GATTS_AppDeregister(tBTA_GATTS_IF server_if)
125{
126    tBTA_GATTS_API_DEREG  *p_buf;
127
128    if ((p_buf = (tBTA_GATTS_API_DEREG *) GKI_getbuf(sizeof(tBTA_GATTS_API_DEREG))) != NULL)
129    {
130        p_buf->hdr.event    = BTA_GATTS_API_DEREG_EVT;
131        p_buf->server_if    = server_if;
132
133        bta_sys_sendmsg(p_buf);
134    }
135    return;
136}
137
138/*******************************************************************************
139**
140** Function         BTA_GATTS_CreateService
141**
142** Description      Create a service. When service creation is done, a callback
143**                  event BTA_GATTS_CREATE_SRVC_EVT is called to report status
144**                  and service ID to the profile. The service ID obtained in
145**                  the callback function needs to be used when adding included
146**                  service and characteristics/descriptors into the service.
147**
148** Parameters       app_id: Profile ID this service is belonged to.
149**                  p_service_uuid: service UUID.
150**                  inst: instance ID number of this service.
151**                  num_handle: numble of handle requessted for this service.
152**                  is_primary: is this service a primary one or not.
153**
154** Returns          void
155**
156*******************************************************************************/
157void BTA_GATTS_CreateService(tBTA_GATTS_IF server_if, tBT_UUID *p_service_uuid, UINT8 inst,
158                             UINT16 num_handle, BOOLEAN is_primary)
159{
160    tBTA_GATTS_API_CREATE_SRVC  *p_buf;
161
162    if ((p_buf = (tBTA_GATTS_API_CREATE_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_CREATE_SRVC))) != NULL)
163    {
164        p_buf->hdr.event = BTA_GATTS_API_CREATE_SRVC_EVT;
165
166        p_buf->server_if = server_if;
167        p_buf->inst = inst;
168        memcpy(&p_buf->service_uuid, p_service_uuid, sizeof(tBT_UUID));
169        p_buf->num_handle = num_handle;
170        p_buf->is_pri = is_primary;
171
172        bta_sys_sendmsg(p_buf);
173    }
174    return;
175}
176/*******************************************************************************
177**
178** Function         BTA_GATTS_AddIncludeService
179**
180** Description      This function is called to add an included service. After included
181**                  service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
182**                  is reported the included service ID.
183**
184** Parameters       service_id: service ID to which this included service is to
185**                              be added.
186**                  included_service_id: the service ID to be included.
187**
188** Returns          void
189**
190*******************************************************************************/
191void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_service_id)
192{
193    tBTA_GATTS_API_ADD_INCL_SRVC  *p_buf;
194
195    if ((p_buf =
196         (tBTA_GATTS_API_ADD_INCL_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_INCL_SRVC)))
197        != NULL)
198    {
199        p_buf->hdr.event = BTA_GATTS_API_ADD_INCL_SRVC_EVT;
200
201        p_buf->hdr.layer_specific = service_id;
202        p_buf->included_service_id = included_service_id;
203
204        bta_sys_sendmsg(p_buf);
205    }
206    return;
207
208}
209/*******************************************************************************
210**
211** Function         BTA_GATTS_AddCharacteristic
212**
213** Description      This function is called to add a characteristic into a service.
214**
215** Parameters       service_id: service ID to which this included service is to
216**                              be added.
217**                  p_char_uuid : Characteristic UUID.
218**                  perm      : Characteristic value declaration attribute permission.
219**                  property  : Characteristic Properties
220**
221** Returns          None
222**
223*******************************************************************************/
224void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID  *p_char_uuid,
225                                  tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property)
226{
227    tBTA_GATTS_API_ADD_CHAR  *p_buf;
228
229    if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL)
230    {
231        memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR));
232
233        p_buf->hdr.event = BTA_GATTS_API_ADD_CHAR_EVT;
234        p_buf->hdr.layer_specific = service_id;
235        p_buf->perm = perm;
236        p_buf->property = property;
237
238        if (p_char_uuid)
239        {
240            memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID));
241        }
242        bta_sys_sendmsg(p_buf);
243    }
244    return;
245}
246
247/*******************************************************************************
248**
249** Function         BTA_GATTS_AddCharDescriptor
250**
251** Description      This function is called to add characteristic descriptor. When
252**                  it's done, a callback event BTA_GATTS_ADD_DESCR_EVT is called
253**                  to report the status and an ID number for this descriptor.
254**
255** Parameters       service_id: service ID to which this charatceristic descriptor is to
256**                              be added.
257**                  perm: descriptor access permission.
258**                  p_descr_uuid: descriptor UUID.
259**
260** Returns          returns status.
261**
262*******************************************************************************/
263void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
264                                  tBTA_GATT_PERM perm,
265                                  tBT_UUID  * p_descr_uuid)
266{
267    tBTA_GATTS_API_ADD_DESCR  *p_buf;
268    UINT16  len = sizeof(tBTA_GATTS_API_ADD_DESCR);
269
270
271    if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(len)) != NULL)
272    {
273        memset(p_buf, 0, len);
274
275        p_buf->hdr.event = BTA_GATTS_API_ADD_DESCR_EVT;
276        p_buf->hdr.layer_specific = service_id;
277        p_buf->perm = perm;
278
279        if (p_descr_uuid)
280        {
281            memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
282        }
283        bta_sys_sendmsg(p_buf);
284    }
285    return;
286
287}
288
289/*******************************************************************************
290**
291** Function         BTA_GATTS_DeleteService
292**
293** Description      This function is called to delete a service. When this is done,
294**                  a callback event BTA_GATTS_DELETE_EVT is report with the status.
295**
296** Parameters       service_id: service_id to be deleted.
297**
298** Returns          returns none.
299**
300*******************************************************************************/
301void  BTA_GATTS_DeleteService(UINT16 service_id)
302{
303    BT_HDR  *p_buf;
304
305    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
306    {
307        p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT;
308
309        p_buf->layer_specific = service_id;
310
311        bta_sys_sendmsg(p_buf);
312    }
313    return;
314
315}
316
317/*******************************************************************************
318**
319** Function         BTA_GATTS_StartService
320**
321** Description      This function is called to start a service.
322**
323** Parameters       service_id: the service ID to be started.
324**                  sup_transport: supported trasnport.
325**
326** Returns          None.
327**
328*******************************************************************************/
329void  BTA_GATTS_StartService(UINT16 service_id, tBTA_GATT_TRANSPORT sup_transport)
330{
331    tBTA_GATTS_API_START  *p_buf;
332
333    if ((p_buf = (tBTA_GATTS_API_START *) GKI_getbuf(sizeof(tBTA_GATTS_API_START))) != NULL)
334    {
335        p_buf->hdr.event = BTA_GATTS_API_START_SRVC_EVT;
336
337        p_buf->hdr.layer_specific = service_id;
338        p_buf->transport = sup_transport;
339
340        bta_sys_sendmsg(p_buf);
341    }
342    return;
343}
344
345/*******************************************************************************
346**
347** Function         BTA_GATTS_StopService
348**
349** Description      This function is called to stop a service.
350**
351** Parameters       service_id - service to be topped.
352**
353** Returns          None
354**
355*******************************************************************************/
356void BTA_GATTS_StopService(UINT16 service_id)
357{
358    BT_HDR  *p_buf;
359
360    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
361    {
362        p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT;
363
364        p_buf->layer_specific = service_id;
365
366        bta_sys_sendmsg(p_buf);
367    }
368    return;
369}
370
371/*******************************************************************************
372**
373** Function         BTA_GATTS_HandleValueIndication
374**
375** Description      This function is called to read a characteristics descriptor.
376**
377** Parameters       bda - remote device bd address to indicate.
378**					attr_id - attribute ID to indicate.
379**                  data_len - indicate data length.
380**                  p_data: data to indicate.
381**                  need_confirm - if this indication expects a confirmation or not.
382**
383** Returns          None
384**
385*******************************************************************************/
386void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 data_len,
387                                      UINT8 *p_data, BOOLEAN need_confirm)
388{
389    tBTA_GATTS_API_INDICATION  *p_buf;
390    UINT16  len = sizeof(tBTA_GATTS_API_INDICATION);
391
392    if ((p_buf = (tBTA_GATTS_API_INDICATION *) GKI_getbuf(len)) != NULL)
393    {
394        memset(p_buf, 0, len);
395
396        p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT;
397        p_buf->hdr.layer_specific = conn_id;
398        p_buf->attr_id = attr_id;
399        p_buf->need_confirm = need_confirm;
400
401        if (data_len > 0 && p_data != NULL)
402        {
403            p_buf->len = data_len;
404            memcpy(p_buf->value, p_data, data_len);
405
406        }
407        bta_sys_sendmsg(p_buf);
408    }
409    return;
410
411}
412/*******************************************************************************
413**
414** Function         BTA_GATTS_SendRsp
415**
416** Description      This function is called to send a response to a request.
417**
418** Parameters       conn_id - connection identifier.
419**                  trans_id - transaction ID.
420**                  status - response status
421**                  p_msg - response data.
422**
423** Returns          None
424**
425*******************************************************************************/
426void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
427                        tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg)
428{
429    tBTA_GATTS_API_RSP  *p_buf;
430    UINT16  len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tBTA_GATTS_RSP);
431
432    if ((p_buf = (tBTA_GATTS_API_RSP *) GKI_getbuf(len)) != NULL)
433    {
434        memset(p_buf, 0, len);
435
436        p_buf->hdr.event    = BTA_GATTS_API_RSP_EVT;
437        p_buf->hdr.layer_specific = conn_id;
438        p_buf->trans_id = trans_id;
439        p_buf->status = status;
440
441        if (p_msg != NULL)
442        {
443            p_buf->p_rsp = (tBTA_GATTS_RSP *)(p_buf + 1);
444            memcpy(p_buf->p_rsp, p_msg, sizeof(tBTA_GATTS_RSP));
445        }
446
447        bta_sys_sendmsg(p_buf);
448    }
449    return;
450
451}
452
453
454
455/*******************************************************************************
456**
457** Function         BTA_GATTS_Open
458**
459** Description      Open a direct open connection or add a background auto connection
460**                  bd address
461**
462** Parameters       server_if: server interface.
463**                  remote_bda: remote device BD address.
464**                  is_direct: direct connection or background auto connection
465**                  transport : Transport on which GATT connection to be opened (BR/EDR or LE)
466**
467** Returns          void
468**
469*******************************************************************************/
470void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct,
471                    tBTA_GATT_TRANSPORT transport)
472{
473    tBTA_GATTS_API_OPEN  *p_buf;
474
475    if ((p_buf = (tBTA_GATTS_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_OPEN))) != NULL)
476    {
477        p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
478        p_buf->server_if = server_if;
479        p_buf->is_direct = is_direct;
480        p_buf->transport = transport;
481        memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
482
483        bta_sys_sendmsg(p_buf);
484    }
485    return;
486}
487
488
489/*******************************************************************************
490**
491** Function         BTA_GATTS_CancelOpen
492**
493** Description      Cancel a direct open connection or remove a background auto connection
494**                  bd address
495**
496** Parameters       server_if: server interface.
497**                  remote_bda: remote device BD address.
498**                  is_direct: direct connection or background auto connection
499**
500** Returns          void
501**
502*******************************************************************************/
503void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct)
504{
505    tBTA_GATTS_API_CANCEL_OPEN  *p_buf;
506
507    if ((p_buf = (tBTA_GATTS_API_CANCEL_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_CANCEL_OPEN))) != NULL)
508    {
509        p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT;
510        p_buf->server_if = server_if;
511        p_buf->is_direct = is_direct;
512        memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
513        bta_sys_sendmsg(p_buf);
514    }
515    return;
516}
517
518/*******************************************************************************
519**
520** Function         BTA_GATTS_Close
521**
522** Description      Close a connection  a remote device.
523**
524** Parameters       conn_id: connectino ID to be closed.
525**
526** Returns          void
527**
528*******************************************************************************/
529void BTA_GATTS_Close(UINT16 conn_id)
530{
531    BT_HDR  *p_buf;
532
533    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
534    {
535        p_buf->event = BTA_GATTS_API_CLOSE_EVT;
536        p_buf->layer_specific = conn_id;
537        bta_sys_sendmsg(p_buf);
538    }
539    return;
540
541}
542/*******************************************************************************
543**
544** Function         BTA_GATTS_Listen
545**
546** Description      Start advertisement to listen for connection request for a
547**                  GATT server
548**
549** Parameters       server_if: server interface.
550**                  start: to start or stop listening for connection
551**                  remote_bda: remote device BD address, if listen to all device
552**                              use NULL.
553**
554** Returns          void
555**
556*******************************************************************************/
557void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target_bda)
558{
559    tBTA_GATTS_API_LISTEN  *p_buf;
560
561    if ((p_buf = (tBTA_GATTS_API_LISTEN *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTS_API_LISTEN) + BD_ADDR_LEN))) != NULL)
562    {
563        p_buf->hdr.event = BTA_GATTS_API_LISTEN_EVT;
564
565        p_buf->server_if    = server_if;
566        p_buf->start        = start;
567
568        if (target_bda)
569        {
570            p_buf->remote_bda = (UINT8*)(p_buf + 1);
571            memcpy(p_buf->remote_bda, target_bda, BD_ADDR_LEN);
572        }
573        else
574            p_buf->remote_bda = NULL;
575
576        bta_sys_sendmsg(p_buf);
577    }
578    return;
579}
580
581#endif /* BTA_GATT_INCLUDED */
582