1 /******************************************************************************
2 *
3 * Copyright 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 #define LOG_TAG "bt_btif_gatt"
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <hardware/bluetooth.h>
27 #include <hardware/bt_gatt.h>
28
29 #include "btif_common.h"
30 #include "btif_util.h"
31
32 #include "bta_gatt_api.h"
33 #include "bte_appl.h"
34 #include "btif_dm.h"
35 #include "btif_gatt.h"
36 #include "btif_gatt_util.h"
37 #include "btif_storage.h"
38 #include "gatt_api.h"
39 #include "osi/include/log.h"
40 #include "osi/include/osi.h"
41
42 using bluetooth::Uuid;
43 /*******************************************************************************
44 * Typedefs & Macros
45 ******************************************************************************/
46
47 typedef struct {
48 tGATT_IF gatt_if;
49 uint16_t conn_id;
50 } btif_test_cb_t;
51
52 /*******************************************************************************
53 * Static variables
54 ******************************************************************************/
55
56 static const char* disc_name[GATT_DISC_MAX] = {"Unknown",
57 "GATT_DISC_SRVC_ALL",
58 "GATT_DISC_SRVC_BY_UUID",
59 "GATT_DISC_INC_SRVC",
60 "GATT_DISC_CHAR",
61 "GATT_DISC_CHAR_DSCPT"};
62
63 static btif_test_cb_t test_cb;
64
65 /*******************************************************************************
66 * Callback functions
67 ******************************************************************************/
68
btif_test_connect_cback(tGATT_IF,const RawAddress &,uint16_t conn_id,bool connected,tGATT_DISCONN_REASON,tBT_TRANSPORT)69 static void btif_test_connect_cback(tGATT_IF, const RawAddress&,
70 uint16_t conn_id, bool connected,
71 tGATT_DISCONN_REASON, tBT_TRANSPORT) {
72 LOG_DEBUG(LOG_TAG, "%s: conn_id=%d, connected=%d", __func__, conn_id,
73 connected);
74 test_cb.conn_id = connected ? conn_id : 0;
75 }
76
btif_test_command_complete_cback(uint16_t conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)77 static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op,
78 tGATT_STATUS status,
79 tGATT_CL_COMPLETE* p_data) {
80 LOG_DEBUG(LOG_TAG, "%s: op_code=0x%02x, conn_id=0x%x. status=0x%x", __func__,
81 op, conn_id, status);
82
83 switch (op) {
84 case GATTC_OPTYPE_READ:
85 case GATTC_OPTYPE_WRITE:
86 case GATTC_OPTYPE_CONFIG:
87 case GATTC_OPTYPE_EXE_WRITE:
88 case GATTC_OPTYPE_NOTIFICATION:
89 break;
90
91 case GATTC_OPTYPE_INDICATION:
92 GATTC_SendHandleValueConfirm(conn_id, p_data->handle);
93 break;
94
95 default:
96 LOG_DEBUG(LOG_TAG, "%s: Unknown op_code (0x%02x)", __func__, op);
97 break;
98 }
99 }
100
btif_test_discovery_result_cback(UNUSED_ATTR uint16_t conn_id,tGATT_DISC_TYPE disc_type,tGATT_DISC_RES * p_data)101 static void btif_test_discovery_result_cback(UNUSED_ATTR uint16_t conn_id,
102 tGATT_DISC_TYPE disc_type,
103 tGATT_DISC_RES* p_data) {
104 LOG_DEBUG(LOG_TAG, "------ GATT Discovery result %-22s -------",
105 disc_name[disc_type]);
106 LOG_DEBUG(LOG_TAG, " Attribute handle: 0x%04x (%d)", p_data->handle,
107 p_data->handle);
108
109 if (disc_type != GATT_DISC_CHAR_DSCPT) {
110 LOG_DEBUG(LOG_TAG, " Attribute type: %s",
111 p_data->type.ToString().c_str());
112 }
113
114 switch (disc_type) {
115 case GATT_DISC_SRVC_ALL:
116 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
117 p_data->handle, p_data->value.group_value.e_handle,
118 p_data->handle, p_data->value.group_value.e_handle);
119 LOG_DEBUG(LOG_TAG, " Service UUID: %s",
120 p_data->value.group_value.service_type.ToString().c_str());
121 break;
122
123 case GATT_DISC_SRVC_BY_UUID:
124 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
125 p_data->handle, p_data->value.handle, p_data->handle,
126 p_data->value.handle);
127 break;
128
129 case GATT_DISC_INC_SRVC:
130 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
131 p_data->value.incl_service.s_handle,
132 p_data->value.incl_service.e_handle,
133 p_data->value.incl_service.s_handle,
134 p_data->value.incl_service.e_handle);
135 LOG_DEBUG(LOG_TAG, " Service UUID: %s",
136 p_data->value.incl_service.service_type.ToString().c_str());
137 break;
138
139 case GATT_DISC_CHAR:
140 LOG_DEBUG(LOG_TAG, " Properties: 0x%02x",
141 p_data->value.dclr_value.char_prop);
142 LOG_DEBUG(LOG_TAG, " Characteristic UUID: %s",
143 p_data->value.dclr_value.char_uuid.ToString().c_str());
144 break;
145
146 case GATT_DISC_CHAR_DSCPT:
147 LOG_DEBUG(LOG_TAG, " Descriptor UUID: %s",
148 p_data->type.ToString().c_str());
149 break;
150 }
151
152 LOG_DEBUG(LOG_TAG,
153 "-----------------------------------------------------------");
154 }
155
btif_test_discovery_complete_cback(UNUSED_ATTR uint16_t conn_id,UNUSED_ATTR tGATT_DISC_TYPE disc_type,tGATT_STATUS status)156 static void btif_test_discovery_complete_cback(
157 UNUSED_ATTR uint16_t conn_id, UNUSED_ATTR tGATT_DISC_TYPE disc_type,
158 tGATT_STATUS status) {
159 LOG_DEBUG(LOG_TAG, "%s: status=%d", __func__, status);
160 }
161
162 static tGATT_CBACK btif_test_callbacks = {btif_test_connect_cback,
163 btif_test_command_complete_cback,
164 btif_test_discovery_result_cback,
165 btif_test_discovery_complete_cback,
166 NULL,
167 NULL,
168 NULL,
169 NULL,
170 NULL};
171
172 /*******************************************************************************
173 * Implementation
174 ******************************************************************************/
175
btif_gattc_test_command_impl(int command,const btgatt_test_params_t * params)176 bt_status_t btif_gattc_test_command_impl(int command,
177 const btgatt_test_params_t* params) {
178 switch (command) {
179 case 0x01: /* Enable */
180 {
181 LOG_DEBUG(LOG_TAG, "%s: ENABLE - enable=%d", __func__, params->u1);
182 if (params->u1) {
183 std::array<uint8_t, Uuid::kNumBytes128> tmp;
184 tmp.fill(0xAE);
185 test_cb.gatt_if = GATT_Register(bluetooth::Uuid::From128BitBE(tmp),
186 &btif_test_callbacks);
187 GATT_StartIf(test_cb.gatt_if);
188 } else {
189 GATT_Deregister(test_cb.gatt_if);
190 test_cb.gatt_if = 0;
191 }
192 break;
193 }
194
195 case 0x02: /* Connect */
196 {
197 LOG_DEBUG(LOG_TAG, "%s: CONNECT - device=%s (dev_type=%d, addr_type=%d)",
198 __func__, params->bda1->ToString().c_str(), params->u1,
199 params->u2);
200
201 if (params->u1 == BT_DEVICE_TYPE_BLE)
202 BTM_SecAddBleDevice(*params->bda1, NULL, BT_DEVICE_TYPE_BLE,
203 params->u2);
204
205 if (!GATT_Connect(test_cb.gatt_if, *params->bda1, true, BT_TRANSPORT_LE,
206 false)) {
207 LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __func__);
208 }
209 break;
210 }
211
212 case 0x03: /* Disconnect */
213 {
214 LOG_DEBUG(LOG_TAG, "%s: DISCONNECT - conn_id=%d", __func__,
215 test_cb.conn_id);
216 GATT_Disconnect(test_cb.conn_id);
217 break;
218 }
219
220 case 0x04: /* Discover */
221 {
222 if (params->u1 >= GATT_DISC_MAX) {
223 LOG_ERROR(LOG_TAG, "%s: DISCOVER - Invalid type (%d)!", __func__,
224 params->u1);
225 return (bt_status_t)0;
226 }
227
228 LOG_DEBUG(LOG_TAG,
229 "%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x",
230 __func__, disc_name[params->u1], test_cb.conn_id,
231 params->uuid1->ToString().c_str(), params->u2, params->u3);
232 GATTC_Discover(test_cb.conn_id, params->u1, params->u2, params->u3,
233 *params->uuid1);
234 break;
235 }
236
237 case 0xF0: /* Pairing configuration */
238 LOG_DEBUG(LOG_TAG,
239 "%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d",
240 __func__, params->u1, params->u2, params->u3, params->u4,
241 params->u5);
242
243 bte_appl_cfg.ble_auth_req = params->u1;
244 bte_appl_cfg.ble_io_cap = params->u2;
245 bte_appl_cfg.ble_init_key = params->u3;
246 bte_appl_cfg.ble_resp_key = params->u4;
247 bte_appl_cfg.ble_max_key_size = params->u5;
248 break;
249
250 default:
251 LOG_ERROR(LOG_TAG, "%s: UNKNOWN TEST COMMAND 0x%02x", __func__, command);
252 break;
253 }
254 return (bt_status_t)0;
255 }
256