1 /****************************************************************************** 2 * 3 * Copyright (C) 2014 Google, Inc. 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 #include "support/adapter.h" 20 #include "base.h" 21 #include "btcore/include/bdaddr.h" 22 #include "btcore/include/property.h" 23 #include "support/callbacks.h" 24 25 static bt_state_t state; 26 static int property_count = 0; 27 static bt_property_t* properties = NULL; 28 static bt_discovery_state_t discovery_state; 29 static bt_acl_state_t acl_state; 30 static bt_bond_state_t bond_state; 31 32 static void parse_properties(int num_properties, bt_property_t* property); 33 34 // Returns the current adapter state. 35 bt_state_t adapter_get_state() { return state; } 36 37 // Returns the number of adapter properties. 38 int adapter_get_property_count() { return property_count; } 39 40 // Returns the specified property. 41 bt_property_t* adapter_get_property(bt_property_type_t type) { 42 for (int i = 0; i < property_count; ++i) { 43 if (properties[i].type == type) { 44 return &properties[i]; 45 } 46 } 47 48 return NULL; 49 } 50 51 // Returns the device discovery state. 52 bt_discovery_state_t adapter_get_discovery_state() { return discovery_state; } 53 54 // Returns the device acl state. 55 bt_acl_state_t adapter_get_acl_state() { return acl_state; } 56 57 // Returns the device bond state. 58 bt_bond_state_t adapter_get_bond_state() { return bond_state; } 59 60 // callback 61 void acl_state_changed(bt_status_t status, bt_bdaddr_t* remote_bd_addr, 62 bt_acl_state_t state) { 63 acl_state = state; 64 CALLBACK_RET(); 65 } 66 67 // callback 68 void adapter_properties(bt_status_t status, int num_properties, 69 bt_property_t* new_properties) { 70 property_free_array(properties, property_count); 71 properties = property_copy_array(new_properties, num_properties); 72 property_count = num_properties; 73 74 CALLBACK_RET(); 75 } 76 77 // callback 78 void adapter_state_changed(bt_state_t new_state) { 79 state = new_state; 80 CALLBACK_RET(); 81 } 82 83 // callback 84 void bond_state_changed(bt_status_t status, bt_bdaddr_t* bdaddr, 85 bt_bond_state_t state) { 86 char buf[18]; 87 bond_state = state; 88 89 const char* state_name = "Bond state unknown"; 90 switch (bond_state) { 91 case BT_BOND_STATE_NONE: 92 state_name = "Bond state none"; 93 break; 94 95 case BT_BOND_STATE_BONDING: 96 state_name = "Bond state bonding"; 97 break; 98 99 case BT_BOND_STATE_BONDED: 100 state_name = "Bond state bonded"; 101 break; 102 103 // default none 104 } 105 fprintf(stdout, "Bond state changed callback addr:%s state:%s\n", 106 bdaddr_to_string(bdaddr, buf, sizeof(buf)), state_name); 107 108 CALLBACK_RET(); 109 } 110 111 // callback 112 void device_found(int num_properties, bt_property_t* property) { 113 fprintf(stdout, "Device found num_properties:%d\n", num_properties); 114 parse_properties(num_properties, property); 115 116 CALLBACK_RET(); 117 } 118 119 // callback 120 void discovery_state_changed(bt_discovery_state_t state) { 121 const char* state_name = "Unknown"; 122 discovery_state = state; 123 124 switch (discovery_state) { 125 case BT_DISCOVERY_STOPPED: 126 state_name = "Discovery stopped"; 127 break; 128 129 case BT_DISCOVERY_STARTED: 130 state_name = "Discovery started"; 131 break; 132 133 // default omitted 134 } 135 fprintf(stdout, "Discover state %s\n", state_name); 136 137 CALLBACK_RET(); 138 } 139 140 // callback 141 void remote_device_properties(bt_status_t status, bt_bdaddr_t* bdaddr, 142 int num_properties, bt_property_t* properties) { 143 char buf[18]; 144 fprintf(stdout, "Device found bdaddr:%s num_properties:%d\n", 145 bdaddr_to_string(bdaddr, buf, sizeof(buf)), num_properties); 146 147 parse_properties(num_properties, properties); 148 149 CALLBACK_RET(); 150 } 151 152 // callback 153 void ssp_request(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, 154 uint32_t cod, bt_ssp_variant_t pairing_variant, 155 uint32_t pass_key) { 156 char* pairing_variant_name = "Unknown"; 157 158 switch (pairing_variant) { 159 case BT_SSP_VARIANT_PASSKEY_CONFIRMATION: 160 pairing_variant_name = "Passkey confirmation"; 161 break; 162 case BT_SSP_VARIANT_PASSKEY_ENTRY: 163 pairing_variant_name = "Passkey entry"; 164 break; 165 166 case BT_SSP_VARIANT_CONSENT: 167 pairing_variant_name = "Passkey consent"; 168 break; 169 170 case BT_SSP_VARIANT_PASSKEY_NOTIFICATION: 171 pairing_variant_name = "Passkey notification"; 172 break; 173 } 174 175 fprintf(stdout, 176 "Got ssp request device_class:%u passkey:%x pairing_variant:%s\n", 177 cod, pass_key, pairing_variant_name); 178 char buf[18]; 179 fprintf(stdout, "Device found:%s %s\n", 180 bdaddr_to_string(remote_bd_addr, buf, sizeof(buf)), bd_name->name); 181 182 fprintf(stdout, "auto-accepting bond\n"); 183 bool accept = true; 184 int rc = bt_interface->ssp_reply(remote_bd_addr, pairing_variant, 185 (uint8_t)accept, pass_key); 186 CALLBACK_RET(); 187 } 188 189 // callback 190 void thread_evt(bt_cb_thread_evt evt) { CALLBACK_RET(); } 191 192 static void parse_properties(int num_properties, bt_property_t* property) { 193 while (num_properties-- > 0) { 194 switch (property->type) { 195 case BT_PROPERTY_BDNAME: { 196 const bt_bdname_t* name = property_as_name(property); 197 if (name) fprintf(stdout, " name:%s\n", name->name); 198 } break; 199 200 case BT_PROPERTY_BDADDR: { 201 char buf[18]; 202 const bt_bdaddr_t* addr = property_as_addr(property); 203 if (addr) 204 fprintf(stdout, " addr:%s\n", 205 bdaddr_to_string(addr, buf, sizeof(buf))); 206 } break; 207 208 case BT_PROPERTY_UUIDS: { 209 size_t num_uuid; 210 const bt_uuid_t* uuid = property_as_uuids(property, &num_uuid); 211 if (uuid) { 212 for (size_t i = 0; i < num_uuid; i++) { 213 fprintf(stdout, " uuid:%zd: ", i); 214 for (size_t j = 0; j < sizeof(uuid); j++) { 215 fprintf(stdout, "%02x", uuid->uu[j]); 216 } 217 fprintf(stdout, "\n"); 218 } 219 } 220 } break; 221 222 case BT_PROPERTY_TYPE_OF_DEVICE: { 223 bt_device_type_t device_type = property_as_device_type(property); 224 if (device_type) { 225 const struct { 226 const char* device_type; 227 } device_type_lookup[] = { 228 {"Unknown"}, 229 {"Classic Only"}, 230 {"BLE Only"}, 231 {"Both Classic and BLE"}, 232 }; 233 int idx = (int)device_type; 234 if (idx > BT_DEVICE_DEVTYPE_DUAL) idx = 0; 235 fprintf(stdout, " device_type:%s\n", 236 device_type_lookup[idx].device_type); 237 } 238 } break; 239 240 case BT_PROPERTY_CLASS_OF_DEVICE: { 241 const bt_device_class_t* dc = property_as_device_class(property); 242 int dc_int = device_class_to_int(dc); 243 fprintf(stdout, " device_class:0x%x\n", dc_int); 244 } break; 245 246 case BT_PROPERTY_REMOTE_RSSI: { 247 int8_t rssi = property_as_rssi(property); 248 fprintf(stdout, " rssi:%d\n", rssi); 249 } break; 250 251 case BT_PROPERTY_REMOTE_FRIENDLY_NAME: { 252 const bt_bdname_t* name = property_as_name(property); 253 if (name) fprintf(stdout, " remote_name:%s\n", name->name); 254 } break; 255 256 case BT_PROPERTY_SERVICE_RECORD: 257 case BT_PROPERTY_ADAPTER_SCAN_MODE: 258 case BT_PROPERTY_ADAPTER_BONDED_DEVICES: 259 case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: 260 case BT_PROPERTY_REMOTE_VERSION_INFO: 261 case BT_PROPERTY_LOCAL_LE_FEATURES: 262 case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: 263 default: { 264 fprintf(stderr, "Unhandled property type:%d len:%d\n", property->type, 265 property->len); 266 uint8_t* p = (uint8_t*)property->val; 267 for (int i = 0; i < property->len; ++i, p++) { 268 fprintf(stderr, " %02x", *p); 269 } 270 if (property->len != 0) fprintf(stderr, "\n"); 271 } 272 } 273 property++; 274 } 275 } 276