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