1 /*
2  * Copyright (c) 2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/bluetooth/mesh.h>
8 #include <zephyr/bluetooth/bluetooth.h>
9 
10 #include "mesh.h"
11 #include "net.h"
12 #include "rpl.h"
13 #include "beacon.h"
14 #include "settings.h"
15 #include "heartbeat.h"
16 #include "friend.h"
17 #include "adv.h"
18 #include "cfg.h"
19 
20 #define LOG_LEVEL CONFIG_BT_MESH_CFG_LOG_LEVEL
21 #include <zephyr/logging/log.h>
22 LOG_MODULE_REGISTER(bt_mesh_cfg);
23 
24 /* Miscellaneous configuration server model states */
25 struct cfg_val {
26 	uint8_t net_transmit;
27 	uint8_t relay;
28 	uint8_t relay_retransmit;
29 	uint8_t beacon;
30 	uint8_t gatt_proxy;
31 	uint8_t frnd;
32 	uint8_t default_ttl;
33 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
34 	uint8_t priv_beacon;
35 	uint8_t priv_beacon_int;
36 #endif
37 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
38 	uint8_t on_demand_state;
39 #endif
40 };
41 
bt_mesh_beacon_set(bool beacon)42 void bt_mesh_beacon_set(bool beacon)
43 {
44 	if (atomic_test_bit(bt_mesh.flags, BT_MESH_BEACON) == beacon) {
45 		return;
46 	}
47 
48 	atomic_set_bit_to(bt_mesh.flags, BT_MESH_BEACON, beacon);
49 
50 	if (beacon) {
51 		bt_mesh_beacon_enable();
52 	} else {
53 		/* Beacon timer will stop automatically when all beacons are disabled. */
54 	}
55 
56 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
57 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
58 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
59 	}
60 }
61 
bt_mesh_beacon_enabled(void)62 bool bt_mesh_beacon_enabled(void)
63 {
64 	return atomic_test_bit(bt_mesh.flags, BT_MESH_BEACON);
65 }
66 
feature_set(int feature_flag,enum bt_mesh_feat_state state)67 static int feature_set(int feature_flag, enum bt_mesh_feat_state state)
68 {
69 	if (state != BT_MESH_FEATURE_DISABLED &&
70 	    state != BT_MESH_FEATURE_ENABLED) {
71 		return -EINVAL;
72 	}
73 
74 	if (atomic_test_bit(bt_mesh.flags, feature_flag) ==
75 	    (state == BT_MESH_FEATURE_ENABLED)) {
76 		return -EALREADY;
77 	}
78 
79 	atomic_set_bit_to(bt_mesh.flags, feature_flag,
80 			  (state == BT_MESH_FEATURE_ENABLED));
81 
82 	return 0;
83 }
84 
feature_get(int feature_flag)85 static enum bt_mesh_feat_state feature_get(int feature_flag)
86 {
87 	return atomic_test_bit(bt_mesh.flags, feature_flag) ?
88 		       BT_MESH_FEATURE_ENABLED :
89 		       BT_MESH_FEATURE_DISABLED;
90 }
91 
bt_mesh_priv_beacon_set(enum bt_mesh_feat_state priv_beacon)92 int bt_mesh_priv_beacon_set(enum bt_mesh_feat_state priv_beacon)
93 {
94 	int err;
95 
96 	if (!IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS)) {
97 		return -ENOTSUP;
98 	}
99 
100 	err = feature_set(BT_MESH_PRIV_BEACON, priv_beacon);
101 	if (err) {
102 		return err;
103 	}
104 
105 	if (priv_beacon == BT_MESH_FEATURE_ENABLED) {
106 		bt_mesh_beacon_enable();
107 	} else {
108 		/* Beacon timer will stop automatically when all beacons are disabled. */
109 	}
110 
111 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
112 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
113 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
114 	}
115 
116 	return 0;
117 }
118 
bt_mesh_priv_beacon_get(void)119 enum bt_mesh_feat_state bt_mesh_priv_beacon_get(void)
120 {
121 	if (!IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS)) {
122 		return BT_MESH_FEATURE_NOT_SUPPORTED;
123 	}
124 
125 	return feature_get(BT_MESH_PRIV_BEACON);
126 }
127 
bt_mesh_priv_beacon_update_interval_set(uint8_t interval)128 void bt_mesh_priv_beacon_update_interval_set(uint8_t interval)
129 {
130 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
131 	bt_mesh.priv_beacon_int = interval;
132 #endif
133 }
134 
bt_mesh_priv_beacon_update_interval_get(void)135 uint8_t bt_mesh_priv_beacon_update_interval_get(void)
136 {
137 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
138 	return bt_mesh.priv_beacon_int;
139 #else
140 	return 0;
141 #endif
142 }
143 
bt_mesh_od_priv_proxy_get(void)144 int bt_mesh_od_priv_proxy_get(void)
145 {
146 #if IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
147 	return bt_mesh.on_demand_state;
148 #else
149 	return -ENOTSUP;
150 #endif
151 }
152 
bt_mesh_od_priv_proxy_set(uint8_t on_demand_proxy)153 int bt_mesh_od_priv_proxy_set(uint8_t on_demand_proxy)
154 {
155 #if !IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
156 	return -ENOTSUP;
157 #else
158 
159 	if (bt_mesh_priv_gatt_proxy_get() != BT_MESH_FEATURE_NOT_SUPPORTED) {
160 		bt_mesh.on_demand_state = on_demand_proxy;
161 	}
162 
163 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
164 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
165 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
166 	}
167 	return 0;
168 #endif
169 }
170 
node_id_is_running(struct bt_mesh_subnet * sub,void * cb_data)171 static bool node_id_is_running(struct bt_mesh_subnet *sub, void *cb_data)
172 {
173 	return sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING;
174 }
175 
bt_mesh_gatt_proxy_set(enum bt_mesh_feat_state gatt_proxy)176 int bt_mesh_gatt_proxy_set(enum bt_mesh_feat_state gatt_proxy)
177 {
178 	int err;
179 
180 	if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
181 		return -ENOTSUP;
182 	}
183 
184 	err = feature_set(BT_MESH_GATT_PROXY, gatt_proxy);
185 	if (err) {
186 		return err;
187 	}
188 
189 	if ((gatt_proxy == BT_MESH_FEATURE_ENABLED) ||
190 	    (gatt_proxy == BT_MESH_FEATURE_DISABLED &&
191 	     !bt_mesh_subnet_find(node_id_is_running, NULL))) {
192 		bt_mesh_adv_gatt_update();
193 	}
194 
195 	bt_mesh_hb_feature_changed(BT_MESH_FEAT_PROXY);
196 
197 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
198 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
199 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
200 	}
201 
202 	return 0;
203 }
204 
bt_mesh_gatt_proxy_get(void)205 enum bt_mesh_feat_state bt_mesh_gatt_proxy_get(void)
206 {
207 	if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
208 		return BT_MESH_FEATURE_NOT_SUPPORTED;
209 	}
210 
211 	return feature_get(BT_MESH_GATT_PROXY);
212 }
213 
bt_mesh_priv_gatt_proxy_set(enum bt_mesh_feat_state priv_gatt_proxy)214 int bt_mesh_priv_gatt_proxy_set(enum bt_mesh_feat_state priv_gatt_proxy)
215 {
216 	int err;
217 
218 	if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) || !IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS)) {
219 		return BT_MESH_FEATURE_NOT_SUPPORTED;
220 	}
221 
222 	err = feature_set(BT_MESH_PRIV_GATT_PROXY, priv_gatt_proxy);
223 	if (err) {
224 		return err;
225 	}
226 
227 	if (priv_gatt_proxy == BT_MESH_FEATURE_ENABLED) {
228 		/* Re-generate proxy beacon */
229 		bt_mesh_adv_gatt_update();
230 	}
231 
232 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
233 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
234 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
235 	}
236 
237 	return 0;
238 }
239 
bt_mesh_priv_gatt_proxy_get(void)240 enum bt_mesh_feat_state bt_mesh_priv_gatt_proxy_get(void)
241 {
242 	if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) || !IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS)) {
243 		return BT_MESH_FEATURE_NOT_SUPPORTED;
244 	}
245 
246 	return feature_get(BT_MESH_PRIV_GATT_PROXY);
247 }
248 
249 
bt_mesh_default_ttl_set(uint8_t default_ttl)250 int bt_mesh_default_ttl_set(uint8_t default_ttl)
251 {
252 	if (default_ttl == 1 || default_ttl > BT_MESH_TTL_MAX) {
253 		return -EINVAL;
254 	}
255 
256 	if (default_ttl == bt_mesh.default_ttl) {
257 		return 0;
258 	}
259 
260 	bt_mesh.default_ttl = default_ttl;
261 
262 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
263 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
264 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
265 	}
266 
267 	return 0;
268 }
269 
bt_mesh_default_ttl_get(void)270 uint8_t bt_mesh_default_ttl_get(void)
271 {
272 	return bt_mesh.default_ttl;
273 }
274 
bt_mesh_friend_set(enum bt_mesh_feat_state friendship)275 int bt_mesh_friend_set(enum bt_mesh_feat_state friendship)
276 {
277 	int err;
278 
279 	if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
280 		return -ENOTSUP;
281 	}
282 
283 	err = feature_set(BT_MESH_FRIEND, friendship);
284 	if (err) {
285 		return err;
286 	}
287 
288 	bt_mesh_hb_feature_changed(BT_MESH_FEAT_FRIEND);
289 
290 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
291 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
292 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
293 	}
294 
295 	if (friendship == BT_MESH_FEATURE_DISABLED) {
296 		bt_mesh_friends_clear();
297 	}
298 
299 	return 0;
300 }
301 
bt_mesh_friend_get(void)302 enum bt_mesh_feat_state bt_mesh_friend_get(void)
303 {
304 	if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
305 		return BT_MESH_FEATURE_NOT_SUPPORTED;
306 	}
307 
308 	return feature_get(BT_MESH_FRIEND);
309 }
310 
bt_mesh_net_transmit_set(uint8_t xmit)311 void bt_mesh_net_transmit_set(uint8_t xmit)
312 {
313 	if (bt_mesh.net_xmit == xmit) {
314 		return;
315 	}
316 
317 	bt_mesh.net_xmit = xmit;
318 
319 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
320 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
321 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
322 	}
323 }
324 
bt_mesh_net_transmit_get(void)325 uint8_t bt_mesh_net_transmit_get(void)
326 {
327 	return bt_mesh.net_xmit;
328 }
329 
bt_mesh_relay_set(enum bt_mesh_feat_state relay,uint8_t xmit)330 int bt_mesh_relay_set(enum bt_mesh_feat_state relay, uint8_t xmit)
331 {
332 	int err;
333 
334 	if (!IS_ENABLED(CONFIG_BT_MESH_RELAY)) {
335 		return -ENOTSUP;
336 	}
337 
338 	err = feature_set(BT_MESH_RELAY, relay);
339 	if (err == -EINVAL) {
340 		return err;
341 	}
342 
343 	if (err == -EALREADY && bt_mesh.relay_xmit == xmit) {
344 		return -EALREADY;
345 	}
346 
347 	bt_mesh.relay_xmit = xmit;
348 	bt_mesh_hb_feature_changed(BT_MESH_FEAT_RELAY);
349 
350 	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
351 	    atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
352 		bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
353 	}
354 
355 	return 0;
356 }
357 
bt_mesh_relay_get(void)358 enum bt_mesh_feat_state bt_mesh_relay_get(void)
359 {
360 	return feature_get(BT_MESH_RELAY);
361 }
362 
bt_mesh_relay_retransmit_get(void)363 uint8_t bt_mesh_relay_retransmit_get(void)
364 {
365 	if (!IS_ENABLED(CONFIG_BT_MESH_RELAY)) {
366 		return 0;
367 	}
368 
369 	return bt_mesh.relay_xmit;
370 }
371 
bt_mesh_fixed_group_match(uint16_t addr)372 bool bt_mesh_fixed_group_match(uint16_t addr)
373 {
374 	/* Check for fixed group addresses */
375 	switch (addr) {
376 	case BT_MESH_ADDR_ALL_NODES:
377 		return true;
378 	case BT_MESH_ADDR_PROXIES:
379 		return (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED);
380 	case BT_MESH_ADDR_FRIENDS:
381 		return (bt_mesh_friend_get() == BT_MESH_FEATURE_ENABLED);
382 	case BT_MESH_ADDR_RELAYS:
383 		return (bt_mesh_relay_get() == BT_MESH_FEATURE_ENABLED);
384 	default:
385 		return false;
386 	}
387 }
388 
bt_mesh_cfg_default_set(void)389 void bt_mesh_cfg_default_set(void)
390 {
391 	bt_mesh.default_ttl = CONFIG_BT_MESH_DEFAULT_TTL;
392 	bt_mesh.net_xmit =
393 		BT_MESH_TRANSMIT(CONFIG_BT_MESH_NETWORK_TRANSMIT_COUNT,
394 				 CONFIG_BT_MESH_NETWORK_TRANSMIT_INTERVAL);
395 
396 #if defined(CONFIG_BT_MESH_RELAY)
397 	bt_mesh.relay_xmit =
398 		BT_MESH_TRANSMIT(CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT,
399 				 CONFIG_BT_MESH_RELAY_RETRANSMIT_INTERVAL);
400 #endif
401 
402 	if (IS_ENABLED(CONFIG_BT_MESH_RELAY_ENABLED)) {
403 		atomic_set_bit(bt_mesh.flags, BT_MESH_RELAY);
404 	}
405 
406 	if (IS_ENABLED(CONFIG_BT_MESH_BEACON_ENABLED)) {
407 		atomic_set_bit(bt_mesh.flags, BT_MESH_BEACON);
408 	}
409 
410 	if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY_ENABLED)) {
411 		atomic_set_bit(bt_mesh.flags, BT_MESH_GATT_PROXY);
412 	}
413 
414 	if (IS_ENABLED(CONFIG_BT_MESH_FRIEND_ENABLED)) {
415 		atomic_set_bit(bt_mesh.flags, BT_MESH_FRIEND);
416 	}
417 }
418 
cfg_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)419 static int cfg_set(const char *name, size_t len_rd,
420 		   settings_read_cb read_cb, void *cb_arg)
421 {
422 	struct cfg_val cfg;
423 	int err;
424 
425 	if (len_rd == 0) {
426 		LOG_DBG("Cleared configuration state");
427 		return 0;
428 	}
429 
430 	err = bt_mesh_settings_set(read_cb, cb_arg, &cfg, sizeof(cfg));
431 	if (err) {
432 		LOG_ERR("Failed to set \'cfg\'");
433 		return err;
434 	}
435 
436 	bt_mesh_net_transmit_set(cfg.net_transmit);
437 	bt_mesh_relay_set(cfg.relay, cfg.relay_retransmit);
438 	bt_mesh_beacon_set(cfg.beacon);
439 	bt_mesh_gatt_proxy_set(cfg.gatt_proxy);
440 	bt_mesh_friend_set(cfg.frnd);
441 	bt_mesh_default_ttl_set(cfg.default_ttl);
442 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
443 	bt_mesh_priv_beacon_set(cfg.priv_beacon);
444 	bt_mesh_priv_beacon_update_interval_set(cfg.priv_beacon_int);
445 #endif
446 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
447 	bt_mesh_od_priv_proxy_set(cfg.on_demand_state);
448 #endif
449 
450 	LOG_DBG("Restored configuration state");
451 
452 	return 0;
453 }
454 
455 BT_MESH_SETTINGS_DEFINE(cfg, "Cfg", cfg_set);
456 
clear_cfg(void)457 static void clear_cfg(void)
458 {
459 	int err;
460 
461 	err = settings_delete("bt/mesh/Cfg");
462 	if (err) {
463 		LOG_ERR("Failed to clear configuration");
464 	} else {
465 		LOG_DBG("Cleared configuration");
466 	}
467 }
468 
store_pending_cfg(void)469 static void store_pending_cfg(void)
470 {
471 	struct cfg_val val;
472 	int err;
473 
474 	val.net_transmit = bt_mesh_net_transmit_get();
475 	val.relay = bt_mesh_relay_get();
476 	val.relay_retransmit = bt_mesh_relay_retransmit_get();
477 	val.beacon = bt_mesh_beacon_enabled();
478 	val.gatt_proxy = bt_mesh_gatt_proxy_get();
479 	val.frnd = bt_mesh_friend_get();
480 	val.default_ttl = bt_mesh_default_ttl_get();
481 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
482 	val.priv_beacon = bt_mesh_priv_beacon_get();
483 	val.priv_beacon_int = bt_mesh_priv_beacon_update_interval_get();
484 #endif
485 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
486 	val.on_demand_state = bt_mesh_od_priv_proxy_get();
487 #endif
488 
489 
490 	err = settings_save_one("bt/mesh/Cfg", &val, sizeof(val));
491 	if (err) {
492 		LOG_ERR("Failed to store configuration value");
493 	} else {
494 		LOG_DBG("Stored configuration value");
495 		LOG_HEXDUMP_DBG(&val, sizeof(val), "raw value");
496 	}
497 }
498 
bt_mesh_cfg_pending_store(void)499 void bt_mesh_cfg_pending_store(void)
500 {
501 	if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
502 		store_pending_cfg();
503 	} else {
504 		clear_cfg();
505 	}
506 }
507