1 /*
2  * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include "btc_gatt_util.h"
11 
12 #define GATTC_READ_VALUE_TYPE_VALUE          0x0000  /* Attribute value itself */
13 #define GATTC_READ_VALUE_TYPE_AGG_FORMAT     0x2905  /* Characteristic Aggregate Format*/
14 
15 static const unsigned char BASE_UUID[16] = {
16     0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
17     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
18 };
19 
20 /*******************************************************************************
21  * BTIF -> BTA conversion functions
22  *******************************************************************************/
uuidType(unsigned char * p_uuid)23 int uuidType(unsigned char *p_uuid)
24 {
25     int i = 0;
26     int match = 0;
27     int all_zero = 1;
28 
29     for (i = 0; i != 16; ++i) {
30         if (i == 12 || i == 13) {
31             continue;
32         }
33 
34         if (p_uuid[i] == BASE_UUID[i]) {
35             ++match;
36         }
37 
38         if (p_uuid[i] != 0) {
39             all_zero = 0;
40         }
41     }
42     if (all_zero) {
43         return 0;
44     }
45     if (match == 12) {
46         return LEN_UUID_32;
47     }
48     if (match == 14) {
49         return LEN_UUID_16;
50     }
51     return LEN_UUID_128;
52 }
53 
btc128_to_bta_uuid(tBT_UUID * p_dest,uint8_t * p_src)54 void btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src)
55 {
56     int i = 0;
57 
58     p_dest->len = uuidType(p_src);
59 
60     switch (p_dest->len) {
61     case LEN_UUID_16:
62         p_dest->uu.uuid16 = (p_src[13] << 8) + p_src[12];
63         break;
64 
65     case LEN_UUID_32:
66         p_dest->uu.uuid32  = (p_src[13] <<  8) + p_src[12];
67         p_dest->uu.uuid32 += (p_src[15] << 24) + (p_src[14] << 16);
68         break;
69 
70     case LEN_UUID_128:
71         for (i = 0; i != 16; ++i) {
72             p_dest->uu.uuid128[i] = p_src[i];
73         }
74         break;
75 
76     default:
77         BTC_TRACE_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_dest->len);
78         break;
79     }
80 }
81 
82 /*******************************************************************************
83  * BTC -> BTA conversion functions
84  *******************************************************************************/
btc_to_bta_gatt_id(tBTA_GATT_ID * p_dest,esp_gatt_id_t * p_src)85 void btc_to_bta_gatt_id(tBTA_GATT_ID *p_dest, esp_gatt_id_t *p_src)
86 {
87     p_dest->inst_id = p_src->inst_id;
88     btc_to_bta_uuid(&p_dest->uuid, &p_src->uuid);
89 }
90 
btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID * p_dest,esp_gatt_srvc_id_t * p_src)91 void btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID *p_dest, esp_gatt_srvc_id_t *p_src)
92 {
93     p_dest->is_primary = p_src->is_primary;
94     btc_to_bta_gatt_id(&p_dest->id, &p_src->id);
95 }
96 
97 
98 /*******************************************************************************
99  * BTA -> BTC conversion functions
100  *******************************************************************************/
bta_to_btc_gatt_id(esp_gatt_id_t * p_dest,tBTA_GATT_ID * p_src)101 void bta_to_btc_gatt_id(esp_gatt_id_t *p_dest, tBTA_GATT_ID *p_src)
102 {
103     p_dest->inst_id = p_src->inst_id;
104     bta_to_btc_uuid(&p_dest->uuid, &p_src->uuid);
105 }
106 
bta_to_btc_srvc_id(esp_gatt_srvc_id_t * p_dest,tBTA_GATT_SRVC_ID * p_src)107 void bta_to_btc_srvc_id(esp_gatt_srvc_id_t *p_dest, tBTA_GATT_SRVC_ID *p_src)
108 {
109     p_dest->is_primary = p_src->is_primary;
110     bta_to_btc_gatt_id(&p_dest->id, &p_src->id);
111 }
112 
btc_to_bta_response(tBTA_GATTS_RSP * p_dest,esp_gatt_rsp_t * p_src)113 void btc_to_bta_response(tBTA_GATTS_RSP *p_dest, esp_gatt_rsp_t *p_src)
114 {
115     p_dest->attr_value.auth_req = p_src->attr_value.auth_req;
116     p_dest->attr_value.handle   = p_src->attr_value.handle;
117     p_dest->attr_value.len      = p_src->attr_value.len;
118     p_dest->attr_value.offset   = p_src->attr_value.offset;
119     memcpy(p_dest->attr_value.value, p_src->attr_value.value, ESP_GATT_MAX_ATTR_LEN);
120 }
121 
get_uuid16(tBT_UUID * p_uuid)122 uint16_t get_uuid16(tBT_UUID *p_uuid)
123 {
124     if (p_uuid->len == LEN_UUID_16) {
125         return p_uuid->uu.uuid16;
126     } else if (p_uuid->len == LEN_UUID_128) {
127         UINT16 u16;
128         UINT8 *p = &p_uuid->uu.uuid128[LEN_UUID_128 - 4];
129         STREAM_TO_UINT16(u16, p);
130         return u16;
131     } else { /* p_uuid->len == LEN_UUID_32 */
132         return (UINT16) p_uuid->uu.uuid32;
133     }
134 }
135 
set_read_value(uint8_t * gattc_if,esp_ble_gattc_cb_param_t * p_dest,tBTA_GATTC_READ * p_src)136 uint16_t set_read_value(uint8_t *gattc_if, esp_ble_gattc_cb_param_t *p_dest, tBTA_GATTC_READ *p_src)
137 {
138     uint16_t len = 0;
139 
140     p_dest->read.status = p_src->status;
141     p_dest->read.conn_id = BTC_GATT_GET_CONN_ID(p_src->conn_id);
142     *gattc_if = BTC_GATT_GET_GATT_IF(p_src->conn_id);
143     p_dest->read.status = p_src->status;
144     p_dest->read.handle = p_src->handle;
145 
146     if (( p_src->status == BTA_GATT_OK ) && (p_src->p_value != NULL))
147     {
148         BTC_TRACE_DEBUG("%s len = %d ", __func__, p_src->p_value->len);
149         p_dest->read.value_len = p_src->p_value->len;
150         if ( p_src->p_value->len > 0  && p_src->p_value->p_value != NULL ) {
151             p_dest->read.value = p_src->p_value->p_value;
152         }
153         len += p_src->p_value->len;
154     } else {
155         p_dest->read.value_len = 0;
156     }
157 
158     return len;
159 }
160