btif_gatt_test.cc revision 6bd442f543972b072ef2cbbcf2f7c91202de1045
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#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#if (BLE_INCLUDED == TRUE) 33 34#include "bta_gatt_api.h" 35#include "bte_appl.h" 36#include "btif_dm.h" 37#include "btif_gatt.h" 38#include "btif_gatt_util.h" 39#include "btif_storage.h" 40#include "gatt_api.h" 41#include "osi/include/log.h" 42 43/******************************************************************************* 44 * Typedefs & Macros 45 *******************************************************************************/ 46 47typedef struct { 48 tGATT_IF gatt_if; 49 uint16_t conn_id; 50} btif_test_cb_t; 51 52/******************************************************************************* 53 * Static variables 54 *******************************************************************************/ 55 56static 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 63static btif_test_cb_t test_cb; 64 65/******************************************************************************* 66 * Callback functions 67 *******************************************************************************/ 68 69static char* format_uuid(tBT_UUID bt_uuid, char* str_buf, size_t buf_size) { 70 if (bt_uuid.len == LEN_UUID_16) { 71 snprintf(str_buf, buf_size, "0x%04x", bt_uuid.uu.uuid16); 72 } else if (bt_uuid.len == LEN_UUID_128) { 73 int x = snprintf(str_buf, buf_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x", 74 bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14], 75 bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12], 76 bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10], 77 bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]); 78 snprintf(&str_buf[x], buf_size - x, "%02x%02x-%02x%02x%02x%02x%02x%02x", 79 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6], 80 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4], 81 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2], 82 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]); 83 } else { 84 snprintf(str_buf, buf_size, "Unknown (len=%d)", bt_uuid.len); 85 } 86 87 return str_buf; 88} 89 90static void btif_test_connect_cback(tGATT_IF gatt_if, BD_ADDR bda, 91 uint16_t conn_id, bool connected, 92 tGATT_DISCONN_REASON reason, 93 tBT_TRANSPORT transport) { 94 UNUSED(gatt_if); 95 UNUSED(bda); 96 UNUSED(reason); 97 UNUSED(transport); 98 99 LOG_DEBUG(LOG_TAG, "%s: conn_id=%d, connected=%d", __func__, conn_id, 100 connected); 101 test_cb.conn_id = connected ? conn_id : 0; 102} 103 104static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op, 105 tGATT_STATUS status, 106 tGATT_CL_COMPLETE* p_data) { 107 LOG_DEBUG(LOG_TAG, "%s: op_code=0x%02x, conn_id=0x%x. status=0x%x", __func__, 108 op, conn_id, status); 109 110 switch (op) { 111 case GATTC_OPTYPE_READ: 112 case GATTC_OPTYPE_WRITE: 113 case GATTC_OPTYPE_CONFIG: 114 case GATTC_OPTYPE_EXE_WRITE: 115 case GATTC_OPTYPE_NOTIFICATION: 116 break; 117 118 case GATTC_OPTYPE_INDICATION: 119 GATTC_SendHandleValueConfirm(conn_id, p_data->handle); 120 break; 121 122 default: 123 LOG_DEBUG(LOG_TAG, "%s: Unknown op_code (0x%02x)", __func__, op); 124 break; 125 } 126} 127 128static void btif_test_discovery_result_cback(uint16_t conn_id, 129 tGATT_DISC_TYPE disc_type, 130 tGATT_DISC_RES* p_data) { 131 char str_buf[50]; 132 UNUSED(conn_id); 133 134 LOG_DEBUG(LOG_TAG, "------ GATT Discovery result %-22s -------", 135 disc_name[disc_type]); 136 LOG_DEBUG(LOG_TAG, " Attribute handle: 0x%04x (%d)", p_data->handle, 137 p_data->handle); 138 139 if (disc_type != GATT_DISC_CHAR_DSCPT) { 140 LOG_DEBUG(LOG_TAG, " Attribute type: %s", 141 format_uuid(p_data->type, str_buf, sizeof(str_buf))); 142 } 143 144 switch (disc_type) { 145 case GATT_DISC_SRVC_ALL: 146 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)", 147 p_data->handle, p_data->value.group_value.e_handle, 148 p_data->handle, p_data->value.group_value.e_handle); 149 LOG_DEBUG(LOG_TAG, " Service UUID: %s", 150 format_uuid(p_data->value.group_value.service_type, str_buf, 151 sizeof(str_buf))); 152 break; 153 154 case GATT_DISC_SRVC_BY_UUID: 155 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)", 156 p_data->handle, p_data->value.handle, p_data->handle, 157 p_data->value.handle); 158 break; 159 160 case GATT_DISC_INC_SRVC: 161 LOG_DEBUG(LOG_TAG, " Handle range: 0x%04x ~ 0x%04x (%d ~ %d)", 162 p_data->value.incl_service.s_handle, 163 p_data->value.incl_service.e_handle, 164 p_data->value.incl_service.s_handle, 165 p_data->value.incl_service.e_handle); 166 LOG_DEBUG(LOG_TAG, " Service UUID: %s", 167 format_uuid(p_data->value.incl_service.service_type, str_buf, 168 sizeof(str_buf))); 169 break; 170 171 case GATT_DISC_CHAR: 172 LOG_DEBUG(LOG_TAG, " Properties: 0x%02x", 173 p_data->value.dclr_value.char_prop); 174 LOG_DEBUG(LOG_TAG, " Characteristic UUID: %s", 175 format_uuid(p_data->value.dclr_value.char_uuid, str_buf, 176 sizeof(str_buf))); 177 break; 178 179 case GATT_DISC_CHAR_DSCPT: 180 LOG_DEBUG(LOG_TAG, " Descriptor UUID: %s", 181 format_uuid(p_data->type, str_buf, sizeof(str_buf))); 182 break; 183 } 184 185 LOG_DEBUG(LOG_TAG, 186 "-----------------------------------------------------------"); 187} 188 189static void btif_test_discovery_complete_cback(uint16_t conn_id, 190 tGATT_DISC_TYPE disc_type, 191 tGATT_STATUS status) { 192 UNUSED(conn_id); 193 UNUSED(disc_type); 194 LOG_DEBUG(LOG_TAG, "%s: status=%d", __func__, status); 195} 196 197static tGATT_CBACK btif_test_callbacks = {btif_test_connect_cback, 198 btif_test_command_complete_cback, 199 btif_test_discovery_result_cback, 200 btif_test_discovery_complete_cback, 201 NULL, 202 NULL, 203 NULL}; 204 205/******************************************************************************* 206 * Implementation 207 *******************************************************************************/ 208 209bt_status_t btif_gattc_test_command_impl(int command, 210 btgatt_test_params_t* params) { 211 switch (command) { 212 case 0x01: /* Enable */ 213 { 214 LOG_DEBUG(LOG_TAG, "%s: ENABLE - enable=%d", __func__, params->u1); 215 if (params->u1) { 216 tBT_UUID app_uuid = {LEN_UUID_128, {0xAE}}; 217 test_cb.gatt_if = GATT_Register(&app_uuid, &btif_test_callbacks); 218 GATT_StartIf(test_cb.gatt_if); 219 } else { 220 GATT_Deregister(test_cb.gatt_if); 221 test_cb.gatt_if = 0; 222 } 223 break; 224 } 225 226 case 0x02: /* Connect */ 227 { 228 LOG_DEBUG(LOG_TAG, 229 "%s: CONNECT - device=%02x:%02x:%02x:%02x:%02x:%02x " 230 "(dev_type=%d, addr_type=%d)", 231 __func__, params->bda1->address[0], params->bda1->address[1], 232 params->bda1->address[2], params->bda1->address[3], 233 params->bda1->address[4], params->bda1->address[5], params->u1, 234 params->u2); 235 236 if (params->u1 == BT_DEVICE_TYPE_BLE) 237 BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE, 238 params->u2); 239 240 if (!GATT_Connect(test_cb.gatt_if, params->bda1->address, true, 241 BT_TRANSPORT_LE, false)) { 242 LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __func__); 243 } 244 break; 245 } 246 247 case 0x03: /* Disconnect */ 248 { 249 LOG_DEBUG(LOG_TAG, "%s: DISCONNECT - conn_id=%d", __func__, 250 test_cb.conn_id); 251 GATT_Disconnect(test_cb.conn_id); 252 break; 253 } 254 255 case 0x04: /* Discover */ 256 { 257 char buf[50] = {0}; 258 tGATT_DISC_PARAM param; 259 memset(¶m, 0, sizeof(tGATT_DISC_PARAM)); 260 261 if (params->u1 >= GATT_DISC_MAX) { 262 LOG_ERROR(LOG_TAG, "%s: DISCOVER - Invalid type (%d)!", __func__, 263 params->u1); 264 return (bt_status_t)0; 265 } 266 267 param.s_handle = params->u2; 268 param.e_handle = params->u3; 269 btif_to_bta_uuid(¶m.service, params->uuid1); 270 271 LOG_DEBUG(LOG_TAG, 272 "%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x", 273 __func__, disc_name[params->u1], test_cb.conn_id, 274 format_uuid(param.service, buf, sizeof(buf)), params->u2, 275 params->u3); 276 GATTC_Discover(test_cb.conn_id, params->u1, ¶m); 277 break; 278 } 279 280 case 0xF0: /* Pairing configuration */ 281 LOG_DEBUG(LOG_TAG, 282 "%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d", 283 __func__, params->u1, params->u2, params->u3, params->u4, 284 params->u5); 285 286 bte_appl_cfg.ble_auth_req = params->u1; 287 bte_appl_cfg.ble_io_cap = params->u2; 288 bte_appl_cfg.ble_init_key = params->u3; 289 bte_appl_cfg.ble_resp_key = params->u4; 290 bte_appl_cfg.ble_max_key_size = params->u5; 291 break; 292 293 default: 294 LOG_ERROR(LOG_TAG, "%s: UNKNOWN TEST COMMAND 0x%02x", __func__, command); 295 break; 296 } 297 return (bt_status_t)0; 298} 299 300#endif 301