card10.c 24 KB
Newer Older
1
2
#include "wsf_types.h"
#include "util/bstream.h"
genofire's avatar
genofire committed
3
#include "wsf_assert.h"
4
5
6
7
8
9
10
11
12
13
14
#include "att_api.h"

#include "epicardium.h"

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <machine/endian.h>

#define CARD10_UUID_SUFFIX                                                     \
	0x42, 0x23, 0x42, 0x23, 0x42, 0x23, 0x42, 0x23, 0x42, 0x23, 0x42, 0x23
genofire's avatar
genofire committed
15
#define CARD10_UUID_PREFIX 0x02, 0x23, 0x42
16
17
18
19
20
21
22
23

/*!< \brief Service start handle. */
#define CARD10_START_HDL 0x920
/*!< \brief Service end handle. */
#define CARD10_END_HDL (CARD10_MAX_HDL - 1)

/*
 * This has to match in order and number of members to the functions
genofire's avatar
genofire committed
24
 * called in addCard10GroupDyn() otherwise the stack breaks.
25
26
27
28
 */
enum {
	/*!< \brief card10 service declaration */
	CARD10_SVC_HDL = CARD10_START_HDL,
29
	/*!< \brief time update characteristic */
genofire's avatar
genofire committed
30
31
	CARD10_TIME_CH_HDL,
	CARD10_TIME_VAL_HDL,
32
33
34
35
36
37
	/*!< \brief vibra characteristic */
	CARD10_VIRBA_CH_HDL,
	CARD10_VIBRA_VAL_HDL,
	/*!< \brief rockets led characteristic */
	CARD10_ROCKETS_CH_HDL,
	CARD10_ROCKETS_VAL_HDL,
genofire's avatar
genofire committed
38
39
40
41
42
43
44
45
46
47
48
49
	/*!< \brief led for background on bottom left characteristic */
	CARD10_LED_BG_BOTTOM_LEFT_CH_HDL,
	CARD10_LED_BG_BOTTOM_LEFT_VAL_HDL,
	/*!< \brief led for background on bottom right characteristic */
	CARD10_LED_BG_BOTTOM_RIGHT_CH_HDL,
	CARD10_LED_BG_BOTTOM_RIGHT_VAL_HDL,
	/*!< \brief led for background on top right characteristic */
	CARD10_LED_BG_TOP_RIGHT_CH_HDL,
	CARD10_LED_BG_TOP_RIGHT_VAL_HDL,
	/*!< \brief led for background on top left characteristic */
	CARD10_LED_BG_TOP_LEFT_CH_HDL,
	CARD10_LED_BG_TOP_LEFT_VAL_HDL,
genofire's avatar
genofire committed
50
51
52
53
54
55
	/*!< \brief dim leds on bottom characteristic */
	CARD10_LEDS_BOTTOM_DIM_CH_HDL,
	CARD10_LEDS_BOTTOM_DIM_VAL_HDL,
	/*!< \brief dim leds on top characteristic */
	CARD10_LEDS_TOP_DIM_CH_HDL,
	CARD10_LEDS_TOP_DIM_VAL_HDL,
56
57
58
59
60
61
	/*!< \brief led powersafe characteristic */
	CARD10_LED_POWERSAFE_CH_HDL,
	CARD10_LED_POWERSAFE_VAL_HDL,
	/*!< \brief flashlight characteristic */
	CARD10_FLASHLIGHT_CH_HDL,
	CARD10_FLASHLIGHT_VAL_HDL,
genofire's avatar
genofire committed
62
63
64
	/*!< \brief flashlight characteristic */
	CARD10_PERSONAL_STATE_CH_HDL,
	CARD10_PERSONAL_STATE_VAL_HDL,
genofire's avatar
genofire committed
65
66
67
	/*!< \brief leds above characteristic */
	CARD10_LEDS_ABOVE_CH_HDL,
	CARD10_LEDS_ABOVE_VAL_HDL,
68
69
70
71
72
73
74
	/*!< \brief light sensor characteristic */
	CARD10_LIGHT_SENSOR_CH_HDL,
	CARD10_LIGHT_SENSOR_VAL_HDL,
	/*!< \brief Maximum handle. */
	CARD10_MAX_HDL
};

genofire's avatar
genofire committed
75
76
/* clang-format off */

77
/* BLE UUID for card10 service*/
genofire's avatar
genofire committed
78
static const uint8_t UUID_svc[] = { CARD10_UUID_SUFFIX, 0x0, CARD10_UUID_PREFIX };
genofire's avatar
genofire committed
79
80
// works vor everyone?
static const uint16_t UUID_len = sizeof(UUID_svc);
81
82
83

