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
SharedValidator()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
BtBinderEnable()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(&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
BtBinderGetAddress()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
BtBinderGetName()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
BtBinderSetName(std::string name)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
BtBinderInitInterface()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
BtBinderRegisterBLE()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
BtBinderSetAdvSettings(int mode,int timeout_seconds,int tx_power_level,bool is_connectable)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
bt_binder_get_local_name_wrapper(rapidjson::Document & doc)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
bt_binder_init_interface_wapper(rapidjson::Document & doc)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
bt_binder_set_local_name_wrapper(rapidjson::Document & doc)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
bt_binder_get_local_address_wrapper(rapidjson::Document & doc)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
bt_binder_enable_wrapper(rapidjson::Document & doc)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
bt_binder_register_ble_wrapper(rapidjson::Document & doc)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
bt_binder_set_adv_settings_wrapper(rapidjson::Document & doc)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
BtBinderFacade()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