From d88eee8fcf23e20ae76b3dd346b36af693849ccd Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 22 Nov 2018 19:30:14 +0100 Subject: o Working enabling of notifications. --- include/ble/Bluetooth.h | 52 +++++++++++++++++------------------ include/ble/ByteBuffer.h | 71 ++++++++++++++++++++++++++---------------------- include/ble/att.h | 37 +++++++++++++++++++++++-- include/ble/misc.h | 46 ++++++++++++++++++++++++++++++- 4 files changed, 144 insertions(+), 62 deletions(-) (limited to 'include') diff --git a/include/ble/Bluetooth.h b/include/ble/Bluetooth.h index f97f3b8..b0228e5 100644 --- a/include/ble/Bluetooth.h +++ b/include/ble/Bluetooth.h @@ -27,19 +27,15 @@ template using o = std::optional; class BluetoothAdapter; - class BluetoothDevice; - class BluetoothGatt; -typedef shared_ptr BluetoothGattPtr; - class BluetoothGattService; -typedef shared_ptr BluetoothGattServicePtr; - class BluetoothGattCharacteristic; -typedef shared_ptr BluetoothGattCharacteristicPtr; - class BluetoothGattDescriptor; + +typedef shared_ptr BluetoothGattPtr; +typedef shared_ptr BluetoothGattServicePtr; +typedef shared_ptr BluetoothGattCharacteristicPtr; typedef shared_ptr BluetoothGattDescriptorPtr; class Mac { @@ -69,29 +65,29 @@ private: uint8_t bytes[6]; }; -template -class Iterator { -public: -private: -}; - -template -class Collection { -public: - Iterator begin(); - - Iterator end(); -}; - class BluetoothGattDescriptor { public: - static const uint8_t DISABLE_NOTIFICATION_VALUE[]; - static const uint8_t ENABLE_INDICATION_VALUE[]; - static const uint8_t ENABLE_NOTIFICATION_VALUE[]; + static const uint8_t DISABLE_NOTIFICATION_VALUE[2]; + static const uint8_t ENABLE_INDICATION_VALUE[2]; + static const uint8_t ENABLE_NOTIFICATION_VALUE[2]; virtual ~BluetoothGattDescriptor() = default; virtual BluetoothGattCharacteristicPtr getCharacteristic() const = 0; + + virtual uint16_t getHandle() const = 0; + + virtual const Uuid getUuid() const = 0; + + template + void setValue(const uint8_t (&buffer)[N]) { + auto tmp = ByteBuffer::wrap(buffer, N); + setValue(&tmp); + } + + virtual void setValue(const ByteBuffer &buffer) = 0; + + virtual ByteBuffer getValue() const = 0; }; class BluetoothGattCharacteristic { @@ -104,7 +100,7 @@ public: virtual const Uuid getUuid() const = 0; - virtual uint8_t getProperties() const = 0; + virtual CharacteristicProperties getProperties() const = 0; virtual uint16_t getValueHandle() const = 0; @@ -153,7 +149,9 @@ public: virtual void writeValue(const BluetoothGattCharacteristicPtr &c, const ByteBuffer &bytes) = 0; - virtual ByteBuffer readValue(const BluetoothGattCharacteristicPtr &c, ByteBuffer& response) = 0; + virtual void write(const BluetoothGattDescriptorPtr &d) = 0; + + virtual ByteBuffer readValue(const BluetoothGattCharacteristicPtr &c, ByteBuffer &response) = 0; virtual void setCharacteristicNotification(const BluetoothGattDescriptorPtr &c, bool enable) = 0; diff --git a/include/ble/ByteBuffer.h b/include/ble/ByteBuffer.h index 09deca5..6b09049 100644 --- a/include/ble/ByteBuffer.h +++ b/include/ble/ByteBuffer.h @@ -1,5 +1,5 @@ -#ifndef BYTE_STREAM_WRAPPER_H -#define BYTE_STREAM_WRAPPER_H +#ifndef BYTE_BUFFER_H +#define BYTE_BUFFER_H #include #include @@ -34,16 +34,29 @@ public: class ByteBuffer { public: + ByteBuffer() noexcept : zero(nullptr), end_(nullptr), cursor(nullptr) {}; + template - explicit ByteBuffer(uint8_t (&bytes)[N]) : zero(bytes), end_(&bytes[N]), cursor(bytes) {} + constexpr explicit ByteBuffer(uint8_t (&bytes)[N]) noexcept : zero(bytes), end_(&bytes[N]), cursor(zero) {}; + + ByteBuffer(uint8_t *bytes, size_t size) noexcept : zero(bytes), end_(&bytes[size]), cursor(zero) {}; - ByteBuffer(uint8_t* bytes, size_t capacity); + ByteBuffer(uint8_t *bytes, size_t size, size_t position) : zero(bytes), end_(&bytes[size]), cursor(zero) { + setPosition(position); + }; + + template + static const ByteBuffer wrapInitialized(const uint8_t (&bytes)[N], size_t cursor = 0) noexcept { + return wrap(bytes, N, N); + }; + + static const ByteBuffer wrap(const uint8_t *bytes, size_t size, size_t cursor = 0) noexcept; inline size_t getSize() const { return end_ - zero; } - inline size_t getCursor() const { + inline size_t getPosition() const { return cursor - zero; } @@ -51,10 +64,8 @@ public: return end_ - cursor; } - inline ByteBuffer &setCursor(size_t newCursor) { - auto tmp = (uint8_t *) &zero[newCursor]; - assertCanAccessIndex(tmp); - cursor = tmp; + inline ByteBuffer &setPosition(size_t newCursor) { + cursor = &zero[newCursor]; return *this; } @@ -70,12 +81,12 @@ public: return end_; } - inline uint8_t *begin() const { + inline uint8_t *underlying() { return const_cast(zero); } inline uint8_t *end() const { - return const_cast(end_); + return const_cast(cend()); } ByteBuffer &write8(uint8_t value); @@ -99,7 +110,7 @@ public: uint8_t get8(size_t index) const; /** - * Reads a uint8_t relative to the pointer. + * Reads a uint8_t relative to the cursor. */ uint8_t peek8(size_t relative_index) const; @@ -114,35 +125,31 @@ public: */ double readFLOAT(); - void copy(uint8_t *bytes, size_t length) const; + void copyFromEntire(const ByteBuffer &other) const; - void copy(ByteBuffer& other) const; + void copyTo(uint8_t *bytes, size_t length) const; - void reset(); + ByteBuffer viewCursorToEnd() const; - /** - * Creates a view from cursor to size. - */ - ByteBuffer view() const; + ByteBuffer viewBeginningToCursor() const; - ByteBuffer view(size_t length) const; + /** + * Creates a view from cursor to cursor + length. + */ + ByteBuffer viewForward(size_t length) const; - ByteBuffer viewAndSkip(size_t length) { - auto v = view(length); - skip(length); - return v; - } + /** + * Creates a view from cursor to cursor + length and then moves the cursor length further. + */ + ByteBuffer viewForwardAndSkip(size_t length); std::string toString() const; -private: - void assertCanAccessRelative(size_t diff) const; - - void assertCanAccessIndex(uint8_t *p) const; + void assertCanAccessPosition(size_t position) const; + void assertCanAccessPtr(uint8_t* ptr) const; - const uint8_t *zero; - const uint8_t *end_; - uint8_t *cursor; +protected: + uint8_t *zero, *end_, *cursor; }; template diff --git a/include/ble/att.h b/include/ble/att.h index 1db560e..db21d2e 100644 --- a/include/ble/att.h +++ b/include/ble/att.h @@ -49,6 +49,8 @@ std::string to_string(AttPduType t); class AttributeData; +class InformationData; + /** * Application Error 0x80 – 0xFF Application error code defined by a higher layer specification. * @@ -92,7 +94,7 @@ struct ErrorRes { */ uint8_t errorCode; - static ErrorRes parse(ByteBuffer& buffer) { + static ErrorRes parse(ByteBuffer &buffer) { return {buffer.read8(), buffer.read16le(), buffer.read8()}; } }; @@ -109,6 +111,13 @@ struct ExchangeMtuRes { uint16_t serverRxMtu; }; +struct FindInformationRes { + static constexpr auto att_pdu_type = AttPduType::FIND_INFORMATION_RES; + + uint8_t format; + std::vector information; +}; + struct ReadByGroupTypeRes { static constexpr auto att_pdu_type = AttPduType::READ_BY_GROUP_TYPE_RES; @@ -124,9 +133,10 @@ struct ReadByTypeRes { using AttVariant = std::variant; -o attPduType(const AttVariant& v); +o attPduType(const AttVariant &v); class AttPdu { public: @@ -139,14 +149,19 @@ public: static AttVariant parse(ByteBuffer &bytes); static ExchangeMtuReq parseExchangeMtuReq(ByteBuffer &bytes); + static ExchangeMtuRes parseExchangeMtuRes(ByteBuffer &bytes); + static FindInformationRes parseFindInformationRes(ByteBuffer &bytes); + static void parseRead(ByteBuffer &bytes); static void parseWrite(ByteBuffer &bytes); static void makeExchangeMtuRes(ByteBuffer &bytes, uint16_t serverRxMtu); + static void makeFindInformationReq(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle); + static void makeReadByGroupType(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle, ShortUuid uuid); static void makeReadByType(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle, ShortUuid uuid); @@ -178,5 +193,23 @@ private: std::shared_ptr raw; }; +class InformationData { +public: + static constexpr uint8_t FORMAT_SHORT_UUID = 0x01; + static constexpr uint8_t FORMAT_LONG_UUID = 0x02; + + ~InformationData() = default; + + static InformationData fromByteBufferShortUuid(ByteBuffer &value); + + static InformationData fromByteBufferLongUuid(ByteBuffer &value); + + const uint16_t handle; + const Uuid uuid; + +private: + InformationData(uint16_t handle, const Uuid &uuid); +}; + } // namespace bluetooth } // namespace trygvis diff --git a/include/ble/misc.h b/include/ble/misc.h index 2508d8e..70a19f5 100644 --- a/include/ble/misc.h +++ b/include/ble/misc.h @@ -1,7 +1,8 @@ #pragma once -#include +#include "ByteBuffer.h" +#include #include #include #include @@ -34,6 +35,10 @@ struct Uuid { std::memcpy(this->value, value, 16); } + explicit Uuid(ByteBuffer& buffer) noexcept : value() { + std::memcpy(value, buffer.cbegin(), 16); + } + Uuid(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7, uint8_t b8, uint8_t b9, uint8_t b10, uint8_t b11, uint8_t b12, uint8_t b13, uint8_t b14, uint8_t b15) noexcept : value{ b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15} {} @@ -62,6 +67,8 @@ private: public: explicit ShortUuid(uint16_t value) noexcept : value(value) {} + explicit ShortUuid(ByteBuffer& buffer) noexcept : value(buffer.read16le()) {} + Uuid toLong() const noexcept { auto b2 = static_cast(value >> 8); @@ -91,5 +98,42 @@ const ShortUuid CLIENT_CHARACTERISTIC_CONFIG{0x2902}; const ShortUuid TemperatureMeasurement{0x2A1C}; } +class CharacteristicProperties { +public: + const uint16_t value; + + bool broadcast() { + return static_cast(value & 0x01); + } + + bool read() { + return static_cast(value & 0x02); + } + + bool writeWithoutResponse() { + return static_cast(value & 0x04); + } + + bool write() { + return static_cast(value & 0x08); + } + + bool notify() { + return static_cast(value & 0x10); + } + + bool indicate() { + return static_cast(value & 0x20); + } + + bool authenticatedSignedWrites() { + return static_cast(value & 0x40); + } + + bool extendedProperties() { + return static_cast(value & 0x80); + } +}; + } // namespace bluetooth } // namespace trygvis -- cgit v1.2.3