// starting at 0x01 with write (non visual) charateristics

genofire's avatar
genofire committed
84
/* BLE UUID for card10 time */
85
static const uint8_t UUID_char_time[] = {
genofire's avatar
genofire committed
86
87
	(ATT_PROP_READ | ATT_PROP_WRITE_NO_RSP),
	UINT16_TO_BYTES(CARD10_TIME_VAL_HDL),
88
89
	CARD10_UUID_SUFFIX, 0x01, CARD10_UUID_PREFIX
};
genofire's avatar
genofire committed
90
91
92
93

static uint8_t timeValue[] = { UINT32_TO_BYTES(0), UINT32_TO_BYTES(0) };
static uint16_t timeLen = sizeof(timeValue);

genofire's avatar
genofire committed
94
95
// works vor everyone?
static const uint16_t UUID_char_len = sizeof(UUID_char_time);
96
97
98
99
100

static const uint8_t UUID_attChar_time[] = {
	CARD10_UUID_SUFFIX, 0x01, CARD10_UUID_PREFIX
};

101
/* BLE UUID for card10 char vibra */
genofire's avatar
genofire committed
102
static const uint8_t UUID_char_vibra[] = {
genofire's avatar
genofire committed
103
	ATT_PROP_WRITE_NO_RSP,
genofire's avatar
genofire committed
104
	UINT16_TO_BYTES(CARD10_VIBRA_VAL_HDL),
105
	CARD10_UUID_SUFFIX, 0x0f, CARD10_UUID_PREFIX
genofire's avatar
genofire committed
106
};
107
108

static const uint8_t UUID_attChar_vibra[] = {
109
	CARD10_UUID_SUFFIX, 0x0f, CARD10_UUID_PREFIX
110
111
};

112
113
114

// starting at 0x10 with write of leds (visual output)

115
/* BLE UUID for card10 char rockets */
genofire's avatar
genofire committed
116
static const uint8_t UUID_char_rockets[] = {
117
	ATT_PROP_READ | ATT_PROP_WRITE_NO_RSP,
genofire's avatar
genofire committed
118
	UINT16_TO_BYTES(CARD10_ROCKETS_VAL_HDL),
genofire's avatar
genofire committed
119
	CARD10_UUID_SUFFIX, 0x10, CARD10_UUID_PREFIX
genofire's avatar
genofire committed
120
};
121
122

static const uint8_t UUID_attChar_rockets[] = {
genofire's avatar
genofire committed
123
	CARD10_UUID_SUFFIX, 0x10, CARD10_UUID_PREFIX
124
125
};

126
127
128
static uint8_t rocketsValue[] = { 0, 0, 0 };
static uint16_t rocketsLen = sizeof(rocketsValue);

