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 client utility function.
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 "utl.h"
31#include "gki.h"
32#include "bta_sys.h"
33#include "bta_gatts_int.h"
34
35static const UINT8  base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
36    0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
37
38/*******************************************************************************
39**
40** Function         bta_gatt_convert_uuid16_to_uuid128
41**
42** Description      Convert a 16 bits UUID to be an standard 128 bits one.
43**
44** Returns          TRUE if two uuid match; FALSE otherwise.
45**
46*******************************************************************************/
47static void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
48{
49    UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
50
51    memcpy (uuid_128, base_uuid, LEN_UUID_128);
52
53    UINT16_TO_STREAM(p, uuid_16);
54}
55/*******************************************************************************
56**
57** Function         bta_gatts_alloc_srvc_cb
58**
59** Description      allocate a service control block.
60**
61** Returns          pointer to the control block, or otherwise NULL when failed.
62**
63*******************************************************************************/
64UINT8 bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB *p_cb, UINT8 rcb_idx)
65{
66    UINT8 i;
67
68    for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++)
69    {
70        if (!p_cb->srvc_cb[i].in_use)
71        {
72            p_cb->srvc_cb[i].in_use = TRUE;
73            p_cb->srvc_cb[i].rcb_idx = rcb_idx;
74            return i;
75        }
76    }
77    return BTA_GATTS_INVALID_APP;
78}
79
80/*******************************************************************************
81**
82** Function         bta_gatts_find_app_rcb_by_app_if
83**
84** Description      find the index of the application control block by app ID.
85**
86** Returns          pointer to the control block if success, otherwise NULL
87**
88*******************************************************************************/
89tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if)
90{
91    UINT8 i;
92    tBTA_GATTS_RCB *p_reg;
93
94    for (i = 0, p_reg = bta_gatts_cb.rcb; i < BTA_GATTS_MAX_APP_NUM; i ++, p_reg++)
95    {
96        if (p_reg->in_use && p_reg->gatt_if == server_if)
97            return p_reg;
98    }
99    return NULL;
100}
101
102/*******************************************************************************
103**
104** Function         bta_gatts_find_app_rcb_idx_by_app_if
105**
106** Description      find the index of the application control block by app ID.
107**
108** Returns          index of the control block, or BTA_GATTS_INVALID_APP if failed.
109**
110*******************************************************************************/
111
112UINT8 bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_IF server_if)
113{
114    UINT8 i;
115
116    for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
117    {
118        if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == server_if)
119            return i;
120    }
121    return BTA_GATTS_INVALID_APP;
122}
123/*******************************************************************************
124**
125** Function         bta_gatts_find_srvc_cb_by_srvc_id
126**
127** Description      find the service control block by service ID.
128**
129** Returns          pointer to the rcb.
130**
131*******************************************************************************/
132tBTA_GATTS_SRVC_CB * bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id)
133{
134    UINT8 i;
135    APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id  service_id=%d", service_id);
136    for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++)
137    {
138        if (p_cb->srvc_cb[i].in_use &&
139            p_cb->srvc_cb[i].service_id == service_id)
140        {
141            APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id  found service cb index =%d", i);
142            return &p_cb->srvc_cb[i];
143        }
144    }
145    return NULL;
146}
147/*******************************************************************************
148**
149** Function         bta_gatts_find_srvc_cb_by_attr_id
150**
151** Description      find the service control block by attribute ID.
152**
153** Returns          pointer to the rcb.
154**
155*******************************************************************************/
156tBTA_GATTS_SRVC_CB * bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB *p_cb, UINT16 attr_id)
157{
158    UINT8 i;
159
160    for (i = 0; i < (BTA_GATTS_MAX_SRVC_NUM); i ++)
161    {
162        if (/* middle service */
163            (i < (BTA_GATTS_MAX_SRVC_NUM - 1) &&
164             p_cb->srvc_cb[i].in_use &&
165             p_cb->srvc_cb[i + 1].in_use &&
166             attr_id >= p_cb->srvc_cb[i].service_id &&
167             attr_id < p_cb->srvc_cb[i + 1].service_id) ||
168            /* last active service */
169            (i < (BTA_GATTS_MAX_SRVC_NUM - 1) &&
170             p_cb->srvc_cb[i].in_use &&
171             !p_cb->srvc_cb[i + 1].in_use &&
172             attr_id >= p_cb->srvc_cb[i].service_id)    ||
173            /* last service incb */
174            (i == (BTA_GATTS_MAX_SRVC_NUM - 1) &&
175             attr_id >= p_cb->srvc_cb[i].service_id)
176           )
177        {
178            return &p_cb->srvc_cb[i];
179        }
180    }
181    return NULL;
182}
183/*******************************************************************************
184**
185** Function         bta_gatts_uuid_compare
186**
187** Description      Compare two UUID to see if they are the same.
188**
189** Returns          TRUE if two uuid match; FALSE otherwise.
190**
191*******************************************************************************/
192BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src)
193{
194    UINT8  su[LEN_UUID_128], tu[LEN_UUID_128];
195    UINT8  *ps, *pt;
196
197    /* any of the UUID is unspecified */
198    if (src.len == 0 || tar.len == 0)
199    {
200        return TRUE;
201    }
202
203    /* If both are 16-bit, we can do a simple compare */
204    if (src.len == 2 && tar.len == 2)
205    {
206        return src.uu.uuid16 == tar.uu.uuid16;
207    }
208
209    /* One or both of the UUIDs is 128-bit */
210    if (src.len == LEN_UUID_16)
211    {
212        /* convert a 16 bits UUID to 128 bits value */
213        bta_gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
214        ps = su;
215    }
216    else
217        ps = src.uu.uuid128;
218
219    if (tar.len == LEN_UUID_16)
220    {
221        /* convert a 16 bits UUID to 128 bits value */
222        bta_gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
223        pt = tu;
224    }
225    else
226        pt = tar.uu.uuid128;
227
228    return(memcmp(ps, pt, LEN_UUID_128) == 0);
229}
230
231
232
233
234#endif
235