1 /*
2  * Copyright (c) 2021 Xiaomi Corporation
3  * Copyright (c) 2018 Nordic Semiconductor ASA
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/debug/stack.h>
11 #include <zephyr/sys/iterable_sections.h>
12 #include <zephyr/net/buf.h>
13 #include <zephyr/bluetooth/bluetooth.h>
14 #include <zephyr/bluetooth/hci.h>
15 #include <zephyr/bluetooth/mesh.h>
16 
17 #include "common/bt_str.h"
18 
19 #include "host/hci_core.h"
20 
21 #include "net.h"
22 #include "proxy.h"
23 #include "solicitation.h"
24 
25 #define LOG_LEVEL CONFIG_BT_MESH_ADV_LOG_LEVEL
26 #include <zephyr/logging/log.h>
27 LOG_MODULE_REGISTER(bt_mesh_adv_ext);
28 
29 /* Convert from ms to 0.625ms units */
30 #define ADV_INT_FAST_MS    20
31 
32 #ifndef CONFIG_BT_MESH_RELAY_ADV_SETS
33 #define CONFIG_BT_MESH_RELAY_ADV_SETS 0
34 #endif
35 
36 enum {
37 	/** Controller is currently advertising */
38 	ADV_FLAG_ACTIVE,
39 	/** Advertising sending completed */
40 	ADV_FLAG_SENT,
41 	/** Currently performing proxy advertising */
42 	ADV_FLAG_PROXY,
43 	/** The proxy has been start, but maybe pending. */
44 	ADV_FLAG_PROXY_START,
45 	/** The send-call has been pending. */
46 	ADV_FLAG_SCHEDULE_PENDING,
47 	/** Custom adv params have been set, we need to update the parameters on
48 	 *  the next send.
49 	 */
50 	ADV_FLAG_UPDATE_PARAMS,
51 
52 	/** The advertiser is suspending. */
53 	ADV_FLAG_SUSPENDING,
54 
55 	/* Number of adv flags. */
56 	ADV_FLAGS_NUM
57 };
58 
59 struct bt_mesh_ext_adv {
60 	const enum bt_mesh_adv_tag_bit tags;
61 	ATOMIC_DEFINE(flags, ADV_FLAGS_NUM);
62 	struct bt_le_ext_adv *instance;
63 	struct bt_mesh_adv *adv;
64 	uint32_t timestamp;
65 	struct k_work work;
66 	struct bt_le_adv_param adv_param;
67 };
68 
69 static void send_pending_adv(struct k_work *work);
70 static bool schedule_send(struct bt_mesh_ext_adv *ext_adv);
71 
72 static struct bt_mesh_ext_adv advs[] = {
73 	[0] = {
74 		.tags = (
75 #if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
76 			BT_MESH_ADV_TAG_BIT_FRIEND |
77 #endif
78 #if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
79 			BT_MESH_ADV_TAG_BIT_PROXY |
80 #endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
81 #if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET)
82 			BT_MESH_ADV_TAG_BIT_RELAY |
83 #endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */
84 #if defined(CONFIG_BT_MESH_PB_ADV)
85 			BT_MESH_ADV_TAG_BIT_PROV |
86 #endif /* CONFIG_BT_MESH_PB_ADV */
87 			BT_MESH_ADV_TAG_BIT_LOCAL
88 		),
89 		.work = Z_WORK_INITIALIZER(send_pending_adv),
90 	},
91 #if CONFIG_BT_MESH_RELAY_ADV_SETS
92 	[1 ... CONFIG_BT_MESH_RELAY_ADV_SETS] = {
93 		.tags = (
94 #if defined(CONFIG_BT_MESH_RELAY)
95 			BT_MESH_ADV_TAG_BIT_RELAY |
96 #endif /* CONFIG_BT_MESH_RELAY */
97 #if defined(CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS)
98 			BT_MESH_ADV_TAG_BIT_PROV |
99 #endif /* CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS */
100 		0),
101 		.work = Z_WORK_INITIALIZER(send_pending_adv),
102 	},
103 #endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */
104 #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
105 	{
106 		.tags = BT_MESH_ADV_TAG_BIT_FRIEND,
107 		.work = Z_WORK_INITIALIZER(send_pending_adv),
108 	},
109 #endif /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */
110 #if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
111 	{
112 		.tags = BT_MESH_ADV_TAG_BIT_PROXY,
113 		.work = Z_WORK_INITIALIZER(send_pending_adv),
114 	},
115 #endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
116 };
117 
118 BUILD_ASSERT(ARRAY_SIZE(advs) <= CONFIG_BT_EXT_ADV_MAX_ADV_SET,
119 	     "Insufficient adv instances");
120 
relay_adv_get(void)121 static inline struct bt_mesh_ext_adv *relay_adv_get(void)
122 {
123 	if (!!(CONFIG_BT_MESH_RELAY_ADV_SETS)) {
124 		return &advs[1];
125 	} else {
126 		return &advs[0];
127 	}
128 }
129 
gatt_adv_get(void)130 static inline struct bt_mesh_ext_adv *gatt_adv_get(void)
131 {
132 	if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)) {
133 		return &advs[ARRAY_SIZE(advs) - 1];
134 	} else {
135 		return &advs[0];
136 	}
137 }
138 
adv_start(struct bt_mesh_ext_adv * ext_adv,const struct bt_le_adv_param * param,struct bt_le_ext_adv_start_param * start,const struct bt_data * ad,size_t ad_len,const struct bt_data * sd,size_t sd_len)139 static int adv_start(struct bt_mesh_ext_adv *ext_adv,
140 		     const struct bt_le_adv_param *param,
141 		     struct bt_le_ext_adv_start_param *start,
142 		     const struct bt_data *ad, size_t ad_len,
143 		     const struct bt_data *sd, size_t sd_len)
144 {
145 	int err;
146 
147 	if (!ext_adv->instance) {
148 		LOG_ERR("Mesh advertiser not enabled");
149 		return -ENODEV;
150 	}
151 
152 	if (atomic_test_and_set_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) {
153 		LOG_ERR("Advertiser is busy");
154 		return -EBUSY;
155 	}
156 
157 	if (atomic_test_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS)) {
158 		err = bt_le_ext_adv_update_param(ext_adv->instance, param);
159 		if (err) {
160 			LOG_ERR("Failed updating adv params: %d", err);
161 			atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
162 			return err;
163 		}
164 
165 		atomic_set_bit_to(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS,
166 				  param != &ext_adv->adv_param);
167 	}
168 
169 	err = bt_le_ext_adv_set_data(ext_adv->instance, ad, ad_len, sd, sd_len);
170 	if (err) {
171 		LOG_ERR("Failed setting adv data: %d", err);
172 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
173 		return err;
174 	}
175 
176 	ext_adv->timestamp = k_uptime_get_32();
177 
178 	err = bt_le_ext_adv_start(ext_adv->instance, start);
179 	if (err) {
180 		LOG_ERR("Advertising failed: err %d", err);
181 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
182 	}
183 
184 	return err;
185 }
186 
bt_data_send(struct bt_mesh_ext_adv * ext_adv,uint8_t num_events,uint16_t adv_interval,const struct bt_data * ad,size_t ad_len)187 static int bt_data_send(struct bt_mesh_ext_adv *ext_adv, uint8_t num_events, uint16_t adv_interval,
188 			const struct bt_data *ad, size_t ad_len)
189 {
190 	struct bt_le_ext_adv_start_param start = {
191 		.num_events = num_events,
192 	};
193 
194 	adv_interval = MAX(ADV_INT_FAST_MS, adv_interval);
195 
196 	/* Only update advertising parameters if they're different */
197 	if (ext_adv->adv_param.interval_min != BT_MESH_ADV_SCAN_UNIT(adv_interval)) {
198 		ext_adv->adv_param.interval_min = BT_MESH_ADV_SCAN_UNIT(adv_interval);
199 		ext_adv->adv_param.interval_max = ext_adv->adv_param.interval_min;
200 		atomic_set_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS);
201 	}
202 
203 	return adv_start(ext_adv, &ext_adv->adv_param, &start, ad, ad_len, NULL, 0);
204 }
205 
adv_send(struct bt_mesh_ext_adv * ext_adv,struct bt_mesh_adv * adv)206 static int adv_send(struct bt_mesh_ext_adv *ext_adv, struct bt_mesh_adv *adv)
207 {
208 	uint8_t num_events = BT_MESH_TRANSMIT_COUNT(adv->ctx.xmit) + 1;
209 	uint16_t duration, adv_int;
210 	struct bt_data ad;
211 	int err;
212 
213 	adv_int = BT_MESH_TRANSMIT_INT(adv->ctx.xmit);
214 	/* Upper boundary estimate: */
215 	duration = num_events * (adv_int + 10);
216 
217 	LOG_DBG("type %u len %u: %s", adv->ctx.type,
218 	       adv->b.len, bt_hex(adv->b.data, adv->b.len));
219 	LOG_DBG("count %u interval %ums duration %ums",
220 	       num_events, adv_int, duration);
221 
222 	ad.type = bt_mesh_adv_type[adv->ctx.type];
223 	ad.data_len = adv->b.len;
224 	ad.data = adv->b.data;
225 
226 	err = bt_data_send(ext_adv, num_events, adv_int, &ad, 1);
227 	if (!err) {
228 		ext_adv->adv = bt_mesh_adv_ref(adv);
229 	}
230 
231 	bt_mesh_adv_send_start(duration, err, &adv->ctx);
232 
233 	return err;
234 }
235 
236 static const char * const adv_tag_to_str[] = {
237 	[BT_MESH_ADV_TAG_LOCAL]  = "local adv",
238 	[BT_MESH_ADV_TAG_RELAY]  = "relay adv",
239 	[BT_MESH_ADV_TAG_PROXY]  = "proxy adv",
240 	[BT_MESH_ADV_TAG_FRIEND] = "friend adv",
241 	[BT_MESH_ADV_TAG_PROV]   = "prov adv",
242 };
243 
send_pending_adv(struct k_work * work)244 static void send_pending_adv(struct k_work *work)
245 {
246 	struct bt_mesh_ext_adv *ext_adv;
247 	struct bt_mesh_adv *adv;
248 	int err;
249 
250 	ext_adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work);
251 
252 	if (atomic_test_bit(ext_adv->flags, ADV_FLAG_SUSPENDING)) {
253 		LOG_DBG("Advertiser is suspending");
254 		return;
255 	}
256 
257 	if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SENT)) {
258 		LOG_DBG("Advertising stopped after %u ms for %s",
259 			k_uptime_get_32() - ext_adv->timestamp,
260 			ext_adv->adv ? adv_tag_to_str[ext_adv->adv->ctx.tag]
261 				     : adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]);
262 
263 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
264 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY);
265 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START);
266 
267 		if (ext_adv->adv) {
268 			struct bt_mesh_adv_ctx ctx = ext_adv->adv->ctx;
269 
270 			ext_adv->adv->ctx.started = 0;
271 			bt_mesh_adv_unref(ext_adv->adv);
272 			bt_mesh_adv_send_end(0, &ctx);
273 
274 			ext_adv->adv = NULL;
275 		}
276 	}
277 
278 	while ((adv = bt_mesh_adv_get_by_tag(ext_adv->tags, K_NO_WAIT))) {
279 		/* busy == 0 means this was canceled */
280 		if (!adv->ctx.busy) {
281 			bt_mesh_adv_unref(adv);
282 			continue;
283 		}
284 
285 		adv->ctx.busy = 0U;
286 		err = adv_send(ext_adv, adv);
287 
288 		bt_mesh_adv_unref(adv);
289 
290 		if (!err) {
291 			return; /* Wait for advertising to finish */
292 		}
293 	}
294 
295 	if (ext_adv->instance == NULL) {
296 		LOG_DBG("Advertiser is suspended or deleted");
297 		return;
298 	}
299 
300 	if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) &&
301 	    !bt_mesh_sol_send()) {
302 		return;
303 	}
304 
305 	if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) ||
306 	    !(ext_adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) {
307 		return;
308 	}
309 
310 	atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY_START);
311 
312 	if (!bt_mesh_adv_gatt_send()) {
313 		atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY);
314 	}
315 
316 	if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING)) {
317 		schedule_send(ext_adv);
318 	}
319 }
320 
schedule_send(struct bt_mesh_ext_adv * ext_adv)321 static bool schedule_send(struct bt_mesh_ext_adv *ext_adv)
322 {
323 	if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY)) {
324 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START);
325 		(void)bt_le_ext_adv_stop(ext_adv->instance);
326 
327 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
328 	}
329 
330 	if (atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) {
331 		atomic_set_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING);
332 		return false;
333 	} else if (k_work_is_pending(&ext_adv->work)) {
334 		return false;
335 	}
336 
337 	atomic_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING);
338 	k_work_submit(&ext_adv->work);
339 
340 	return true;
341 }
342 
bt_mesh_adv_gatt_update(void)343 void bt_mesh_adv_gatt_update(void)
344 {
345 	(void)schedule_send(gatt_adv_get());
346 }
347 
bt_mesh_adv_local_ready(void)348 void bt_mesh_adv_local_ready(void)
349 {
350 	(void)schedule_send(advs);
351 }
352 
bt_mesh_adv_relay_ready(void)353 void bt_mesh_adv_relay_ready(void)
354 {
355 	struct bt_mesh_ext_adv *ext_adv = relay_adv_get();
356 
357 	for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) {
358 		if (schedule_send(&ext_adv[i])) {
359 			return;
360 		}
361 	}
362 
363 	/* Attempt to use the main adv set for the sending of relay messages. */
364 	if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET)) {
365 		(void)schedule_send(advs);
366 	}
367 }
368 
bt_mesh_adv_friend_ready(void)369 void bt_mesh_adv_friend_ready(void)
370 {
371 	if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) {
372 		schedule_send(&advs[1 + CONFIG_BT_MESH_RELAY_ADV_SETS]);
373 	} else {
374 		schedule_send(&advs[0]);
375 	}
376 }
377 
bt_mesh_adv_terminate(struct bt_mesh_adv * adv)378 int bt_mesh_adv_terminate(struct bt_mesh_adv *adv)
379 {
380 	int err;
381 
382 	for (int i = 0; i < ARRAY_SIZE(advs); i++) {
383 		struct bt_mesh_ext_adv *ext_adv = &advs[i];
384 
385 		if (ext_adv->adv != adv) {
386 			continue;
387 		}
388 
389 		if (!atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) {
390 			return 0;
391 		}
392 
393 		err = bt_le_ext_adv_stop(ext_adv->instance);
394 		if (err) {
395 			LOG_ERR("Failed to stop adv %d", err);
396 			return err;
397 		}
398 
399 		/* Do not call `cb:end`, since this user action */
400 		adv->ctx.cb = NULL;
401 
402 		atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT);
403 
404 		k_work_submit(&ext_adv->work);
405 
406 		return 0;
407 	}
408 
409 	return -EINVAL;
410 }
411 
bt_mesh_adv_init(void)412 void bt_mesh_adv_init(void)
413 {
414 	struct bt_le_adv_param adv_param = {
415 		.id = BT_ID_DEFAULT,
416 		.interval_min = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS),
417 		.interval_max = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS),
418 #if defined(CONFIG_BT_MESH_DEBUG_USE_ID_ADDR)
419 		.options = BT_LE_ADV_OPT_USE_IDENTITY,
420 #endif
421 	};
422 
423 	for (int i = 0; i < ARRAY_SIZE(advs); i++) {
424 		(void)memcpy(&advs[i].adv_param, &adv_param, sizeof(adv_param));
425 	}
426 }
427 
adv_instance_find(struct bt_le_ext_adv * instance)428 static struct bt_mesh_ext_adv *adv_instance_find(struct bt_le_ext_adv *instance)
429 {
430 	for (int i = 0; i < ARRAY_SIZE(advs); i++) {
431 		if (advs[i].instance == instance) {
432 			return &advs[i];
433 		}
434 	}
435 
436 	return NULL;
437 }
438 
adv_sent(struct bt_le_ext_adv * instance,struct bt_le_ext_adv_sent_info * info)439 static void adv_sent(struct bt_le_ext_adv *instance,
440 		     struct bt_le_ext_adv_sent_info *info)
441 {
442 	struct bt_mesh_ext_adv *ext_adv = adv_instance_find(instance);
443 
444 	if (!ext_adv) {
445 		LOG_WRN("Unexpected adv instance");
446 		return;
447 	}
448 
449 	if (!atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) {
450 		return;
451 	}
452 
453 	atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT);
454 
455 	k_work_submit(&ext_adv->work);
456 }
457 
458 #if defined(CONFIG_BT_MESH_GATT_SERVER)
connected(struct bt_le_ext_adv * instance,struct bt_le_ext_adv_connected_info * info)459 static void connected(struct bt_le_ext_adv *instance,
460 		      struct bt_le_ext_adv_connected_info *info)
461 {
462 	struct bt_mesh_ext_adv *ext_adv = gatt_adv_get();
463 
464 	if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START)) {
465 		atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
466 		(void)schedule_send(ext_adv);
467 	}
468 }
469 #endif /* CONFIG_BT_MESH_GATT_SERVER */
470 
bt_mesh_adv_enable(void)471 int bt_mesh_adv_enable(void)
472 {
473 	int err;
474 
475 	static const struct bt_le_ext_adv_cb adv_cb = {
476 		.sent = adv_sent,
477 #if defined(CONFIG_BT_MESH_GATT_SERVER)
478 		.connected = connected,
479 #endif /* CONFIG_BT_MESH_GATT_SERVER */
480 	};
481 
482 	if (advs[0].instance) {
483 		/* Already initialized */
484 		return 0;
485 	}
486 
487 	for (int i = 0; i < ARRAY_SIZE(advs); i++) {
488 		err = bt_le_ext_adv_create(&advs[i].adv_param, &adv_cb,
489 					   &advs[i].instance);
490 		if (err) {
491 			return err;
492 		}
493 	}
494 
495 	return 0;
496 }
497 
bt_mesh_adv_disable(void)498 int bt_mesh_adv_disable(void)
499 {
500 	int err;
501 	struct k_work_sync sync;
502 
503 	for (int i = 0; i < ARRAY_SIZE(advs); i++) {
504 		atomic_set_bit(advs[i].flags, ADV_FLAG_SUSPENDING);
505 
506 		if (k_current_get() != &k_sys_work_q.thread ||
507 		    (k_work_busy_get(&advs[i].work) & K_WORK_RUNNING) == 0) {
508 			k_work_flush(&advs[i].work, &sync);
509 		}
510 
511 		err = bt_le_ext_adv_stop(advs[i].instance);
512 		if (err) {
513 			LOG_ERR("Failed to stop adv %d", err);
514 			return err;
515 		}
516 
517 		/* `adv_sent` is called to finish transmission of an adv buffer that was pushed to
518 		 * the host before the advertiser was stopped, but did not finish.
519 		 */
520 		adv_sent(advs[i].instance, NULL);
521 
522 		err = bt_le_ext_adv_delete(advs[i].instance);
523 		if (err) {
524 			LOG_ERR("Failed to delete adv %d", err);
525 			return err;
526 		}
527 
528 		advs[i].instance = NULL;
529 
530 		atomic_clear_bit(advs[i].flags, ADV_FLAG_SUSPENDING);
531 	}
532 
533 	return 0;
534 }
535 
bt_mesh_adv_gatt_start(const struct bt_le_adv_param * param,int32_t duration,const struct bt_data * ad,size_t ad_len,const struct bt_data * sd,size_t sd_len)536 int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param,
537 			   int32_t duration,
538 			   const struct bt_data *ad, size_t ad_len,
539 			   const struct bt_data *sd, size_t sd_len)
540 {
541 	struct bt_mesh_ext_adv *ext_adv = gatt_adv_get();
542 	struct bt_le_ext_adv_start_param start = {
543 		/* Timeout is set in 10 ms steps, with 0 indicating "forever" */
544 		.timeout = (duration == SYS_FOREVER_MS) ? 0 : MAX(1, duration / 10),
545 	};
546 
547 	LOG_DBG("Start advertising %d ms", duration);
548 
549 	atomic_set_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS);
550 
551 	return adv_start(ext_adv, param, &start, ad, ad_len, sd, sd_len);
552 }
553 
bt_mesh_adv_bt_data_send(uint8_t num_events,uint16_t adv_interval,const struct bt_data * ad,size_t ad_len)554 int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_interval,
555 			     const struct bt_data *ad, size_t ad_len)
556 {
557 	return bt_data_send(advs, num_events, adv_interval, ad, ad_len);
558 }
559