genofire's avatar
genofire committed
129
130
/* BLE UUID for card10 led background bottom left */
static const uint8_t UUID_char_led_bg_bottom_left[] = {
131
	ATT_PROP_READ | ATT_PROP_WRITE_NO_RSP,
genofire's avatar
genofire committed
132
133
134
135
136
137
138
139
	UINT16_TO_BYTES(CARD10_LED_BG_BOTTOM_LEFT_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x11, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_led_bg_bottom_left[] = {
	CARD10_UUID_SUFFIX, 0x11, CARD10_UUID_PREFIX
};

140
141
142
143
static uint8_t ledBGBottomLeftValue[] = { 0,0,0 };
// works vor everyone?
static uint16_t rgbLen = sizeof(ledBGBottomLeftValue);

genofire's avatar
genofire committed
144
145
/* BLE UUID for card10 led background bottom right */
static const uint8_t UUID_char_led_bg_bottom_right[] = {
146
	ATT_PROP_READ | ATT_PROP_WRITE_NO_RSP,
genofire's avatar
genofire committed
147
148
149
150
151
152
153
154
	UINT16_TO_BYTES(CARD10_LED_BG_BOTTOM_RIGHT_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x12, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_led_bg_bottom_right[] = {
	CARD10_UUID_SUFFIX, 0x12, CARD10_UUID_PREFIX
};

155
156
static uint8_t ledBGBottomRightValue[] = { 0,0,0 };

genofire's avatar
genofire committed
157
158
/* BLE UUID for card10 led background top right */
static const uint8_t UUID_char_led_bg_top_right[] = {
159
	ATT_PROP_READ | ATT_PROP_WRITE_NO_RSP,
genofire's avatar
genofire committed
160
161
162
163
164
165
166
167
	UINT16_TO_BYTES(CARD10_LED_BG_TOP_RIGHT_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x13, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_led_bg_top_right[] = {
	CARD10_UUID_SUFFIX, 0x13, CARD10_UUID_PREFIX
};

168
169
static uint8_t ledBGTopRightValue[] = { 0,0,0 };

genofire's avatar
genofire committed
170
171
/* BLE UUID for card10 led background top left */
static const uint8_t UUID_char_led_bg_top_left[] = {
172
	ATT_PROP_READ | ATT_PROP_WRITE_NO_RSP,
genofire's avatar
genofire committed
173
174
175
176
177
178
179
180
	UINT16_TO_BYTES(CARD10_LED_BG_TOP_LEFT_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x14, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_led_bg_top_left[] = {
	CARD10_UUID_SUFFIX, 0x14, CARD10_UUID_PREFIX
};

181
182
static uint8_t ledBGTopLeftValue[] = { 0,0,0 };

genofire's avatar
genofire committed
183
184
/* BLE UUID for card10 dim leds on bottom */
static const uint8_t UUID_char_leds_bottom_dim[] = {
185
	ATT_PROP_WRITE,
genofire's avatar
genofire committed
186
187
188
189
190
191
192
193
194
195
	UINT16_TO_BYTES(CARD10_LEDS_BOTTOM_DIM_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x15, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_leds_bottom_dim[] = {
	CARD10_UUID_SUFFIX, 0x15, CARD10_UUID_PREFIX
};

/* BLE UUID for card10 dim leds on top */
static const uint8_t UUID_char_leds_top_dim[] = {
196
	ATT_PROP_WRITE,
genofire's avatar
genofire committed
197
198
199
200
201
202
203
204
	UINT16_TO_BYTES(CARD10_LEDS_TOP_DIM_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x16, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_leds_top_dim[] = {
	CARD10_UUID_SUFFIX, 0x16, CARD10_UUID_PREFIX
};

205
206
/* BLE UUID for card10 powersafe */
static const uint8_t UUID_char_led_powersafe[] = {
genofire's avatar
genofire committed
207
	ATT_PROP_WRITE_NO_RSP,
208
209
210
211
212
213
214
215
216
217
	UINT16_TO_BYTES(CARD10_LED_POWERSAFE_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x17, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_led_powersafe[] = {
	CARD10_UUID_SUFFIX, 0x17, CARD10_UUID_PREFIX
};

/* BLE UUID for card10 flashlight */
static const uint8_t UUID_char_flashlight[] = {
genofire's avatar
genofire committed
218
	ATT_PROP_WRITE_NO_RSP,
219
220
221
222
223
224
225
226
	UINT16_TO_BYTES(CARD10_FLASHLIGHT_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x18, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_flashlight[] = {
	CARD10_UUID_SUFFIX, 0x18, CARD10_UUID_PREFIX
};

genofire's avatar
genofire committed
227
228
229
230
231
232
233
234
235
236
237
/* BLE UUID for card10 personal state */
static const uint8_t UUID_char_personal_state[] = {
	ATT_PROP_READ | ATT_PROP_WRITE,
	UINT16_TO_BYTES(CARD10_PERSONAL_STATE_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x19, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_personal_state[] = {
	CARD10_UUID_SUFFIX, 0x19, CARD10_UUID_PREFIX
};

Rahix's avatar
Rahix committed
238
static uint8_t personalStateValue = 0;
genofire's avatar
genofire committed
239
240
static uint16_t personalStateLen = sizeof(personalStateValue);

genofire's avatar
genofire committed
241
242
/* BLE UUID for card10 above leds */
static const uint8_t UUID_char_leds_above[] = {
243
	ATT_PROP_READ | ATT_PROP_WRITE_NO_RSP,
genofire's avatar
genofire committed
244
245
246
247
248
249
250
	UINT16_TO_BYTES(CARD10_LEDS_ABOVE_VAL_HDL),
	CARD10_UUID_SUFFIX, 0x20, CARD10_UUID_PREFIX
};

static const uint8_t UUID_attChar_leds_above[] = {
	CARD10_UUID_SUFFIX, 0x20, CARD10_UUID_PREFIX
};
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
static uint8_t aboveLEDsValue[] = {
	0,0,0, //  0
	0,0,0, //  1
	0,0,0, //  2
	0,0,0, //  3
	0,0,0, //  4
	0,0,0, //  5
	0,0,0, //  6
	0,0,0, //  7
	0,0,0, //  8
	0,0,0, //  9
	0,0,0, // 10
};
static uint16_t aboveLEDsLen = sizeof(aboveLEDsValue);

266
267
// starting at 0xf0 with read only characteristics

268
269
270
271
/* BLE UUID for card10 char light sensor */
static const uint8_t UUID_char_light_sensor[] = {
	ATT_PROP_READ,
	UINT16_TO_BYTES(CARD10_LIGHT_SENSOR_VAL_HDL),
genofire's avatar
genofire committed
272
	CARD10_UUID_SUFFIX, 0xf0, CARD10_UUID_PREFIX
273
274
};
static const uint8_t UUID_attChar_light_sensor[] = {
genofire's avatar
genofire committed
275
	CARD10_UUID_SUFFIX, 0xf0, CARD10_UUID_PREFIX
276
};
genofire's avatar
genofire committed
277
278
279

static uint8_t initLightSensorValue[] = { UINT16_TO_BYTES(0) };
static uint16_t initLightSensorLen = sizeof(initLightSensorValue);
genofire's avatar
genofire committed
280
/* clang-format on */
281
282

/*
Rahix's avatar
Rahix committed
283
 * Create the BLE service description.
284
 */
genofire's avatar
genofire committed
285

genofire's avatar
genofire committed
286
static const attsAttr_t card10SvcAttrList[] = {
287
288
289
290
291
292
293
	{
		.pUuid       = attPrimSvcUuid,
		.pValue      = (uint8_t *)UUID_svc,
		.pLen        = (uint16_t *)&UUID_len,
		.maxLen      = sizeof(UUID_svc),
		.permissions = ATTS_PERMIT_READ,
	},
genofire's avatar
genofire committed
294

genofire's avatar
genofire committed
295
	// TIME
genofire's avatar
genofire committed
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_time,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_time),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_time,
		.pValue      = timeValue,
		.pLen        = &timeLen,
		.maxLen      = sizeof(uint64_t),
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
	},
genofire's avatar
genofire committed
314
315
316

	// VIBRA

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_vibra,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_vibra),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_vibra,
		.pValue      = NULL,
		.maxLen      = sizeof(uint16_t),
		.settings    = ATTS_SET_WRITE_CBACK,
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
			       ATTS_PERMIT_WRITE_AUTH,
	},
genofire's avatar
genofire committed
332
333
334

	// ROCKETS

335
336
337
338
339
340
341
342
343
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_rockets,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_rockets),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_rockets,
344
345
		.pValue      = rocketsValue,
		.pLen        = &rocketsLen,
346
		.maxLen      = 3 * sizeof(uint8_t),
347
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
348
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
349
350
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
351
	},
genofire's avatar
genofire committed
352
353
354

	// BG LED Bottom left

355
356
357
358
359
360
361
362
363
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_led_bg_bottom_left,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_led_bg_bottom_left),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_led_bg_bottom_left,
364
365
		.pValue      = ledBGBottomLeftValue,
		.pLen        = &rgbLen,
366
		.maxLen      = 3 * sizeof(uint8_t),
367
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
368
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
369
370
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
371
	},
genofire's avatar
genofire committed
372
373
374

	// BG LED Bottom right

375
376
377
378
379
380
381
382
383
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_led_bg_bottom_right,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_led_bg_bottom_right),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_led_bg_bottom_right,
384
385
		.pValue      = ledBGBottomRightValue,
		.pLen        = &rgbLen,
386
		.maxLen      = 3 * sizeof(uint8_t),
387
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
388
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
389
390
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
391
	},
genofire's avatar
genofire committed
392
393

	// BG LED top right
394
395
396
397
398
399
400
401
402
403
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_led_bg_top_right,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_led_bg_top_right),
		.settings    = 0,
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_led_bg_top_right,
404
405
		.pValue      = ledBGTopRightValue,
		.pLen        = &rgbLen,
406
		.maxLen      = 3 * sizeof(uint8_t),
407
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
408
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
409
410
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
411
	},
genofire's avatar
genofire committed
412
413
414

	// BG LED top left

415
416
417
418
419
420
421
422
423
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_led_bg_top_left,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_led_bg_top_left),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_led_bg_top_left,
424
425
		.pValue      = ledBGTopLeftValue,
		.pLen        = &rgbLen,
426
		.maxLen      = 3 * sizeof(uint8_t),
427
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
428
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
429
430
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
431
	},
genofire's avatar
genofire committed
432
433
434

	// Dim bottom module

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_leds_bottom_dim,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_leds_bottom_dim),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_leds_bottom_dim,
		.pValue      = NULL,
		.pLen        = 0,
		.maxLen      = sizeof(uint8_t),
		.settings    = ATTS_SET_WRITE_CBACK,
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
			       ATTS_PERMIT_WRITE_AUTH,
	},
genofire's avatar
genofire committed
451
452
453

	// Dim top module

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_leds_top_dim,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_leds_top_dim),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_leds_top_dim,
		.pValue      = NULL,
		.maxLen      = sizeof(uint8_t),
		.settings    = ATTS_SET_WRITE_CBACK,
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
			       ATTS_PERMIT_WRITE_AUTH,
	},
genofire's avatar
genofire committed
469

genofire's avatar
genofire committed
470
	// led powersafe
genofire's avatar
genofire committed
471

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_led_powersafe,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_led_powersafe),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_led_powersafe,
		.pValue      = NULL,
		.maxLen      = sizeof(uint8_t),
		.settings    = ATTS_SET_WRITE_CBACK,
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
			       ATTS_PERMIT_WRITE_AUTH,
	},
