blob: 73cffc5a5af2c4fe96cf1913ffe8501b0aa0ee9c [file] [log] [blame]
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001/******************************************************************************
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
Marie Janssen49a86702015-07-08 11:48:57 -070019#define LOG_TAG "bt_btif_gatt"
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080020
Marie Janssen49a86702015-07-08 11:48:57 -070021#include <errno.h>
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080022#include <stdio.h>
23#include <stdlib.h>
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080024#include <string.h>
25
Marie Janssendb554582015-06-26 14:53:46 -070026#include <hardware/bluetooth.h>
27#include <hardware/bt_gatt.h>
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080028
29#include "btif_common.h"
30#include "btif_util.h"
31
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080032#include "bta_gatt_api.h"
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080033#include "bte_appl.h"
Marie Janssendb554582015-06-26 14:53:46 -070034#include "btif_dm.h"
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080035#include "btif_gatt.h"
36#include "btif_gatt_util.h"
Marie Janssendb554582015-06-26 14:53:46 -070037#include "btif_storage.h"
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080038#include "gatt_api.h"
Sharvil Nanavati44802762014-12-23 23:08:58 -080039#include "osi/include/log.h"
Myles Watsond7ffd642016-10-27 10:27:36 -070040#include "osi/include/osi.h"
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080041
42/*******************************************************************************
43 * Typedefs & Macros
Myles Watsonee96a3c2016-11-23 14:49:54 -080044 ******************************************************************************/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080045
Myles Watson6bd442f2016-10-19 09:50:22 -070046typedef struct {
47 tGATT_IF gatt_if;
48 uint16_t conn_id;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080049} btif_test_cb_t;
50
51/*******************************************************************************
52 * Static variables
Myles Watsonee96a3c2016-11-23 14:49:54 -080053 ******************************************************************************/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080054
Myles Watson6bd442f2016-10-19 09:50:22 -070055static const char* disc_name[GATT_DISC_MAX] = {"Unknown",
56 "GATT_DISC_SRVC_ALL",
57 "GATT_DISC_SRVC_BY_UUID",
58 "GATT_DISC_INC_SRVC",
59 "GATT_DISC_CHAR",
60 "GATT_DISC_CHAR_DSCPT"};
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080061
62static btif_test_cb_t test_cb;
63
64/*******************************************************************************
65 * Callback functions
Myles Watsonee96a3c2016-11-23 14:49:54 -080066 ******************************************************************************/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080067
Myles Watson6bd442f2016-10-19 09:50:22 -070068static char* format_uuid(tBT_UUID bt_uuid, char* str_buf, size_t buf_size) {
69 if (bt_uuid.len == LEN_UUID_16) {
70 snprintf(str_buf, buf_size, "0x%04x", bt_uuid.uu.uuid16);
71 } else if (bt_uuid.len == LEN_UUID_128) {
72 int x = snprintf(str_buf, buf_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x",
73 bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14],
74 bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12],
75 bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
76 bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
77 snprintf(&str_buf[x], buf_size - x, "%02x%02x-%02x%02x%02x%02x%02x%02x",
78 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6],
79 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4],
80 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
81 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
82 } else {
83 snprintf(str_buf, buf_size, "Unknown (len=%d)", bt_uuid.len);
84 }
George Burgess IV80d7f602016-03-02 14:00:19 -080085
Myles Watson6bd442f2016-10-19 09:50:22 -070086 return str_buf;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080087}
88
Myles Watson90088882016-11-15 16:33:22 -080089static void btif_test_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
90 UNUSED_ATTR BD_ADDR bda, uint16_t conn_id,
91 bool connected,
Myles Watsond35a6482016-10-27 08:52:16 -070092 UNUSED_ATTR tGATT_DISCONN_REASON reason,
93 UNUSED_ATTR tBT_TRANSPORT transport) {
Myles Watson6bd442f2016-10-19 09:50:22 -070094 LOG_DEBUG(LOG_TAG, "%s: conn_id=%d, connected=%d", __func__, conn_id,
95 connected);
96 test_cb.conn_id = connected ? conn_id : 0;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -080097}
98
Marie Janssenb7f64bc2016-06-22 12:52:19 -070099static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op,
Myles Watson6bd442f2016-10-19 09:50:22 -0700100 tGATT_STATUS status,
101 tGATT_CL_COMPLETE* p_data) {
102 LOG_DEBUG(LOG_TAG, "%s: op_code=0x%02x, conn_id=0x%x. status=0x%x", __func__,
103 op, conn_id, status);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800104
Myles Watson6bd442f2016-10-19 09:50:22 -0700105 switch (op) {
106 case GATTC_OPTYPE_READ:
107 case GATTC_OPTYPE_WRITE:
108 case GATTC_OPTYPE_CONFIG:
109 case GATTC_OPTYPE_EXE_WRITE:
110 case GATTC_OPTYPE_NOTIFICATION:
111 break;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800112
Myles Watson6bd442f2016-10-19 09:50:22 -0700113 case GATTC_OPTYPE_INDICATION:
114 GATTC_SendHandleValueConfirm(conn_id, p_data->handle);
115 break;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800116
Myles Watson6bd442f2016-10-19 09:50:22 -0700117 default:
118 LOG_DEBUG(LOG_TAG, "%s: Unknown op_code (0x%02x)", __func__, op);
119 break;
120 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800121}
122
Myles Watsond35a6482016-10-27 08:52:16 -0700123static void btif_test_discovery_result_cback(UNUSED_ATTR uint16_t conn_id,
Myles Watson6bd442f2016-10-19 09:50:22 -0700124 tGATT_DISC_TYPE disc_type,
125 tGATT_DISC_RES* p_data) {
126 char str_buf[50];
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800127
Myles Watson6bd442f2016-10-19 09:50:22 -0700128 LOG_DEBUG(LOG_TAG, "------ GATT Discovery result %-22s -------",
129 disc_name[disc_type]);
130 LOG_DEBUG(LOG_TAG, " Attribute handle: 0x%04x (%d)", p_data->handle,
131 p_data->handle);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800132
Myles Watson6bd442f2016-10-19 09:50:22 -0700133 if (disc_type != GATT_DISC_CHAR_DSCPT) {
134 LOG_DEBUG(LOG_TAG, " Attribute type: %s",
135 format_uuid(p_data->type, str_buf, sizeof(str_buf)));
136 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800137
Myles Watson6bd442f2016-10-19 09:50:22 -0700138 switch (disc_type) {
139 case GATT_DISC_SRVC_ALL:
140 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
141 p_data->handle, p_data->value.group_value.e_handle,
142 p_data->handle, p_data->value.group_value.e_handle);
143 LOG_DEBUG(LOG_TAG, " Service UUID: %s",
144 format_uuid(p_data->value.group_value.service_type, str_buf,
145 sizeof(str_buf)));
146 break;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800147
Myles Watson6bd442f2016-10-19 09:50:22 -0700148 case GATT_DISC_SRVC_BY_UUID:
149 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
150 p_data->handle, p_data->value.handle, p_data->handle,
151 p_data->value.handle);
152 break;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800153
Myles Watson6bd442f2016-10-19 09:50:22 -0700154 case GATT_DISC_INC_SRVC:
155 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
156 p_data->value.incl_service.s_handle,
157 p_data->value.incl_service.e_handle,
158 p_data->value.incl_service.s_handle,
159 p_data->value.incl_service.e_handle);
160 LOG_DEBUG(LOG_TAG, " Service UUID: %s",
161 format_uuid(p_data->value.incl_service.service_type, str_buf,
162 sizeof(str_buf)));
163 break;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800164
Myles Watson6bd442f2016-10-19 09:50:22 -0700165 case GATT_DISC_CHAR:
166 LOG_DEBUG(LOG_TAG, " Properties: 0x%02x",
167 p_data->value.dclr_value.char_prop);
168 LOG_DEBUG(LOG_TAG, " Characteristic UUID: %s",
169 format_uuid(p_data->value.dclr_value.char_uuid, str_buf,
170 sizeof(str_buf)));
171 break;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800172
Myles Watson6bd442f2016-10-19 09:50:22 -0700173 case GATT_DISC_CHAR_DSCPT:
174 LOG_DEBUG(LOG_TAG, " Descriptor UUID: %s",
175 format_uuid(p_data->type, str_buf, sizeof(str_buf)));
176 break;
177 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800178
Myles Watson6bd442f2016-10-19 09:50:22 -0700179 LOG_DEBUG(LOG_TAG,
180 "-----------------------------------------------------------");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800181}
182
Myles Watson90088882016-11-15 16:33:22 -0800183static void btif_test_discovery_complete_cback(
184 UNUSED_ATTR uint16_t conn_id, UNUSED_ATTR tGATT_DISC_TYPE disc_type,
185 tGATT_STATUS status) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700186 LOG_DEBUG(LOG_TAG, "%s: status=%d", __func__, status);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800187}
188
Myles Watson6bd442f2016-10-19 09:50:22 -0700189static tGATT_CBACK btif_test_callbacks = {btif_test_connect_cback,
190 btif_test_command_complete_cback,
191 btif_test_discovery_result_cback,
192 btif_test_discovery_complete_cback,
193 NULL,
194 NULL,
Jakub Pawlowskieafd45d2017-03-22 19:00:47 -0700195 NULL,
Jakub Pawlowskib5ba4fd2017-03-23 18:11:04 -0700196 NULL,
Myles Watson6bd442f2016-10-19 09:50:22 -0700197 NULL};
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800198
199/*******************************************************************************
200 * Implementation
Myles Watsonee96a3c2016-11-23 14:49:54 -0800201 ******************************************************************************/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800202
Myles Watson6bd442f2016-10-19 09:50:22 -0700203bt_status_t btif_gattc_test_command_impl(int command,
204 btgatt_test_params_t* params) {
205 switch (command) {
206 case 0x01: /* Enable */
207 {
208 LOG_DEBUG(LOG_TAG, "%s: ENABLE - enable=%d", __func__, params->u1);
209 if (params->u1) {
210 tBT_UUID app_uuid = {LEN_UUID_128, {0xAE}};
211 test_cb.gatt_if = GATT_Register(&app_uuid, &btif_test_callbacks);
212 GATT_StartIf(test_cb.gatt_if);
213 } else {
214 GATT_Deregister(test_cb.gatt_if);
215 test_cb.gatt_if = 0;
216 }
217 break;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800218 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700219
220 case 0x02: /* Connect */
221 {
222 LOG_DEBUG(LOG_TAG,
223 "%s: CONNECT - device=%02x:%02x:%02x:%02x:%02x:%02x "
224 "(dev_type=%d, addr_type=%d)",
225 __func__, params->bda1->address[0], params->bda1->address[1],
226 params->bda1->address[2], params->bda1->address[3],
227 params->bda1->address[4], params->bda1->address[5], params->u1,
228 params->u2);
229
230 if (params->u1 == BT_DEVICE_TYPE_BLE)
231 BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE,
232 params->u2);
233
234 if (!GATT_Connect(test_cb.gatt_if, params->bda1->address, true,
235 BT_TRANSPORT_LE, false)) {
236 LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __func__);
237 }
238 break;
239 }
240
241 case 0x03: /* Disconnect */
242 {
243 LOG_DEBUG(LOG_TAG, "%s: DISCONNECT - conn_id=%d", __func__,
244 test_cb.conn_id);
245 GATT_Disconnect(test_cb.conn_id);
246 break;
247 }
248
249 case 0x04: /* Discover */
250 {
251 char buf[50] = {0};
252 tGATT_DISC_PARAM param;
253 memset(&param, 0, sizeof(tGATT_DISC_PARAM));
254
255 if (params->u1 >= GATT_DISC_MAX) {
256 LOG_ERROR(LOG_TAG, "%s: DISCOVER - Invalid type (%d)!", __func__,
257 params->u1);
258 return (bt_status_t)0;
259 }
260
261 param.s_handle = params->u2;
262 param.e_handle = params->u3;
263 btif_to_bta_uuid(&param.service, params->uuid1);
264
265 LOG_DEBUG(LOG_TAG,
266 "%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x",
267 __func__, disc_name[params->u1], test_cb.conn_id,
268 format_uuid(param.service, buf, sizeof(buf)), params->u2,
269 params->u3);
270 GATTC_Discover(test_cb.conn_id, params->u1, &param);
271 break;
272 }
273
274 case 0xF0: /* Pairing configuration */
275 LOG_DEBUG(LOG_TAG,
276 "%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d",
277 __func__, params->u1, params->u2, params->u3, params->u4,
278 params->u5);
279
280 bte_appl_cfg.ble_auth_req = params->u1;
281 bte_appl_cfg.ble_io_cap = params->u2;
282 bte_appl_cfg.ble_init_key = params->u3;
283 bte_appl_cfg.ble_resp_key = params->u4;
284 bte_appl_cfg.ble_max_key_size = params->u5;
285 break;
286
287 default:
288 LOG_ERROR(LOG_TAG, "%s: UNKNOWN TEST COMMAND 0x%02x", __func__, command);
289 break;
290 }
291 return (bt_status_t)0;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800292}