aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-02-22 16:16:48 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2015-02-22 16:16:48 +0100
commitd0fb1850606ce003887259675e271a9aade4fda0 (patch)
tree0bf3be59348c0fd64f17c9e9a727e85ffc7bd98b
parentba6324930118a62e05d3869f99543c4a7507f105 (diff)
downloadble-toys-d0fb1850606ce003887259675e271a9aade4fda0.tar.gz
ble-toys-d0fb1850606ce003887259675e271a9aade4fda0.tar.bz2
ble-toys-d0fb1850606ce003887259675e271a9aade4fda0.tar.xz
ble-toys-d0fb1850606ce003887259675e271a9aade4fda0.zip
o Starting a new class for all SoilMoisture GATT stuff.
-rw-r--r--apps/CMakeLists.txt3
-rw-r--r--apps/SoilMoisture.cpp121
-rw-r--r--apps/SoilMoisture.h47
-rw-r--r--apps/sm-get-value.cpp120
-rw-r--r--apps/soil-moisture.h122
-rw-r--r--include/ble/ByteBuffer.h7
6 files changed, 179 insertions, 241 deletions
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index aefb0fb..e210716 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -1,4 +1,5 @@
set(APPS sm-get-value ble-inspect-device)
+set(shared_sources SoilMoisture.cpp)
# Boost
find_package(Boost COMPONENTS system log thread REQUIRED)
@@ -12,7 +13,7 @@ find_package(Threads REQUIRED)
foreach(app ${APPS})
include_directories("${PROJECT_SOURCE_DIR}/include")
- add_executable(${app} ${app}.cpp)
+ add_executable(${app} ${app}.cpp ${shared_sources})
add_dependencies(${app} ble)
target_link_libraries(${app} ble)
diff --git a/apps/SoilMoisture.cpp b/apps/SoilMoisture.cpp
new file mode 100644
index 0000000..0fed8ab
--- /dev/null
+++ b/apps/SoilMoisture.cpp
@@ -0,0 +1,121 @@
+#include "SoilMoisture.h"
+
+namespace trygvis {
+namespace soil_moisture {
+
+
+#define BLUETOOTH_UUID_INITIALIZER \
+ { \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, \
+ 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb \
+ };
+
+auto trygvis_io_base_uuid = boost::uuids::uuid {
+ 0x32, 0xd0, 0x00, 0x00,
+ 0x03, 0x5d,
+ 0x59, 0xc5,
+ 0x70, 0xd3,
+ 0xbc, 0x8e, 0x4a, 0x1f, 0xd8, 0x3f};
+
+const boost::uuids::uuid soil_moisture_service = makeUuid(trygvis_io_base_uuid, 0x00, 0x10);
+const boost::uuids::uuid soil_moisture_characteristic = makeUuid(trygvis_io_base_uuid, 0x00, 0x11);
+
+using namespace trygvis::bluetooth;
+
+ByteBuffer createGetSensorCount() {
+ return ByteBuffer::alloc(100).
+ write8(static_cast<uint8_t>(sm_cmd_code::SM_CMD_GET_SENSOR_COUNT));
+}
+
+ByteBuffer createGetValue(uint8_t sensor) {
+ return ByteBuffer::alloc(100).
+ write8(static_cast<uint8_t>(sm_cmd_code::SM_CMD_GET_VALUE)).
+ write16le(sensor);
+}
+
+ByteBuffer createSetWarningValue(uint8_t sensor, uint16_t warning_value) {
+ return ByteBuffer::alloc(100).
+ write8(static_cast<uint8_t>(sm_cmd_code::SM_CMD_SET_WARNING_VALUE)).
+ write8(sensor).
+ write16le(warning_value);
+}
+
+ByteBuffer createSetSensorName(uint8_t sensor, string name) {
+ return ByteBuffer::alloc(100).
+ write8(static_cast<uint8_t>(sm_cmd_code::SM_CMD_SET_SENSOR_NAME)).
+ write8(sensor).
+ write(reinterpret_cast<const uint8_t *>(name.c_str()), name.length());
+}
+
+ByteBuffer createGetSensorName(uint8_t sensor) {
+ return ByteBuffer::alloc(100).
+ write8(static_cast<uint8_t>(sm_cmd_code::SM_CMD_GET_SENSOR_NAME)).
+ write8(sensor);
+}
+
+ByteBuffer createSetUpdateInterval(uint8_t sensor, uint8_t interval_in_seconds) {
+ return ByteBuffer::alloc(100).
+ write8(static_cast<uint8_t>(sm_cmd_code::SM_CMD_SET_UPDATE_INTERVAL)).
+ write8(sensor).
+ write8(interval_in_seconds);
+}
+
+SoilMoisture SoilMoisture::create(BluetoothGatt & gatt) {
+ gatt.discoverServices();
+
+ auto service = gatt.findService(soil_moisture_service);
+
+ if (!service) {
+ throw runtime_error("The device is missing the soil moisture service");
+ }
+
+ auto c = service->findCharacteristic(soil_moisture_characteristic);
+
+ if (!c) {
+ throw runtime_error("The device is missing the soil moisture characteristic");
+ }
+
+ return SoilMoisture(gatt, *service, *c);
+}
+
+SoilMoisture::SoilMoisture(BluetoothGatt & gatt, BluetoothGattService &s, BluetoothGattCharacteristic &c) :
+ gatt(gatt), s(s), c(c) {
+}
+
+ByteBuffer SoilMoisture::writeAndRead(ByteBuffer &requestBytes) {
+ requestBytes.setCursor(0);
+
+ uint8_t expectedCode = requestBytes.get8(0);
+
+ gatt.writeValue(c, requestBytes);
+
+ auto responseBytes = gatt.readValue(c);
+
+ if (responseBytes.getSize() < 1) {
+ throw runtime_error("Unexpected number of bytes read: " + to_string(requestBytes.getSize()));
+ }
+
+ uint8_t actualCode = responseBytes.read8();
+ if (actualCode != expectedCode) {
+ throw runtime_error("Unexpected response code: " + to_string(actualCode) + ", expected " + to_string(expectedCode));
+ }
+
+ return responseBytes;
+}
+
+uint8_t SoilMoisture::getSensorCount() {
+ auto buffer = createGetSensorCount();
+ return writeAndRead(buffer).read8();
+}
+
+uint16_t SoilMoisture::getValue(uint8_t sensor) {
+ auto req = createGetValue(sensor);
+
+ return writeAndRead(req).read16le();
+}
+
+}
+}
diff --git a/apps/SoilMoisture.h b/apps/SoilMoisture.h
new file mode 100644
index 0000000..ea64032
--- /dev/null
+++ b/apps/SoilMoisture.h
@@ -0,0 +1,47 @@
+#ifndef SOIL_MOISTURE_H
+#define SOIL_MOISTURE_H
+
+#include <ble/Bluetooth.h>
+#include <boost/uuid/uuid.hpp>
+
+namespace trygvis {
+namespace soil_moisture {
+
+using namespace trygvis::bluetooth;
+
+enum class sm_cmd_code : uint8_t {
+ SM_CMD_GET_SENSOR_COUNT = 1,
+ SM_CMD_GET_VALUE = 2,
+ SM_CMD_SET_WARNING_VALUE = 3,
+ SM_CMD_GET_WARNING_VALUE = 4,
+ SM_CMD_SET_SENSOR_NAME = 5,
+ SM_CMD_GET_SENSOR_NAME = 6,
+ SM_CMD_SET_UPDATE_INTERVAL = 7,
+ SM_CMD_FAIL = 255,
+};
+
+extern const boost::uuids::uuid soil_moisture_service;
+extern const boost::uuids::uuid soil_moisture_characteristic;
+
+class SoilMoisture {
+public:
+ static SoilMoisture create(BluetoothGatt &gatt);
+
+ uint8_t getSensorCount();
+
+ uint16_t getValue(uint8_t sensor);
+
+private:
+ SoilMoisture(BluetoothGatt &gatt, BluetoothGattService &s, BluetoothGattCharacteristic &c);
+
+ ByteBuffer writeAndRead(ByteBuffer &requestBytes);
+
+ BluetoothGatt &gatt;
+ BluetoothGattService &s;
+ BluetoothGattCharacteristic &c;
+};
+
+}
+}
+
+#endif
diff --git a/apps/sm-get-value.cpp b/apps/sm-get-value.cpp
index e4ddc16..46177f2 100644
--- a/apps/sm-get-value.cpp
+++ b/apps/sm-get-value.cpp
@@ -2,100 +2,22 @@
#include <boost/uuid/uuid_io.hpp>
#include <boost/optional.hpp>
#include "ble/Bluetooth.h"
-#include "soil-moisture.h"
+#include "SoilMoisture.h"
using namespace std;
using namespace trygvis::bluetooth;
-
-#define BLUETOOTH_UUID_INITIALIZER \
- { \
- 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, \
- 0x10, 0x00, \
- 0x80, 0x00, \
- 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb \
- };
-
-auto trygvis_io_base_uuid = boost::uuids::uuid {
- 0x32, 0xd0, 0x00, 0x00,
- 0x03, 0x5d,
- 0x59, 0xc5,
- 0x70, 0xd3,
- 0xbc, 0x8e, 0x4a, 0x1f, 0xd8, 0x3f};
-
-auto soil_moisture_service = makeUuid(trygvis_io_base_uuid, 0x00, 0x10);
-auto soil_moisture_characteristic = makeUuid(trygvis_io_base_uuid, 0x00, 0x11);
-
-ByteBuffer &operator<<(ByteBuffer &bytes, const sm_req &req);
+using namespace trygvis::soil_moisture;
bool loop = true;
-ByteBuffer writeAndRead(BluetoothGatt &gatt, const BluetoothGattCharacteristic &c, const ByteBuffer &requestBytes) {
- uint8_t expectedCode = requestBytes.get8(0);
-
- gatt.writeValue(c, requestBytes);
-
- auto responseBytes = gatt.readValue(c);
-
- if (responseBytes.getSize() < 1) {
- throw runtime_error("Unexpected number of bytes read: " + to_string(requestBytes.getSize()));
- }
-
- uint8_t actualCode = responseBytes.read8();
- if (actualCode != expectedCode) {
- throw runtime_error("Unexpected response code: " + to_string(actualCode) + ", expected " + to_string(expectedCode));
- }
-
- return responseBytes;
-}
-
-uint8_t getSensorCount(BluetoothGatt &gatt, BluetoothGattCharacteristic &c) {
- sm_req req = {
- .code = SM_CMD_GET_SENSOR_COUNT,
- };
-
- auto requestBytes = ByteBuffer::alloc(sizeof(struct sm_req));
- requestBytes << req;
- requestBytes.setCursor(0);
-
- return writeAndRead(gatt, c, requestBytes).read8();
-}
-
-uint16_t getValue(BluetoothGatt &gatt, BluetoothGattCharacteristic &c, uint8_t sensor) {
- sm_req req = {
- .code = SM_CMD_GET_VALUE,
- };
- req.get_value = {
- .sensor = sensor,
- };
-
- auto requestBytes = ByteBuffer::alloc(sizeof(struct sm_req));
- requestBytes << req;
- requestBytes.setCursor(0);
-
- return writeAndRead(gatt, c, requestBytes).read16le();
-}
-
void withConnection(BluetoothGatt &gatt) {
- gatt.discoverServices();
+ SoilMoisture soilMoisture = SoilMoisture::create(gatt);
- auto service = gatt.findService(soil_moisture_service);
-
- if (!service) {
- throw runtime_error("The device is missing the soil moisture service");
- }
-
- auto c = service->findCharacteristic(soil_moisture_characteristic);
-
- if (!c) {
- throw runtime_error("The device is missing the soil moisture characteristic");
- }
-
- int sensorCount = getSensorCount(gatt, *c);
+ int sensorCount = soilMoisture.getSensorCount();
while (loop) {
for (uint8_t i = 0; i < sensorCount; i++) {
- uint16_t value = getValue(gatt, *c, i);
+ uint16_t value = soilMoisture.getValue(i);
cout << "sensor=" << to_string(i) << ", value=" << (int) value << endl;
}
@@ -141,35 +63,3 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
}
-
-ByteBuffer &operator<<(ByteBuffer &bytes, const sm_req &req) {
- bytes.write8(req.code);
- switch (req.code) {
- case SM_CMD_GET_SENSOR_COUNT:
- return bytes;
- case SM_CMD_GET_VALUE:
- return bytes.
- write8(req.get_value.sensor);
- case SM_CMD_SET_WARNING_VALUE:
- return bytes.
- write8(req.set_warning_value.sensor).
- write16le(req.set_warning_value.warning_value);
- case SM_CMD_GET_WARNING_VALUE:
- return bytes.
- write8(req.set_warning_value.sensor);
- case SM_CMD_SET_SENSOR_NAME:
- return bytes.
- write8(req.set_sensor_name.sensor).
- write8(req.set_sensor_name.length).
- write(req.set_sensor_name.name, req.set_sensor_name.length);
- case SM_CMD_GET_SENSOR_NAME:
- return bytes.
- write8(req.get_sensor_name.sensor);
- case SM_CMD_SET_UPDATE_INTERVAL:
- return bytes.
- write8(req.set_update_interval.sensor).
- write8(req.set_update_interval.interval_in_seconds);
- default:
- throw runtime_error("Unknown code: " + to_string(req.code));
- }
-}
diff --git a/apps/soil-moisture.h b/apps/soil-moisture.h
deleted file mode 100644
index c960f79..0000000
--- a/apps/soil-moisture.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef SOIL_MOISTURE_H
-#define SOIL_MOISTURE_H
-
-#define SENSOR_NAME_LEN 10
-
-enum sm_cmd_code {
- SM_CMD_GET_SENSOR_COUNT = 1,
- SM_CMD_GET_VALUE = 2,
- SM_CMD_SET_WARNING_VALUE = 3,
- SM_CMD_GET_WARNING_VALUE = 4,
- SM_CMD_SET_SENSOR_NAME = 5,
- SM_CMD_GET_SENSOR_NAME = 6,
- SM_CMD_SET_UPDATE_INTERVAL = 7,
- SM_CMD_FAIL = 255,
-};
-
-struct sm_get_sensor_count_req {
-} __attribute__((packed));
-
-struct sm_get_sensor_count_res {
- uint8_t count;
-} __attribute__((packed));
-
-struct sm_get_value_req {
- uint8_t sensor;
-} __attribute__((packed));
-
-struct sm_get_value_res {
- uint16_t value;
-} __attribute__((packed));
-
-struct sm_set_warning_value_req {
- uint8_t sensor;
- uint16_t warning_value;
-} __attribute__((packed));
-
-struct sm_set_warning_value_res {
-} __attribute__((packed));
-
-struct sm_get_warning_value_req {
- uint8_t sensor;
-} __attribute__((packed));
-
-struct sm_get_warning_value_res {
- uint16_t warning_value;
-} __attribute__((packed));
-
-struct sm_set_sensor_name_req {
- uint8_t sensor;
- uint8_t length;
- uint8_t name[SENSOR_NAME_LEN];
-} __attribute__((packed));
-
-struct sm_set_sensor_name_res {
-} __attribute__((packed));
-
-struct sm_get_sensor_name_req {
- uint8_t sensor;
-} __attribute__((packed));
-
-struct sm_get_sensor_name_res {
- uint8_t length;
- uint8_t name[SENSOR_NAME_LEN];
-} __attribute__((packed));
-
-struct sm_set_update_interval_req {
- uint8_t sensor;
- uint8_t interval_in_seconds;
-} __attribute__((packed));
-
-struct sm_set_update_interval_res {
-} __attribute__((packed));
-
-#define SM_REQ_HEADER_SIZE 1
-
-struct sm_req {
- // header
- uint8_t code;
-
- // body
- union {
- struct sm_get_sensor_count_req get_sensor_count;
- struct sm_get_value_req get_value;
- struct sm_set_warning_value_req set_warning_value;
- struct sm_get_warning_value_req get_warning_value;
- struct sm_set_sensor_name_req set_sensor_name;
- struct sm_get_sensor_name_req get_sensor_name;
- struct sm_set_update_interval_req set_update_interval;
- } __attribute__((packed));
-} __attribute__((packed));
-
-#define SM_RES_HEADER_SIZE 1
-
-struct sm_res {
- // header
- uint8_t code;
-
- // body
- union {
- struct sm_get_sensor_count_res get_sensor_count;
- struct sm_get_value_res get_value;
- struct sm_set_warning_value_res set_warning_value;
- struct sm_get_warning_value_res get_warning_value;
- struct sm_set_sensor_name_res set_sensor_name;
- struct sm_get_sensor_name_res get_sensor_name;
- struct sm_set_update_interval_res set_update_interval;
- } __attribute__((packed));
-} __attribute__((packed));
-
-#ifndef SM_DEBUG
-#define SM_DEBUG 1
-#endif
-
-#if SM_DEBUG == 1
-
-void write_req(struct sm_req const &req);
-
-void write_res(struct sm_res const &res);
-
-#endif
-
-#endif
diff --git a/include/ble/ByteBuffer.h b/include/ble/ByteBuffer.h
index f884d6e..74a1bf7 100644
--- a/include/ble/ByteBuffer.h
+++ b/include/ble/ByteBuffer.h
@@ -39,8 +39,9 @@ public:
return end - ptr;
}
- inline void setCursor(size_t newCursor) {
+ inline ByteBuffer &setCursor(size_t newCursor) {
ptr = (uint8_t *) &zero[newCursor];
+ return *this;
}
inline void skip(size_t length) {
@@ -52,8 +53,8 @@ public:
ByteBuffer &write16le(uint16_t value);
/**
- * Appends the entire buffer. Make a view if you want to write a part of it.
- */
+ * Appends the entire buffer. Make a view if you want to write a part of it.
+ */
ByteBuffer &write(const ByteBuffer &value);
ByteBuffer &write(const uint8_t *bytes, size_t len);