genofire's avatar
genofire committed
487

genofire's avatar
genofire committed
488
	// flashlight
489

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_flashlight,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_flashlight),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_flashlight,
		.pValue      = NULL,
		.maxLen      = sizeof(uint8_t),
		.settings    = ATTS_SET_WRITE_CBACK,
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
			       ATTS_PERMIT_WRITE_AUTH,
	},
genofire's avatar
genofire committed
505

genofire's avatar
genofire committed
506
507
	// personal state

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_personal_state,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_personal_state),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_personal_state,
		.pValue      = &personalStateValue,
		.pLen        = &personalStateLen,
		.maxLen      = sizeof(uint16_t),
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
	},
genofire's avatar
genofire committed
525

genofire's avatar
genofire committed
526
527
	// ABOVE LEDS

528
529
530
531
532
533
534
535
536
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_leds_above,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_leds_above),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_leds_above,
537
538
		.pValue      = aboveLEDsValue,
		.pLen        = &aboveLEDsLen,
539
		.maxLen      = 11 * 3 * sizeof(uint8_t),
540
		.settings    = ATTS_SET_WRITE_CBACK | ATTS_SET_READ_CBACK,
541
		.permissions = ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC |
542
543
			       ATTS_PERMIT_WRITE_AUTH | ATTS_PERMIT_READ |
			       ATTS_PERMIT_READ_ENC | ATTS_PERMIT_READ_AUTH,
