#pragma once #include "ble/compiler-support.h" #include "ByteBuffer.h" #include #include #include #include namespace trygvis { namespace bluetooth { using ::trygvis::compiler::o; class BluetoothAdapter; class BluetoothDevice; class BluetoothException : public std::runtime_error { public: BluetoothException(const BluetoothAdapter *adapter, std::string const &what) : runtime_error(what), adapter(adapter), device(nullptr) {} BluetoothException(const BluetoothDevice *device, std::string const &what) : runtime_error(what), adapter(nullptr), device(device) {} explicit BluetoothException(std::string const &what) : runtime_error(what), adapter(nullptr), device(nullptr) {} const BluetoothAdapter *adapter; const BluetoothDevice *device; }; struct Uuid { uint8_t value[16]; explicit Uuid(uint8_t value[16]) noexcept : value() { 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} {} bool operator==(const Uuid &other) { return std::memcmp(value, other.value, 16) == 0; } bool operator==(const Uuid &other) const { return std::memcmp(value, other.value, 16) == 0; } friend std::ostream &operator<<(std::ostream &s, Uuid const &uuid); std::string str() const; static Uuid fromShort(uint8_t b2, uint8_t b3) { return {0x00, 0x00, b2, b3, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}; } static o fromString(const std::string &str); }; struct ShortUuid { 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); auto b3 = static_cast(value & 0xff); return Uuid::fromShort(b2, b3); } std::string str() const noexcept; uint16_t value; }; Uuid makeUuid(const Uuid& base, uint8_t a, uint8_t b); namespace uuids { const ShortUuid HealthTermometerService{0x1809}; const ShortUuid DeviceInformationService{0x180a}; const ShortUuid BatteryService{0x180f}; const ShortUuid PRIMARY_SERVICE{0x2800}; const ShortUuid SECONDARY_SERVICE{0x2801}; const ShortUuid CHARACTERISTIC{0x2803}; 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); } explicit operator uint16_t() { return value; } }; } // namespace bluetooth } // namespace trygvis