#include "ble/Bluetooth.h" #include "apps.h" #include #include "apps.h" namespace trygvis { namespace apps { using namespace std; using namespace trygvis::bluetooth; using namespace trygvis::apps; namespace ble_bts_utils { static std::function onSignal; static void signal_handler(int signal) { onSignal(signal); } } class ble_bts : public app { public: ble_bts() : app("ble-scan") {} ~ble_bts() override = default; string adapter_name; void add_options(po::options_description_easy_init &options) override { auto adapter_value = po::value<>(&adapter_name)->default_value("0"); options("adapter", adapter_value, "Which adapter to use."); options("device", po::value()->required(), "The MAC of the device to inspect"); } int main(app_execution &execution) override { BluetoothSystem bluetoothSystem; shared_ptr adapter; struct sigaction sigIntHandler{}; ble_bts_utils::onSignal = [&](int signal) { adapter->stopScan(); }; sigIntHandler.sa_handler = &ble_bts_utils::signal_handler; sigemptyset(&sigIntHandler.sa_mask); sigIntHandler.sa_flags = 0; sigaction(SIGINT, &sigIntHandler, nullptr); try { adapter = bluetoothSystem.getAdapter(adapter_name); string mac_str = execution.vm["device"].as(); Mac mac = Mac::parseMac(mac_str); auto device = adapter->getDevice(mac); auto gatt = device->connectGatt(); cout << "Connected" << endl; gatt->discoverServices(); auto bts = gatt->findService(uuids::HealthTermometerService); if (!bts) { cout << "Device does not implement Health thermometer service (" << uuids::HealthTermometerService.str() << ")" << endl; return EXIT_FAILURE; } auto tmc = bts->get()->findCharacteristic(uuids::TemperatureMeasurement); if (!tmc) { cout << "The device does not have temperature measurement characteristic" << endl; return EXIT_FAILURE; } with_characteristic(gatt, tmc.value()); return EXIT_SUCCESS; } catch (std::runtime_error &ex) { cout << "std::runtime_error: " << ex.what() << endl; return EXIT_FAILURE; } catch (std::exception &ex) { cout << "std::exception: " << ex.what() << endl; return EXIT_FAILURE; } } void with_characteristic(const BluetoothGattPtr &gatt, const BluetoothGattCharacteristicPtr &tmc) { auto svc = tmc->getService(); cout << "Reading temp value" << endl; StaticByteBuffer<100> response; auto buf = gatt->readValue(tmc, response); cout << "bytes " << buf.getSize() << endl; for (size_t i = 0; i < buf.getSize(); i++) { cout << "byte " << i << " = " << hex << buf.peek8(i) << endl; } } }; } // namespace apps } // namespace trygvis int main(int argc, const char *argv[]) { using namespace trygvis::apps; return real_main(new ble_bts(), argc, argv); }