aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt18
-rw-r--r--apps/CMakeLists.txt12
-rw-r--r--apps/apps.cpp13
-rw-r--r--apps/apps.h6
-rw-r--r--apps/ble-inspect-device.h2
-rw-r--r--apps/ble-scan.h11
-rw-r--r--apps/generate.cpp1
-rw-r--r--apps/launcher.cpp1
-rw-r--r--apps/sm-get-value.h6
-rw-r--r--ble/Bluetooth.cpp25
-rw-r--r--ble/BluetoothImpl.h14
-rw-r--r--ble/CMakeLists.txt21
-rw-r--r--ble/LinuxBluetooth.cpp6
-rw-r--r--ble/OsxBluetooth.h39
-rw-r--r--ble/OsxBluetooth.mm181
-rw-r--r--include/ble/Bluetooth.h14
-rw-r--r--sensor/CMakeLists.txt8
-rw-r--r--sensor/include/trygvis/sensor.h1
-rw-r--r--test/ByteBufferTest.cpp1
19 files changed, 341 insertions, 39 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9da7eb6..e4530c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,24 @@
cmake_minimum_required(VERSION 2.8.4)
project(ble_toys C CXX)
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+ set(IS_APPLE "YES")
+else()
+ set(IS_APPLE "NO")
+endif()
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ set(IS_LINUX "YES")
+else()
+ set(IS_LINUX "NO")
+endif()
+
+message(STATUS "IS_LINUX ${IS_LINUX}")
+message(STATUS "IS_APPLE ${IS_APPLE}")
+
+if(IS_LINUX)
find_package(PkgConfig)
+endif()
# Use Clang by default: http://stackoverflow.com/a/7031553/245614
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index 01252cf..a7defa2 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -3,8 +3,10 @@ list(APPEND APPS ble-scan)
list(APPEND APPS sample-add-timestamp)
list(APPEND APPS sample-convert)
list(APPEND APPS sample-select)
+if(IS_LINUX)
list(APPEND APPS sm-db-insert)
list(APPEND APPS sm-db-select)
+endif()
list(APPEND APPS sm-get-value)
list(APPEND APPS sm-serial-read)
list(APPEND APPS sm-serial-read-all)
@@ -12,6 +14,7 @@ list(APPEND APPS sm-serial-read-all)
# Boost
find_package(Boost COMPONENTS regex system program_options REQUIRED)
+if(IS_LINUX)
# Bluez
pkg_check_modules(BLUEZ bluez REQUIRED)
@@ -19,6 +22,8 @@ pkg_check_modules(BLUEZ bluez REQUIRED)
find_package(Threads REQUIRED)
pkg_check_modules(PQXX libpqxx REQUIRED)
+elseif()
+endif()
find_path(LOG4CPLUS_INCLUDE_DIRECTORIES log4cplus/logger.h)
if(LOG4CPLUS_INCLUDE_DIRECTORIES MATCHES NOTFOUND)
@@ -47,6 +52,12 @@ list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/generated/apps-list.gen.h)
list(APPEND SOURCES SoilMoisture.cpp SoilMoisture.h)
list(APPEND SOURCES apps.cpp apps.h)
+if(IS_LINUX)
+ list(APPEND COMPILE_OPTIONS -DIS_LINUX)
+elseif(IS_APPLE)
+ list(APPEND COMPILE_OPTIONS -DIS_APPLE)
+endif()
+
add_executable(launcher launcher.cpp
${SOURCES}
${APPS_SOURCES})
@@ -65,6 +76,7 @@ target_link_libraries(launcher ${BLUEZ_LIBRARIES})
target_link_libraries(launcher ${PQXX_LIBRARIES})
target_link_libraries(launcher ${LOG4CPLUS_LIBRARIES})
target_link_libraries(launcher ${CMAKE_THREAD_LIBS_INIT})
+target_compile_options(launcher PRIVATE -Wno-deprecated-register ${COMPILE_OPTIONS})
foreach(app ${APPS})
add_custom_command(
diff --git a/apps/apps.cpp b/apps/apps.cpp
index e0bb631..0034ba9 100644
--- a/apps/apps.cpp
+++ b/apps/apps.cpp
@@ -8,6 +8,19 @@ using namespace log4cplus;
using namespace std;
namespace po = boost::program_options;
+static string adapter_name;
+
+void add_ble_options(po::options_description &options) {
+ po::options_description bluetooth("Bluetooth");
+
+ bluetooth.add_options()
+ ("adapter", po::value<string>(&adapter_name), "Which local adapter to use");
+}
+
+std::string ble_adapter_name() {
+ return adapter_name;
+}
+
std::string get_hostname() {
static string s = "";
diff --git a/apps/apps.h b/apps/apps.h
index 7569a9f..b4de0a0 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -4,7 +4,9 @@
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include "json.hpp"
+#include "ble/Bluetooth.h"
#include <exception>
+#include <memory>
namespace trygvis {
namespace apps {
@@ -63,6 +65,10 @@ public:
const std::string app_name;
};
+void add_ble_options(po::options_description &options);
+
+std::string ble_adapter_name();
+
std::string get_hostname();
template<typename T>
diff --git a/apps/ble-inspect-device.h b/apps/ble-inspect-device.h
index 346f9be..d6f7255 100644
--- a/apps/ble-inspect-device.h
+++ b/apps/ble-inspect-device.h
@@ -56,7 +56,7 @@ public:
try {
Mac mac = Mac::parseMac(mac_str);
- shared_ptr<BluetoothAdapter> adapter = getAdapter(0);
+ shared_ptr<BluetoothAdapter> adapter = bluetoothSystem.getAdapter(ble_adapter_name());
BluetoothDevice &device = adapter->getDevice(mac);
diff --git a/apps/ble-scan.h b/apps/ble-scan.h
index 9a72388..cd1d979 100644
--- a/apps/ble-scan.h
+++ b/apps/ble-scan.h
@@ -28,9 +28,8 @@ public:
~ble_scan() = default;
- void add_options(po::options_description_easy_init &options) override {
- options
- ("adapter", po::value<int>()->default_value(0), "Which adapter to use.");
+ void add_extra_options(po::options_description & options) {
+ add_ble_options(options);
}
int main(app_execution &execution) override {
@@ -50,13 +49,11 @@ public:
sigaction(SIGINT, &sigIntHandler, NULL);
try {
- auto adapter_index = execution.vm["adapter"].as<int>();
-
- adapter = getAdapter(adapter_index);
+ adapter = bluetoothSystem.getAdapter(ble_adapter_name());
set<Mac> seen_devices;
- cout << "Scanning with adapter #" << adapter_index << ", mac=" << adapter->getMac().str() << endl;
+ cout << "Scanning with adapter " << adapter->getName() << ", mac=" << adapter->getMac().str() << endl;
adapter->runScan([&](BluetoothDevice &device) {
auto mac = device.getMac();
diff --git a/apps/generate.cpp b/apps/generate.cpp
index 9dcc271..89272d4 100644
--- a/apps/generate.cpp
+++ b/apps/generate.cpp
@@ -2,6 +2,7 @@
#include <iostream>
#include <fstream>
#include <regex>
+#include <sstream>
using namespace std;
diff --git a/apps/launcher.cpp b/apps/launcher.cpp
index 2a1e039..e20a6db 100644
--- a/apps/launcher.cpp
+++ b/apps/launcher.cpp
@@ -2,6 +2,7 @@
#include "apps-list.gen.h"
#include <log4cplus/consoleappender.h>
#include <log4cplus/configurator.h>
+#include <log4cplus/hierarchy.h>
namespace trygvis {
namespace apps {
diff --git a/apps/sm-get-value.h b/apps/sm-get-value.h
index 0535f68..58e7005 100644
--- a/apps/sm-get-value.h
+++ b/apps/sm-get-value.h
@@ -53,6 +53,10 @@ public:
("format", default_format, "Output format");
}
+ void add_extra_options(po::options_description & options) override {
+ add_ble_options(options);
+ }
+
int main(app_execution &execution) override {
__attribute__((unused))
BluetoothSystem bluetoothSystem;
@@ -71,7 +75,7 @@ public:
Mac mac = Mac::parseMac(MAC);
- auto adapter = getAdapter(0);
+ auto adapter = bluetoothSystem.getAdapter(ble_adapter_name());
auto &device = adapter->getDevice(mac);
diff --git a/ble/Bluetooth.cpp b/ble/Bluetooth.cpp
index 14a8cda..48fc87c 100644
--- a/ble/Bluetooth.cpp
+++ b/ble/Bluetooth.cpp
@@ -4,6 +4,12 @@
#include <sstream>
#include <iomanip>
+#if defined(IS_LINUX)
+#include "LinuxBluetooth.h"
+#elif defined(IS_APPLE)
+#include "OsxBluetooth.h"
+#endif
+
namespace trygvis {
namespace bluetooth {
using namespace std;
@@ -201,19 +207,26 @@ BluetoothAdapter::BluetoothAdapter() {
BluetoothAdapter::~BluetoothAdapter() {
}
+// -----------------------------------------------------------------------
+// BluetoothSystem
+// -----------------------------------------------------------------------
+
BluetoothSystem::BluetoothSystem() {
}
BluetoothSystem::~BluetoothSystem() {
- shutdown();
}
-shared_ptr<BluetoothAdapter> getAdapter(int hciDevice) {
- return getAdapterImpl(hciDevice);
-}
+shared_ptr<BluetoothAdapter> BluetoothSystem::getAdapter(string adapter_name) {
+#if defined(IS_LINUX)
+ typedef linux::LinuxBluetoothAdapter Impl;
+#elif defined(IS_APPLE)
+ typedef osx::OsxBluetoothAdapter Impl;
+
+ shared_ptr<Impl> adapter = osx::getAdapterImpl();
+#endif
-void shutdown() {
- shutdownImpl();
+ return std::static_pointer_cast<BluetoothAdapter>(std::move(adapter));
}
uuid_t makeUuid(const uuid_t base, uint8_t a, uint8_t b) {
diff --git a/ble/BluetoothImpl.h b/ble/BluetoothImpl.h
index 3f4615e..648961f 100644
--- a/ble/BluetoothImpl.h
+++ b/ble/BluetoothImpl.h
@@ -221,9 +221,14 @@ protected:
class DefaultBluetoothAdapter : protected LogSetup, public BluetoothAdapter {
public:
+
+ string getName() override {
+ return _name;
+ };
+
protected:
- DefaultBluetoothAdapter(Mac &mac) :
- LogSetup("BluetoothAdapter"), mac(mac) {
+ DefaultBluetoothAdapter(const string name, Mac &mac) :
+ LogSetup("BluetoothAdapter"), _name(name), mac(mac) {
}
Mac const &getMac() override {
@@ -231,12 +236,9 @@ protected:
};
Mac &mac;
+ const string _name;
};
-shared_ptr<BluetoothAdapter> getAdapterImpl(int hciDevice);
-
-void shutdownImpl();
-
}
};
diff --git a/ble/CMakeLists.txt b/ble/CMakeLists.txt
index 543e85d..5f20a21 100644
--- a/ble/CMakeLists.txt
+++ b/ble/CMakeLists.txt
@@ -1,4 +1,21 @@
-file(GLOB SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h)
+list(APPEND SOURCE_FILES Bluetooth.cpp)
+list(APPEND SOURCE_FILES BluetoothImpl.h)
+list(APPEND SOURCE_FILES ByteBuffer.cpp)
+list(APPEND SOURCE_FILES log.h)
+list(APPEND SOURCE_FILES "${PROJECT_SOURCE_DIR}/include/ble/Bluetooth.h")
+list(APPEND SOURCE_FILES "${PROJECT_SOURCE_DIR}/include/ble/ByteBuffer.h")
+
+if(IS_LINUX)
+ list(APPEND SOURCE_FILES LinuxBluetooth.cpp LinuxBluetooth.h)
+ list(APPEND COMPILE_OPTIONS -DIS_LINUX)
+elseif(IS_APPLE)
+ list(APPEND SOURCE_FILES OsxBluetooth.mm OsxBluetooth.h)
+ list(APPEND COMPILE_OPTIONS -DIS_APPLE)
+endif()
+
+find_package(Boost COMPONENTS regex system program_options REQUIRED)
add_library(ble ${SOURCE_FILES})
-include_directories("${PROJECT_SOURCE_DIR}/include")
+target_include_directories(ble PUBLIC "${PROJECT_SOURCE_DIR}/include")
+target_include_directories(ble PUBLIC "${Boost_INCLUDE_DIRS}")
+target_compile_options(ble PRIVATE -Wno-deprecated-register ${COMPILE_OPTIONS})
diff --git a/ble/LinuxBluetooth.cpp b/ble/LinuxBluetooth.cpp
index d48bfcd..4450d4d 100644
--- a/ble/LinuxBluetooth.cpp
+++ b/ble/LinuxBluetooth.cpp
@@ -22,8 +22,6 @@ class LinuxBluetoothGatt;
class LinuxBluetoothDevice;
-class LinuxBluetoothAdapter;
-
class LinuxBluetoothManager;
class LinuxBluetoothAdapter : public DefaultBluetoothAdapter {
@@ -207,7 +205,7 @@ void LinuxBluetoothGatt::disconnect() {
close(l2cap);
}
-uuid_t readUuid(BluetoothDevice *device, const ByteBuffer &bytes) {
+static uuid_t readUuid(BluetoothDevice *device, const ByteBuffer &bytes) {
size_t bytesLeft = bytes.getBytesLeft();
uuid_t u;
@@ -437,7 +435,7 @@ LinuxBluetoothAdapter::LinuxBluetoothAdapter(int hciDeviceId, Mac &mac) : Defaul
}
LinuxBluetoothAdapter::~LinuxBluetoothAdapter() {
- LOG_DEBUG("Stopping scan on device #" << hciDeviceId);
+ LOG_DEBUG("Closing adapter");
stopScan();
diff --git a/ble/OsxBluetooth.h b/ble/OsxBluetooth.h
new file mode 100644
index 0000000..8fa06a9
--- /dev/null
+++ b/ble/OsxBluetooth.h
@@ -0,0 +1,39 @@
+#ifndef OSX_BLUETOOTH_H
+#define OSX_BLUETOOTH_H
+
+#include <map>
+
+namespace trygvis {
+namespace bluetooth {
+namespace osx {
+
+class OsxBluetoothDevice;
+
+class OsxBluetoothAdapter : public DefaultBluetoothAdapter {
+public:
+ OsxBluetoothAdapter(const string name, Mac &mac);
+
+ ~OsxBluetoothAdapter();
+
+ void startScan() override;
+
+ void stopScan() override;
+
+ void runScan(std::function<void(BluetoothDevice &device)>) override;
+
+ BluetoothDevice &getDevice(Mac &mac) override;
+
+private:
+ bool scanning;
+
+ map<Mac, OsxBluetoothDevice *> devices;
+};
+
+shared_ptr<OsxBluetoothAdapter>&& getAdapterImpl();
+void shutdownImpl();
+
+}
+}
+}
+
+#endif
diff --git a/ble/OsxBluetooth.mm b/ble/OsxBluetooth.mm
new file mode 100644
index 0000000..e94edaf
--- /dev/null
+++ b/ble/OsxBluetooth.mm
@@ -0,0 +1,181 @@
+#import <CoreFoundation/CoreFoundation.h>
+#import <IOBluetooth/IOBluetoothUtilities.h>
+#import <IOBluetooth/objc/IOBluetoothSDPUUID.h>
+#import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h>
+
+#import "BluetoothImpl.h"
+#import "OsxBluetooth.h"
+
+#include <map>
+using namespace std;
+
+namespace trygvis {
+namespace bluetooth {
+namespace osx {
+
+class OsxBluetoothDevice;
+class OsxBluetoothGatt;
+
+class OsxBluetoothDevice : public DefaultBluetoothDevice<OsxBluetoothAdapter> {
+public:
+ OsxBluetoothDevice(OsxBluetoothAdapter &adapter, Mac &mac);
+
+ ~OsxBluetoothDevice();
+
+ shared_ptr<BluetoothGatt> connectGatt() override;
+
+private:
+ weak_ptr<OsxBluetoothGatt> gatt;
+};
+
+class OsxBluetoothGatt : public DefaultBluetoothGatt<OsxBluetoothDevice> {
+public:
+ OsxBluetoothGatt(OsxBluetoothDevice &device);
+
+ ~OsxBluetoothGatt();
+
+ OsxBluetoothGatt(const OsxBluetoothGatt&) = delete;
+
+ OsxBluetoothGatt& operator=(const OsxBluetoothGatt&) = delete;
+
+ bool isConnected() const override;
+
+ void discoverServices() override;
+
+ void writeValue(const BluetoothGattCharacteristic &c, const ByteBuffer &bytes) override;
+
+ ByteBuffer readValue(const BluetoothGattCharacteristic &c) override;
+
+private:
+ void connect();
+
+ void disconnect();
+
+ vector<AttributeData> discoverServices(uint16_t startHandle);
+
+ vector<AttributeData> discoverCharacteristics(uint16_t startHandle, uint16_t endHandle);
+
+ ByteBuffer writeAndRead(ByteBuffer &out, shared_ptr<uint8_t> buffer, size_t size);
+
+ int l2cap;
+
+ bool connected;
+};
+
+OsxBluetoothAdapter::OsxBluetoothAdapter(const string name, Mac &mac) : DefaultBluetoothAdapter(name, mac) {
+}
+
+OsxBluetoothAdapter::~OsxBluetoothAdapter() {
+}
+
+void OsxBluetoothAdapter::startScan() {
+}
+
+void OsxBluetoothAdapter::stopScan() {
+}
+
+void OsxBluetoothAdapter::runScan(std::function<void(BluetoothDevice &device)>) {
+}
+
+BluetoothDevice &OsxBluetoothAdapter::getDevice(Mac &mac) {
+ map<Mac, OsxBluetoothDevice *>::iterator it = devices.find(mac);
+
+ if (it == devices.end()) {
+ OsxBluetoothDevice *device = new OsxBluetoothDevice(*this, mac);
+ devices[mac] = device;
+ return *device;
+ }
+
+ return *it->second;
+}
+
+OsxBluetoothDevice::OsxBluetoothDevice(OsxBluetoothAdapter &adapter, Mac &mac) : DefaultBluetoothDevice(adapter, mac) {
+}
+
+OsxBluetoothDevice::~OsxBluetoothDevice() {
+}
+
+shared_ptr<BluetoothGatt> OsxBluetoothDevice::connectGatt() {
+ if (auto p = gatt.lock()) {
+ return p;
+ }
+ auto ref = make_shared<OsxBluetoothGatt>(*this);
+
+ gatt = ref;
+
+ return ref;
+}
+
+// -----------------------------------------------------------------------
+// Gatt
+// -----------------------------------------------------------------------
+
+OsxBluetoothGatt::OsxBluetoothGatt(OsxBluetoothDevice &device) :
+ DefaultBluetoothGatt(device) {
+ connect();
+}
+
+OsxBluetoothGatt::~OsxBluetoothGatt() {
+ disconnect();
+}
+
+bool OsxBluetoothGatt::isConnected() const {
+ return connected;
+}
+
+void OsxBluetoothGatt::connect() {
+}
+
+void OsxBluetoothGatt::disconnect() {
+ if (!connected) {
+ return;
+ }
+}
+
+void OsxBluetoothGatt::writeValue(const BluetoothGattCharacteristic &c, const ByteBuffer &bytes) {
+}
+
+ByteBuffer OsxBluetoothGatt::readValue(const BluetoothGattCharacteristic &c) {
+ shared_ptr<uint8_t> buffer(new uint8_t[0]);
+
+ return ByteBuffer(buffer, 0);
+}
+
+void OsxBluetoothGatt::discoverServices() {
+}
+
+/*
+ByteBuffer OsxBluetoothGatt::writeAndRead(ByteBuffer &out, shared_ptr<uint8_t> buffer, size_t size) {
+}
+
+vector<AttributeData> OsxBluetoothGatt::discoverServices(uint16_t startHandle) {
+}
+
+vector<AttributeData> OsxBluetoothGatt::discoverCharacteristics(uint16_t startHandle, uint16_t endHandle) {
+}
+*/
+
+// -----------------------------------------------------------------------
+// OsxBluetoothSystem
+// -----------------------------------------------------------------------
+
+
+// We only have a single adapter on OSX.
+shared_ptr<OsxBluetoothAdapter> adapter;
+
+shared_ptr<OsxBluetoothAdapter>&& getAdapterImpl() {
+ if(!adapter) {
+ auto mac = Mac::parseMac("00:00:00:00:00:00");
+ adapter = make_shared<OsxBluetoothAdapter>("system", mac);
+ }
+
+ return std::move(adapter);
+}
+
+void shutdownImpl() {
+ adapter.reset();
+}
+
+}
+}
+}
diff --git a/include/ble/Bluetooth.h b/include/ble/Bluetooth.h
index 6a974d5..b035223 100644
--- a/include/ble/Bluetooth.h
+++ b/include/ble/Bluetooth.h
@@ -3,6 +3,7 @@
#include <string>
#include <stdexcept>
+#include <vector>
#include <boost/uuid/uuid.hpp>
#include <boost/optional.hpp>
@@ -167,21 +168,20 @@ public:
virtual BluetoothDevice &getDevice(Mac &mac) = 0;
+ virtual string getName() = 0;
+
protected:
BluetoothAdapter();
virtual ~BluetoothAdapter();
};
-/**
-* Right this is only RAII support to properly call shutdown().
-*
-* TODO: move getAdapter() here. Make this control all shutdowns.
-*/
class BluetoothSystem {
public:
BluetoothSystem();
+ shared_ptr<BluetoothAdapter> getAdapter(string adapter_name);
+
~BluetoothSystem();
};
@@ -245,10 +245,6 @@ private:
AttributeData(uint16_t handle, ByteBuffer value);
};
-shared_ptr<BluetoothAdapter> getAdapter(int hciDevice);
-
-void shutdown();
-
boost::uuids::uuid makeUuid(const boost::uuids::uuid base, uint8_t a, uint8_t b);
}
diff --git a/sensor/CMakeLists.txt b/sensor/CMakeLists.txt
index d571e38..fb118d1 100644
--- a/sensor/CMakeLists.txt
+++ b/sensor/CMakeLists.txt
@@ -5,10 +5,12 @@ add_library(trygvis-sensor
main/io.cpp
${INCLUDES})
-include_directories("${PROJECT_SOURCE_DIR}/json/src")
-include_directories(include)
-
# Boost
find_package(Boost COMPONENTS regex system REQUIRED)
+target_include_directories(trygvis-sensor
+ PUBLIC "${PROJECT_SOURCE_DIR}/json/src"
+ PUBLIC "${PROJECT_SOURCE_DIR}/sensor/include"
+ PUBLIC "${Boost_INCLUDE_DIRS}")
+
add_subdirectory(test)
diff --git a/sensor/include/trygvis/sensor.h b/sensor/include/trygvis/sensor.h
index b5199e2..e78d845 100644
--- a/sensor/include/trygvis/sensor.h
+++ b/sensor/include/trygvis/sensor.h
@@ -4,6 +4,7 @@
#include <string>
#include <iostream>
#include <memory>
+#include <vector>
#include <boost/optional/optional.hpp>
namespace trygvis {
diff --git a/test/ByteBufferTest.cpp b/test/ByteBufferTest.cpp
index 5aad376..d7b1736 100644
--- a/test/ByteBufferTest.cpp
+++ b/test/ByteBufferTest.cpp
@@ -1,4 +1,5 @@
#include "ble/ByteBuffer.h"
+#include <iostream>
#define BOOST_TEST_MODULE "ByteBuffer"