544
	},
genofire's avatar
genofire committed
545

genofire's avatar
genofire committed
546
	// Light sensor
genofire's avatar
genofire committed
547

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
	{
		.pUuid       = attChUuid,
		.pValue      = (uint8_t *)UUID_char_light_sensor,
		.pLen        = (uint16_t *)&UUID_char_len,
		.maxLen      = sizeof(UUID_char_light_sensor),
		.permissions = ATTS_PERMIT_READ,
	},
	{
		.pUuid       = UUID_attChar_light_sensor,
		.pValue      = initLightSensorValue,
		.pLen        = &initLightSensorLen,
		.maxLen      = sizeof(uint8_t),
		.settings    = ATTS_SET_READ_CBACK,
		.permissions = ATTS_PERMIT_READ | ATTS_PERMIT_READ_ENC |
			       ATTS_PERMIT_READ_AUTH,
	},
genofire's avatar
genofire committed
564
};
565

genofire's avatar
genofire committed
566
567
568
569
// validating, that the service really get all charateristics
WSF_CT_ASSERT(
	((sizeof(card10SvcAttrList) / sizeof(card10SvcAttrList[0])) ==
	 CARD10_END_HDL - CARD10_START_HDL + 1));
570
571
572
/*
 * Set the time given in milliseconds since 1.1.1970 as 64 bit integer.
 */
genofire's avatar
genofire committed
573
static uint8_t setTime(uint8_t *pValue)
574
575
576
577
578
579
580
581
{
	uint64_t timeNet;
	uint64_t time;

	memcpy(&timeNet, pValue, sizeof(timeNet));
	time = __bswap64(timeNet);
	epic_rtc_set_milliseconds(time);

genofire's avatar
genofire committed
582
	APP_TRACE_INFO0("ble-card10: set time");
583
584
585
	return ATT_SUCCESS;
}

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
/*
 * Set a rgb led
 */
