From 91e54cf9150b37036447d423857d2bd18e4bf02b Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Wed, 5 Sep 2018 14:14:42 +0200 Subject: Major overhaul of BLE code: o Starting to remove shared_ptr. The code shouldn't be shared between threads, any thread safety will have to be built on the outside. o Better service discovery, don't fail when there are multiple requests that have to be done. o AttributeData was buggy, now it is just less than ideal. o Much better ByteBuffer. Now it is a simple view + cursor. --- include/ble/att.h | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 include/ble/att.h (limited to 'include/ble/att.h') diff --git a/include/ble/att.h b/include/ble/att.h new file mode 100644 index 0000000..3c7914f --- /dev/null +++ b/include/ble/att.h @@ -0,0 +1,186 @@ +#pragma once + +#include +#include +#include + +#include "ble/ByteBuffer.h" +#include "ble/misc.h" + +namespace trygvis { +namespace bluetooth { + +template +using o = std::experimental::optional; + +/** + * BLUETOOTH SPECIFICATION Version 4.0 [Vol 3] - Attribute Protocol (ATT) - 3.4.8 Attribute Opcode Summary + * Table 3.37 + */ +enum AttPduType { + 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, +}; + +std::string to_string(AttPduType t); + +class AttributeData; + +/** + * Application Error 0x80 – 0xFF Application error code defined by a higher layer specification. + * + * BLUETOOTH SPECIFICATION Version 4.0 [Vol 3] - 3.4.1.1 Error Response - Table 3.3 + */ +enum ErrorCode : uint8_t { + INVALID_HANDLE = 0x01, ///< The attribute handle given was not valid on this server. + READ_NOT_PERMITTED = 0x02,///< The attribute cannot be read. + WRITE_NOT_PERMITTED = 0x03,///< The attribute cannot be written. + INVALID_PDU = 0x04, /// attributes; +}; + +struct ReadByTypeRes { + static constexpr auto att_pdu_type = AttPduType::READ_BY_TYPE_RES; + + std::vector attributes; +}; + +using AttVariant = std::variant; + +o attPduType(const AttVariant& v); + +class AttPdu { +public: + explicit AttPdu(ByteBuffer &bytes); + + AttPdu(ByteBuffer &bytes, AttPduType type); + + AttPduType getType(); + + static AttVariant parse(ByteBuffer &bytes); + + static ExchangeMtuReq parseExchangeMtuReq(ByteBuffer &bytes); + static ExchangeMtuRes parseExchangeMtuRes(ByteBuffer &bytes); + + static void parseRead(ByteBuffer &bytes); + + static void parseWrite(ByteBuffer &bytes); + + static void makeExchangeMtuRes(ByteBuffer &bytes, uint16_t serverRxMtu); + + 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); + + static void makeRead(ByteBuffer &bytes, uint16_t handle); + + static void makeWrite(ByteBuffer &req, uint16_t handle, const ByteBuffer &bytes); + +private: +// static void checkType(ByteBuffer &bytes, AttPduType type); + + static std::vector parseAttributeData(ByteBuffer &bytes); + + ByteBuffer &bytes; +}; + +class AttributeData { +public: + ~AttributeData(); + + static AttributeData fromByteBuffer(ByteBuffer &value); + + const uint16_t handle; + ByteBuffer value; + +private: + AttributeData(uint16_t handle, ByteBuffer value, std::shared_ptr raw); + + std::shared_ptr raw; +}; + +} // namespace bluetooth +} // namespace trygvis -- cgit v1.2.3