aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt56
-rw-r--r--apps/CMakeLists.txt22
-rw-r--r--apps/ble-inspect-device.cpp (renamed from main.cpp)0
-rw-r--r--apps/sm-get-value.cpp75
-rw-r--r--apps/soil-moisture.h118
-rw-r--r--ble/Bluetooth.cpp (renamed from Bluetooth.cpp)0
-rw-r--r--ble/Bluetooth.h (renamed from Bluetooth.h)3
-rw-r--r--ble/BluetoothImpl.h (renamed from BluetoothImpl.h)13
-rw-r--r--ble/ByteBuffer.cpp (renamed from ByteBuffer.cpp)0
-rw-r--r--ble/ByteBuffer.h (renamed from ByteBuffer.h)0
-rw-r--r--ble/CMakeLists.txt3
-rw-r--r--ble/LinuxBluetooth.cpp (renamed from LinuxBluetooth.cpp)0
-rw-r--r--ble/log.h (renamed from log.h)0
-rw-r--r--test/CMakeLists.txt30
14 files changed, 267 insertions, 53 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bd0d7a7..a6e2d6e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,65 +3,15 @@ project(ble_toys C CXX)
find_package(PkgConfig)
# Use Clang by default: http://stackoverflow.com/a/7031553/245614
-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
-set(SOURCE_FILES "${SOURCE_FILES}"
- Bluetooth.cpp
- LinuxBluetooth.cpp
- ByteBuffer.cpp)
-
-add_library(ble ${SOURCE_FILES})
-
-add_executable(ble_toys main.cpp)
-target_link_libraries(ble_toys ble)
-
# Boost
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
-find_package(Boost COMPONENTS system log thread REQUIRED)
-target_link_libraries(ble_toys ${Boost_LIBRARIES})
-
add_definitions(-DBOOST_ALL_DYN_LINK)
-# Bluez
-pkg_check_modules(BLUEZ bluez REQUIRED)
-target_link_libraries(ble_toys ${BLUEZ_LIBRARIES})
-
-# pthreads
-find_package(Threads REQUIRED)
-target_link_libraries(ble_toys ${CMAKE_THREAD_LIBS_INIT})
-
-enable_testing()
-find_package(Boost COMPONENTS log unit_test_framework REQUIRED)
-
-# If we can change directory here add_definition and test-specific stuff could be moved to the test directory
-file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} test/*.cpp)
-add_definitions(-DBOOST_TEST_DYN_LINK)
-
-foreach(testSrc ${TEST_SRCS})
- #Extract the filename without an extension (NAME_WE)
- get_filename_component(testName ${testSrc} NAME_WE)
-
- #Add compile target
- add_executable(${testName} ${testSrc})
-
- include_directories(${PROJECT_SOURCE_DIR})
-
- #link to Boost libraries AND your targets and dependencies
- target_link_libraries(${testName} ble)
- target_link_libraries(${testName} pthread)
- target_link_libraries(${testName} ${Boost_LIBRARIES})
-
- #I like to move testing binaries into a testBin directory
- set_target_properties(${testName} PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test)
-
- #Finally add it to test execution -
- #Notice the WORKING_DIRECTORY and COMMAND
- add_test(NAME ${testName}
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test
- COMMAND ${CMAKE_BINARY_DIR}/test/${testName} )
-endforeach(testSrc)
+add_subdirectory(ble)
+add_subdirectory(apps)
+add_subdirectory(test)
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
new file mode 100644
index 0000000..a138336
--- /dev/null
+++ b/apps/CMakeLists.txt
@@ -0,0 +1,22 @@
+set(APPS sm-get-value ble-inspect-device)
+
+# Boost
+find_package(Boost COMPONENTS system log thread REQUIRED)
+
+# Bluez
+pkg_check_modules(BLUEZ bluez REQUIRED)
+
+# pthreads
+find_package(Threads REQUIRED)
+
+foreach(app ${APPS})
+ include_directories("${PROJECT_SOURCE_DIR}/ble")
+
+ add_executable(${app} ${app}.cpp)
+ add_dependencies(${app} ble)
+
+ target_link_libraries(${app} ble)
+ target_link_libraries(${app} ${Boost_LIBRARIES})
+ target_link_libraries(${app} ${BLUEZ_LIBRARIES})
+ target_link_libraries(${app} ${CMAKE_THREAD_LIBS_INIT})
+endforeach(app)
diff --git a/main.cpp b/apps/ble-inspect-device.cpp
index 361311c..361311c 100644
--- a/main.cpp
+++ b/apps/ble-inspect-device.cpp
diff --git a/apps/sm-get-value.cpp b/apps/sm-get-value.cpp
new file mode 100644
index 0000000..232c166
--- /dev/null
+++ b/apps/sm-get-value.cpp
@@ -0,0 +1,75 @@
+#include <exception>
+#include <iostream>
+#include <vector>
+#include <boost/uuid/uuid_io.hpp>
+#include <boost/optional.hpp>
+#include "Bluetooth.h"
+#include "soil-moisture.h"
+
+using namespace std;
+using namespace trygvis::bluetooth;
+
+Mac *targetMac;
+
+void scan_callback(BluetoothDevice &device) {
+ device.adapter().stopScan();
+
+ if (device.mac() != *targetMac) {
+ cout << "found device: " << device.mac().str() << ", but not the one we want " << targetMac->str() << endl;
+ return;
+ }
+
+ cout << "Connecting to device: " << device.mac().str() << endl;
+
+ device.connect();
+
+ device.discoverServices();
+
+ vector<BluetoothGattService *> services = device.getServices();
+ cout << "Device has " << services.size() << " services" << endl;
+
+ for (auto &s: services) {
+ const vector<BluetoothGattCharacteristic *> characteristics = s->getCharacteristics();
+
+ cout << "Service: UUID: " << s->getUuid() << ", has " << characteristics.size() << " characteristics" << endl;
+
+ for (auto &c: characteristics) {
+ cout << "Characteristic: UUID: " << c->getUuid() << ", properties: " << (int) c->getProperties() << endl;
+ }
+ }
+
+ boost::uuids::uuid soil_moisture_service;
+ boost::optional<BluetoothGattService*> service = device.findService(soil_moisture_service);
+
+ device.disconnect();
+}
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ cerr << "usage: " << argv[0] << " [mac]" << endl;
+ return EXIT_FAILURE;
+ }
+
+ int e;
+// try {
+ Mac mac = Mac::parseMac(argv[1]);
+ targetMac = &mac;
+
+ BluetoothAdapter &adapter = getAdapter(0);
+
+ BluetoothDevice &device = adapter.getDevice(mac);
+
+ scan_callback(device);
+
+ e = EXIT_SUCCESS;
+// } catch (std::runtime_error ex) {
+// W << "std::runtime_error: " << ex.what();
+// e = EXIT_FAILURE;
+// } catch (std::exception ex) {
+// W << "std::exception: " << ex.what();
+// e = EXIT_FAILURE;
+// }
+
+ shutdown();
+ return e;
+}
diff --git a/apps/soil-moisture.h b/apps/soil-moisture.h
new file mode 100644
index 0000000..4f19de1
--- /dev/null
+++ b/apps/soil-moisture.h
@@ -0,0 +1,118 @@
+#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));
+
+struct sm_req {
+ uint8_t code;
+ 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));
+
+// len + code
+#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/Bluetooth.cpp b/ble/Bluetooth.cpp
index b135282..b135282 100644
--- a/Bluetooth.cpp
+++ b/ble/Bluetooth.cpp
diff --git a/Bluetooth.h b/ble/Bluetooth.h
index 4314d8e..e47ff3e 100644
--- a/Bluetooth.h
+++ b/ble/Bluetooth.h
@@ -4,6 +4,7 @@
#include <string>
#include <stdexcept>
#include <boost/uuid/uuid.hpp>
+#include <boost/optional.hpp>
#include "ByteBuffer.h"
@@ -128,6 +129,8 @@ public:
virtual void discoverServices() = 0;
virtual const vector<BluetoothGattService *> getServices() const = 0;
+
+ virtual const boost::optional<BluetoothGattService*> findService(boost::uuids::uuid uuid) const = 0;
};
class BluetoothAdapter {
diff --git a/BluetoothImpl.h b/ble/BluetoothImpl.h
index 3fad164..69fac6e 100644
--- a/BluetoothImpl.h
+++ b/ble/BluetoothImpl.h
@@ -3,6 +3,7 @@
#include "Bluetooth.h"
#include <boost/uuid/uuid_io.hpp>
+#include <cstring>
#define BLUETOOTH_UUID_INITIALIZER \
{ \
@@ -17,6 +18,8 @@ namespace trygvis {
namespace bluetooth {
typedef boost::uuids::uuid uuid_t;
+template <class t>
+using o = boost::optional<t>;
class DefaultBluetoothGattCharacteristic : public BluetoothGattCharacteristic {
public:
@@ -113,6 +116,16 @@ public:
return services;
};
+ virtual const o<BluetoothGattService*> findService(boost::uuids::uuid uuid) const {
+ for (auto s: services) {
+ if (memcmp(s->getUuid().data, uuid.data, 16) == 0) {
+ return o<BluetoothGattService*>(s);
+ }
+ }
+
+ return o<BluetoothGattService*>();
+ }
+
virtual void addService(BluetoothGattService *service) {
services.push_back(service);
}
diff --git a/ByteBuffer.cpp b/ble/ByteBuffer.cpp
index 820c638..820c638 100644
--- a/ByteBuffer.cpp
+++ b/ble/ByteBuffer.cpp
diff --git a/ByteBuffer.h b/ble/ByteBuffer.h
index 3836966..3836966 100644
--- a/ByteBuffer.h
+++ b/ble/ByteBuffer.h
diff --git a/ble/CMakeLists.txt b/ble/CMakeLists.txt
new file mode 100644
index 0000000..1ecfb6c
--- /dev/null
+++ b/ble/CMakeLists.txt
@@ -0,0 +1,3 @@
+file(GLOB SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
+
+add_library(ble ${SOURCE_FILES})
diff --git a/LinuxBluetooth.cpp b/ble/LinuxBluetooth.cpp
index 4b7f0e0..4b7f0e0 100644
--- a/LinuxBluetooth.cpp
+++ b/ble/LinuxBluetooth.cpp
diff --git a/log.h b/ble/log.h
index 1d62121..1d62121 100644
--- a/log.h
+++ b/ble/log.h
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..14dcdf7
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,30 @@
+enable_testing()
+find_package(Boost COMPONENTS log unit_test_framework REQUIRED)
+
+# If we can change directory here add_definition and test-specific stuff could be moved to the test directory
+file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *Test.cpp)
+add_definitions(-DBOOST_TEST_DYN_LINK)
+
+foreach(testSrc ${TEST_SRCS})
+ #Extract the filename without an extension (NAME_WE)
+ get_filename_component(testName ${testSrc} NAME_WE)
+
+ #Add compile target
+ add_executable(${testName} ${testSrc})
+
+ include_directories("${PROJECT_SOURCE_DIR}/ble")
+ add_dependencies(${testName} ble)
+ target_link_libraries(${testName} ble)
+ target_link_libraries(${testName} pthread)
+ target_link_libraries(${testName} ${Boost_LIBRARIES})
+
+ #I like to move testing binaries into a testBin directory
+ set_target_properties(${testName} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test)
+
+ #Finally add it to test execution -
+ #Notice the WORKING_DIRECTORY and COMMAND
+ add_test(NAME ${testName}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/testBin
+ COMMAND ${CMAKE_BINARY_DIR}/testBin/${testName})
+endforeach(testSrc)