static uint8_t setRGBLed(uint8_t led, uint8_t *pValue)
{
	epic_leds_set(led, pValue[0], pValue[1], pValue[2]);
	APP_TRACE_INFO4(
		"ble-card10: set rgb led %d: #%02x%02x%02x\n",
		led,
		pValue[0],
		pValue[1],
		pValue[2]
	);
	return ATT_SUCCESS;
}

/*
 * Get value of a rgb led
 */
static uint8_t getRGBLed(uint8_t led, attsAttr_t *pAttr)
{
	epic_leds_get_rgb(led, pAttr->pValue);
	APP_TRACE_INFO4(
		"ble-card10: set rgb led %d: #%02x%02x%02x\n",
		led,
		pAttr->pValue[0],
		pAttr->pValue[1],
		pAttr->pValue[2]
	);
	return ATT_SUCCESS;
}

618
/*
genofire's avatar
genofire committed
619
 * BLE card10 write callback.
620
621
622
623
624
625
626
627
628
629
630
 */

static uint8_t writeCard10CB(
	dmConnId_t connId,
	uint16_t handle,
	uint8_t operation,
	uint16_t offset,
	uint16_t len,
	uint8_t *pValue,
	attsAttr_t *pAttr
) {
631
	uint16_t ui16 = 0;
632
	uint8_t ui8   = 0;
633
634

	switch (handle) {
635
	// time
genofire's avatar
genofire committed
636
	case CARD10_TIME_VAL_HDL:
genofire's avatar
genofire committed
637
		return setTime(pValue);
638
	// vibra
639
640
641
642
643
	case CARD10_VIBRA_VAL_HDL:
		BYTES_TO_UINT16(ui16, pValue);
		epic_vibra_vibrate(ui16);
		APP_TRACE_INFO1("ble-card10: set vibra for %dms\n", ui16);
		return ATT_SUCCESS;
644
	// rockets
645
646
647
648
649
650
651
652
653
654
655
	case CARD10_ROCKETS_VAL_HDL:
		epic_leds_set_rocket(0, pValue[0]);
		epic_leds_set_rocket(1, pValue[1]);
		epic_leds_set_rocket(2, pValue[2]);
		APP_TRACE_INFO3(
			"ble-card10: set rockets 0:%d, 1:%d, 2:%d\n",
			pValue[0],
			pValue[1],
			pValue[2]
		);
		return ATT_SUCCESS;
656
	// bg leds
genofire's avatar
genofire committed
657
	case CARD10_LED_BG_BOTTOM_LEFT_VAL_HDL:
658
		return setRGBLed(11, pValue);
genofire's avatar
genofire committed
659
	case CARD10_LED_BG_BOTTOM_RIGHT_VAL_HDL:
660
		return setRGBLed(12, pValue);
genofire's avatar
genofire committed
661
	case CARD10_LED_BG_TOP_RIGHT_VAL_HDL:
662
		return setRGBLed(13, pValue);
genofire's avatar
genofire committed
663
	case CARD10_LED_BG_TOP_LEFT_VAL_HDL:
664
		return setRGBLed(14, pValue);
665
	// dim
genofire's avatar
genofire committed
666
	case CARD10_LEDS_BOTTOM_DIM_VAL_HDL:
667
		ui8 = pValue[0];
668
		if (ui8 >= 1 && ui8 <= 8) {
genofire's avatar
genofire committed
669
670
671
672
			if (operation == ATT_PDU_WRITE_CMD ||
			    operation == ATT_PDU_SIGNED_WRITE_CMD ||
			    operation == ATT_PDU_WRITE_REQ ||
			    operation == ATT_PDU_EXEC_WRITE_REQ) {
673
				epic_leds_dim_bottom(pValue[0]);
genofire's avatar
genofire committed
674
				APP_TRACE_INFO1(
genofire's avatar
genofire committed
675
676
					"ble-card10: dim bottom to: %d\n",
					pValue[0]
677
678
679
680
681
				);
				return ATT_SUCCESS;
			} else if (operation == ATT_PDU_PREP_WRITE_REQ) {
				APP_TRACE_INFO1(
					"ble_card10: value for dim bottom would be okay: %d\n",
genofire's avatar
genofire committed
682
683
684
					pValue[0]
				);
				return ATT_SUCCESS;
685
686
687
688
689
690
			} else {
				APP_TRACE_INFO1(
					"ble-card10: dim bottom with unknown operation: %d\n",
					operation
				);
				return ATT_ERR_INVALID_PDU;
genofire's avatar
genofire committed
691
			}
692
		} else {
genofire's avatar
genofire committed
693
694
695
696
697
			APP_TRACE_INFO1(
				"ble-card: prep dim bottom invalid value (1-8): %d\n",
				ui8
			);
			return ATT_ERR_RANGE;
698
		}
genofire's avatar
genofire committed
699
	case CARD10_LEDS_TOP_DIM_VAL_HDL:
700
		ui8 = pValue[0];
701
		if (ui8 >= 1 && ui8 <= 8) {
genofire's avatar
genofire committed
702
703
704
705
			if (operation == ATT_PDU_WRITE_CMD ||
			    operation == ATT_PDU_SIGNED_WRITE_CMD ||
			    operation == ATT_PDU_WRITE_REQ ||
			    operation == ATT_PDU_EXEC_WRITE_REQ) {
706
				epic_leds_dim_top(pValue[0]);
genofire's avatar
genofire committed
707
				APP_TRACE_INFO1(
genofire's avatar
genofire committed
708
709
					"ble-card10: dim top to: %d\n",
					pValue[0]
710
711
712
713
714
				);
				return ATT_SUCCESS;
			} else if (operation == ATT_PDU_PREP_WRITE_REQ) {
				APP_TRACE_INFO1(
					"ble_card10: value for dim top would be okay: %d\n",
genofire's avatar
genofire committed
715
716
717
					pValue[0]
				);
				return ATT_SUCCESS;
718
719
720
721
722
723
			} else {
				APP_TRACE_INFO1(
					"ble-card10: dim top with unknown operation: %d\n",
					operation
				);
				return ATT_ERR_INVALID_PDU;
genofire's avatar
genofire committed
724
			}
725
		} else {
genofire's avatar
genofire committed
726
727
728
729
730
			APP_TRACE_INFO1(
				"ble-card: prep dim top invalid value (1-8): %d\n",
				ui8
			);
			return ATT_ERR_RANGE;
731
		}
732
733
734
735
736
737
738
739
740
741
	// led powersafe
	case CARD10_LED_POWERSAFE_VAL_HDL:
		epic_leds_set_powersave(pValue[0]);
		APP_TRACE_INFO1("set powersafe to: %d\n", pValue[0]);
		return ATT_SUCCESS;
	// flashlight
	case CARD10_FLASHLIGHT_VAL_HDL:
		epic_set_flashlight(pValue[0]);
		APP_TRACE_INFO1("set flashlight to: %d\n", pValue[0]);
		return ATT_SUCCESS;
genofire's avatar
genofire committed
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
	// personal state
	case CARD10_PERSONAL_STATE_VAL_HDL:
		BYTES_TO_UINT16(ui16, pValue);
		if (ui16 <= STATE_MAX) {
			if (operation == ATT_PDU_WRITE_CMD ||
			    operation == ATT_PDU_SIGNED_WRITE_CMD ||
			    operation == ATT_PDU_WRITE_REQ ||
			    operation == ATT_PDU_EXEC_WRITE_REQ) {
				epic_personal_state_set(ui16, true);
				APP_TRACE_INFO1(
					"ble-card10: set personal state to: %d\n",
					ui16
				);
				return ATT_SUCCESS;
			} else if (operation == ATT_PDU_PREP_WRITE_REQ) {
				APP_TRACE_INFO1(
					"ble_card10: personal state would be okay: %d\n",
					ui16
				);
				return ATT_SUCCESS;
			} else {
				APP_TRACE_INFO1(
					"ble-card10: personal state with unknown operation: %d\n",
					operation
				);
				return ATT_ERR_INVALID_PDU;
			}
		} else {
			APP_TRACE_INFO2(
				"ble-card: personal state invalid value (0-%d): %d\n",
				STATE_MAX - 1,
				ui16
			);
			return ATT_ERR_RANGE;
		}
777
	// leds above
genofire's avatar
genofire committed
778
	case CARD10_LEDS_ABOVE_VAL_HDL:
779
780
		APP_TRACE_INFO0("ble-card10: update LEDs above");

genofire's avatar
genofire committed
781
		for (ui16 = 0; ui16 < 11; ui16++) {
782
			epic_leds_prep(
genofire's avatar
genofire committed
783
784
785
786
787
788
				ui16,
				pValue[ui16 * 3],
				pValue[ui16 * 3 + 1],
				pValue[ui16 * 3 + 2]
			);
		}
789
790
		epic_leds_update();
		return ATT_SUCCESS;
791
	default:
792
		APP_TRACE_INFO1("ble-card10: unsupported handle: %x\n", handle);
793
794
795
796
		return ATT_ERR_HANDLE;
	}
}

