1 // 2 // Copyright (C) 2016 Google, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include <base.h> 18 #include <base/at_exit.h> 19 #include <base/command_line.h> 20 #include <base/logging.h> 21 #include <base/macros.h> 22 #include <base/strings/string_split.h> 23 #include <base/strings/string_util.h> 24 #include <binder/IPCThreadState.h> 25 #include <binder/IServiceManager.h> 26 #include <binder/ProcessState.h> 27 28 #include "bt_binder_facade.h" 29 #include <rapidjson/document.h> 30 #include <rapidjson/writer.h> 31 #include <rapidjson/stringbuffer.h> 32 #include <android/bluetooth/IBluetooth.h> 33 #include <android/bluetooth/IBluetoothCallback.h> 34 #include <android/bluetooth/IBluetoothLowEnergy.h> 35 #include <service/common/bluetooth/low_energy_constants.h> 36 #include <tuple> 37 #include <utils/command_receiver.h> 38 #include <utils/common_utils.h> 39 40 using android::bluetooth::IBluetooth; 41 using android::bluetooth::IBluetoothLowEnergy; 42 using android::getService; 43 using android::OK; 44 using android::sp; 45 using android::String8; 46 using android::String16; 47 48 std::atomic_bool ble_registering(false); 49 std::atomic_int ble_client_id(0); 50 51 std::string kServiceName = "bluetooth-service"; 52 53 bool BtBinderFacade::SharedValidator() { 54 if (bt_iface == NULL) { 55 LOG(ERROR) << sl4n::kTagStr << " IBluetooth interface not initialized"; 56 return false; 57 } 58 bool ret; 59 bt_iface->IsEnabled(&ret); 60 if (!ret) { 61 LOG(ERROR) << sl4n::kTagStr << " IBluetooth interface not enabled"; 62 return false; 63 } 64 return true; 65 } 66 67 std::tuple<bool, int> BtBinderFacade::BtBinderEnable() { 68 if (bt_iface == NULL) { 69 LOG(ERROR) << sl4n::kTagStr << ": IBluetooth interface not enabled"; 70 return std::make_tuple(false, sl4n_error_codes::kFailInt); 71 } 72 bool ret; 73 bt_iface->Enable(false, &ret); 74 if (!ret) { 75 LOG(ERROR) << sl4n::kTagStr << ": Failed to enable the Bluetooth service"; 76 return std::make_tuple(false, sl4n_error_codes::kPassInt); 77 } else { 78 return std::make_tuple(true, sl4n_error_codes::kPassInt); 79 } 80 } 81 82 std::tuple<std::string, int> BtBinderFacade::BtBinderGetAddress() { 83 if (!SharedValidator()) { 84 return std::make_tuple(sl4n::kFailStr, sl4n_error_codes::kFailInt); 85 } 86 String16 address; 87 bt_iface->GetAddress(&address); 88 return std::make_tuple(std::string(String8(address).string()), sl4n_error_codes::kPassInt); 89 } 90 91 std::tuple<std::string, int> BtBinderFacade::BtBinderGetName() { 92 if (!SharedValidator()) { 93 return std::make_tuple(sl4n::kFailStr,sl4n_error_codes::kFailInt); 94 } 95 96 String16 name16; 97 bt_iface->GetName(&name16); 98 std::string name = std::string(String8(name16).string()); 99 if (name.empty()) { 100 LOG(ERROR) << sl4n::kTagStr << ": Failed to get device name"; 101 return std::make_tuple(sl4n::kFailStr, sl4n_error_codes::kFailInt); 102 } else { 103 return std::make_tuple(name, sl4n_error_codes::kPassInt); 104 } 105 } 106 107 std::tuple<bool, int> BtBinderFacade::BtBinderSetName( 108 std::string name) { 109 110 if (!SharedValidator()) { 111 return std::make_tuple(false, sl4n_error_codes::kFailInt); 112 } 113 114 bool result; 115 bt_iface->SetName(String16(String8(name.c_str())), &result); 116 if (!result) { 117 LOG(ERROR) << sl4n::kTagStr << ": Failed to set device name"; 118 return std::make_tuple(false, sl4n_error_codes::kFailInt); 119 } 120 return std::make_tuple(true, sl4n_error_codes::kPassInt); 121 } 122 123 std::tuple<bool, int> BtBinderFacade::BtBinderInitInterface() { 124 status_t status = getService(String16(kServiceName.c_str()), &bt_iface); 125 if (status != OK) { 126 LOG(ERROR) << "Failed to get service binder: '" << kServiceName 127 << "' status=" << status; 128 return std::make_tuple(false, sl4n_error_codes::kFailInt); 129 } 130 return std::make_tuple(true, sl4n_error_codes::kPassInt); 131 } 132 133 std::tuple<bool, int> BtBinderFacade::BtBinderRegisterBLE() { 134 // TODO (tturney): verify bt_iface initialized everywhere 135 if (!SharedValidator()) { 136 return std::make_tuple(false, sl4n_error_codes::kFailInt); 137 } 138 bt_iface->GetLowEnergyInterface(&ble_iface); 139 if(!ble_iface.get()) { 140 LOG(ERROR) << sl4n::kTagStr << ": Failed to register BLE"; 141 return std::make_tuple(false, sl4n_error_codes::kFailInt); 142 } 143 return std::make_tuple(true, sl4n_error_codes::kPassInt); 144 } 145 146 std::tuple<int, int> BtBinderFacade::BtBinderSetAdvSettings( 147 int mode, int timeout_seconds, int tx_power_level, bool is_connectable) { 148 if (!SharedValidator()) { 149 return std::make_tuple(false,sl4n_error_codes::kFailInt); 150 } 151 bluetooth::AdvertiseSettings::Mode adv_mode; 152 switch (mode) { 153 case sl4n_ble::kAdvSettingsModeLowPowerInt : 154 adv_mode = bluetooth::AdvertiseSettings::Mode::MODE_LOW_POWER; 155 break; 156 case sl4n_ble::kAdvSettingsModeBalancedInt : 157 adv_mode = bluetooth::AdvertiseSettings::Mode::MODE_BALANCED; 158 break; 159 case sl4n_ble::kAdvSettingsModeLowLatencyInt : 160 adv_mode = bluetooth::AdvertiseSettings::Mode::MODE_LOW_LATENCY; 161 break; 162 default : 163 LOG(ERROR) << sl4n::kTagStr << 164 ": Input mode is outside the accepted values"; 165 return std::make_tuple( 166 sl4n::kFailedCounterInt, sl4n_error_codes::kFailInt); 167 } 168 169 base::TimeDelta adv_timeout = base::TimeDelta::FromSeconds( 170 timeout_seconds); 171 172 bluetooth::AdvertiseSettings::TxPowerLevel adv_tx_power_level; 173 switch (tx_power_level) { 174 case sl4n_ble::kAdvSettingsTxPowerLevelUltraLowInt: adv_tx_power_level = 175 bluetooth::AdvertiseSettings::TxPowerLevel::TX_POWER_LEVEL_ULTRA_LOW; 176 break; 177 case sl4n_ble::kAdvSettingsTxPowerLevelLowInt: adv_tx_power_level = 178 bluetooth::AdvertiseSettings::TxPowerLevel::TX_POWER_LEVEL_LOW; 179 break; 180 case sl4n_ble::kAdvSettingsTxPowerLevelMediumInt: adv_tx_power_level = 181 bluetooth::AdvertiseSettings::TxPowerLevel::TX_POWER_LEVEL_MEDIUM; 182 break; 183 case sl4n_ble::kAdvSettingsTxPowerLevelHighInt: adv_tx_power_level = 184 bluetooth::AdvertiseSettings::TxPowerLevel::TX_POWER_LEVEL_HIGH; 185 break; 186 default : 187 LOG(ERROR) << sl4n::kTagStr << 188 ": Input tx power level is outside the accepted values"; 189 return std::make_tuple( 190 sl4n::kFailedCounterInt, sl4n_error_codes::kFailInt); 191 } 192 193 bluetooth::AdvertiseSettings adv_settings = bluetooth::AdvertiseSettings( 194 adv_mode, adv_timeout, adv_tx_power_level, is_connectable); 195 adv_settings_map[adv_settings_count] = adv_settings; 196 int adv_settings_id = adv_settings_count; 197 adv_settings_count++; 198 return std::make_tuple(adv_settings_id, sl4n_error_codes::kPassInt); 199 } 200 201 ////////////////// 202 // wrappers 203 ////////////////// 204 205 static BtBinderFacade facade; // triggers registration with CommandReceiver 206 207 void bt_binder_get_local_name_wrapper(rapidjson::Document &doc) { 208 int expected_param_size = 0; 209 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 210 return; 211 } 212 //check for kfailedstr or NULL??? 213 std::string name; 214 int error_code; 215 std::tie(name, error_code) = facade.BtBinderGetName(); 216 if (error_code == sl4n_error_codes::kFailInt) { 217 doc.AddMember(sl4n::kResultStr, sl4n::kFailStr, doc.GetAllocator()); 218 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 219 return; 220 } 221 rapidjson::Value tmp; 222 tmp.SetString(name.c_str(), doc.GetAllocator()); 223 doc.AddMember(sl4n::kResultStr, tmp, doc.GetAllocator()); 224 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 225 return; 226 } 227 228 void bt_binder_init_interface_wapper(rapidjson::Document &doc) { 229 int expected_param_size = 0; 230 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 231 return; 232 } 233 bool init_result; 234 int error_code; 235 std::tie(init_result, error_code) = facade.BtBinderInitInterface(); 236 if (error_code == sl4n_error_codes::kFailInt) { 237 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 238 } else { 239 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 240 } 241 doc.AddMember(sl4n::kResultStr, init_result, doc.GetAllocator()); 242 return; 243 } 244 245 void bt_binder_set_local_name_wrapper(rapidjson::Document &doc) { 246 int expected_param_size = 1; 247 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 248 return; 249 } 250 std::string name; 251 if (!doc[sl4n::kParamsStr][0].IsString()) { 252 LOG(ERROR) << sl4n::kTagStr << ": Expected String input for name"; 253 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 254 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 255 return; 256 } else { 257 name = doc[sl4n::kParamsStr][0].GetString(); 258 } 259 bool set_result; 260 int error_code; 261 std::tie(set_result, error_code) = facade.BtBinderSetName(name); 262 if (error_code == sl4n_error_codes::kFailInt) { 263 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 264 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 265 } else { 266 doc.AddMember(sl4n::kResultStr, set_result, doc.GetAllocator()); 267 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 268 } 269 return; 270 } 271 272 void bt_binder_get_local_address_wrapper(rapidjson::Document &doc) { 273 int expected_param_size = 0; 274 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 275 return; 276 } 277 //check for kfailedstr or NULL??? 278 std::string address; 279 int error_code; 280 std::tie(address, error_code) = facade.BtBinderGetAddress(); 281 if (error_code == sl4n_error_codes::kFailInt) { 282 doc.AddMember(sl4n::kResultStr, sl4n::kFailStr, doc.GetAllocator()); 283 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 284 } else { 285 rapidjson::Value tmp; 286 tmp.SetString(address.c_str(), doc.GetAllocator()); 287 doc.AddMember(sl4n::kResultStr, tmp, doc.GetAllocator()); 288 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 289 } 290 return; 291 } 292 293 void bt_binder_enable_wrapper(rapidjson::Document &doc) { 294 int expected_param_size = 0; 295 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 296 return; 297 } 298 bool enable_result; 299 int error_code; 300 std::tie(enable_result, error_code) = facade.BtBinderEnable(); 301 if (error_code == sl4n_error_codes::kFailInt) { 302 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 303 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 304 } else { 305 doc.AddMember(sl4n::kResultStr, enable_result, doc.GetAllocator()); 306 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 307 } 308 } 309 310 void bt_binder_register_ble_wrapper(rapidjson::Document &doc) { 311 int expected_param_size = 0; 312 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 313 return; 314 } 315 bool register_result; 316 int error_code; 317 std::tie(register_result, error_code) = 318 facade.BtBinderRegisterBLE(); 319 if (error_code == sl4n_error_codes::kFailInt) { 320 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 321 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 322 } else { 323 doc.AddMember(sl4n::kResultStr, register_result, doc.GetAllocator()); 324 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 325 } 326 } 327 328 void bt_binder_set_adv_settings_wrapper(rapidjson::Document &doc) { 329 int expected_param_size = 4; 330 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 331 return; 332 } 333 int mode; 334 int timeout_seconds; 335 int tx_power_level; 336 bool is_connectable; 337 // TODO(tturney) Verify inputs better 338 if (!doc[sl4n::kParamsStr][0].IsInt()) { 339 LOG(ERROR) << sl4n::kTagStr << ": Expected Int input for mode"; 340 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 341 doc.AddMember(sl4n::kErrorStr, sl4n::kInvalidParamStr, doc.GetAllocator()); 342 return; 343 } else { 344 mode = doc[sl4n::kParamsStr][0].GetInt(); 345 } 346 if (!doc[sl4n::kParamsStr][1].IsInt()) { 347 LOG(ERROR) << sl4n::kTagStr << ": Expected Int input for timeout"; 348 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 349 doc.AddMember(sl4n::kErrorStr, sl4n::kInvalidParamStr, doc.GetAllocator()); 350 return; 351 } else { 352 timeout_seconds = doc[sl4n::kParamsStr][1].GetInt(); 353 } 354 if (!doc[sl4n::kParamsStr][2].IsInt()) { 355 LOG(ERROR) << sl4n::kTagStr << ": Expected Int input for tx power level"; 356 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 357 doc.AddMember(sl4n::kErrorStr, sl4n::kInvalidParamStr, doc.GetAllocator()); 358 return; 359 } else { 360 tx_power_level = doc[sl4n::kParamsStr][2].GetInt(); 361 } 362 if (!doc[sl4n::kParamsStr][3].IsBool()) { 363 LOG(ERROR) << sl4n::kTagStr << ": Expected Bool input for connectable"; 364 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 365 doc.AddMember(sl4n::kErrorStr, sl4n::kInvalidParamStr, doc.GetAllocator()); 366 return; 367 } else { 368 is_connectable = doc[sl4n::kParamsStr][3].GetBool(); 369 } 370 371 int adv_settings; 372 int error_code; 373 std::tie(adv_settings, error_code) = facade.BtBinderSetAdvSettings( 374 mode, timeout_seconds, tx_power_level, is_connectable); 375 if(error_code == sl4n_error_codes::kFailInt) { 376 doc.AddMember( 377 sl4n::kResultStr, sl4n_error_codes::kFailInt, doc.GetAllocator()); 378 doc.AddMember(sl4n::kErrorStr, sl4n::kFailedCounterInt, doc.GetAllocator()); 379 return; 380 } else { 381 doc.AddMember(sl4n::kResultStr, adv_settings, doc.GetAllocator()); 382 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 383 } 384 } 385 386 //////////////// 387 // constructor 388 //////////////// 389 390 BtBinderFacade::BtBinderFacade() { 391 adv_settings_count = 0; 392 manu_data_count = 0; 393 394 CommandReceiver::RegisterCommand("BtBinderInitInterface", 395 &bt_binder_init_interface_wapper); 396 CommandReceiver::RegisterCommand("BtBinderGetName", 397 &bt_binder_get_local_name_wrapper); 398 CommandReceiver::RegisterCommand("BtBinderSetName", 399 &bt_binder_set_local_name_wrapper); 400 CommandReceiver::RegisterCommand("BtBinderGetAddress", 401 &bt_binder_get_local_address_wrapper); 402 CommandReceiver::RegisterCommand("BtBinderEnable", 403 &bt_binder_enable_wrapper); 404 CommandReceiver::RegisterCommand("BtBinderRegisterBLE", 405 &bt_binder_register_ble_wrapper); 406 CommandReceiver::RegisterCommand("BtBinderSetAdvSettings", 407 &bt_binder_set_adv_settings_wrapper); 408 } 409 410