aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-06-21 12:27:48 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2015-06-21 12:27:48 +0200
commitf4afc04ee7a085a89ad84ba89344bb50ca9e6e04 (patch)
tree404058c5ffd4773dfe13ddcd7a1cafc39864ae21 /apps
parent7e2fb834d8ba2eb3fd6453f135d3e8ef30c852c6 (diff)
downloadble-toys-f4afc04ee7a085a89ad84ba89344bb50ca9e6e04.tar.gz
ble-toys-f4afc04ee7a085a89ad84ba89344bb50ca9e6e04.tar.bz2
ble-toys-f4afc04ee7a085a89ad84ba89344bb50ca9e6e04.tar.xz
ble-toys-f4afc04ee7a085a89ad84ba89344bb50ca9e6e04.zip
o Trying to make the Bluetooth API more C++ idiomatic, a GATT connection has the same lifecycle as a BluetoothGatt.
sm-get-value: o Better error handling.
Diffstat (limited to 'apps')
-rw-r--r--apps/SoilMoisture.cpp14
-rw-r--r--apps/SoilMoisture.h6
-rw-r--r--apps/ble-inspect-device.h8
-rw-r--r--apps/generate.cpp8
-rw-r--r--apps/launcher.cpp12
-rw-r--r--apps/sm-get-value.h180
6 files changed, 114 insertions, 114 deletions
diff --git a/apps/SoilMoisture.cpp b/apps/SoilMoisture.cpp
index 89c2fe5..d1d8b7c 100644
--- a/apps/SoilMoisture.cpp
+++ b/apps/SoilMoisture.cpp
@@ -62,10 +62,10 @@ ByteBuffer createSetUpdateInterval(uint8_t sensor, uint8_t interval_in_seconds)
write8(interval_in_seconds);
}
-SoilMoisture SoilMoisture::create(BluetoothGatt &gatt) {
- gatt.discoverServices();
+SoilMoisture SoilMoisture::create(shared_ptr<BluetoothGatt> gatt) {
+ gatt->discoverServices();
- auto service = gatt.findService(soil_moisture_service);
+ auto service = gatt->findService(soil_moisture_service);
if (!service) {
throw runtime_error("The device is missing the soil moisture service");
@@ -80,8 +80,8 @@ SoilMoisture SoilMoisture::create(BluetoothGatt &gatt) {
return SoilMoisture(gatt, *service, *c);
}
-SoilMoisture::SoilMoisture(BluetoothGatt &gatt, BluetoothGattService &s, BluetoothGattCharacteristic &c) :
- gatt(gatt), s(s), c(c) {
+SoilMoisture::SoilMoisture(shared_ptr<BluetoothGatt> gatt, BluetoothGattService &s, BluetoothGattCharacteristic &c) :
+ gatt(std::move(gatt)), s(s), c(c) {
}
ByteBuffer SoilMoisture::writeAndRead(ByteBuffer &requestBytes) {
@@ -89,9 +89,9 @@ ByteBuffer SoilMoisture::writeAndRead(ByteBuffer &requestBytes) {
uint8_t expectedCode = requestBytes.get8(0);
- gatt.writeValue(c, requestBytes);
+ gatt->writeValue(c, requestBytes);
- auto responseBytes = gatt.readValue(c);
+ auto responseBytes = gatt->readValue(c);
if (responseBytes.getSize() < 1) {
throw runtime_error("Unexpected number of bytes read: " + to_string(requestBytes.getSize()));
diff --git a/apps/SoilMoisture.h b/apps/SoilMoisture.h
index 2016c9a..938da07 100644
--- a/apps/SoilMoisture.h
+++ b/apps/SoilMoisture.h
@@ -24,18 +24,18 @@ extern const boost::uuids::uuid soil_moisture_characteristic;
class SoilMoisture {
public:
- static SoilMoisture create(BluetoothGatt &gatt);
+ static SoilMoisture create(shared_ptr<BluetoothGatt> gatt);
uint8_t getSensorCount();
uint16_t getValue(uint8_t sensor);
private:
- SoilMoisture(BluetoothGatt &gatt, BluetoothGattService &s, BluetoothGattCharacteristic &c);
+ SoilMoisture(shared_ptr<BluetoothGatt> gatt, BluetoothGattService &s, BluetoothGattCharacteristic &c);
ByteBuffer writeAndRead(ByteBuffer &requestBytes);
- BluetoothGatt &gatt;
+ shared_ptr<BluetoothGatt> gatt;
BluetoothGattService &s;
BluetoothGattCharacteristic &c;
};
diff --git a/apps/ble-inspect-device.h b/apps/ble-inspect-device.h
index bf79b2c..7d93f95 100644
--- a/apps/ble-inspect-device.h
+++ b/apps/ble-inspect-device.h
@@ -28,11 +28,11 @@ public:
void scan_callback(BluetoothDevice &device) {
cout << "Inspecting device: " << device.getMac().str() << endl;
- auto &gatt = device.connectGatt();
+ auto gatt = device.connectGatt();
- gatt.discoverServices();
+ gatt->discoverServices();
- vector < BluetoothGattService * > services = gatt.getServices();
+ vector < BluetoothGattService * > services = gatt->getServices();
cout << "Device has " << services.size() << " services" << endl;
for (auto &s: services) {
@@ -46,8 +46,6 @@ public:
endl;
}
}
-
- gatt.disconnect();
}
int main(app_execution &execution) override {
diff --git a/apps/generate.cpp b/apps/generate.cpp
index ca6f8de..9dcc271 100644
--- a/apps/generate.cpp
+++ b/apps/generate.cpp
@@ -46,7 +46,10 @@ int main(int argc, char *argv[]) {
bool first = true;
- out << "template<typename App>" << endl
+ out << "namespace trygvis {" << endl
+ << "namespace apps {" << endl
+ << endl
+ << "template<typename App>" << endl
<< "int launch_app(int argc, const char *argv[]);" << endl
<< endl;
@@ -67,6 +70,9 @@ int main(int argc, char *argv[]) {
out << " } else {" << endl
<< " return EXIT_FAILURE;" << endl
<< " }" << endl
+ << "}" << endl
+ << endl
+ << "}" << endl
<< "}" << endl;
return EXIT_SUCCESS;
diff --git a/apps/launcher.cpp b/apps/launcher.cpp
index 4c1f687..2a1e039 100644
--- a/apps/launcher.cpp
+++ b/apps/launcher.cpp
@@ -2,9 +2,10 @@
#include "apps-list.gen.h"
#include <log4cplus/consoleappender.h>
#include <log4cplus/configurator.h>
-#include <boost/algorithm/string/predicate.hpp>
-using namespace trygvis::apps;
+namespace trygvis {
+namespace apps {
+
using namespace std;
const po::options_description logging_options() {
@@ -16,7 +17,7 @@ const po::options_description logging_options() {
void setup_logging(string app_name) {
Appender *console = new ConsoleAppender(true, true);
- string pattern = string("%-5p ") /*"%6r "*/ + app_name + "/%-20c %m%n";
+ string pattern = string("%-5p ") /*"%6r "*/ + app_name + "/%-20c %m%n"; // add %M (function name)
PatternLayout *layout = new PatternLayout(LOG4CPLUS_TEXT(pattern));
console->setLayout(auto_ptr<Layout>(layout));
@@ -74,6 +75,11 @@ int launch_app(int argc, const char *argv[]) {
return EXIT_FAILURE;
}
}
+}
+}
+
+using namespace std;
+using namespace trygvis::apps;
int main(int argc, const char *argv[]) {
if (argc == 0) {
diff --git a/apps/sm-get-value.h b/apps/sm-get-value.h
index 11e797f..4083f8e 100644
--- a/apps/sm-get-value.h
+++ b/apps/sm-get-value.h
@@ -6,9 +6,11 @@
#include "ble/Bluetooth.h"
#include "SoilMoisture.h"
#include "trygvis/sensor.h"
-#include "json.hpp"
#include "apps.h"
+namespace trygvis {
+namespace apps {
+
// I'm lazy
using namespace std;
using namespace std::chrono;
@@ -18,92 +20,6 @@ using namespace trygvis::sensor;
using namespace trygvis::sensor::io;
using json = nlohmann::json;
-bool loop;
-sample_format_type format;
-time_point<system_clock> targetTime;
-unsigned int sleepTime;
-vector<unsigned int> sensors;
-
-void withConnection(sample_format_type format, BluetoothGatt &gatt) {
- SoilMoisture soilMoisture = SoilMoisture::create(gatt);
-
- const int sensorCount = soilMoisture.getSensorCount();
-
- if (sensorCount == 0) {
- throw runtime_error("Sensor count is 0");
- }
-
- // If the user didn't specify any sensors, add all.
- if (sensors.size() == 0) {
- for (unsigned int i = 0; i < sensorCount; i++) {
- sensors.push_back(i);
- }
- }
-
- auto mac = gatt.getDevice().getMac();
-
- targetTime = system_clock::now();
-
- do {
- KeyDictionary dict;
- auto hostname_key = dict.indexOf("hostname");
- auto device_key = dict.indexOf("device");
- auto sensor_key = dict.indexOf("sensor");
- auto timestamp_key = dict.indexOf("timestamp");
- auto value_key = dict.indexOf("value");
-
- auto unique_output_stream = open_sample_output_stream(shared_ptr<ostream>(&cout, noop_deleter), dict, format);
- shared_ptr<SampleOutputStream> output_stream{std::move(unique_output_stream)};
-
- for (auto sensor : sensors) {
- if (sensor >= sensorCount) {
- // Ignore invalid sensors
- continue;
- }
-
- auto epoch = system_clock::now().time_since_epoch();
- auto timestamp = duration_cast<seconds>(epoch).count();
- uint16_t value = soilMoisture.getValue((uint8_t) sensor);
-
- SampleRecord sample(dict);
-
- sample.set(hostname_key, get_hostname());
- sample.set(device_key, mac.str());
- sample.set(sensor_key, std::to_string(sensor));
- sample.set(timestamp_key, std::to_string(timestamp));
- sample.set(value_key, std::to_string(value));
-
- output_stream->write(sample);
-
-// if (format == sample_format_type::KEY_VALUE) {
-// cout << "device=" << device.str()
-// << ", sensor=" << to_string(sensor)
-// << ", timestamp=" << to_string(timestamp)
-// << ", value=" << (int) value << endl;
-// } else if (format == sample_format_type::JSON) {
-// json j;
-// j["device"] = device.str();
-// j["sensor"] = sensor;
-// j["timestamp"] = timestamp;
-// j["value"] = value;
-// cout << j << endl;
-// } else if (format == sample_format_type::SQL) {
-// cout << "INSERT INTO soil_moisture_sample(device, sensor, timestamp, value) VALUES("
-// << "'" << device.str() << "', "
-// << sensor << ", "
-// << timestamp << ", "
-// << value << ";" << endl;
-// }
- }
-
- targetTime = targetTime + seconds(sleepTime);
- this_thread::sleep_until(targetTime);
- } while (loop);
-}
-
-namespace trygvis {
-namespace apps {
-
class sm_get_value : public app {
public:
@@ -112,15 +28,21 @@ public:
~sm_get_value() = default;
+ bool loop;
+ sample_format_type format;
+ unsigned int sleepTime;
+ vector<unsigned int> sensors;
+
void add_options(po::options_description_easy_init &options) override {
auto default_sleep = po::value<>(&sleepTime)->default_value(0);
+ auto default_format = po::value<sample_format_type>(&format)->default_value(sample_format_type::KEY_VALUE);
options
("device", po::value<string>()->required(), "MAC of device to poll")
("sensor", po::value<vector<unsigned int>>(&sensors)->multitoken(), "Sensor to poll, defaults to all")
- ("sleep", default_sleep, "How long to sleep in seconds between each poll. If not given, it will exit after first poll")
- ("format", po::value<sample_format_type>(&format)->default_value(sample_format_type::KEY_VALUE),
- "Output format");
+ ("sleep", default_sleep,
+ "How long to sleep in seconds between each poll. If not given, it will exit after first poll")
+ ("format", default_format, "Output format");
}
int main(app_execution &execution) override {
@@ -148,15 +70,21 @@ public:
loop = sleepTime > 0;
do {
- LOG4CPLUS_INFO(execution.logger, "Connecting to device: " + device.getMac().str());
-
- auto &gatt = device.connectGatt();
try {
+ LOG4CPLUS_INFO(execution.logger, "Connecting to device: " + device.getMac().str());
+ auto gatt = device.connectGatt();
+
withConnection(format, gatt);
} catch (runtime_error &e) {
- cout << "exception: " << e.what() << endl;
+ LOG4CPLUS_ERROR(execution.logger, "Exception: " << e.what());
+ }
+
+ if (loop) {
+ LOG4CPLUS_DEBUG(execution.logger, "Sleeping for " + std::to_string(sleepTime) + " seconds after failure.");
+
+ auto targetTime = system_clock::now() + seconds(sleepTime);
+ this_thread::sleep_until(targetTime);
}
- gatt.disconnect();
} while (loop);
return EXIT_SUCCESS;
@@ -168,6 +96,68 @@ public:
return EXIT_FAILURE;
}
}
+
+ void withConnection(sample_format_type format, shared_ptr<BluetoothGatt> gatt) {
+ SoilMoisture soilMoisture = SoilMoisture::create(gatt);
+
+ const int sensorCount = soilMoisture.getSensorCount();
+
+ if (sensorCount == 0) {
+ throw runtime_error("Sensor count is 0");
+ }
+
+ // If the user didn't specify any sensors, add all.
+ if (sensors.size() == 0) {
+ for (unsigned int i = 0; i < sensorCount; i++) {
+ sensors.push_back(i);
+ }
+ }
+
+ auto mac = gatt->getDevice().getMac();
+
+ KeyDictionary dict;
+ auto hostname_key = dict.indexOf("hostname");
+ auto device_key = dict.indexOf("device");
+ auto sensor_key = dict.indexOf("sensor");
+ auto timestamp_key = dict.indexOf("timestamp");
+ auto value_key = dict.indexOf("value");
+
+ time_point<system_clock> targetTime;
+ targetTime = system_clock::now();
+
+ do {
+ auto unique_output_stream = open_sample_output_stream(shared_ptr<ostream>(&cout, noop_deleter), dict,
+ format);
+ shared_ptr<SampleOutputStream> output_stream{std::move(unique_output_stream)};
+
+ auto epoch = system_clock::now().time_since_epoch();
+ auto timestamp = duration_cast<seconds>(epoch).count();
+
+ for (auto sensor : sensors) {
+ if (sensor >= sensorCount) {
+ // Ignore invalid sensors
+ continue;
+ }
+
+ uint16_t value = soilMoisture.getValue((uint8_t) sensor);
+
+ auto sample = SampleRecord(dict)
+ .set(hostname_key, get_hostname())
+ .set(device_key, mac.str())
+ .set(sensor_key, std::to_string(sensor))
+ .set(timestamp_key, std::to_string(timestamp))
+ .set(value_key, std::to_string(value));
+
+ output_stream->write(sample);
+ }
+
+ do {
+ targetTime = targetTime + seconds(sleepTime);
+ } while (targetTime < system_clock::now());
+
+ this_thread::sleep_until(targetTime);
+ } while (loop);
+ }
};
}