1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2015-2016 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/types.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <zephyr/sys/printk.h>
14 #include <zephyr/sys/util.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/kernel.h>
17 
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/hci.h>
20 #include <zephyr/bluetooth/conn.h>
21 #include <zephyr/bluetooth/uuid.h>
22 #include <zephyr/bluetooth/gatt.h>
23 
24 #define NUMBER_OF_SLOTS 1
25 #define EDS_VERSION 0x00
26 #define EDS_URL_READ_OFFSET 2
27 #define EDS_URL_WRITE_OFFSET 4
28 #define EDS_IDLE_TIMEOUT K_SECONDS(30)
29 
30 /* Idle timer */
31 struct k_work_delayable idle_work;
32 
33 static const struct bt_data ad[] = {
34 	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
35 	/* Eddystone Service UUID a3c87500-8ed3-4bdf-8a39-a01bebede295 */
36 	BT_DATA_BYTES(BT_DATA_UUID128_ALL,
37 		      0x95, 0xe2, 0xed, 0xeb, 0x1b, 0xa0, 0x39, 0x8a,
38 		      0xdf, 0x4b, 0xd3, 0x8e, 0x00, 0x75, 0xc8, 0xa3),
39 };
40 
41 static const struct bt_data sd[] = {
42 	BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
43 };
44 
45 /* Eddystone Service Variables */
46 /* Service UUID a3c87500-8ed3-4bdf-8a39-a01bebede295 */
47 static const struct bt_uuid_128 eds_uuid = BT_UUID_INIT_128(
48 	BT_UUID_128_ENCODE(0xa3c87500, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
49 
50 /* Characteristic UUID a3c87501-8ed3-4bdf-8a39-a01bebede295 */
51 static const struct bt_uuid_128 eds_caps_uuid = BT_UUID_INIT_128(
52 	BT_UUID_128_ENCODE(0xa3c87501, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
53 
54 /* Characteristic UUID a3c87502-8ed3-4bdf-8a39-a01bebede295 */
55 static const struct bt_uuid_128 eds_slot_uuid = BT_UUID_INIT_128(
56 	BT_UUID_128_ENCODE(0xa3c87502, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
57 
58 /* Characteristic UUID a3c87503-8ed3-4bdf-8a39-a01bebede295 */
59 static const struct bt_uuid_128 eds_intv_uuid = BT_UUID_INIT_128(
60 	BT_UUID_128_ENCODE(0xa3c87503, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
61 
62 /* Characteristic UUID a3c87504-8ed3-4bdf-8a39-a01bebede295 */
63 static const struct bt_uuid_128 eds_tx_uuid = BT_UUID_INIT_128(
64 	BT_UUID_128_ENCODE(0xa3c87504, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
65 
66 /* Characteristic UUID a3c87505-8ed3-4bdf-8a39-a01bebede295 */
67 static const struct bt_uuid_128 eds_adv_tx_uuid = BT_UUID_INIT_128(
68 	BT_UUID_128_ENCODE(0xa3c87505, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
69 
70 /* Characteristic UUID a3c87506-8ed3-4bdf-8a39-a01bebede295 */
71 static const struct bt_uuid_128 eds_lock_uuid = BT_UUID_INIT_128(
72 	BT_UUID_128_ENCODE(0xa3c87506, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
73 
74 /* Characteristic UUID a3c87507-8ed3-4bdf-8a39-a01bebede295 */
75 static const struct bt_uuid_128 eds_unlock_uuid = BT_UUID_INIT_128(
76 	BT_UUID_128_ENCODE(0xa3c87507, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
77 
78 /* Characteristic UUID a3c87508-8ed3-4bdf-8a39-a01bebede295 */
79 static const struct bt_uuid_128 eds_ecdh_uuid = BT_UUID_INIT_128(
80 	BT_UUID_128_ENCODE(0xa3c87508, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
81 
82 /* Characteristic UUID a3c87509-8ed3-4bdf-8a39-a01bebede295 */
83 static const struct bt_uuid_128 eds_eid_uuid = BT_UUID_INIT_128(
84 	BT_UUID_128_ENCODE(0xa3c87509, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
85 
86 /* Characteristic UUID a3c8750a-8ed3-4bdf-8a39-a01bebede295 */
87 static const struct bt_uuid_128 eds_data_uuid = BT_UUID_INIT_128(
88 	BT_UUID_128_ENCODE(0xa3c8750a, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
89 
90 /* Characteristic UUID a3c8750b-8ed3-4bdf-8a39-a01bebede295 */
91 static const struct bt_uuid_128 eds_reset_uuid = BT_UUID_INIT_128(
92 	BT_UUID_128_ENCODE(0xa3c8750b, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
93 
94 /* Characteristic UUID a3c8750c-8ed3-4bdf-8a39-a01bebede295 */
95 static const struct bt_uuid_128 eds_connectable_uuid = BT_UUID_INIT_128(
96 	BT_UUID_128_ENCODE(0xa3c8750c, 0x8ed3, 0x4bdf, 0x8a39, 0xa01bebede295));
97 
98 enum {
99 	EDS_TYPE_UID = 0x00,
100 	EDS_TYPE_URL = 0x10,
101 	EDS_TYPE_TLM = 0x20,
102 	EDS_TYPE_EID = 0x30,
103 	EDS_TYPE_NONE = 0xff,
104 };
105 
106 enum {
107 	EDS_SLOT_UID = sys_cpu_to_be16(BIT(0)),
108 	EDS_SLOT_URL = sys_cpu_to_be16(BIT(1)),
109 	EDS_SLOT_TLM = sys_cpu_to_be16(BIT(2)),
110 	EDS_SLOT_EID = sys_cpu_to_be16(BIT(3)),
111 };
112 
113 struct eds_capabilities {
114 	uint8_t version;
115 	uint8_t slots;
116 	uint8_t uids;
117 	uint8_t adv_types;
118 	uint16_t slot_types;
119 	uint8_t tx_power;
120 } __packed;
121 
122 static struct eds_capabilities eds_caps = {
123 	.version = EDS_VERSION,
124 	.slots = NUMBER_OF_SLOTS,
125 	.slot_types = EDS_SLOT_URL, /* TODO: Add support for other slot types */
126 };
127 
128 uint8_t eds_active_slot;
129 
130 enum {
131 	EDS_LOCKED = 0x00,
132 	EDS_UNLOCKED = 0x01,
133 	EDS_UNLOCKED_NO_RELOCKING = 0x02,
134 };
135 
136 struct eds_slot {
137 	uint8_t type;
138 	uint8_t state;
139 	uint8_t connectable;
140 	uint16_t interval;
141 	uint8_t tx_power;
142 	uint8_t adv_tx_power;
143 	uint8_t lock[16];
144 	uint8_t challenge[16];
145 	struct bt_data ad[3];
146 };
147 
148 static struct eds_slot eds_slots[NUMBER_OF_SLOTS] = {
149 	[0 ... (NUMBER_OF_SLOTS - 1)] = {
150 		.type = EDS_TYPE_NONE,  /* Start as disabled */
151 		.state = EDS_UNLOCKED, /* Start unlocked */
152 		.interval = sys_cpu_to_be16(BT_GAP_ADV_FAST_INT_MIN_2),
153 		.lock = { 'Z', 'e', 'p', 'h', 'y', 'r', ' ', 'E', 'd', 'd',
154 			  'y', 's', 't', 'o', 'n', 'e' },
155 		.challenge = {},
156 		.ad = {
157 			BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
158 			BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0xaa, 0xfe),
159 			BT_DATA_BYTES(BT_DATA_SVC_DATA16,
160 				      0xaa, 0xfe, /* Eddystone UUID */
161 				      0x10, /* Eddystone-URL frame type */
162 				      0x00, /* Calibrated Tx power at 0m */
163 				      0x00, /* URL Scheme Prefix http://www. */
164 				      'z', 'e', 'p', 'h', 'y', 'r',
165 				      'p', 'r', 'o', 'j', 'e', 'c', 't',
166 				      0x08) /* .org */
167 		},
168 	},
169 };
170 
read_caps(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)171 static ssize_t read_caps(struct bt_conn *conn, const struct bt_gatt_attr *attr,
172 			 void *buf, uint16_t len, uint16_t offset)
173 {
174 	const struct eds_capabilities *caps = attr->user_data;
175 
176 	return bt_gatt_attr_read(conn, attr, buf, len, offset, caps,
177 				 sizeof(*caps));
178 }
179 
read_slot(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)180 static ssize_t read_slot(struct bt_conn *conn, const struct bt_gatt_attr *attr,
181 			 void *buf, uint16_t len, uint16_t offset)
182 {
183 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
184 				 &eds_active_slot, sizeof(eds_active_slot));
185 }
186 
write_slot(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)187 static ssize_t write_slot(struct bt_conn *conn,
188 			  const struct bt_gatt_attr *attr, const void *buf,
189 			  uint16_t len, uint16_t offset, uint8_t flags)
190 {
191 	uint8_t value;
192 
193 	if (offset + len > sizeof(value)) {
194 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
195 	}
196 
197 	memcpy(&value, buf, len);
198 
199 	if (value + 1 > NUMBER_OF_SLOTS) {
200 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
201 	}
202 
203 	eds_active_slot = value;
204 
205 	return len;
206 }
207 
read_tx_power(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)208 static ssize_t read_tx_power(struct bt_conn *conn,
209 			     const struct bt_gatt_attr *attr,
210 			     void *buf, uint16_t len, uint16_t offset)
211 {
212 	struct eds_slot *slot = &eds_slots[eds_active_slot];
213 
214 	if (slot->state == EDS_LOCKED) {
215 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
216 	}
217 
218 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &slot->tx_power,
219 				 sizeof(slot->tx_power));
220 }
221 
write_tx_power(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)222 static ssize_t write_tx_power(struct bt_conn *conn,
223 			      const struct bt_gatt_attr *attr,
224 			      const void *buf, uint16_t len, uint16_t offset,
225 			      uint8_t flags)
226 {
227 	struct eds_slot *slot = &eds_slots[eds_active_slot];
228 
229 	if (slot->state == EDS_LOCKED) {
230 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
231 	}
232 
233 	if (offset + len > sizeof(slot->tx_power)) {
234 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
235 	}
236 
237 	memcpy(&slot->tx_power, buf, len);
238 
239 	return len;
240 }
241 
read_adv_tx_power(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)242 static ssize_t read_adv_tx_power(struct bt_conn *conn,
243 				 const struct bt_gatt_attr *attr,
244 				 void *buf, uint16_t len, uint16_t offset)
245 {
246 	struct eds_slot *slot = &eds_slots[eds_active_slot];
247 
248 	if (slot->state == EDS_LOCKED) {
249 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
250 	}
251 
252 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &slot->tx_power,
253 				 sizeof(slot->tx_power));
254 }
255 
write_adv_tx_power(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)256 static ssize_t write_adv_tx_power(struct bt_conn *conn,
257 				  const struct bt_gatt_attr *attr,
258 				  const void *buf, uint16_t len,
259 				  uint16_t offset,
260 				  uint8_t flags)
261 {
262 	struct eds_slot *slot = &eds_slots[eds_active_slot];
263 
264 	if (slot->state == EDS_LOCKED) {
265 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
266 	}
267 
268 	if (offset + len > sizeof(slot->adv_tx_power)) {
269 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
270 	}
271 
272 	memcpy(&slot->adv_tx_power, buf, len);
273 
274 	return len;
275 }
276 
read_interval(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)277 static ssize_t read_interval(struct bt_conn *conn,
278 			     const struct bt_gatt_attr *attr,
279 			     void *buf, uint16_t len, uint16_t offset)
280 {
281 	struct eds_slot *slot = &eds_slots[eds_active_slot];
282 
283 	if (slot->state == EDS_LOCKED) {
284 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
285 	}
286 
287 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &slot->interval,
288 				 sizeof(slot->interval));
289 }
290 
read_lock(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)291 static ssize_t read_lock(struct bt_conn *conn, const struct bt_gatt_attr *attr,
292 			 void *buf, uint16_t len, uint16_t offset)
293 {
294 	struct eds_slot *slot = &eds_slots[eds_active_slot];
295 
296 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &slot->state,
297 				 sizeof(slot->state));
298 }
299 
write_lock(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)300 static ssize_t write_lock(struct bt_conn *conn,
301 			  const struct bt_gatt_attr *attr, const void *buf,
302 			  uint16_t len, uint16_t offset, uint8_t flags)
303 {
304 	struct eds_slot *slot = &eds_slots[eds_active_slot];
305 	uint8_t value;
306 
307 	if (slot->state == EDS_LOCKED) {
308 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
309 	}
310 
311 	if (offset) {
312 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
313 	}
314 
315 	/* Write 1 byte to lock or 17 bytes to transition to a new lock state */
316 	if (len != 1U) {
317 		/* TODO: Allow setting new lock code, using AES-128-ECB to
318 		 * decrypt with the existing lock code and set the unencrypted
319 		 * value as the new code.
320 		 */
321 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
322 	}
323 
324 	memcpy(&value, buf, sizeof(value));
325 
326 	if (value > EDS_UNLOCKED_NO_RELOCKING) {
327 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
328 	}
329 
330 	slot->state = value;
331 
332 	return len;
333 }
334 
read_unlock(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)335 static ssize_t read_unlock(struct bt_conn *conn,
336 			   const struct bt_gatt_attr *attr,
337 			   void *buf, uint16_t len, uint16_t offset)
338 {
339 	struct eds_slot *slot = &eds_slots[eds_active_slot];
340 
341 	if (slot->state != EDS_LOCKED) {
342 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
343 	}
344 
345 	/* returns a 128-bit challenge token. This token is for one-time use
346 	 * and cannot be replayed.
347 	 */
348 	if (bt_rand(slot->challenge, sizeof(slot->challenge))) {
349 		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
350 	}
351 
352 	return bt_gatt_attr_read(conn, attr, buf, len, offset, slot->challenge,
353 				 sizeof(slot->challenge));
354 }
355 
write_unlock(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)356 static ssize_t write_unlock(struct bt_conn *conn,
357 			    const struct bt_gatt_attr *attr, const void *buf,
358 			    uint16_t len, uint16_t offset, uint8_t flags)
359 {
360 	struct eds_slot *slot = &eds_slots[eds_active_slot];
361 
362 	if (slot->state != EDS_LOCKED) {
363 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
364 	}
365 
366 	/* TODO: accepts a 128-bit encrypted value that verifies the client
367 	 * knows the beacon's lock code.
368 	 */
369 
370 	return BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED);
371 }
372 
373 static uint8_t eds_ecdh[32] = {}; /* TODO: Add ECDH key */
374 
read_ecdh(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)375 static ssize_t read_ecdh(struct bt_conn *conn, const struct bt_gatt_attr *attr,
376 			 void *buf, uint16_t len, uint16_t offset)
377 {
378 	uint8_t *value = attr->user_data;
379 
380 	return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
381 				 sizeof(eds_ecdh));
382 }
383 
384 static uint8_t eds_eid[16] = {}; /* TODO: Add EID key */
385 
read_eid(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)386 static ssize_t read_eid(struct bt_conn *conn, const struct bt_gatt_attr *attr,
387 			void *buf, uint16_t len, uint16_t offset)
388 {
389 	uint8_t *value = attr->user_data;
390 
391 	return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
392 				 sizeof(eds_eid));
393 }
394 
read_adv_data(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)395 static ssize_t read_adv_data(struct bt_conn *conn,
396 			     const struct bt_gatt_attr *attr, void *buf,
397 			     uint16_t len, uint16_t offset)
398 {
399 	struct eds_slot *slot = &eds_slots[eds_active_slot];
400 
401 	if (slot->state == EDS_LOCKED) {
402 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
403 	}
404 
405 	/* If the slot is currently not broadcasting, reading the slot data
406 	 * shall return either an empty array or a single byte of 0x00.
407 	 */
408 	if (slot->type == EDS_TYPE_NONE) {
409 		return 0;
410 	}
411 
412 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
413 				 slot->ad[2].data + EDS_URL_READ_OFFSET,
414 				 slot->ad[2].data_len - EDS_URL_READ_OFFSET);
415 }
416 
eds_slot_restart(struct eds_slot * slot,uint8_t type)417 static int eds_slot_restart(struct eds_slot *slot, uint8_t type)
418 {
419 	int err;
420 	char addr_s[BT_ADDR_LE_STR_LEN];
421 	bt_addr_le_t addr = {0};
422 
423 	/* Restart advertising */
424 	bt_le_adv_stop();
425 
426 	if (type == EDS_TYPE_NONE) {
427 		struct bt_le_oob oob;
428 
429 		/* Restore connectable if slot */
430 		if (bt_le_oob_get_local(BT_ID_DEFAULT, &oob) == 0) {
431 			addr = oob.addr;
432 		}
433 
434 		err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), NULL, 0);
435 	} else {
436 		size_t count = 1;
437 
438 		bt_id_get(&addr, &count);
439 		err = bt_le_adv_start(BT_LE_ADV_NCONN_IDENTITY, slot->ad,
440 				      ARRAY_SIZE(slot->ad), NULL, 0);
441 	}
442 
443 	if (err) {
444 		printk("Advertising failed to start (err %d)\n", err);
445 		return err;
446 	}
447 
448 	bt_addr_le_to_str(&addr, addr_s, sizeof(addr_s));
449 	printk("Advertising as %s\n", addr_s);
450 
451 	slot->type = type;
452 
453 	return 0;
454 }
455 
write_adv_data(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)456 static ssize_t write_adv_data(struct bt_conn *conn,
457 			      const struct bt_gatt_attr *attr,
458 			      const void *buf, uint16_t len, uint16_t offset,
459 			      uint8_t flags)
460 {
461 	struct eds_slot *slot = &eds_slots[eds_active_slot];
462 	uint8_t type;
463 
464 	if (slot->state == EDS_LOCKED) {
465 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
466 	}
467 
468 	if (offset) {
469 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
470 	}
471 
472 	/* Writing an empty array, clears the slot and stops Tx. */
473 	if (!len) {
474 		eds_slot_restart(slot, EDS_TYPE_NONE);
475 		return len;
476 	}
477 
478 	/* Write length: 17 bytes (UID), 19 bytes (URL), 1 byte (TLM), 34 or
479 	 * 18 bytes (EID)
480 	 */
481 	if (len > 19) {
482 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
483 	}
484 
485 	memcpy(&type, buf, sizeof(type));
486 
487 	switch (type) {
488 	case EDS_TYPE_URL:
489 		/* written data is just the frame type and any ID-related
490 		 * information, and doesn't include the Tx power since that is
491 		 * controlled by characteristics 4 (Radio Tx Power) and
492 		 * 5 (Advertised Tx Power).
493 		 */
494 		slot->ad[2].data_len = MIN(slot->ad[2].data_len,
495 					   len + EDS_URL_WRITE_OFFSET);
496 		memcpy((uint8_t *) slot->ad[2].data + EDS_URL_WRITE_OFFSET, buf,
497 		       slot->ad[2].data_len - EDS_URL_WRITE_OFFSET);
498 
499 		/* Restart slot */
500 		if (eds_slot_restart(slot, type) < 0) {
501 			return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
502 		}
503 
504 		return len;
505 	case EDS_TYPE_UID:
506 	case EDS_TYPE_TLM:
507 	case EDS_TYPE_EID:
508 	default:
509 		/* TODO: Add support for other types. */
510 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
511 	}
512 }
513 
write_reset(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)514 static ssize_t write_reset(struct bt_conn *conn,
515 			   const struct bt_gatt_attr *attr,
516 			   const void *buf, uint16_t len, uint16_t offset,
517 			   uint8_t flags)
518 {
519 	/* TODO: Power cycle or reload for storage the values */
520 	return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
521 }
522 
read_connectable(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)523 static ssize_t read_connectable(struct bt_conn *conn,
524 			     const struct bt_gatt_attr *attr, void *buf,
525 			     uint16_t len, uint16_t offset)
526 {
527 	uint8_t connectable = 0x01;
528 
529 	/* Returning a non-zero value indicates that the beacon is capable
530 	 * of becoming non-connectable
531 	 */
532 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
533 				 &connectable, sizeof(connectable));
534 }
535 
write_connectable(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)536 static ssize_t write_connectable(struct bt_conn *conn,
537 				 const struct bt_gatt_attr *attr,
538 				 const void *buf, uint16_t len, uint16_t offset,
539 				 uint8_t flags)
540 {
541 	struct eds_slot *slot = &eds_slots[eds_active_slot];
542 
543 	if (slot->state == EDS_LOCKED) {
544 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
545 	}
546 
547 	if (offset) {
548 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
549 	}
550 
551 	if (len > sizeof(slot->connectable)) {
552 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
553 	}
554 
555 	/* If any non-zero value is written, the beacon shall remain in its
556 	 * connectable state until any other value is written.
557 	 */
558 	memcpy(&slot->connectable, buf, len);
559 
560 	return len;
561 }
562 
563 /* Eddystone Configuration Service Declaration */
564 BT_GATT_SERVICE_DEFINE(eds_svc,
565 	BT_GATT_PRIMARY_SERVICE(&eds_uuid),
566 	/* Capabilities: Readable only when unlocked. Never writable. */
567 	BT_GATT_CHARACTERISTIC(&eds_caps_uuid.uuid, BT_GATT_CHRC_READ,
568 			       BT_GATT_PERM_READ, read_caps, NULL, &eds_caps),
569 	/* Active slot: Must be unlocked for both read and write. */
570 	BT_GATT_CHARACTERISTIC(&eds_slot_uuid.uuid,
571 			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
572 			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
573 			       read_slot, write_slot, NULL),
574 	/* Advertising Interval: Must be unlocked for both read and write. */
575 	BT_GATT_CHARACTERISTIC(&eds_intv_uuid.uuid, BT_GATT_CHRC_READ,
576 			       BT_GATT_PERM_READ, read_interval, NULL, NULL),
577 	/* Radio TX Power: Must be unlocked for both read and write. */
578 	BT_GATT_CHARACTERISTIC(&eds_tx_uuid.uuid,
579 			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
580 			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
581 			       read_tx_power, write_tx_power, NULL),
582 	/* Advertised TX Power: Must be unlocked for both read and write. */
583 	BT_GATT_CHARACTERISTIC(&eds_adv_tx_uuid.uuid,
584 			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
585 			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
586 			       read_adv_tx_power, write_adv_tx_power, NULL),
587 	/* Lock State:
588 	 * Readable in locked or unlocked state.
589 	 * Writeable only in unlocked state.
590 	 */
591 	BT_GATT_CHARACTERISTIC(&eds_lock_uuid.uuid,
592 			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
593 			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
594 			       read_lock, write_lock, NULL),
595 	/* Unlock:
596 	 * Readable only in locked state.
597 	 * Writeable only in locked state.
598 	 */
599 	BT_GATT_CHARACTERISTIC(&eds_unlock_uuid.uuid,
600 			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
601 			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
602 			       read_unlock, write_unlock, NULL),
603 	/* Public ECDH Key: Readable only in unlocked state. Never writable. */
604 	BT_GATT_CHARACTERISTIC(&eds_ecdh_uuid.uuid, BT_GATT_CHRC_READ,
605 			       BT_GATT_PERM_READ, read_ecdh, NULL, &eds_ecdh),
606 	/* EID Identity Key:Readable only in unlocked state. Never writable. */
607 	BT_GATT_CHARACTERISTIC(&eds_eid_uuid.uuid, BT_GATT_CHRC_READ,
608 			       BT_GATT_PERM_READ, read_eid, NULL, eds_eid),
609 	/* ADV Slot Data: Must be unlocked for both read and write. */
610 	BT_GATT_CHARACTERISTIC(&eds_data_uuid.uuid,
611 			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
612 			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
613 			       read_adv_data, write_adv_data, NULL),
614 	/* ADV Factory Reset: Must be unlocked for write. */
615 	BT_GATT_CHARACTERISTIC(&eds_reset_uuid.uuid,  BT_GATT_CHRC_WRITE,
616 			       BT_GATT_PERM_WRITE, NULL, write_reset, NULL),
617 	/* ADV Remain Connectable: Must be unlocked for write. */
618 	BT_GATT_CHARACTERISTIC(&eds_connectable_uuid.uuid,
619 			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
620 			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
621 			       read_connectable, write_connectable, NULL),
622 );
623 
bt_ready(int err)624 static void bt_ready(int err)
625 {
626 	char addr_s[BT_ADDR_LE_STR_LEN];
627 	struct bt_le_oob oob;
628 
629 	if (err) {
630 		printk("Bluetooth init failed (err %d)\n", err);
631 		return;
632 	}
633 
634 	printk("Bluetooth initialized\n");
635 
636 	/* Start advertising */
637 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
638 	if (err) {
639 		printk("Advertising failed to start (err %d)\n", err);
640 		return;
641 	}
642 
643 	/* Restore connectable if slot */
644 	bt_le_oob_get_local(BT_ID_DEFAULT, &oob);
645 	bt_addr_le_to_str(&oob.addr, addr_s, sizeof(addr_s));
646 	printk("Initial advertising as %s\n", addr_s);
647 
648 	k_work_schedule(&idle_work, EDS_IDLE_TIMEOUT);
649 
650 	printk("Configuration mode: waiting connections...\n");
651 }
652 
idle_timeout(struct k_work * work)653 static void idle_timeout(struct k_work *work)
654 {
655 	if (eds_slots[eds_active_slot].type == EDS_TYPE_NONE) {
656 		printk("Switching to Beacon mode %u.\n", eds_active_slot);
657 		eds_slot_restart(&eds_slots[eds_active_slot], EDS_TYPE_URL);
658 	}
659 }
660 
connected(struct bt_conn * conn,uint8_t err)661 static void connected(struct bt_conn *conn, uint8_t err)
662 {
663 	if (err) {
664 		printk("Connection failed err 0x%02x %s\n", err, bt_hci_err_to_str(err));
665 	} else {
666 		printk("Connected\n");
667 		k_work_cancel_delayable(&idle_work);
668 	}
669 }
670 
disconnected(struct bt_conn * conn,uint8_t reason)671 static void disconnected(struct bt_conn *conn, uint8_t reason)
672 {
673 	struct eds_slot *slot = &eds_slots[eds_active_slot];
674 
675 	printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason));
676 
677 	if (!slot->connectable) {
678 		k_work_reschedule(&idle_work, K_NO_WAIT);
679 	}
680 }
681 
682 BT_CONN_CB_DEFINE(conn_callbacks) = {
683 	.connected = connected,
684 	.disconnected = disconnected,
685 };
686 
main(void)687 int main(void)
688 {
689 	int err;
690 
691 	k_work_init_delayable(&idle_work, idle_timeout);
692 
693 	/* Initialize the Bluetooth Subsystem */
694 	err = bt_enable(bt_ready);
695 	if (err) {
696 		printk("Bluetooth init failed (err %d)\n", err);
697 	}
698 	return 0;
699 }
700