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 module 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_gattc_int.h"
34
35/*****************************************************************************
36**  Constants
37*****************************************************************************/
38
39static const tBTA_SYS_REG bta_gattc_reg =
40{
41    bta_gattc_hdl_event,
42    BTA_GATTC_Disable
43};
44
45
46/*******************************************************************************
47**
48** Function         BTA_GATTC_Disable
49**
50** Description      This function is called to disable GATTC module
51**
52** Parameters       None.
53**
54** Returns          None
55**
56*******************************************************************************/
57void BTA_GATTC_Disable(void)
58{
59    BT_HDR  *p_buf;
60
61    if (bta_sys_is_register(BTA_ID_GATTC) == FALSE)
62    {
63        APPL_TRACE_WARNING0("GATTC Module not enabled/already disabled");
64        return;
65    }
66    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
67    {
68        p_buf->event = BTA_GATTC_API_DISABLE_EVT;
69        bta_sys_sendmsg(p_buf);
70    }
71    bta_sys_deregister(BTA_ID_GATTC);
72
73}
74
75/*******************************************************************************
76**
77** Function         BTA_GATTC_AppRegister
78**
79** Description      This function is called to register application callbacks
80**                    with BTA GATTC module.
81**
82** Parameters       p_app_uuid - applicaiton UUID
83**                  p_client_cb - pointer to the application callback function.
84**
85** Returns          None
86**
87*******************************************************************************/
88void BTA_GATTC_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTC_CBACK *p_client_cb)
89{
90    tBTA_GATTC_API_REG  *p_buf;
91
92    if (bta_sys_is_register(BTA_ID_GATTC) == FALSE)
93    {
94        GKI_sched_lock();
95        bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
96        GKI_sched_unlock();
97    }
98
99    if ((p_buf = (tBTA_GATTC_API_REG *) GKI_getbuf(sizeof(tBTA_GATTC_API_REG))) != NULL)
100    {
101        p_buf->hdr.event    = BTA_GATTC_API_REG_EVT;
102        if (p_app_uuid != NULL)
103            memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID));
104        p_buf->p_cback      = p_client_cb;
105
106        bta_sys_sendmsg(p_buf);
107    }
108    return;
109}
110
111/*******************************************************************************
112**
113** Function         BTA_GATTC_AppDeregister
114**
115** Description      This function is called to deregister an application
116**                  from BTA GATTC module.
117**
118** Parameters       client_if - client interface identifier.
119**
120** Returns          None
121**
122*******************************************************************************/
123void BTA_GATTC_AppDeregister(tBTA_GATTC_IF client_if)
124{
125    tBTA_GATTC_API_DEREG  *p_buf;
126
127    if ((p_buf = (tBTA_GATTC_API_DEREG *) GKI_getbuf(sizeof(tBTA_GATTC_API_DEREG))) != NULL)
128    {
129        p_buf->hdr.event = BTA_GATTC_API_DEREG_EVT;
130        p_buf->client_if = client_if;
131        bta_sys_sendmsg(p_buf);
132    }
133    return;
134}
135
136/*******************************************************************************
137**
138** Function         BTA_GATTC_Open
139**
140** Description      Open a direct connection or add a background auto connection
141**                  bd address
142**
143** Parameters       client_if: server interface.
144**                  remote_bda: remote device BD address.
145**                  is_direct: direct connection or background auto connection
146**
147** Returns          void
148**
149*******************************************************************************/
150void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
151{
152    tBTA_GATTC_API_OPEN  *p_buf;
153
154    if ((p_buf = (tBTA_GATTC_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTC_API_OPEN))) != NULL)
155    {
156        p_buf->hdr.event = BTA_GATTC_API_OPEN_EVT;
157
158        p_buf->client_if = client_if;
159        p_buf->is_direct = is_direct;
160        memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
161
162
163        bta_sys_sendmsg(p_buf);
164    }
165    return;
166}
167
168/*******************************************************************************
169**
170** Function         BTA_GATTC_CancelOpen
171**
172** Description      Cancel a direct open connection or remove a background auto connection
173**                  bd address
174**
175** Parameters       client_if: server interface.
176**                  remote_bda: remote device BD address.
177**                  is_direct: direct connection or background auto connection
178**
179** Returns          void
180**
181*******************************************************************************/
182void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
183{
184    tBTA_GATTC_API_CANCEL_OPEN  *p_buf;
185
186    if ((p_buf = (tBTA_GATTC_API_CANCEL_OPEN *) GKI_getbuf(sizeof(tBTA_GATTC_API_CANCEL_OPEN))) != NULL)
187    {
188        p_buf->hdr.event = BTA_GATTC_API_CANCEL_OPEN_EVT;
189
190        p_buf->client_if = client_if;
191        p_buf->is_direct = is_direct;
192        memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
193
194        bta_sys_sendmsg(p_buf);
195    }
196    return;
197}
198
199/*******************************************************************************
200**
201** Function         BTA_GATTC_Close
202**
203** Description      Close a connection to a GATT server.
204**
205** Parameters       conn_id: connectino ID to be closed.
206**
207** Returns          void
208**
209*******************************************************************************/
210void BTA_GATTC_Close(UINT16 conn_id)
211{
212    BT_HDR  *p_buf;
213
214    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
215    {
216        p_buf->event = BTA_GATTC_API_CLOSE_EVT;
217
218        p_buf->layer_specific = conn_id;
219
220        bta_sys_sendmsg(p_buf);
221    }
222    return;
223
224}
225/*******************************************************************************
226**
227** Function         BTA_GATTC_ServiceSearchRequest
228**
229** Description      This function is called to request a GATT service discovery
230**                    on a GATT server. This function report service search result
231**                  by a callback event, and followed by a service search complete
232**                  event.
233**
234** Parameters       conn_id: connection ID.
235**                  p_srvc_uuid: a UUID of the service application is interested in.
236**                              If Null, discover for all services.
237**
238** Returns          None
239**
240*******************************************************************************/
241void BTA_GATTC_ServiceSearchRequest (UINT16 conn_id, tBT_UUID *p_srvc_uuid)
242{
243    tBTA_GATTC_API_SEARCH  *p_buf;
244    UINT16  len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(tBT_UUID);
245
246    if ((p_buf = (tBTA_GATTC_API_SEARCH *) GKI_getbuf(len)) != NULL)
247    {
248        memset(p_buf, 0, len);
249
250        p_buf->hdr.event = BTA_GATTC_API_SEARCH_EVT;
251        p_buf->hdr.layer_specific = conn_id;
252
253        if (p_srvc_uuid)
254        {
255            p_buf->p_srvc_uuid = (tBT_UUID *)(p_buf + 1);
256            memcpy(p_buf->p_srvc_uuid, p_srvc_uuid, sizeof(tBT_UUID));
257        }
258        else
259            p_buf->p_srvc_uuid = NULL;
260
261        bta_sys_sendmsg(p_buf);
262    }
263    return;
264}
265
266
267/*******************************************************************************
268**
269** Function         BTA_GATTC_GetFirstChar
270**
271** Description      This function is called to find the first characteristic of the
272**                  service on the given server.
273**
274** Parameters       conn_id: connection ID which identify the server.
275**                  p_srvc_id: the service ID of which the characteristic is belonged to.
276**                  p_char_uuid_cond: Characteristic UUID, if NULL find the first available
277**                               characteristic.
278**                  p_char_result: output parameter which will store the GATT
279**                                  characteristic ID.
280**                  p_property: output parameter to carry the characteristic property.
281**
282** Returns          returns status.
283**
284*******************************************************************************/
285tBTA_GATT_STATUS  BTA_GATTC_GetFirstChar (UINT16 conn_id, tBTA_GATT_SRVC_ID *p_srvc_id,
286                                          tBT_UUID *p_char_uuid_cond,
287                                          tBTA_GATTC_CHAR_ID *p_char_result,
288                                          tBTA_GATT_CHAR_PROP *p_property)
289{
290    tBTA_GATT_STATUS    status;
291
292    if (!p_srvc_id || !p_char_result)
293        return BTA_GATT_ILLEGAL_PARAMETER;
294
295    if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR, p_srvc_id, NULL,
296                                        p_char_uuid_cond, &p_char_result->char_id, (void *)p_property))
297        == BTA_GATT_OK)
298    {
299        memcpy(&p_char_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
300    }
301
302    return status;
303
304}
305/*******************************************************************************
306**
307** Function         BTA_GATTC_GetNextChar
308**
309** Description      This function is called to find the next characteristic of the
310**                  service on the given server.
311**
312** Parameters       conn_id: connection ID which identify the server.
313**                  p_start_char_id: start the characteristic search from the next record
314**                           after the one identified by char_id.
315**                  p_char_uuid_cond: Characteristic UUID, if NULL find the first available
316**                               characteristic.
317**                  p_char_result: output parameter which will store the GATT
318**                                  characteristic ID.
319**                  p_property: output parameter to carry the characteristic property.
320**
321** Returns          returns status.
322**
323*******************************************************************************/
324tBTA_GATT_STATUS  BTA_GATTC_GetNextChar (UINT16 conn_id,
325                                         tBTA_GATTC_CHAR_ID *p_start_char_id,
326                                         tBT_UUID           *p_char_uuid_cond,
327                                         tBTA_GATTC_CHAR_ID *p_char_result,
328                                         tBTA_GATT_CHAR_PROP    *p_property)
329{
330    tBTA_GATT_STATUS    status;
331
332    if (!p_start_char_id || !p_char_result)
333        return BTA_GATT_ILLEGAL_PARAMETER;
334
335    if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR,
336                                        &p_start_char_id->srvc_id,
337                                        &p_start_char_id->char_id,
338                                        p_char_uuid_cond,
339                                        &p_char_result->char_id,
340                                        (void *) p_property))
341        == BTA_GATT_OK)
342    {
343        memcpy(&p_char_result->srvc_id, &p_start_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
344    }
345
346    return status;
347}
348
349/*******************************************************************************
350**
351** Function         BTA_GATTC_GetFirstCharDescr
352**
353** Description      This function is called to find the first characteristic descriptor of the
354**                  characteristic on the given server.
355**
356** Parameters       conn_id: connection ID which identify the server.
357**                  p_char_id: the characteristic ID of which the descriptor is belonged to.
358**                  p_descr_uuid_cond: Characteristic Descr UUID, if NULL find the first available
359**                               characteristic.
360**                  p_descr_result: output parameter which will store the GATT
361**                                  characteristic descriptor ID.
362**
363** Returns          returns status.
364**
365*******************************************************************************/
366tBTA_GATT_STATUS  BTA_GATTC_GetFirstCharDescr (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
367                                                tBT_UUID *p_descr_uuid_cond,
368                                                tBTA_GATTC_CHAR_DESCR_ID *p_descr_result)
369{
370    tBTA_GATT_STATUS    status;
371
372    if (!p_char_id || !p_descr_result)
373        return BTA_GATT_ILLEGAL_PARAMETER;
374
375    memset(p_descr_result, 0, sizeof(tBTA_GATTC_CHAR_DESCR_ID));
376
377    if ((status = bta_gattc_query_cache(conn_id,
378                                        BTA_GATTC_ATTR_TYPE_CHAR_DESCR,
379                                        &p_char_id->srvc_id,
380                                        &p_char_id->char_id,
381                                        p_descr_uuid_cond,
382                                        &p_descr_result->char_id.char_id,
383                                        NULL))
384        == BTA_GATT_OK)
385    {
386        memcpy(&p_descr_result->descr_id, &p_descr_result->char_id.char_id, sizeof(tBTA_GATT_ID));
387        memcpy(&p_descr_result->char_id, p_char_id, sizeof(tBTA_GATTC_CHAR_ID));
388    }
389
390    return status;
391
392}
393/*******************************************************************************
394**
395** Function         BTA_GATTC_GetNextCharDescr
396**
397** Description      This function is called to find the next characteristic descriptor
398**                  of the characterisctic.
399**
400** Parameters       conn_id: connection ID which identify the server.
401**                  p_start_descr_id: start the characteristic search from the next record
402**                           after the one identified by p_start_descr_id.
403**                  p_descr_uuid_cond: Characteristic descriptor UUID, if NULL find
404**                               the first available characteristic descriptor.
405**                  p_descr_result: output parameter which will store the GATT
406**                                  characteristic descriptor ID.
407**
408** Returns          returns status.
409**
410*******************************************************************************/
411tBTA_GATT_STATUS  BTA_GATTC_GetNextCharDescr (UINT16 conn_id,
412                                             tBTA_GATTC_CHAR_DESCR_ID *p_start_descr_id,
413                                             tBT_UUID           *p_descr_uuid_cond,
414                                             tBTA_GATTC_CHAR_DESCR_ID *p_descr_result)
415{
416    tBTA_GATT_STATUS    status;
417
418    if (!p_start_descr_id || !p_descr_result)
419        return BTA_GATT_ILLEGAL_PARAMETER;
420
421    memset(p_descr_result, 0, sizeof(tBTA_GATTC_CHAR_DESCR_ID));
422
423    if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR_DESCR,
424                                        &p_start_descr_id->char_id.srvc_id,
425                                        &p_start_descr_id->char_id.char_id,
426                                        p_descr_uuid_cond,
427                                        &p_descr_result->char_id.char_id,
428                                        (void *)&p_start_descr_id->descr_id))
429        == BTA_GATT_OK)
430    {
431        memcpy(&p_descr_result->descr_id, &p_descr_result->char_id.char_id, sizeof(tBTA_GATT_ID));
432        memcpy(&p_descr_result->char_id, p_start_descr_id, sizeof(tBTA_GATTC_CHAR_ID));
433    }
434
435    return status;
436}
437
438
439/*******************************************************************************
440**
441** Function         BTA_GATTC_GetFirstIncludedService
442**
443** Description      This function is called to find the first included service of the
444**                  service on the given server.
445**
446** Parameters       conn_id: connection ID which identify the server.
447**                  p_srvc_id: the service ID of which the characteristic is belonged to.
448**                  p_uuid_cond: Characteristic UUID, if NULL find the first available
449**                               characteristic.
450**                  p_result: output parameter which will store the GATT ID
451**                              of the included service found.
452**
453** Returns          returns status.
454**
455*******************************************************************************/
456tBTA_GATT_STATUS  BTA_GATTC_GetFirstIncludedService(UINT16 conn_id, tBTA_GATT_SRVC_ID *p_srvc_id,
457                                                    tBT_UUID *p_uuid_cond, tBTA_GATTC_INCL_SVC_ID *p_result)
458{
459    tBTA_GATT_STATUS    status;
460
461    if (!p_srvc_id || !p_result)
462        return BTA_GATT_ILLEGAL_PARAMETER;
463
464    if ((status = bta_gattc_query_cache(conn_id,
465                                        BTA_GATTC_ATTR_TYPE_INCL_SRVC,
466                                        p_srvc_id,
467                                        NULL,
468                                        p_uuid_cond,
469                                        &p_result->incl_svc_id.id,
470                                        (void *)&p_result->incl_svc_id.is_primary))
471        == BTA_GATT_OK)
472    {
473        memcpy(&p_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
474    }
475
476    return status;
477}
478/*******************************************************************************
479**
480** Function         BTA_GATTC_GetNextIncludedService
481**
482** Description      This function is called to find the next included service of the
483**                  service on the given server.
484**
485** Parameters       conn_id: connection ID which identify the server.
486**                  p_start_id: start the search from the next record
487**                                  after the one identified by p_start_id.
488**                  p_uuid_cond: Included service UUID, if NULL find the first available
489**                               included service.
490**                  p_result: output parameter which will store the GATT ID
491**                              of the included service found.
492**
493** Returns          returns status.
494**
495*******************************************************************************/
496tBTA_GATT_STATUS  BTA_GATTC_GetNextIncludedService(UINT16 conn_id,
497                                                   tBTA_GATTC_INCL_SVC_ID *p_start_id,
498                                                   tBT_UUID               *p_uuid_cond,
499                                                   tBTA_GATTC_INCL_SVC_ID *p_result)
500{
501    tBTA_GATT_STATUS    status;
502
503    if (!p_start_id || !p_result)
504        return BTA_GATT_ILLEGAL_PARAMETER;
505
506    if ((status = bta_gattc_query_cache(conn_id,
507                                        BTA_GATTC_ATTR_TYPE_INCL_SRVC,
508                                        &p_start_id->srvc_id,
509                                        &p_start_id->incl_svc_id.id,
510                                        p_uuid_cond,
511                                        &p_result->incl_svc_id.id,
512                                        (void *)&p_result->incl_svc_id.is_primary))
513        == BTA_GATT_OK)
514    {
515        memcpy(&p_result->srvc_id, &p_start_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
516    }
517
518    return status;
519}
520
521/*******************************************************************************
522**
523** Function         BTA_GATTC_ReadCharacteristic
524**
525** Description      This function is called to read a service's characteristics of
526**                    the given characteritisc ID.
527**
528** Parameters       conn_id - connectino ID.
529**                    p_char_id - characteritic ID to read.
530**
531** Returns          None
532**
533*******************************************************************************/
534void BTA_GATTC_ReadCharacteristic(UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
535                                  tBTA_GATT_AUTH_REQ auth_req)
536{
537    tBTA_GATTC_API_READ  *p_buf;
538
539    if ((p_buf = (tBTA_GATTC_API_READ *) GKI_getbuf(sizeof(tBTA_GATTC_API_READ))) != NULL)
540    {
541        memset(p_buf, 0, sizeof(tBTA_GATTC_API_READ));
542
543        p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
544        p_buf->hdr.layer_specific = conn_id;
545        p_buf->auth_req = auth_req;
546
547        memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
548        memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
549        p_buf->p_descr_type = NULL;
550
551        bta_sys_sendmsg(p_buf);
552    }
553    return;
554}
555
556/*******************************************************************************
557**
558** Function         BTA_GATTC_ReadCharDescr
559**
560** Description      This function is called to read a characteristics descriptor.
561**
562** Parameters       conn_id - connection ID.
563**                    p_char_descr_id - characteritic descriptor ID to read.
564**
565** Returns          None
566**
567*******************************************************************************/
568void BTA_GATTC_ReadCharDescr (UINT16 conn_id,
569                              tBTA_GATTC_CHAR_DESCR_ID  *p_descr_id,
570                              tBTA_GATT_AUTH_REQ auth_req)
571{
572    tBTA_GATTC_API_READ  *p_buf;
573    UINT16  len = (UINT16)(sizeof(tBTA_GATT_ID) + sizeof(tBTA_GATTC_API_READ));
574
575    if ((p_buf = (tBTA_GATTC_API_READ *) GKI_getbuf(len)) != NULL)
576    {
577        memset(p_buf, 0, sizeof(tBTA_GATTC_API_READ));
578
579        p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
580        p_buf->hdr.layer_specific = conn_id;
581        p_buf->auth_req = auth_req;
582
583        memcpy(&p_buf->srvc_id, &p_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
584        memcpy(&p_buf->char_id, &p_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
585        p_buf->p_descr_type  = (tBTA_GATT_ID *)(p_buf + 1);
586
587        memcpy(p_buf->p_descr_type, &p_descr_id->descr_id, sizeof(tBTA_GATT_ID));
588
589        bta_sys_sendmsg(p_buf);
590    }
591    return;
592
593}
594/*******************************************************************************
595**
596** Function         BTA_GATTC_ReadMultiple
597**
598** Description      This function is called to read multiple characteristic or
599**                  characteristic descriptors.
600**
601** Parameters       conn_id - connectino ID.
602**                    p_read_multi - pointer to the read multiple parameter.
603**
604** Returns          None
605**
606*******************************************************************************/
607void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi,
608                            tBTA_GATT_AUTH_REQ auth_req)
609{
610    tBTA_GATTC_API_READ_MULTI  *p_buf;
611    tBTA_GATTC_ATTR_ID          *p_value;
612    UINT16      len = (UINT16)(sizeof(tBTA_GATTC_API_READ_MULTI) +
613                               p_read_multi->num_attr * sizeof(tBTA_GATTC_ATTR_ID));
614    UINT8       i;
615
616    if ((p_buf = (tBTA_GATTC_API_READ_MULTI *) GKI_getbuf(len)) != NULL)
617    {
618        memset(p_buf, 0, len);
619
620        p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_EVT;
621        p_buf->hdr.layer_specific = conn_id;
622        p_buf->auth_req = auth_req;
623
624        p_buf->num_attr = p_read_multi->num_attr;
625
626        if (p_buf->num_attr > 0)
627        {
628            p_buf->p_id_list = p_value = (tBTA_GATTC_ATTR_ID *)(p_buf + 1);
629
630            for (i = 0; i < p_buf->num_attr; i ++, p_value ++)
631            {
632                memcpy(p_value, &p_read_multi->id_list[i], sizeof(tBTA_GATTC_ATTR_ID));
633            }
634        }
635        bta_sys_sendmsg(p_buf);
636    }
637    return;
638}
639
640
641/*******************************************************************************
642**
643** Function         BTA_GATTC_WriteCharValue
644**
645** Description      This function is called to write characteristic value.
646**
647** Parameters       conn_id - connection ID.
648**                    p_char_id - characteristic ID to write.
649**                    write_type - type of write.
650**                  len: length of the data to be written.
651**                  p_value - the value to be written.
652**
653** Returns          None
654**
655*******************************************************************************/
656void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
657                                tBTA_GATTC_CHAR_ID *p_char_id,
658                                tBTA_GATTC_WRITE_TYPE  write_type,
659                                UINT16 len,
660                                UINT8 *p_value,
661                                tBTA_GATT_AUTH_REQ auth_req)
662{
663    tBTA_GATTC_API_WRITE  *p_buf;
664
665    if ((p_buf = (tBTA_GATTC_API_WRITE *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTC_API_WRITE) + len))) != NULL)
666    {
667        memset(p_buf, 0, sizeof(tBTA_GATTC_API_WRITE) + len);
668
669        p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
670        p_buf->hdr.layer_specific = conn_id;
671        p_buf->auth_req = auth_req;
672
673        memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
674        memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
675
676        p_buf->write_type = write_type;
677        p_buf->len = len;
678
679        if (p_value && len > 0)
680        {
681            p_buf->p_value = (UINT8 *)(p_buf + 1);
682            memcpy(p_buf->p_value, p_value, len);
683        }
684
685        bta_sys_sendmsg(p_buf);
686    }
687    return;
688}
689/*******************************************************************************
690**
691** Function         BTA_GATTC_WriteCharDescr
692**
693** Description      This function is called to write characteristic descriptor value.
694**
695** Parameters       conn_id - connection ID
696**                    p_char_descr_id - characteristic descriptor ID to write.
697**                  write_type - write type.
698**                  p_value - the value to be written.
699**
700** Returns          None
701**
702*******************************************************************************/
703void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
704                               tBTA_GATTC_CHAR_DESCR_ID *p_char_descr_id,
705                               tBTA_GATTC_WRITE_TYPE  write_type,
706                               tBTA_GATT_UNFMT      *p_data,
707                               tBTA_GATT_AUTH_REQ auth_req)
708{
709    tBTA_GATTC_API_WRITE  *p_buf;
710    UINT16  len = sizeof(tBTA_GATTC_API_WRITE) + sizeof(tBTA_GATT_ID);
711
712    if (p_data != NULL)
713        len += p_data->len;
714
715    if ((p_buf = (tBTA_GATTC_API_WRITE *) GKI_getbuf(len)) != NULL)
716    {
717        memset(p_buf, 0, len);
718
719        p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
720        p_buf->hdr.layer_specific = conn_id;
721        p_buf->auth_req = auth_req;
722
723        memcpy(&p_buf->srvc_id, &p_char_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
724        memcpy(&p_buf->char_id, &p_char_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
725        p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
726        memcpy(p_buf->p_descr_type, &p_char_descr_id->descr_id, sizeof(tBTA_GATT_ID));
727        p_buf->write_type = write_type;
728
729        if (p_data && p_data->len != 0)
730        {
731            p_buf->p_value  = (UINT8 *)(p_buf->p_descr_type + 1);
732            p_buf->len      = p_data->len;
733            /* pack the descr data */
734            memcpy(p_buf->p_value, p_data->p_value, p_data->len);
735        }
736
737        bta_sys_sendmsg(p_buf);
738    }
739    return;
740
741}
742/*******************************************************************************
743**
744** Function         BTA_GATTC_PrepareWrite
745**
746** Description      This function is called to prepare write a characteristic value.
747**
748** Parameters       conn_id - connection ID.
749**                    p_char_id - GATT characteritic ID of the service.
750**                  offset - offset of the write value.
751**                  len: length of the data to be written.
752**                  p_value - the value to be written.
753**
754** Returns          None
755**
756*******************************************************************************/
757void BTA_GATTC_PrepareWrite  (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id,
758                              UINT16 offset, UINT16 len, UINT8 *p_value,
759                              tBTA_GATT_AUTH_REQ auth_req)
760{
761    tBTA_GATTC_API_WRITE  *p_buf;
762
763    if ((p_buf = (tBTA_GATTC_API_WRITE *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTC_API_WRITE) + len))) != NULL)
764    {
765        memset(p_buf, 0, sizeof(tBTA_GATTC_API_WRITE) + len);
766
767        p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
768        p_buf->hdr.layer_specific = conn_id;
769        p_buf->auth_req = auth_req;
770
771        memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
772        memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
773
774        p_buf->write_type = BTA_GATTC_WRITE_PREPARE;
775        p_buf->offset   = offset;
776        p_buf->len = len;
777
778        if (p_value && len > 0)
779        {
780            p_buf->p_value = (UINT8 *)(p_buf + 1);
781            memcpy(p_buf->p_value, p_value, len);
782        }
783
784        bta_sys_sendmsg(p_buf);
785    }
786    return;
787
788}
789/*******************************************************************************
790**
791** Function         BTA_GATTC_ExecuteWrite
792**
793** Description      This function is called to execute write a prepare write sequence.
794**
795** Parameters       conn_id - connection ID.
796**                    is_execute - execute or cancel.
797**
798** Returns          None
799**
800*******************************************************************************/
801void BTA_GATTC_ExecuteWrite  (UINT16 conn_id, BOOLEAN is_execute)
802{
803    tBTA_GATTC_API_EXEC  *p_buf;
804
805    if ((p_buf = (tBTA_GATTC_API_EXEC *) GKI_getbuf((UINT16)sizeof(tBTA_GATTC_API_EXEC))) != NULL)
806    {
807        memset(p_buf, 0, sizeof(tBTA_GATTC_API_EXEC));
808
809        p_buf->hdr.event = BTA_GATTC_API_EXEC_EVT;
810        p_buf->hdr.layer_specific = conn_id;
811
812        p_buf->is_execute = is_execute;
813
814        bta_sys_sendmsg(p_buf);
815    }
816    return;
817
818}
819/*******************************************************************************
820**
821** Function         BTA_GATTC_SendIndConfirm
822**
823** Description      This function is called to send handle value confirmation.
824**
825** Parameters       conn_id - connection ID.
826**                    p_char_id - characteristic ID to confirm.
827**
828** Returns          None
829**
830*******************************************************************************/
831void BTA_GATTC_SendIndConfirm (UINT16 conn_id, tBTA_GATTC_CHAR_ID *p_char_id)
832{
833    tBTA_GATTC_API_CONFIRM  *p_buf;
834
835    APPL_TRACE_API3("BTA_GATTC_SendIndConfirm conn_id=%d service uuid1=0x%x char uuid=0x%x",
836                    conn_id, p_char_id->srvc_id.id.uuid.uu.uuid16, p_char_id->char_id.uuid.uu.uuid16);
837
838    if ((p_buf = (tBTA_GATTC_API_CONFIRM *) GKI_getbuf(sizeof(tBTA_GATTC_API_CONFIRM))) != NULL)
839    {
840        memset(p_buf, 0, sizeof(tBTA_GATTC_API_CONFIRM));
841
842        p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT;
843        p_buf->hdr.layer_specific = conn_id;
844
845        memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
846        memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
847
848        bta_sys_sendmsg(p_buf);
849    }
850    return;
851
852}
853
854/*******************************************************************************
855**
856** Function         BTA_GATTC_RegisterForNotifications
857**
858** Description      This function is called to register for notification of a service.
859**
860** Parameters       client_if - client interface.
861**                  bda - target GATT server.
862**                  p_char_id - pointer to GATT characteristic ID.
863**
864** Returns          OK if registration succeed, otherwise failed.
865**
866*******************************************************************************/
867tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
868                                                     BD_ADDR bda,
869                                                     tBTA_GATTC_CHAR_ID *p_char_id)
870{
871    tBTA_GATTC_RCB      *p_clreg;
872    tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
873    UINT8               i;
874
875    if (!p_char_id)
876    {
877        APPL_TRACE_ERROR0("deregistration failed, unknow char id");
878        return status;
879    }
880
881    /* lock other GKI task */
882    GKI_sched_lock();
883
884    if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
885    {
886        for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
887        {
888            if ( p_clreg->notif_reg[i].in_use &&
889                 !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
890                  bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id))
891            {
892                APPL_TRACE_WARNING0("notification already registered");
893                status = BTA_GATT_OK;
894                break;
895            }
896        }
897        if (status != BTA_GATT_OK)
898        {
899            for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
900            {
901                if (!p_clreg->notif_reg[i].in_use)
902                {
903                    memset((void *)&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
904
905                    p_clreg->notif_reg[i].in_use = TRUE;
906                    memcpy(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN);
907
908                    p_clreg->notif_reg[i].char_id.srvc_id.is_primary = p_char_id->srvc_id.is_primary;
909                    bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.srvc_id.id, &p_char_id->srvc_id.id);
910                    bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.char_id, &p_char_id->char_id);
911
912                    status = BTA_GATT_OK;
913                    break;
914                }
915            }
916            if (i == BTA_GATTC_NOTIF_REG_MAX)
917            {
918                status = BTA_GATT_NO_RESOURCES;
919                APPL_TRACE_ERROR0("Max Notification Reached, registration failed.");
920            }
921        }
922    }
923    else
924    {
925        APPL_TRACE_ERROR1("Client_if: %d Not Registered", client_if);
926    }
927
928    GKI_sched_unlock();
929
930    return status;
931}
932
933/*******************************************************************************
934**
935** Function         BTA_GATTC_DeregisterForNotifications
936**
937** Description      This function is called to de-register for notification of a service.
938**
939** Parameters       client_if - client interface.
940**                  bda - target GATT server.
941**                  p_char_id - pointer to GATT characteristic ID.
942**
943** Returns          OK if deregistration succeed, otherwise failed.
944**
945*******************************************************************************/
946tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if,
947                                                       BD_ADDR bda,
948                                                       tBTA_GATTC_CHAR_ID *p_char_id)
949{
950    tBTA_GATTC_RCB      *p_clreg;
951    tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
952    UINT8               i;
953
954    if (!p_char_id)
955    {
956        APPL_TRACE_ERROR0("deregistration failed, unknow char id");
957        return status;
958    }
959
960    /* lock other GKI task */
961    GKI_sched_lock();
962
963    if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
964    {
965        for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
966        {
967            if (p_clreg->notif_reg[i].in_use &&
968                !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
969                bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id))
970            {
971                APPL_TRACE_DEBUG0("Deregistered.");
972                memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
973                status = BTA_GATT_OK;
974                break;
975            }
976        }
977        if (i == BTA_GATTC_NOTIF_REG_MAX)
978        {
979            status = BTA_GATT_ERROR;
980
981            APPL_TRACE_ERROR0("registration not found");
982        }
983    }
984    else
985    {
986        APPL_TRACE_ERROR1("Client_if: %d Not Registered", client_if);
987    }
988
989    GKI_sched_unlock();
990
991    return status;
992}
993
994/*******************************************************************************
995**
996** Function         BTA_GATTC_Refresh
997**
998** Description      Refresh the server cache of the remote device
999**
1000** Parameters       remote_bda: remote device BD address.
1001**
1002** Returns          void
1003**
1004*******************************************************************************/
1005void BTA_GATTC_Refresh(BD_ADDR remote_bda)
1006{
1007    tBTA_GATTC_API_OPEN  *p_buf;
1008
1009    if ((p_buf = (tBTA_GATTC_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTC_API_OPEN))) != NULL)
1010    {
1011        p_buf->hdr.event = BTA_GATTC_API_REFRESH_EVT;
1012
1013        memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
1014
1015
1016        bta_sys_sendmsg(p_buf);
1017    }
1018    return;
1019}
1020
1021/*******************************************************************************
1022**
1023** Function         BTA_GATTC_Listen
1024**
1025** Description      Start advertisement to listen for connection request for a GATT
1026**                  client application.
1027**
1028** Parameters       client_if: server interface.
1029**                  start: to start or stop listening for connection
1030**                  remote_bda: remote device BD address, if listen to all device
1031**                              use NULL.
1032**
1033** Returns          void
1034**
1035*******************************************************************************/
1036void BTA_GATTC_Listen(tBTA_GATTC_IF client_if, BOOLEAN start, BD_ADDR_PTR target_bda)
1037{
1038    tBTA_GATTC_API_LISTEN  *p_buf;
1039
1040    if ((p_buf = (tBTA_GATTC_API_LISTEN *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTC_API_LISTEN) + BD_ADDR_LEN))) != NULL)
1041    {
1042        p_buf->hdr.event = BTA_GATTC_API_LISTEN_EVT;
1043
1044        p_buf->client_if = client_if;
1045        p_buf->start = start;
1046        if (target_bda)
1047        {
1048            p_buf->remote_bda = (UINT8*)(p_buf + 1);
1049            memcpy(p_buf->remote_bda, target_bda, BD_ADDR_LEN);
1050        }
1051        else
1052            p_buf->remote_bda = NULL;
1053
1054        bta_sys_sendmsg(p_buf);
1055    }
1056    return;
1057}
1058
1059/*******************************************************************************
1060**
1061** Function         BTA_GATTC_Broadcast
1062**
1063** Description      Start broadcasting (non-connectable advertisements)
1064**
1065** Parameters       client_if: client interface.
1066**                  start: to start or stop listening for connection
1067**
1068** Returns          void
1069**
1070*******************************************************************************/
1071void BTA_GATTC_Broadcast(tBTA_GATTC_IF client_if, BOOLEAN start)
1072{
1073    tBTA_GATTC_API_LISTEN  *p_buf;
1074
1075    if ((p_buf = (tBTA_GATTC_API_LISTEN *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTC_API_LISTEN) + BD_ADDR_LEN))) != NULL)
1076    {
1077        p_buf->hdr.event = BTA_GATTC_API_BROADCAST_EVT;
1078        p_buf->client_if = client_if;
1079        p_buf->start = start;
1080        bta_sys_sendmsg(p_buf);
1081    }
1082    return;
1083}
1084
1085#endif /* BTA_GATT_INCLUDED */
1086
1087