genofire's avatar
genofire committed
797
798
799
800
/*
 * BLE card10 read callback.
 */

801
802
803
804
805
806
807
808
static uint8_t readCard10CB(
	dmConnId_t connId,
	uint16_t handle,
	uint8_t operation,
	uint16_t offset,
	attsAttr_t *pAttr
) {
	uint16_t ui16 = 0;
genofire's avatar
genofire committed
809
	uint64_t ui64 = 0;
810
	uint8_t rgb[] = { 0, 0, 0 };
811
812

	switch (handle) {
813
	// time
genofire's avatar
genofire committed
814
815
816
817
818
819
820
821
822
	case CARD10_TIME_VAL_HDL:
		ui64 = epic_rtc_get_milliseconds();
		uint64_t time;

		time = __bswap64(ui64);
		memcpy(pAttr->pValue, &time, sizeof(time));

		APP_TRACE_INFO0("ble-card10: read time\n");
		return ATT_SUCCESS;
823
824
825
826
827
828
829
830
831
832
833
	case CARD10_ROCKETS_VAL_HDL:
		pAttr->pValue[0] = epic_leds_get_rocket(0);
		pAttr->pValue[1] = epic_leds_get_rocket(1);
		pAttr->pValue[2] = epic_leds_get_rocket(2);
		APP_TRACE_INFO3(
			"ble-card10: get rockets 0:%d, 1:%d, 2:%d\n",
			pAttr->pValue[0],
			pAttr->pValue[1],
			pAttr->pValue[2]
		);
		return ATT_SUCCESS;
834
835
836
837
838
839
840
841
842
843
	// background leds
	case CARD10_LED_BG_BOTTOM_LEFT_VAL_HDL:
		return getRGBLed(11, pAttr);
	case CARD10_LED_BG_BOTTOM_RIGHT_VAL_HDL:
		return getRGBLed(12, pAttr);
	case CARD10_LED_BG_TOP_RIGHT_VAL_HDL:
		return getRGBLed(13, pAttr);
	case CARD10_LED_BG_TOP_LEFT_VAL_HDL:
		return getRGBLed(14, pAttr);
	// personal state
genofire's avatar
genofire committed
844
845
846
847
848
	case CARD10_PERSONAL_STATE_VAL_HDL:
		ui16           = epic_personal_state_get();
		*pAttr->pValue = ui16;
		APP_TRACE_INFO1("ble-card10: read personal state: %d\n", ui16);
		return ATT_SUCCESS;
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
	// leds above
	case CARD10_LEDS_ABOVE_VAL_HDL:
		for (ui16 = 0; ui16 < 11; ui16++) {
			epic_leds_get_rgb(ui16, rgb);
			pAttr->pValue[ui16 * 3]     = rgb[0];
			pAttr->pValue[ui16 * 3 + 1] = rgb[1];
			pAttr->pValue[ui16 * 3 + 2] = rgb[2];
			APP_TRACE_INFO4(
				"ble-card10: get led %ld above to #%02x%02x%02x\n",
				ui16,
				pAttr->pValue[ui16 * 3],
				pAttr->pValue[ui16 * 3 + 1],
				pAttr->pValue[ui16 * 3 + 2]
			);
		}
		return ATT_SUCCESS;
	// light sensor
866
867
868
869
870
871
872
873
874
875
876
	case CARD10_LIGHT_SENSOR_VAL_HDL:
		epic_light_sensor_get(&ui16);
		*pAttr->pValue = ui16;
		APP_TRACE_INFO1("ble-card10: read lightsensor: %d\n", ui16);
		return ATT_SUCCESS;
	default:
		APP_TRACE_INFO0("ble-card10: read no handler found\n");
		return ATT_ERR_HANDLE;
	}
}

genofire's avatar
genofire committed
877
878
879
880
881
882
883
884
885
static attsGroup_t svcCard10Group = {
	.pNext       = NULL,
	.pAttr       = (attsAttr_t *)card10SvcAttrList,
	.readCback   = readCard10CB,
	.writeCback  = writeCard10CB,
	.startHandle = CARD10_START_HDL,
	.endHandle   = CARD10_END_HDL,
};

886
/*
genofire's avatar
genofire committed
887
 * This registers and starts the BLE card10 service.
888
889
890
891
 */

void bleCard10_init(void)
{
genofire's avatar
genofire committed
892
	AttsAddGroup(&svcCard10Group);
893
}