btif_gatt_util.c revision e4020c28c8a9dc56f927b03a8ca3a17d9401bc1e
1/******************************************************************************
2 *
3 *  Copyright (C) 2009-2013 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#include <hardware/bluetooth.h>
20#include <hardware/bt_gatt.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <errno.h>
24#include <string.h>
25
26#define LOG_TAG "BtGatt.btif"
27
28#include "bta_api.h"
29#include "bta_gatt_api.h"
30#include "bd.h"
31#include "btif_storage.h"
32
33#include "btif_common.h"
34#include "btif_dm.h"
35#include "btif_util.h"
36#include "btif_gatt.h"
37#include "btif_gatt_util.h"
38
39#if BTA_GATT_INCLUDED == TRUE
40
41#define GATTC_READ_VALUE_TYPE_VALUE          0x0000  /* Attribute value itself */
42#define GATTC_READ_VALUE_TYPE_AGG_FORMAT     0x2905  /* Characteristic Aggregate Format*/
43
44#define BTIF_GATT_MAX_ENC_LINK_RECORDS       10
45
46typedef struct
47{
48    BD_ADDR         bd_addr;
49    BOOLEAN         in_use;
50}__attribute__((packed)) btif_gatt_encrypted_link_t;
51
52static char BASE_UUID[16] = {
53    0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
54    0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
55};
56
57static btif_gatt_encrypted_link_t encrypted_links[BTIF_GATT_MAX_ENC_LINK_RECORDS];
58
59extern bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr);
60
61int uuidType(unsigned char* p_uuid)
62{
63    int i = 0;
64    int match = 0;
65    int all_zero = 1;
66
67    for(i = 0; i != 16; ++i)
68    {
69        if (i == 12 || i == 13)
70            continue;
71
72        if (p_uuid[i] == BASE_UUID[i])
73            ++match;
74
75        if (p_uuid[i] != 0)
76            all_zero = 0;
77    }
78    if (all_zero)
79        return 0;
80    if (match == 12)
81        return LEN_UUID_32;
82    if (match == 14)
83        return LEN_UUID_16;
84    return LEN_UUID_128;
85}
86
87/*******************************************************************************
88 * BTIF -> BTA conversion functions
89 *******************************************************************************/
90
91void btif_to_bta_uuid(tBT_UUID *p_dest, bt_uuid_t *p_src)
92{
93    char *p_byte = (char*)p_src;
94    int i = 0;
95
96    p_dest->len = uuidType(p_src->uu);
97
98    switch (p_dest->len)
99    {
100        case LEN_UUID_16:
101            p_dest->uu.uuid16 = (p_src->uu[13] << 8) + p_src->uu[12];
102            break;
103
104        case LEN_UUID_32:
105            p_dest->uu.uuid32  = (p_src->uu[13] <<  8) + p_src->uu[12];
106            p_dest->uu.uuid32 += (p_src->uu[15] << 24) + (p_src->uu[14] << 16);
107            break;
108
109        case LEN_UUID_128:
110            for(i = 0; i != 16; ++i)
111                p_dest->uu.uuid128[i] = p_byte[i];
112            break;
113
114        default:
115            ALOGE("%s: Unknown UUID length %d!", __FUNCTION__, p_dest->len);
116            break;
117    }
118}
119
120void btif_to_bta_char_id(tBTA_GATT_ID *p_dest, btgatt_char_id_t *p_src)
121{
122    p_dest->inst_id = p_src->inst_id;
123    btif_to_bta_uuid(&p_dest->uuid, &p_src->uuid);
124}
125
126void btif_to_bta_srvc_id(tBTA_GATT_SRVC_ID *p_dest, btgatt_srvc_id_t *p_src)
127{
128    p_dest->id.inst_id = p_src->id.inst_id;
129    btif_to_bta_uuid(&p_dest->id.uuid, &p_src->id.uuid);
130    p_dest->is_primary = p_src->is_primary;
131}
132
133void btif_to_bta_response(tBTA_GATTS_RSP *p_dest, btgatt_response_t* p_src)
134{
135    p_dest->attr_value.auth_req = p_src->attr_value.auth_req;
136    p_dest->attr_value.handle   = p_src->attr_value.handle;
137    p_dest->attr_value.len      = p_src->attr_value.len;
138    p_dest->attr_value.offset   = p_src->attr_value.offset;
139    memcpy(p_dest->attr_value.value, p_src->attr_value.value, GATT_MAX_ATTR_LEN);
140}
141
142/*******************************************************************************
143 * BTA -> BTIF conversion functions
144 *******************************************************************************/
145
146void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src)
147{
148    int i = 0;
149
150    if (p_src->len == LEN_UUID_16 || p_src->len == LEN_UUID_32)
151    {
152        for(i=0; i != 16; ++i)
153            p_dest->uu[i] = BASE_UUID[i];
154    }
155
156    switch (p_src->len)
157    {
158        case 0:
159            break;
160
161        case LEN_UUID_16:
162            p_dest->uu[12] = p_src->uu.uuid16 & 0xff;
163            p_dest->uu[13] = (p_src->uu.uuid16 >> 8) & 0xff;
164            break;
165
166        case LEN_UUID_32:
167            p_dest->uu[12] = p_src->uu.uuid16 & 0xff;
168            p_dest->uu[13] = (p_src->uu.uuid16 >> 8) & 0xff;
169            p_dest->uu[14] = (p_src->uu.uuid32 >> 16) & 0xff;
170            p_dest->uu[15] = (p_src->uu.uuid32 >> 24) & 0xff;
171            break;
172
173        case LEN_UUID_128:
174            for(i=0; i != 16; ++i)
175                p_dest->uu[i] = p_src->uu.uuid128[i];
176            break;
177
178        default:
179            ALOGE("%s: Unknown UUID length %d!", __FUNCTION__, p_src->len);
180            break;
181    }
182}
183
184
185void bta_to_btif_char_id(btgatt_char_id_t *p_dest, tBTA_GATT_ID *p_src)
186{
187    p_dest->inst_id = p_src->inst_id;
188    bta_to_btif_uuid(&p_dest->uuid, &p_src->uuid);
189}
190
191void bta_to_btif_srvc_id(btgatt_srvc_id_t *p_dest, tBTA_GATT_SRVC_ID *p_src)
192{
193    p_dest->id.inst_id = p_src->id.inst_id;
194    bta_to_btif_uuid(&p_dest->id.uuid, &p_src->id.uuid);
195    p_dest->is_primary = p_src->is_primary;
196}
197
198
199/*******************************************************************************
200 * Utility functions
201 *******************************************************************************/
202
203uint16_t get_uuid16(tBT_UUID *p_uuid)
204{
205    if (p_uuid->len == LEN_UUID_16)
206    {
207        return p_uuid->uu.uuid16;
208    }
209    else if (p_uuid->len == LEN_UUID_128)
210    {
211        UINT16 u16;
212        UINT8 *p = &p_uuid->uu.uuid128[LEN_UUID_128 - 4];
213        STREAM_TO_UINT16(u16, p);
214        return u16;
215    }
216    else  /* p_uuid->len == LEN_UUID_32 */
217    {
218        return(UINT16) p_uuid->uu.uuid32;
219    }
220}
221
222uint16_t set_read_value(btgatt_read_params_t *p_dest, tBTA_GATTC_READ *p_src)
223{
224    int i = 0;
225    uint16_t descr_type = 0;
226    uint16_t len = 0;
227
228    p_dest->status = p_src->status;
229    bta_to_btif_srvc_id(&p_dest->srvc_id, &p_src->srvc_id);
230    bta_to_btif_char_id(&p_dest->char_id, &p_src->char_id);
231    bta_to_btif_uuid(&p_dest->descr_id, &p_src->descr_type);
232
233    descr_type = get_uuid16(&p_src->descr_type);
234
235    switch (descr_type)
236    {
237        case GATT_UUID_CHAR_AGG_FORMAT:
238            /* not supported */
239            p_dest->value_type = GATTC_READ_VALUE_TYPE_AGG_FORMAT;
240            break;
241
242        default:
243            if (( p_src->status == BTA_GATT_OK ) &&(p_src->p_value != NULL))
244            {
245                ALOGI("%s unformat.len = %d ", __FUNCTION__, p_src->p_value->unformat.len);
246                p_dest->value.len = p_src->p_value->unformat.len;
247                if ( p_src->p_value->unformat.len > 0  && p_src->p_value->unformat.p_value != NULL )
248                {
249                    memcpy(p_dest->value.value, p_src->p_value->unformat.p_value,
250                           p_src->p_value->unformat.len);
251                }
252                len += p_src->p_value->unformat.len;
253            }
254            else
255            {
256                p_dest->value.len = 0;
257            }
258
259            p_dest->value_type = GATTC_READ_VALUE_TYPE_VALUE;
260            break;
261    }
262
263    return len;
264}
265
266/*******************************************************************************
267 * Encrypted link map handling
268 *******************************************************************************/
269
270static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result);
271
272static BOOLEAN btif_gatt_is_link_encrypted (BD_ADDR bd_addr)
273{
274    btif_gatt_encrypted_link_t *p_link = &encrypted_links[0];
275    int i;
276
277    if (bd_addr == NULL)
278        return FALSE;
279
280    for (i = 0; i != BTIF_GATT_MAX_ENC_LINK_RECORDS; ++i, ++p_link)
281    {
282        if (p_link->in_use && (!memcmp(p_link->bd_addr, bd_addr, BD_ADDR_LEN)))
283            return TRUE;
284    }
285    return FALSE;
286}
287
288static BOOLEAN btif_gatt_add_encrypted_link (BD_ADDR bd_addr)
289{
290    btif_gatt_encrypted_link_t *p_link = &encrypted_links[0];
291    int i;
292
293    if (bd_addr == NULL)
294        return FALSE;
295
296    if (btif_gatt_is_link_encrypted(bd_addr))
297        return TRUE;
298
299    for (i = 0; i != BTIF_GATT_MAX_ENC_LINK_RECORDS; ++i, ++p_link)
300    {
301        if (!p_link->in_use)
302        {
303            p_link->in_use = TRUE;
304            memcpy( p_link->bd_addr, bd_addr, sizeof(BD_ADDR) );
305            return  TRUE;
306        }
307    }
308
309    return FALSE;
310}
311
312void btif_gatt_remove_encrypted_link (BD_ADDR bd_addr)
313{
314    btif_gatt_encrypted_link_t *p_link = &encrypted_links[0];
315    int i;
316
317    if (bd_addr == NULL)
318        return;
319
320    for (i = 0; i != BTIF_GATT_MAX_ENC_LINK_RECORDS; ++i, ++p_link)
321    {
322        if (p_link->in_use && (!memcmp (p_link->bd_addr, bd_addr, BD_ADDR_LEN)))
323        {
324            p_link->in_use = FALSE;
325            break;
326        }
327    }
328}
329
330static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result)
331{
332    if (result == BTA_SUCCESS)
333    {
334        btif_gatt_add_encrypted_link(bd_addr);
335    } else {
336        bt_bdaddr_t bda;
337        bdcpy(bda.address, bd_addr);
338
339        btif_gatt_remove_encrypted_link(bd_addr);
340        btif_dm_remove_bond(&bda);
341    }
342}
343
344void btif_gatt_check_encrypted_link (BD_ADDR bd_addr)
345{
346    char buf[100];
347
348    bt_bdaddr_t bda;
349    bdcpy(bda.address, bd_addr);
350
351    if ((btif_storage_get_ble_bonding_key(&bda, BTIF_DM_LE_KEY_PENC,
352                    buf, sizeof(btif_dm_ble_penc_keys_t)) == BT_STATUS_SUCCESS)
353        && !btif_gatt_is_link_encrypted(bd_addr))
354    {
355        BTA_DmSetEncryption(bd_addr,
356                            &btif_gatt_set_encryption_cb, BTM_BLE_SEC_ENCRYPT);
357    }
358}
359
360#endif
361