-
Notifications
You must be signed in to change notification settings - Fork 232
/
Copy pathHAPBLEPDU.h
288 lines (252 loc) · 9.69 KB
/
HAPBLEPDU.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// Copyright (c) 2015-2019 The HomeKit ADK Contributors
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// See [CONTRIBUTORS.md] for the list of HomeKit ADK project authors.
#ifndef HAP_BLE_PDU_H
#define HAP_BLE_PDU_H
#ifdef __cplusplus
extern "C" {
#endif
#include "HAP+Internal.h"
#if __has_feature(nullability)
#pragma clang assume_nonnull begin
#endif
/**
* Fragmentation status of a HAP PDU.
*
* @see HomeKit Accessory Protocol Specification R14
* Table 7-3 Control Field Bit 7 Values
*/
HAP_ENUM_BEGIN(uint8_t, HAPBLEPDUFragmentationStatus) { /** First fragment (or no fragmentation). */
kHAPBLEPDUFragmentationStatus_FirstFragment = 0x00,
/** Continuation of fragmented PDU. */
kHAPBLEPDUFragmentationStatus_Continuation = 0x01
} HAP_ENUM_END(uint8_t, HAPBLEPDUFragmentationStatus);
/**
* Instance ID size of a HAP PDU.
*
* @see HomeKit Accessory Protocol Specification R14
* Table 7-4 Control Field Bit 4 Values
*/
HAP_ENUM_BEGIN(uint8_t, HAPBLEPDUInstanceIDSize) { /** 16-bit IIDs (or IID = 0). */
kHAPBLEPDUInstanceIDSize_16Bit = 0x00,
/** 64-bit IIDs. */
kHAPBLEPDUInstanceIDSize_64Bit = 0x01
} HAP_ENUM_END(uint8_t, HAPBLEPDUInstanceIDSize);
/**
* Type of a HAP PDU.
*
* @see HomeKit Accessory Protocol Specification R14
* Table 7-5 Control Field Bit 1-3 Values
*/
HAP_ENUM_BEGIN(uint8_t, HAPBLEPDUType) { /** Request. */
kHAPBLEPDUType_Request,
/** Response. */
kHAPBLEPDUType_Response
} HAP_ENUM_END(uint8_t, HAPBLEPDUType);
/**
* Length of a HAP PDU Control Field.
*
* @see HomeKit Accessory Protocol Specification R14
* Table 7-6 Control Field Bit 0 Values
*/
HAP_ENUM_BEGIN(uint8_t, HAPBLEPDUControlFieldLength) { /** 1 Byte Control Field. */
kHAPBLEPDUControlFieldLength_1Byte
} HAP_ENUM_END(uint8_t, HAPBLEPDUControlFieldLength);
/**
* Returns whether an opcode is a Service operation.
*
* @param opcode Operation.
*
* @return true If opcode is a Service operation.
* @return false Otherwise.
*/
HAP_RESULT_USE_CHECK
bool HAPBLEPDUOpcodeIsServiceOperation(HAPPDUOpcode opcode);
/**
* HAP Status Code.
*
* @see HomeKit Accessory Protocol Specification R14
* Table 7-37 HAP Status Codes Description
*/
HAP_ENUM_BEGIN(uint8_t, HAPBLEPDUStatus) { /** Success. */
kHAPBLEPDUStatus_Success = 0x00,
/** Unsupported-PDU. */
kHAPBLEPDUStatus_UnsupportedPDU = 0x01,
/** Max-Procedures. */
kHAPBLEPDUStatus_MaxProcedures = 0x02,
/** Insufficient Authorization. */
kHAPBLEPDUStatus_InsufficientAuthorization = 0x03,
/** Invalid instance ID. */
kHAPBLEPDUStatus_InvalidInstanceID = 0x04,
/** Insufficient Authentication. */
kHAPBLEPDUStatus_InsufficientAuthentication = 0x05,
/** Invalid Request. */
kHAPBLEPDUStatus_InvalidRequest = 0x06
} HAP_ENUM_END(uint8_t, HAPBLEPDUStatus);
/**
* Header length of a HAP-BLE Request.
*/
#define kHAPBLEPDU_NumRequestHeaderBytes ((size_t)(1 + 4))
/**
* Header length of a HAP-BLE Response.
*/
#define kHAPBLEPDU_NumResponseHeaderBytes ((size_t)(1 + 2))
/**
* Header length of a continuation of a fragmented HAP-BLE PDU.
*/
#define kHAPBLEPDU_NumContinuationHeaderBytes ((size_t)(1 + 1))
/**
* Additional header length of a PDU with a body.
* Only applies to the first fragment of a HAP-BLE PDU.
*/
#define kHAPBLEPDU_NumBodyHeaderBytes ((size_t)(2))
/**
* HAP PDU.
*
* @see HomeKit Accessory Protocol Specification R14
* Section 7.3.3 HAP PDU Format
*/
typedef struct {
/**
* Control Field.
*
* Defines how the PDU and the rest of the bytes in the PDU are interpreted.
*
* @see HomeKit Accessory Protocol Specification R14
* Section 7.3.3.1 HAP PDU Header - Control Field
*/
struct {
/** Fragmentation status. */
HAPBLEPDUFragmentationStatus fragmentationStatus;
/** PDU type. */
HAPBLEPDUType type;
/** Control Field length. */
HAPBLEPDUControlFieldLength length;
} controlField;
/**
* PDU Fixed Params.
*
* Contains fixed params depending on the Control Field.
*/
union {
/**
* HAP Request.
*
* @see HomeKit Accessory Protocol Specification R14
* Section 7.3.3.2 HAP Request Format
*/
struct {
HAPPDUOpcode opcode; /**< HAP Opcode. */
uint8_t tid; /**< TID. Transaction Identifier. */
uint16_t iid; /**< CharID / SvcID. Characteristic / service instance ID. */
} request;
/**
* HAP Response.
*
* @see HomeKit Accessory Protocol Specification R14
* Section 7.3.3.3 HAP Response Format
*/
struct {
uint8_t tid; /**< TID. Transaction Identifier. */
HAPBLEPDUStatus status; /**< Status. */
} response;
/**
* Continuation of fragmented PDU.
*
* @see HomeKit Accessory Protocol Specification R14
* Section 7.3.3.5 HAP PDU Fragmentation Scheme
*/
struct {
uint8_t tid; /**< TID. Transaction Identifier. */
} continuation;
} fixedParams;
/**
* HAP-BLE PDU Body.
*
* - For PDUs without a body:
* - @c totalBodyBytes is 0.
* - @c bytes is NULL.
* - @c numBytes is 0.
* - For PDUs that include a body:
* - @c totalBodyBytes contains the total PDU Body Length across all
* potential fragments.
* - @c bytes points to the start of the current body fragment.
* - @c numBytes contains the length of the current body fragment.
*
* @see HomeKit Accessory Protocol Specification R14
* Section 7.3.3.4 HAP PDU Body
*
* @see #HAPBLEPDUTLVType
*/
struct {
uint16_t totalBodyBytes; /**< PDU Body Length. */
const void* _Nullable bytes; /**< Additional Params and Values in TLV8s. */
uint16_t numBytes; /**< Length of the body fragment. */
} body;
} HAPBLEPDU;
/**
* Deserialize the content of a buffer into a HAP-BLE PDU structure.
* The buffer should contain the complete serialized PDU, or its first fragment.
*
* @param[out] pdu Deserialized PDU.
* @param bytes Start of the memory region to deserialize.
* @param numBytes Length of the memory region to deserialize.
*
* @return kHAPError_None If successful.
* @return kHAPError_InvalidData If the controller sent a malformed request.
*
* @remark To deserialize continuations of fragmented PDUs, use #HAPBLEPDUDeserializeContinuation.
*/
HAP_RESULT_USE_CHECK
HAPError HAPBLEPDUDeserialize(HAPBLEPDU* pdu, const void* bytes, size_t numBytes);
/**
* Deserialize the content of a buffer into a HAP-BLE PDU structure.
* The buffer should contain the serialized continuation of a fragmented PDU. Otherwise, an error is returned.
*
* - To deserialize complete PDUs or their first fragment, use #HAPBLEPDUDeserialize.
*
* @param[out] pdu Deserialized PDU.
* @param bytes Start of the memory region to deserialize.
* @param numBytes Length of the memory region to deserialize.
* @param typeOfFirstFragment Type of the first fragment of the PDU.
* @param remainingBodyBytes Remaining body length.
* @param totalBodyBytesSoFar Combined length of preceding body fragments.
*
* @return kHAPError_None If successful.
* @return kHAPError_InvalidData If the controller sent a malformed request.
*
* @see HomeKit Accessory Protocol Specification R14
* Section 7.3.3.5 HAP PDU Fragmentation Scheme
*/
HAP_RESULT_USE_CHECK
HAPError HAPBLEPDUDeserializeContinuation(
HAPBLEPDU* pdu,
const void* bytes,
size_t numBytes,
HAPBLEPDUType typeOfFirstFragment,
size_t remainingBodyBytes,
size_t totalBodyBytesSoFar);
/**
* Serialize a HAP-BLE PDU structure.
*
* - For continuations of fragmented PDUs, @c pdu->body.totalBodyBytes is not validated.
*
* @param pdu PDU to serialize.
* @param bytes Start of the memory region to serialize into.
* @param maxBytes Capacity of the memory region to serialize into.
* @param[out] numBytes Effective length of the serialized PDU.
*
* @return kHAPError_None If successful.
* @return kHAPError_OutOfResources If the buffer is not large enough.
*/
HAP_RESULT_USE_CHECK
HAPError HAPBLEPDUSerialize(const HAPBLEPDU* pdu, void* bytes, size_t maxBytes, size_t* numBytes);
#if __has_feature(nullability)
#pragma clang assume_nonnull end
#endif
#ifdef __cplusplus
}
#endif
#endif