From 2ca532122d60cff4dbdc7f24fbc5783bcc5ad68d Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 12 Apr 2016 20:06:47 +0200 Subject: Soil Moisture: Adding support for controlling lights. Bluetooth: refectorying, trying to be more c++ idiomatic and modern. SM/Diller: adding bluetooth to Diller bridge. --- ble/BluetoothImpl.h | 131 +++++++++++++++++++++++++++++++------------------ ble/LinuxBluetooth.cpp | 31 +++++++----- 2 files changed, 104 insertions(+), 58 deletions(-) (limited to 'ble') diff --git a/ble/BluetoothImpl.h b/ble/BluetoothImpl.h index 4627443..8663b20 100644 --- a/ble/BluetoothImpl.h +++ b/ble/BluetoothImpl.h @@ -26,8 +26,6 @@ namespace bluetooth { // Utility typedefs typedef boost::uuids::uuid uuid_t; -template -using o = boost::optional; using namespace log4cplus; // Logging @@ -43,18 +41,45 @@ protected: // Shared classes +namespace detail { + +template +struct constify2; + +template +struct constify2 { + typedef T *type; +}; + +template +struct constify2 { + typedef T const *type; +}; + +} + +template +class CollectionImpl : public Collection { +public: + CollectionImpl(B &b) : b(b) { + } + +private: + B &b; +}; + class DefaultBluetoothGattCharacteristic : protected LogSetup, public BluetoothGattCharacteristic { public: - DefaultBluetoothGattCharacteristic(BluetoothGattService &service, uint16_t handle, uuid_t uuid, uint8_t properties, - uint16_t valueHandle) - : LogSetup("BluetoothGattCharacteristic"), service(service), handle(handle), uuid(uuid), - properties(properties), valueHandle(valueHandle) { + DefaultBluetoothGattCharacteristic(const BluetoothGattServicePtr &service, uint16_t handle, uuid_t uuid, + uint8_t properties, uint16_t valueHandle) + : LogSetup("BluetoothGattCharacteristic"), service(service), handle(handle), uuid(uuid), + properties(properties), valueHandle(valueHandle) { } virtual ~DefaultBluetoothGattCharacteristic() { } - BluetoothGattService &getService() const { + BluetoothGattServicePtr getService() const { return service; } @@ -75,22 +100,29 @@ public: } protected: - BluetoothGattService &service; + BluetoothGattServicePtr service; uint16_t handle; uuid_t uuid; uint8_t properties; uint16_t valueHandle; }; +template class DefaultBluetoothGattService : public BluetoothGattService { public: - DefaultBluetoothGattService(BluetoothDevice &device, const uuid_t uuid, const uint16_t handle, + DefaultBluetoothGattService(DeviceType &device, const uuid_t uuid, const uint16_t handle, const uint16_t endGroupHandle) - : device(device), uuid(uuid), handle(handle), endGroupHandle(endGroupHandle) { + : device(device), uuid(uuid), handle(handle), endGroupHandle(endGroupHandle) { + } + + DefaultBluetoothGattService(const DefaultBluetoothGattService &o) = delete; + + DefaultBluetoothGattService(DefaultBluetoothGattService &&o) noexcept + : device(std::move(o.device)), uuid(std::move(o.uuid)), handle(std::move(o.handle)), + endGroupHandle(std::move(o.endGroupHandle)), characteristics(std::move(o.characteristics)) { } virtual ~DefaultBluetoothGattService() { - removeCharacteristics(); } virtual BluetoothDevice &getDevice() const { @@ -109,62 +141,63 @@ public: return endGroupHandle; } - virtual const vector getCharacteristics() const { - return characteristics; + virtual vector> getCharacteristics() const { + vector> cs(characteristics.size()); + std::copy(begin(characteristics), end(characteristics), begin(cs)); + return cs; } - virtual void addCharacteristic(BluetoothGattCharacteristic *characteristic) { - characteristics.push_back(characteristic); + virtual void addCharacteristic(shared_ptr &&characteristic) { + characteristics.emplace_back(characteristic); } - virtual const o findCharacteristic(uuid_t uuid) const { - for (auto c: characteristics) { + virtual o> findCharacteristic(uuid_t uuid) { + for (auto &c: characteristics) { if (memcmp(c->getUuid().data, uuid.data, 16) == 0) { - return o(*c); + return o>(c); } } - return o(); + return o>(); } protected: - BluetoothDevice &device; + DeviceType &device; const uuid_t uuid; const uint16_t handle; const uint16_t endGroupHandle; - vector characteristics; - - void removeCharacteristics() { - for (auto &c: characteristics) { - delete c; - } - characteristics.clear(); - } + vector> characteristics; }; -template +template class DefaultBluetoothGatt : protected LogSetup, public BluetoothGatt { public: virtual _D &getDevice() const { return device; } - virtual const vector getServices() const { - return services; - }; +// virtual Collection getServices() const { +// return CollectionImpl>(services); +// } - virtual const o findService(uuid_t uuid) const { - for (auto s: services) { + virtual vector> getServices() const { + vector> ss(services.size()); + std::copy(begin(services), end(services), begin(ss)); + return ss; + } + + virtual o findService(uuid_t uuid) { + for (auto &s: services) { if (memcmp(s->getUuid().data, uuid.data, 16) == 0) { - return o(*s); + return o>(s); } } - return o(); + return o>(); } - virtual void addService(BluetoothGattService *service) { - services.push_back(service); + void addService(shared_ptr<_S> service) { + services.emplace_back(service); } protected: @@ -172,18 +205,18 @@ protected: } virtual ~DefaultBluetoothGatt() { - removeServices(); +// removeServices(); } void removeServices() { - for (auto s: services) { - delete s; - } +// for (auto s: services) { +// delete s; +// } services.clear(); } _D &device; - vector services; + vector> services; }; template @@ -199,8 +232,12 @@ public: } protected: - DefaultBluetoothDevice(A &adapter, Mac &mac) : LogSetup("BluetoothDevice"), - adapter(adapter), mac(mac) { + DefaultBluetoothDevice(A &adapter, Mac &mac) : + LogSetup("BluetoothDevice"), adapter(adapter), mac(mac) { + } + + DefaultBluetoothDevice(DefaultBluetoothDevice &&o) noexcept : + LogSetup("BluetoothDevice"), adapter(std::move(o.adapter)), mac(std::move(o.mac)) { } virtual ~DefaultBluetoothDevice() { @@ -223,7 +260,7 @@ class DefaultBluetoothAdapter : protected LogSetup, public BluetoothAdapter { public: protected: DefaultBluetoothAdapter(Mac &mac) : - LogSetup("BluetoothAdapter"), mac(mac) { + LogSetup("BluetoothAdapter"), mac(mac) { } Mac const &getMac() override { @@ -233,7 +270,7 @@ protected: Mac &mac; }; -shared_ptr getAdapterImpl(string name); +shared_ptr getAdapterImpl(string name); } }; diff --git a/ble/LinuxBluetooth.cpp b/ble/LinuxBluetooth.cpp index 587016c..d4073d1 100644 --- a/ble/LinuxBluetooth.cpp +++ b/ble/LinuxBluetooth.cpp @@ -28,6 +28,15 @@ class LinuxBluetoothAdapter; class LinuxBluetoothManager; +class LinuxBluetoothGattService : public DefaultBluetoothGattService { +public: + LinuxBluetoothGattService(LinuxBluetoothDevice &device, const uuid_t uuid, const uint16_t handle, + const uint16_t endGroupHandle) : DefaultBluetoothGattService(device, uuid, handle, endGroupHandle) { + }; + + LinuxBluetoothGattService(const LinuxBluetoothGattService &o) = delete; +}; + class LinuxBluetoothAdapter final : public DefaultBluetoothAdapter { public: LinuxBluetoothAdapter(int hciDeviceId, Mac &mac); @@ -72,7 +81,7 @@ private: LinuxBluetoothGatt *gatt; }; -class LinuxBluetoothGatt final : public DefaultBluetoothGatt { +class LinuxBluetoothGatt final : public DefaultBluetoothGatt { public: LinuxBluetoothGatt(LinuxBluetoothDevice &device); @@ -86,9 +95,9 @@ public: void discoverServices() override; - void writeValue(const BluetoothGattCharacteristic &c, const ByteBuffer &bytes) override; + void writeValue(const BluetoothGattCharacteristicPtr &c, const ByteBuffer &bytes) override; - ByteBuffer readValue(const BluetoothGattCharacteristic &c) override; + ByteBuffer readValue(const BluetoothGattCharacteristicPtr &c) override; private: void connect(); @@ -252,24 +261,24 @@ uuid_t readUuid(BluetoothDevice *device, const ByteBuffer &bytes) { return u; } -void LinuxBluetoothGatt::writeValue(const BluetoothGattCharacteristic &c, const ByteBuffer &bytes) { - LOG_DEBUG("Writing to characteristic " << c.getUuid() << ": " << bytes.toString()); +void LinuxBluetoothGatt::writeValue(const BluetoothGattCharacteristicPtr &c, const ByteBuffer &bytes) { + LOG_DEBUG("Writing to characteristic " << c->getUuid() << ": " << bytes.toString()); shared_ptr buffer(new uint8_t[MAX_MTU]); ByteBuffer out = ByteBuffer(buffer, MAX_MTU); - AttPdu::makeWrite(out, c.getValueHandle(), bytes); + AttPdu::makeWrite(out, c->getValueHandle(), bytes); ByteBuffer in = writeAndRead(out, buffer, MAX_MTU); AttPdu::parseWrite(in); } -ByteBuffer LinuxBluetoothGatt::readValue(const BluetoothGattCharacteristic &c) { +ByteBuffer LinuxBluetoothGatt::readValue(const BluetoothGattCharacteristicPtr &c) { shared_ptr buffer(new uint8_t[MAX_MTU]); ByteBuffer out = ByteBuffer(buffer, MAX_MTU); - AttPdu::makeRead(out, c.getValueHandle()); + AttPdu::makeRead(out, c->getValueHandle()); ByteBuffer in = writeAndRead(out, buffer, MAX_MTU); @@ -279,7 +288,7 @@ ByteBuffer LinuxBluetoothGatt::readValue(const BluetoothGattCharacteristic &c) { auto response = in.view(); - LOG_DEBUG("Value of characteristic " << c.getUuid() << "=" << response.toString()); + LOG_DEBUG("Value of characteristic " << c->getUuid() << "=" << response.toString()); return response; } @@ -308,7 +317,7 @@ void LinuxBluetoothGatt::discoverServices() { uuid_t u = readUuid(&device, data.value); - addService(new DefaultBluetoothGattService(device, u, data.handle, endGroupHandle)); + addService(make_shared(device, u, data.handle, endGroupHandle)); } // auto last = values.back(); @@ -358,7 +367,7 @@ void LinuxBluetoothGatt::discoverServices() { // ", valueHandle: 0x" << setw(4) << setfill('0') << hex << (int) valueHandle << // ", uuid: " << uuid; - s->addCharacteristic(new DefaultBluetoothGattCharacteristic(*s, c.handle, uuid, properties, valueHandle)); + s->addCharacteristic(std::move(make_shared(s, c.handle, uuid, properties, valueHandle))); } startHandle = lastHandle + (uint8_t) 2; -- cgit v1.2.3