-
Notifications
You must be signed in to change notification settings - Fork 60
/
types.h
359 lines (297 loc) · 12.3 KB
/
types.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
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
#ifndef __HOMEKIT_TYPES_H__
#define __HOMEKIT_TYPES_H__
#include <stdbool.h>
#include <stdint.h>
#include "port_x.h"
#include "tlv.h"
#ifdef ARDUINO8266_SERVER_CPP
#ifdef __cplusplus
extern "C" {
#endif
#endif
typedef enum {
homekit_format_bool,
homekit_format_uint8,
homekit_format_uint16,
homekit_format_uint32,
homekit_format_uint64,
homekit_format_int,
homekit_format_float,
homekit_format_string,
homekit_format_tlv,
homekit_format_data
} homekit_format_t;
typedef enum {
homekit_unit_none,
homekit_unit_celsius,
homekit_unit_percentage,
homekit_unit_arcdegrees,
homekit_unit_lux,
homekit_unit_seconds
} homekit_unit_t;
typedef enum {
homekit_permissions_paired_read = 1,
homekit_permissions_paired_write = 2,
homekit_permissions_notify = 4,
homekit_permissions_additional_authorization = 8,
homekit_permissions_timed_write = 16,
homekit_permissions_hidden = 32
} homekit_permissions_t;
typedef enum {
homekit_accessory_category_other = 1,
homekit_accessory_category_bridge = 2,
homekit_accessory_category_fan = 3,
homekit_accessory_category_garage = 4,
homekit_accessory_category_lightbulb = 5,
homekit_accessory_category_door_lock = 6,
homekit_accessory_category_outlet = 7,
homekit_accessory_category_switch = 8,
homekit_accessory_category_thermostat = 9,
homekit_accessory_category_sensor = 10,
homekit_accessory_category_security_system = 11,
homekit_accessory_category_door = 12,
homekit_accessory_category_window = 13,
homekit_accessory_category_window_covering = 14,
homekit_accessory_category_programmable_switch = 15,
homekit_accessory_category_range_extender = 16,
homekit_accessory_category_ip_camera = 17,
homekit_accessory_category_video_door_bell = 18,
homekit_accessory_category_air_purifier = 19,
homekit_accessory_category_heater = 20,
homekit_accessory_category_air_conditioner = 21,
homekit_accessory_category_humidifier = 22,
homekit_accessory_category_dehumidifier = 23,
homekit_accessory_category_apple_tv = 24,
homekit_accessory_category_speaker = 26,
homekit_accessory_category_airport = 27,
homekit_accessory_category_sprinkler = 28,
homekit_accessory_category_faucet = 29,
homekit_accessory_category_shower_head = 30,
homekit_accessory_category_television = 31,
homekit_accessory_category_target_controller = 32,
} homekit_accessory_category_t;
struct _homekit_accessory;
struct _homekit_service;
struct _homekit_characteristic;
typedef struct _homekit_accessory homekit_accessory_t;
typedef struct _homekit_service homekit_service_t;
typedef struct _homekit_characteristic homekit_characteristic_t;
typedef struct {
bool is_null : 1;
bool is_static : 1;
homekit_format_t format : 6;
union {
bool bool_value;
int int_value;
float float_value;
char *string_value;
tlv_values_t *tlv_values;
struct {
uint8_t *data_value;
size_t data_size;
};
};
} homekit_value_t;
bool homekit_value_equal(homekit_value_t *a, homekit_value_t *b);
void homekit_value_copy(homekit_value_t *dst, homekit_value_t *src);
homekit_value_t *homekit_value_clone(homekit_value_t *value);
void homekit_value_destruct(homekit_value_t *value);
void homekit_value_free(homekit_value_t *value);
#define HOMEKIT_NULL_(...) \
{.format=homekit_format_bool, .is_null=true, ##__VA_ARGS__}
#define HOMEKIT_NULL(...) (homekit_value_t) HOMEKIT_NULL_( __VA_ARGS__ )
#define HOMEKIT_BOOL_(value, ...) \
{.format=homekit_format_bool, .bool_value=(value), ##__VA_ARGS__}
#define HOMEKIT_BOOL(value, ...) (homekit_value_t) HOMEKIT_BOOL_(value, __VA_ARGS__)
#define HOMEKIT_INT_(value, ...) \
{.format=homekit_format_int, .int_value=(value), ##__VA_ARGS__}
#define HOMEKIT_INT(value, ...) (homekit_value_t) HOMEKIT_INT_(value, ##__VA_ARGS__)
#define HOMEKIT_UINT8_(value, ...) \
{.format=homekit_format_uint8, .int_value=(value), ##__VA_ARGS__}
#define HOMEKIT_UINT8(value, ...) (homekit_value_t) HOMEKIT_UINT8_(value, ##__VA_ARGS__)
#define HOMEKIT_UINT16_(value, ...) \
{.format=homekit_format_uint16, .int_value=(value), ##__VA_ARGS__}
#define HOMEKIT_UINT16(value, ...) (homekit_value_t) HOMEKIT_UINT16_(value, ##__VA_ARGS__)
#define HOMEKIT_UINT32_(value, ...) \
{.format=homekit_format_uint32, .int_value=(value), ##__VA_ARGS__}
#define HOMEKIT_UINT32(value, ...) (homekit_value_t) HOMEKIT_UINT32_(value, ##__VA_ARGS__)
#define HOMEKIT_UINT64_(value, ...) \
{.format=homekit_format_uint64, .int_value=(value), ##__VA_ARGS__}
#define HOMEKIT_UINT64(value, ...) (homekit_value_t) HOMEKIT_UINT64_(value, ##__VA_ARGS__)
#define HOMEKIT_FLOAT_(value, ...) \
{.format=homekit_format_float, .float_value=(value), ##__VA_ARGS__}
#define HOMEKIT_FLOAT(value, ...) (homekit_value_t) HOMEKIT_FLOAT_(value, ##__VA_ARGS__)
#define HOMEKIT_STRING_(value, ...) \
{.format=homekit_format_string, .string_value=(value), ##__VA_ARGS__}
#define HOMEKIT_STRING(value, ...) (homekit_value_t) HOMEKIT_STRING_(value, ##__VA_ARGS__)
#define HOMEKIT_TLV_(value, ...) \
{.format=homekit_format_tlv, .tlv_values=(value), ##__VA_ARGS__}
#define HOMEKIT_TLV(value, ...) (homekit_value_t) HOMEKIT_TLV_(value, ##__VA_ARGS__)
#define HOMEKIT_DATA_(value, size, ...) \
{.format=homekit_format_data, .data_value=value, .data_size=size, ##__VA_ARGS__}
#define HOMEKIT_DATA(value, size, ...) (homekit_value_t) HOMEKIT_DATA_(value, size, ##__VA_ARGS__)
typedef struct {
int count;
uint8_t *values;
} homekit_valid_values_t;
typedef struct {
uint8_t start;
uint8_t end;
} homekit_valid_values_range_t;
typedef struct {
int count;
homekit_valid_values_range_t *ranges;
} homekit_valid_values_ranges_t;
typedef void(*homekit_characteristic_change_callback_fn)(homekit_characteristic_t *ch, homekit_value_t value, void *context);
typedef struct _homekit_characteristic_change_callback {
homekit_characteristic_change_callback_fn function;
void *context;
struct _homekit_characteristic_change_callback *next;
} homekit_characteristic_change_callback_t;
#define HOMEKIT_CHARACTERISTIC_CALLBACK(f, ...) &(homekit_characteristic_change_callback_t) { .function = f, ##__VA_ARGS__ }
struct _homekit_characteristic {
homekit_service_t *service;
unsigned int id;
const char *type;
const char *description;
homekit_format_t format;
homekit_unit_t unit;
homekit_permissions_t permissions;
homekit_value_t value;
float *min_value;
float *max_value;
float *min_step;
int *max_len;
int *max_data_len;
homekit_valid_values_t valid_values;
homekit_valid_values_ranges_t valid_values_ranges;
homekit_value_t(*getter)();
void(*setter)(const homekit_value_t);
homekit_characteristic_change_callback_t *callback;
homekit_value_t(*getter_ex)(const homekit_characteristic_t *ch);
void(*setter_ex)(homekit_characteristic_t *ch, const homekit_value_t value);
void *context;
};
struct _homekit_service {
homekit_accessory_t *accessory;
unsigned int id;
const char *type;
bool hidden;
bool primary;
homekit_service_t **linked;
homekit_characteristic_t **characteristics;
};
struct _homekit_accessory {
unsigned int id;
homekit_accessory_category_t category;
int config_number;
homekit_service_t **services;
};
// Macro to define accessory
#define HOMEKIT_ACCESSORY(...) \
&(homekit_accessory_t) { \
.config_number=1, \
.category=homekit_accessory_category_other, \
##__VA_ARGS__ \
}
// Macro to define service inside accessory definition.
// Requires HOMEKIT_SERVICE_<name> define to expand to service type UUID string
#define HOMEKIT_SERVICE(_type, ...) \
&(homekit_service_t) { .type=HOMEKIT_SERVICE_ ## _type, ##__VA_ARGS__ }
// Macro to define standalone service (outside of accessory definition)
// Requires HOMEKIT_SERVICE_<name> define to expand to service type UUID string
#define HOMEKIT_SERVICE_(_type, ...) \
{ .type=HOMEKIT_SERVICE_ ## _type, ##__VA_ARGS__ }
// Macro to define characteristic inside service definition
#define HOMEKIT_CHARACTERISTIC(name, ...) \
&(homekit_characteristic_t) { \
HOMEKIT_DECLARE_CHARACTERISTIC_ ## name( __VA_ARGS__ ) \
}
// Macro to define standalone characteristic (outside of service definition)
// Requires HOMEKIT_DECLARE_CHARACTERISTIC_<name>() macro
#define HOMEKIT_CHARACTERISTIC_(name, ...) \
{ \
HOMEKIT_DECLARE_CHARACTERISTIC_ ## name( __VA_ARGS__ ) \
}
// Declaration macro to create a custom characteristic inplace without
// having to define HOMKIT_DECLARE_CHARACTERISTIC_<name>() macro.
//
// Useage:
// homekit_characteristic_t custom_ch = HOMEKIT_CHARACTERISTIC_(
// CUSTOM,
// .type = "00000023-0000-1000-8000-0026BB765291",
// .description = "My custom characteristic",
// .format = homekit_format_string,
// .permissions = homekit_permissions_paired_read
// | homekit_permissions_paired_write,
// .value = HOMEKIT_STRING_("my value"),
// );
#define HOMEKIT_DECLARE_CHARACTERISTIC_CUSTOM(...) \
.format = homekit_format_uint8, \
.unit = homekit_unit_none, \
.permissions = homekit_permissions_paired_read, \
##__VA_ARGS__
// Allocate memory and copy given accessory
// Does not make copies of all accessory services, so make sure thay are
// either allocated on heap or in static memory (but not on stack).
homekit_accessory_t *homekit_accessory_clone(homekit_accessory_t *accessory);
// Allocate memory and copy given service.
// Does not make copies of all service characteristics, so make sure that are
// either allocated on heap or in static memory (but not on stack).
homekit_service_t *homekit_service_clone(homekit_service_t *service);
// Allocate memory and copy given characteristic.
homekit_characteristic_t *homekit_characteristic_clone(homekit_characteristic_t *characteristic);
///Adding new characheristic to service
homekit_characteristic_t* homekit_add_characteristic_to_service(homekit_service_t* service, homekit_characteristic_t* ch);
// Macro to define an accessory in dynamic memory.
// Used to aid creating accessories definitions in runtime.
// Makes copy of all internal services/characteristics.
#define NEW_HOMEKIT_ACCESSORY(...) \
homekit_accessory_clone(HOMEKIT_ACCESSORY(__VA_ARGS__))
// Macro to define an service in dynamic memory.
// Used to aid creating services definitions in runtime.
// Makes copy of all internal characteristics.
#define NEW_HOMEKIT_SERVICE(name, ...) \
homekit_service_clone(HOMEKIT_SERVICE(name, ## __VA_ARGS__))
// Macro to define an characteristic in dynamic memory.
// Used to aid creating characteristics definitions in runtime.
#define NEW_HOMEKIT_CHARACTERISTIC(name, ...) \
homekit_characteristic_clone(HOMEKIT_CHARACTERISTIC(name, ## __VA_ARGS__))
// Init accessories by automatically assigning IDs to all
// accessories/services/characteristics, normalizing internal data.
void homekit_accessories_init(homekit_accessory_t **accessories);
// Find accessory by ID. Returns NULL if not found
homekit_accessory_t *homekit_accessory_by_id(homekit_accessory_t **accessories, int aid);
// Find service inside accessory by service type. Returns NULL if not found
homekit_service_t *homekit_service_by_type(homekit_accessory_t *accessory, const char *type);
// Find characteristic inside service by type. Returns NULL if not found
homekit_characteristic_t *homekit_service_characteristic_by_type(homekit_service_t *service, const char *type);
// Find characteristic by accessory ID and characteristic ID. Returns NULL if not found
homekit_characteristic_t *homekit_characteristic_by_aid_and_iid(homekit_accessory_t **accessories, int aid, int iid);
void homekit_characteristic_notify(homekit_characteristic_t *ch, const homekit_value_t value);
void homekit_characteristic_add_notify_callback(
homekit_characteristic_t *ch,
homekit_characteristic_change_callback_fn callback,
void *context
);
void homekit_characteristic_remove_notify_callback(
homekit_characteristic_t *ch,
homekit_characteristic_change_callback_fn callback,
void *context
);
void homekit_accessories_clear_notify_callbacks(
homekit_accessory_t **accessories,
homekit_characteristic_change_callback_fn callback,
void *context
);
bool homekit_characteristic_has_notify_callback(
const homekit_characteristic_t *ch,
homekit_characteristic_change_callback_fn callback,
void *context
);
#ifdef ARDUINO8266_SERVER_CPP
#ifdef __cplusplus
} //extern C
#endif
#endif
#endif // __HOMEKIT_TYPES_H__