aboutsummaryrefslogtreecommitdiff
path: root/include/ble
diff options
context:
space:
mode:
Diffstat (limited to 'include/ble')
-rw-r--r--include/ble/Bluetooth.h52
-rw-r--r--include/ble/ByteBuffer.h71
-rw-r--r--include/ble/att.h37
-rw-r--r--include/ble/misc.h46
4 files changed, 144 insertions, 62 deletions
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<typename T>
using o = std::optional<T>;
class BluetoothAdapter;
-
class BluetoothDevice;
-
class BluetoothGatt;
-typedef shared_ptr<BluetoothGatt> BluetoothGattPtr;
-
class BluetoothGattService;
-typedef shared_ptr<BluetoothGattService> BluetoothGattServicePtr;
-
class BluetoothGattCharacteristic;
-typedef shared_ptr<BluetoothGattCharacteristic> BluetoothGattCharacteristicPtr;
-
class BluetoothGattDescriptor;
+
+typedef shared_ptr<BluetoothGatt> BluetoothGattPtr;
+typedef shared_ptr<BluetoothGattService> BluetoothGattServicePtr;
+typedef shared_ptr<BluetoothGattCharacteristic> BluetoothGattCharacteristicPtr;
typedef shared_ptr<BluetoothGattDescriptor> BluetoothGattDescriptorPtr;
class Mac {
@@ -69,29 +65,29 @@ private:
uint8_t bytes[6];
};
-template<typename T>
-class Iterator {
-public:
-private:
-};
-
-template<typename T>
-class Collection {
-public:
- Iterator<T> begin();
-
- Iterator<T> 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<size_t N>
+ 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 <cstdint>
#include <memory>
@@ -34,16 +34,29 @@ public:
class ByteBuffer {
public:
+ ByteBuffer() noexcept : zero(nullptr), end_(nullptr), cursor(nullptr) {};
+
template<size_t N>
- 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<size_t N>
+ 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<uint8_t *>(zero);
}
inline uint8_t *end() const {
- return const_cast<uint8_t *>(end_);
+ return const_cast<uint8_t *>(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<size_t N>
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<InformationData> 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<std::monostate,
ErrorRes,
ExchangeMtuReq, ExchangeMtuRes,
+ FindInformationRes,
ReadByGroupTypeRes, ReadByTypeRes>;
-o<AttPduType> attPduType(const AttVariant& v);
+o<AttPduType> 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<uint8_t[]> 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 <optional>
+#include "ByteBuffer.h"
+#include <optional>
#include <cstring>
#include <cctype>
#include <stdexcept>
@@ -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<uint8_t>(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<bool>(value & 0x01);
+ }
+
+ bool read() {
+ return static_cast<bool>(value & 0x02);
+ }
+
+ bool writeWithoutResponse() {
+ return static_cast<bool>(value & 0x04);
+ }
+
+ bool write() {
+ return static_cast<bool>(value & 0x08);
+ }
+
+ bool notify() {
+ return static_cast<bool>(value & 0x10);
+ }
+
+ bool indicate() {
+ return static_cast<bool>(value & 0x20);
+ }
+
+ bool authenticatedSignedWrites() {
+ return static_cast<bool>(value & 0x40);
+ }
+
+ bool extendedProperties() {
+ return static_cast<bool>(value & 0x80);
+ }
+};
+
} // namespace bluetooth
} // namespace trygvis