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