aboutsummaryrefslogtreecommitdiff
path: root/include/ble/Bluetooth.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ble/Bluetooth.h')
-rw-r--r--include/ble/Bluetooth.h143
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);
}
}