Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
ATTPDUTypes.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 * Copyright (c) 2020 ZAFENA AB
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include <cstring>
27#include <string>
28#include <memory>
29#include <cstdint>
30#include <vector>
31#include <cstdio>
32
33#include <algorithm>
34
35#include <jau/debug.hpp>
36
37#include "ATTPDUTypes.hpp"
38
39
40using namespace direct_bt;
41
42#define OPCODE_ENUM(X) \
43 X(PDU_UNDEFINED) \
44 X(ERROR_RSP) \
45 X(EXCHANGE_MTU_REQ) \
46 X(EXCHANGE_MTU_RSP) \
47 X(FIND_INFORMATION_REQ) \
48 X(FIND_INFORMATION_RSP) \
49 X(FIND_BY_TYPE_VALUE_REQ) \
50 X(FIND_BY_TYPE_VALUE_RSP) \
51 X(READ_BY_TYPE_REQ) \
52 X(READ_BY_TYPE_RSP) \
53 X(READ_REQ) \
54 X(READ_RSP) \
55 X(READ_BLOB_REQ) \
56 X(READ_BLOB_RSP) \
57 X(READ_MULTIPLE_REQ) \
58 X(READ_MULTIPLE_RSP) \
59 X(READ_BY_GROUP_TYPE_REQ) \
60 X(READ_BY_GROUP_TYPE_RSP) \
61 X(WRITE_REQ) \
62 X(WRITE_RSP) \
63 X(WRITE_CMD) \
64 X(PREPARE_WRITE_REQ) \
65 X(PREPARE_WRITE_RSP) \
66 X(EXECUTE_WRITE_REQ) \
67 X(EXECUTE_WRITE_RSP) \
68 X(READ_MULTIPLE_VARIABLE_REQ) \
69 X(READ_MULTIPLE_VARIABLE_RSP) \
70 X(MULTIPLE_HANDLE_VALUE_NTF) \
71 X(HANDLE_VALUE_NTF) \
72 X(HANDLE_VALUE_IND) \
73 X(HANDLE_VALUE_CFM) \
74 X(SIGNED_WRITE_CMD)
75
76#define CASE_TO_STRING(V) case Opcode::V: return #V;
77
78std::string AttPDUMsg::getOpcodeString(const Opcode opc) noexcept {
79 switch(opc) {
81 default: ; // fall through intended
82 }
83 return "Unknown Opcode";
84}
85
86std::string AttErrorRsp::getErrorCodeString(const ErrorCode errorCode) noexcept {
87 switch(errorCode) {
88 case ErrorCode::NO_ERROR: return "No error";
89 case ErrorCode::INVALID_HANDLE: return "Invalid Handle";
90 case ErrorCode::NO_READ_PERM: return "Read Not Permitted";
91 case ErrorCode::NO_WRITE_PERM: return "Write Not Permitted";
92 case ErrorCode::INVALID_PDU: return "Invalid PDU";
93 case ErrorCode::INSUFF_AUTHENTICATION: return "Insufficient Authentication";
94 case ErrorCode::UNSUPPORTED_REQUEST: return "Request Not Supported";
95 case ErrorCode::INVALID_OFFSET: return "Invalid Offset";
96 case ErrorCode::INSUFF_AUTHORIZATION: return "Insufficient Authorization";
97 case ErrorCode::PREPARE_QUEUE_FULL: return "Prepare Queue Full";
98 case ErrorCode::ATTRIBUTE_NOT_FOUND: return "Attribute Not Found";
99 case ErrorCode::ATTRIBUTE_NOT_LONG: return "Attribute Not Long";
100 case ErrorCode::INSUFF_ENCRYPTION_KEY_SIZE: return "Insufficient Encryption Key Size";
101 case ErrorCode::INVALID_ATTRIBUTE_VALUE_LEN: return "Invalid Attribute Value Length";
102 case ErrorCode::UNLIKELY_ERROR: return "Unlikely Error";
103 case ErrorCode::INSUFF_ENCRYPTION: return "Insufficient Encryption";
104 case ErrorCode::UNSUPPORTED_GROUP_TYPE: return "Unsupported Group Type";
105 case ErrorCode::INSUFFICIENT_RESOURCES: return "Insufficient Resources";
106 case ErrorCode::DB_OUT_OF_SYNC: return "Database Out Of Sync";
107 case ErrorCode::FORBIDDEN_VALUE: return "Value Not Allowed";
108 default: ; // fall through intended
109 }
110 if( 0x80 <= number(errorCode) && number(errorCode) <= 0x9F ) {
111 return "Application Error";
112 }
113 if( 0xE0 <= number(errorCode) /* && number(errorCode) <= 0xFF */ ) {
114 return "Common Profile and Services Error";
115 }
116 return "Error Reserved for future use";
117}
118
119std::unique_ptr<const AttPDUMsg> AttPDUMsg::getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept {
120 const AttPDUMsg::Opcode opc = static_cast<AttPDUMsg::Opcode>(*buffer);
121 switch( opc ) {
122 case Opcode::PDU_UNDEFINED: return std::make_unique<AttPDUUndefined>(buffer, buffer_size);
123 case Opcode::ERROR_RSP: return std::make_unique<AttErrorRsp>(buffer, buffer_size);
124 case Opcode::EXCHANGE_MTU_REQ: return std::make_unique<AttExchangeMTU>(buffer, buffer_size);
125 case Opcode::EXCHANGE_MTU_RSP: return std::make_unique<AttExchangeMTU>(buffer, buffer_size);
126 case Opcode::FIND_INFORMATION_REQ: return std::make_unique<AttFindInfoReq>(buffer, buffer_size);
127 case Opcode::FIND_INFORMATION_RSP: return std::make_unique<AttFindInfoRsp>(buffer, buffer_size);
128 case Opcode::FIND_BY_TYPE_VALUE_REQ: return std::make_unique<AttFindByTypeValueReq>(buffer, buffer_size);
129 case Opcode::FIND_BY_TYPE_VALUE_RSP: return std::make_unique<AttFindByTypeValueRsp>(buffer, buffer_size);
130 case Opcode::READ_BY_TYPE_REQ: return std::make_unique<AttReadByNTypeReq>(buffer, buffer_size);
131 case Opcode::READ_BY_TYPE_RSP: return std::make_unique<AttReadByTypeRsp>(buffer, buffer_size);
132 case Opcode::READ_REQ: return std::make_unique<AttReadReq>(buffer, buffer_size);
133 case Opcode::READ_RSP: return std::make_unique<AttReadNRsp>(buffer, buffer_size);
134 case Opcode::READ_BLOB_REQ: return std::make_unique<AttReadBlobReq>(buffer, buffer_size);
135 case Opcode::READ_BLOB_RSP: return std::make_unique<AttReadNRsp>(buffer, buffer_size);
136 case Opcode::READ_MULTIPLE_REQ: return std::make_unique<AttPDUMsg>(buffer, buffer_size); // TODO
137 case Opcode::READ_MULTIPLE_RSP: return std::make_unique<AttPDUMsg>(buffer, buffer_size); // TODO
138 case Opcode::READ_BY_GROUP_TYPE_REQ: return std::make_unique<AttReadByNTypeReq>(buffer, buffer_size);
139 case Opcode::READ_BY_GROUP_TYPE_RSP: return std::make_unique<AttReadByGroupTypeRsp>(buffer, buffer_size);
140 case Opcode::WRITE_REQ: return std::make_unique<AttWriteReq>(buffer, buffer_size);
141 case Opcode::WRITE_RSP: return std::make_unique<AttWriteRsp>(buffer, buffer_size);
142 case Opcode::WRITE_CMD: return std::make_unique<AttWriteCmd>(buffer, buffer_size);
143 case Opcode::PREPARE_WRITE_REQ: return std::make_unique<AttPrepWrite>(buffer, buffer_size);
144 case Opcode::PREPARE_WRITE_RSP: return std::make_unique<AttPrepWrite>(buffer, buffer_size);
145 case Opcode::EXECUTE_WRITE_REQ: return std::make_unique<AttExeWriteReq>(buffer, buffer_size);
146 case Opcode::EXECUTE_WRITE_RSP: return std::make_unique<AttExeWriteRsp>(buffer, buffer_size);
147 case Opcode::READ_MULTIPLE_VARIABLE_REQ: return std::make_unique<AttPDUMsg>(buffer, buffer_size); // TODO
148 case Opcode::READ_MULTIPLE_VARIABLE_RSP: return std::make_unique<AttPDUMsg>(buffer, buffer_size); // TODO
149 case Opcode::MULTIPLE_HANDLE_VALUE_NTF: return std::make_unique<AttPDUMsg>(buffer, buffer_size); // TODO
150 case Opcode::HANDLE_VALUE_NTF: return std::make_unique<AttHandleValueRcv>(buffer, buffer_size);
151 case Opcode::HANDLE_VALUE_IND: return std::make_unique<AttHandleValueRcv>(buffer, buffer_size);
152 case Opcode::HANDLE_VALUE_CFM: return std::make_unique<AttHandleValueCfm>(buffer, buffer_size);
153 case Opcode::SIGNED_WRITE_CMD: return std::make_unique<AttPDUMsg>(buffer, buffer_size); // TODO
154 default: return std::make_unique<AttPDUMsg>(buffer, buffer_size);
155 }
156}
#define CASE_TO_STRING(V)
Definition: ATTPDUTypes.cpp:76
#define OPCODE_ENUM(X)
Definition: ATTPDUTypes.cpp:42
Opcode
ATT Opcode Summary Vol 3, Part F 3.4.8.
constexpr uint32_t number(const iostate rhs) noexcept
Definition: byte_stream.hpp:72
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:53