1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include "btc_gatt_util.h"
19 
20 #define GATTC_READ_VALUE_TYPE_VALUE          0x0000  /* Attribute value itself */
21 #define GATTC_READ_VALUE_TYPE_AGG_FORMAT     0x2905  /* Characteristic Aggregate Format*/
22 
23 static const unsigned char BASE_UUID[16] = {
24     0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
25     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
26 };
27 
28 /*******************************************************************************
29  * BTIF -> BTA conversion functions
30  *******************************************************************************/
uuidType(unsigned char * p_uuid)31 int uuidType(unsigned char *p_uuid)
32 {
33     int i = 0;
34     int match = 0;
35     int all_zero = 1;
36 
37     for (i = 0; i != 16; ++i) {
38         if (i == 12 || i == 13) {
39             continue;
40         }
41 
42         if (p_uuid[i] == BASE_UUID[i]) {
43             ++match;
44         }
45 
46         if (p_uuid[i] != 0) {
47             all_zero = 0;
48         }
49     }
50     if (all_zero) {
51         return 0;
52     }
53     if (match == 12) {
54         return LEN_UUID_32;
55     }
56     if (match == 14) {
57         return LEN_UUID_16;
58     }
59     return LEN_UUID_128;
60 }
61 
btc128_to_bta_uuid(tBT_UUID * p_dest,uint8_t * p_src)62 void btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src)
63 {
64     int i = 0;
65 
66     p_dest->len = uuidType(p_src);
67 
68     switch (p_dest->len) {
69     case LEN_UUID_16:
70         p_dest->uu.uuid16 = (p_src[13] << 8) + p_src[12];
71         break;
72 
73     case LEN_UUID_32:
74         p_dest->uu.uuid32  = (p_src[13] <<  8) + p_src[12];
75         p_dest->uu.uuid32 += (p_src[15] << 24) + (p_src[14] << 16);
76         break;
77 
78     case LEN_UUID_128:
79         for (i = 0; i != 16; ++i) {
80             p_dest->uu.uuid128[i] = p_src[i];
81         }
82         break;
83 
84     default:
85         BTC_TRACE_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_dest->len);
86         break;
87     }
88 }
89 
90 /*******************************************************************************
91  * BTC -> BTA conversion functions
92  *******************************************************************************/
93 
btc_to_bta_uuid(tBT_UUID * p_dest,esp_bt_uuid_t * p_src)94 void btc_to_bta_uuid(tBT_UUID *p_dest, esp_bt_uuid_t *p_src)
95 {
96     p_dest->len = p_src->len;
97     if (p_src->len == LEN_UUID_16) {
98         p_dest->uu.uuid16 = p_src->uuid.uuid16;
99     } else if (p_src->len == LEN_UUID_32) {
100         p_dest->uu.uuid32 = p_src->uuid.uuid32;
101     } else if (p_src->len == LEN_UUID_128) {
102         memcpy(&p_dest->uu.uuid128, p_src->uuid.uuid128, p_dest->len);
103     } else if (p_src->len == 0) {
104         /* do nothing for now, there's some scenario will input 0 */
105     } else {
106         BTC_TRACE_ERROR("%s UUID len is invalid %d\n", __func__, p_src->len);
107     }
108 }
109 
btc_to_bta_gatt_id(tBTA_GATT_ID * p_dest,esp_gatt_id_t * p_src)110 void btc_to_bta_gatt_id(tBTA_GATT_ID *p_dest, esp_gatt_id_t *p_src)
111 {
112     p_dest->inst_id = p_src->inst_id;
113     btc_to_bta_uuid(&p_dest->uuid, &p_src->uuid);
114 }
115 
btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID * p_dest,esp_gatt_srvc_id_t * p_src)116 void btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID *p_dest, esp_gatt_srvc_id_t *p_src)
117 {
118     p_dest->is_primary = p_src->is_primary;
119     btc_to_bta_gatt_id(&p_dest->id, &p_src->id);
120 }
121 
122 
123 /*******************************************************************************
124  * BTA -> BTC conversion functions
125  *******************************************************************************/
bta_to_btc_uuid(esp_bt_uuid_t * p_dest,tBT_UUID * p_src)126 void bta_to_btc_uuid(esp_bt_uuid_t *p_dest, tBT_UUID *p_src)
127 {
128     p_dest->len = p_src->len;
129     if (p_src->len == LEN_UUID_16) {
130         p_dest->uuid.uuid16 = p_src->uu.uuid16;
131     } else if (p_src->len == LEN_UUID_32) {
132         p_dest->uuid.uuid32 = p_src->uu.uuid32;
133     } else if (p_src->len == LEN_UUID_128) {
134         memcpy(&p_dest->uuid.uuid128, p_src->uu.uuid128, p_dest->len);
135     } else if (p_src->len == 0) {
136         /* do nothing for now, there's some scenario will input 0
137            such as, receive notify, the descriptor may be 0 */
138     } else {
139         BTC_TRACE_ERROR("%s UUID len is invalid %d\n", __func__, p_src->len);
140     }
141 }
142 
bta_to_btc_gatt_id(esp_gatt_id_t * p_dest,tBTA_GATT_ID * p_src)143 void bta_to_btc_gatt_id(esp_gatt_id_t *p_dest, tBTA_GATT_ID *p_src)
144 {
145     p_dest->inst_id = p_src->inst_id;
146     bta_to_btc_uuid(&p_dest->uuid, &p_src->uuid);
147 }
148 
bta_to_btc_srvc_id(esp_gatt_srvc_id_t * p_dest,tBTA_GATT_SRVC_ID * p_src)149 void bta_to_btc_srvc_id(esp_gatt_srvc_id_t *p_dest, tBTA_GATT_SRVC_ID *p_src)
150 {
151     p_dest->is_primary = p_src->is_primary;
152     bta_to_btc_gatt_id(&p_dest->id, &p_src->id);
153 }
154 
btc_to_bta_response(tBTA_GATTS_RSP * p_dest,esp_gatt_rsp_t * p_src)155 void btc_to_bta_response(tBTA_GATTS_RSP *p_dest, esp_gatt_rsp_t *p_src)
156 {
157     p_dest->attr_value.auth_req = p_src->attr_value.auth_req;
158     p_dest->attr_value.handle   = p_src->attr_value.handle;
159     p_dest->attr_value.len      = p_src->attr_value.len;
160     p_dest->attr_value.offset   = p_src->attr_value.offset;
161     memcpy(p_dest->attr_value.value, p_src->attr_value.value, ESP_GATT_MAX_ATTR_LEN);
162 }
163 
get_uuid16(tBT_UUID * p_uuid)164 uint16_t get_uuid16(tBT_UUID *p_uuid)
165 {
166     if (p_uuid->len == LEN_UUID_16) {
167         return p_uuid->uu.uuid16;
168     } else if (p_uuid->len == LEN_UUID_128) {
169         UINT16 u16;
170         UINT8 *p = &p_uuid->uu.uuid128[LEN_UUID_128 - 4];
171         STREAM_TO_UINT16(u16, p);
172         return u16;
173     } else { /* p_uuid->len == LEN_UUID_32 */
174         return (UINT16) p_uuid->uu.uuid32;
175     }
176 }
177 
set_read_value(uint8_t * gattc_if,esp_ble_gattc_cb_param_t * p_dest,tBTA_GATTC_READ * p_src)178 uint16_t set_read_value(uint8_t *gattc_if, esp_ble_gattc_cb_param_t *p_dest, tBTA_GATTC_READ *p_src)
179 {
180     uint16_t len = 0;
181 
182     p_dest->read.status = p_src->status;
183     p_dest->read.conn_id = BTC_GATT_GET_CONN_ID(p_src->conn_id);
184     *gattc_if = BTC_GATT_GET_GATT_IF(p_src->conn_id);
185     p_dest->read.status = p_src->status;
186     p_dest->read.handle = p_src->handle;
187 
188     if (( p_src->status == BTA_GATT_OK ) && (p_src->p_value != NULL))
189     {
190         BTC_TRACE_DEBUG("%s len = %d ", __func__, p_src->p_value->len);
191         p_dest->read.value_len = p_src->p_value->len;
192         if ( p_src->p_value->len > 0  && p_src->p_value->p_value != NULL ) {
193             p_dest->read.value = p_src->p_value->p_value;
194         }
195         len += p_src->p_value->len;
196     } else {
197         p_dest->read.value_len = 0;
198     }
199 
200     return len;
201 }
202