diff options
Diffstat (limited to 'include/ble')
-rw-r--r-- | include/ble/Bluetooth.h | 143 |
1 files changed, 113 insertions, 30 deletions
diff --git a/include/ble/Bluetooth.h b/include/ble/Bluetooth.h index d5875a5..abddc94 100644 --- a/include/ble/Bluetooth.h +++ b/include/ble/Bluetooth.h @@ -1,14 +1,15 @@ #ifndef BLUETOOTH_H #define BLUETOOTH_H -#include <boost/uuid/uuid.hpp> #include <experimental/optional> #include <iosfwd> +#include <iostream> #include <stdexcept> #include <vector> #include <cstdint> #include <map> #include <functional> +#include <cstring> #include "ByteBuffer.h" @@ -19,44 +20,95 @@ using namespace std; template<typename T> using o = std::experimental::optional<T>; -struct SpecUuid { +struct Uuid { + uint8_t value[16]; + + explicit Uuid(uint8_t value[16]) noexcept : value() { + memcpy(this->value, value, 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) { + auto &v = uuid.value; + s << std::hex << + v[0] << v[1] << ":" << + v[2] << v[3] << ":" << + v[4] << v[5] << ":" << + v[6] << v[7] << ":" << + v[8] << v[9] << ":" << + v[10] << v[11] << ":" << + v[12] << v[13] << ":" << + v[14] << v[15] << ":" << + std::endl; + return s; + } + + 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}; + } +}; + +struct ShortUuid { +private: public: - SpecUuid(uint16_t value) : value(value) { + explicit ShortUuid(uint16_t value) : value(value) {} + + Uuid toLong() + { + auto b2 = static_cast<uint8_t>(value >> 8); + auto b3 = static_cast<uint8_t>(value & 0xff); + return Uuid::fromShort(b2, b3); } uint16_t value; }; + namespace uuids { -const SpecUuid PRIMARY_SERVICE = SpecUuid(0x2800); -const SpecUuid SECONDARY_SERVICE = SpecUuid(0x2801); -const SpecUuid CHARACTERISTIC = SpecUuid(0x2803); + +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 TemperatureMeasurement{0x2A1C}; } class BluetoothAdapter; class BluetoothDevice; +class BluetoothGatt; + class BluetoothGattService; class BluetoothGattCharacteristic; +typedef shared_ptr<BluetoothGatt> BluetoothGattPtr; typedef shared_ptr<BluetoothGattCharacteristic> BluetoothGattCharacteristicPtr; typedef shared_ptr<BluetoothGattService> BluetoothGattServicePtr; class BluetoothException : public runtime_error { public: - BluetoothException(const BluetoothAdapter *adapter, string const &what) : - runtime_error(what), adapter(adapter), device(nullptr) { - } + BluetoothException(const BluetoothAdapter *adapter, string const &what) : runtime_error(what), adapter(adapter), device(nullptr) {} - BluetoothException(const BluetoothDevice *device, string const &what) : - runtime_error(what), adapter(nullptr), device(device) { - } + BluetoothException(const BluetoothDevice *device, string const &what) : runtime_error(what), adapter(nullptr), device(device) {} - BluetoothException(string const &what) : - runtime_error(what), adapter(nullptr), device(nullptr) { - } + explicit BluetoothException(string const &what) : runtime_error(what), adapter(nullptr), device(nullptr) {} const BluetoothAdapter *adapter; const BluetoothDevice *device; @@ -64,7 +116,7 @@ public: class Mac { public: - Mac(uint8_t _5, uint8_t _4, uint8_t _3, uint8_t _2, uint8_t _1, uint8_t _0) { + explicit Mac(uint8_t _5, uint8_t _4, uint8_t _3, uint8_t _2, uint8_t _1, uint8_t _0) : bytes() { bytes[5] = _5; bytes[4] = _4; bytes[3] = _3; @@ -105,14 +157,13 @@ public: class BluetoothGattCharacteristic { public: - virtual ~BluetoothGattCharacteristic() { - }; + virtual ~BluetoothGattCharacteristic() = default; virtual BluetoothGattServicePtr getService() const = 0; virtual uint16_t getHandle() const = 0; - virtual const boost::uuids::uuid getUuid() const = 0; + virtual const Uuid getUuid() const = 0; virtual uint8_t getProperties() const = 0; @@ -121,12 +172,11 @@ public: class BluetoothGattService { public: - virtual ~BluetoothGattService() { - }; + virtual ~BluetoothGattService() = default; virtual BluetoothDevice &getDevice() const = 0; - virtual boost::uuids::uuid getUuid() const = 0; + virtual Uuid getUuid() const = 0; virtual uint16_t getHandle() const = 0; @@ -134,7 +184,11 @@ public: virtual vector<shared_ptr<BluetoothGattCharacteristic>> getCharacteristics() const = 0; - virtual o<BluetoothGattCharacteristicPtr> findCharacteristic(boost::uuids::uuid uuid) = 0; + virtual o<BluetoothGattCharacteristicPtr> findCharacteristic(Uuid uuid) = 0; + + o<BluetoothGattCharacteristicPtr> findCharacteristic(ShortUuid uuid) { + return findCharacteristic(uuid.toLong()); + }; }; class BluetoothGatt { @@ -160,7 +214,11 @@ public: virtual vector<shared_ptr<BluetoothGattService>> getServices() const = 0; - virtual o<BluetoothGattServicePtr> findService(boost::uuids::uuid uuid) = 0; + virtual o<BluetoothGattServicePtr> findService(Uuid uuid) = 0; + + o<BluetoothGattServicePtr> findService(ShortUuid uuid) { + return findService(uuid.toLong()); + } }; class BluetoothDevice { @@ -211,24 +269,47 @@ private: map<string, shared_ptr<BluetoothAdapter>> adapters; }; +/** + * BLUETOOTH SPECIFICATION Version 4.0 [Vol 3] - Attribute Protocol (ATT) - 3.4.8 Attribute Opcode Summary + * Table 3.37 + */ enum AttPduType { - ERROR = 0x00, - INVALID_HANDLE = 0x01, + ERROR = 0x01, + EXCHANGE_MTU_REQ = 0x02, + EXCHANGE_MTU_RES = 0x03, + FIND_INFORMATION_REQ = 0x04, + FIND_INFORMATION_RES = 0x05, + FIND_BY_TYPE_VALUE_REQ = 0x06, + FIND_BY_TYPE_VALUE_RES = 0x07, READ_BY_TYPE_REQ = 0x08, READ_BY_TYPE_RES = 0x09, READ_REQ = 0x0a, READ_RES = 0x0b, + READ_BLOB_REQ = 0x0c, + READ_BLOB_RES = 0x0d, + READ_MULTIPLE_REQ = 0x0e, + READ_MULTIPLE_RES = 0x0f, READ_BY_GROUP_TYPE_REQ = 0x10, READ_BY_GROUP_TYPE_RES = 0x11, WRITE_REQ = 0x12, WRITE_RES = 0x13, + + WRITE_CMD = 0x52, + PREPARE_WRITE_REQ = 0x16, + PREPARE_WRITE_RES = 0x17, + EXECUTE_WRITE_REQ = 0x18, + EXECUTE_WRITE_RES = 0x19, + HANDLE_VALUE_NOTIFICATION = 0x1b, + HANDLE_VALUE_INDICATION = 0x1d, + HANDLE_VALUE_CONFIRMATION = 0x1e, + SIGNED_WRITE_COMMAND = 0xd2, }; class AttributeData; class AttPdu { public: - AttPdu(ByteBuffer &bytes); + explicit AttPdu(ByteBuffer &bytes); AttPdu(ByteBuffer &bytes, AttPduType type); @@ -238,13 +319,15 @@ public: static vector<AttributeData> parseReadByType(ByteBuffer &bytes); + static uint16_t parseExchangeMtuReq(ByteBuffer &bytes); + static void parseRead(ByteBuffer &bytes); static void parseWrite(ByteBuffer &bytes); - static void makeReadByGroupType(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle, SpecUuid uuid); + static void makeReadByGroupType(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle, ShortUuid uuid); - static void makeReadByType(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle, SpecUuid uuid); + static void makeReadByType(ByteBuffer &bytes, uint16_t startHandle, uint16_t endHandle, ShortUuid uuid); static void makeRead(ByteBuffer &bytes, uint16_t handle); @@ -271,7 +354,7 @@ private: AttributeData(uint16_t handle, ByteBuffer value); }; -boost::uuids::uuid makeUuid(const boost::uuids::uuid base, uint8_t a, uint8_t b); +Uuid makeUuid(const Uuid& base, uint8_t a, uint8_t b); } } |