1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <zephyr/sys/util.h>
11
12 #include <zephyr/bluetooth/hci.h>
13
14 #include <zephyr/settings/settings.h>
15 #include <zephyr/bluetooth/mesh.h>
16
17 #include "host/hci_core.h"
18 #include "mesh.h"
19 #include "subnet.h"
20 #include "app_keys.h"
21 #include "net.h"
22 #include "cdb.h"
23 #include "crypto.h"
24 #include "rpl.h"
25 #include "transport.h"
26 #include "heartbeat.h"
27 #include "access.h"
28 #include "proxy.h"
29 #include "pb_gatt_srv.h"
30 #include "settings.h"
31 #include "cfg.h"
32 #include "brg_cfg.h"
33 #include "solicitation.h"
34 #include "va.h"
35
36 #define LOG_LEVEL CONFIG_BT_MESH_SETTINGS_LOG_LEVEL
37 #include <zephyr/logging/log.h>
38 LOG_MODULE_REGISTER(bt_mesh_settings);
39
40 #ifdef CONFIG_BT_MESH_RPL_STORE_TIMEOUT
41 #define RPL_STORE_TIMEOUT CONFIG_BT_MESH_RPL_STORE_TIMEOUT
42 #else
43 #define RPL_STORE_TIMEOUT (-1)
44 #endif
45
46 #ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO
47 #define SETTINGS_WORKQ_PRIO CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO
48 #else
49 #define SETTINGS_WORKQ_PRIO 1
50 #endif
51
52 #ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE
53 #define SETTINGS_WORKQ_STACK_SIZE CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE
54 #else
55 #define SETTINGS_WORKQ_STACK_SIZE 0
56 #endif
57
58 static struct k_work_q settings_work_q;
59 static K_THREAD_STACK_DEFINE(settings_work_stack, SETTINGS_WORKQ_STACK_SIZE);
60
61 static struct k_work_delayable pending_store;
62 static ATOMIC_DEFINE(pending_flags, BT_MESH_SETTINGS_FLAG_COUNT);
63
bt_mesh_settings_set(settings_read_cb read_cb,void * cb_arg,void * out,size_t read_len)64 int bt_mesh_settings_set(settings_read_cb read_cb, void *cb_arg,
65 void *out, size_t read_len)
66 {
67 ssize_t len;
68
69 len = read_cb(cb_arg, out, read_len);
70 if (len < 0) {
71 LOG_ERR("Failed to read value (err %zd)", len);
72 return len;
73 }
74
75 LOG_HEXDUMP_DBG(out, len, "val");
76
77 if (len != read_len) {
78 LOG_ERR("Unexpected value length (%zd != %zu)", len, read_len);
79 return -EINVAL;
80 }
81
82 return 0;
83 }
84
mesh_commit(void)85 static int mesh_commit(void)
86 {
87 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_INIT)) {
88 return 0;
89 }
90
91 if (!atomic_test_bit(bt_dev.flags, BT_DEV_ENABLE)) {
92 /* The Bluetooth Mesh settings loader calls bt_mesh_start() immediately
93 * after loading the settings. This is not intended to work before
94 * bt_enable(). The doc on @ref bt_enable requires the "bt/" settings
95 * tree to be loaded after @ref bt_enable is completed, so this handler
96 * will be called again later.
97 */
98 return 0;
99 }
100
101 if (!bt_mesh_subnet_next(NULL)) {
102 /* Nothing to do since we're not yet provisioned */
103 return 0;
104 }
105
106 if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
107 (void)bt_mesh_pb_gatt_srv_disable();
108 }
109
110 bt_mesh_net_settings_commit();
111 bt_mesh_model_settings_commit();
112
113 atomic_set_bit(bt_mesh.flags, BT_MESH_VALID);
114
115 bt_mesh_start();
116
117 return 0;
118 }
119
120 SETTINGS_STATIC_HANDLER_DEFINE(bt_mesh, "bt/mesh", NULL, NULL, mesh_commit,
121 NULL);
122
123 /* Pending flags that use K_NO_WAIT as the storage timeout */
124 #define NO_WAIT_PENDING_BITS (BIT(BT_MESH_SETTINGS_NET_PENDING) | \
125 BIT(BT_MESH_SETTINGS_IV_PENDING) | \
126 BIT(BT_MESH_SETTINGS_SEQ_PENDING) | \
127 BIT(BT_MESH_SETTINGS_CDB_PENDING))
128
129 /* Pending flags that use CONFIG_BT_MESH_STORE_TIMEOUT */
130 #define GENERIC_PENDING_BITS \
131 (BIT(BT_MESH_SETTINGS_NET_KEYS_PENDING) | BIT(BT_MESH_SETTINGS_APP_KEYS_PENDING) | \
132 BIT(BT_MESH_SETTINGS_HB_PUB_PENDING) | BIT(BT_MESH_SETTINGS_CFG_PENDING) | \
133 BIT(BT_MESH_SETTINGS_MOD_PENDING) | BIT(BT_MESH_SETTINGS_VA_PENDING) | \
134 BIT(BT_MESH_SETTINGS_SSEQ_PENDING) | BIT(BT_MESH_SETTINGS_COMP_PENDING) | \
135 BIT(BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING) | BIT(BT_MESH_SETTINGS_BRG_PENDING))
136
bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag)137 void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag)
138 {
139 uint32_t timeout_ms, remaining_ms;
140
141 atomic_set_bit(pending_flags, flag);
142
143 if (atomic_get(pending_flags) & NO_WAIT_PENDING_BITS) {
144 timeout_ms = 0;
145 } else if (IS_ENABLED(CONFIG_BT_MESH_RPL_STORAGE_MODE_SETTINGS) && RPL_STORE_TIMEOUT >= 0 &&
146 (atomic_test_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING) ||
147 atomic_test_bit(pending_flags, BT_MESH_SETTINGS_SRPL_PENDING)) &&
148 !(atomic_get(pending_flags) & GENERIC_PENDING_BITS)) {
149 timeout_ms = RPL_STORE_TIMEOUT * MSEC_PER_SEC;
150 } else {
151 timeout_ms = CONFIG_BT_MESH_STORE_TIMEOUT * MSEC_PER_SEC;
152 }
153
154 remaining_ms = k_ticks_to_ms_floor32(k_work_delayable_remaining_get(&pending_store));
155 LOG_DBG("Waiting %u ms vs rem %u ms", timeout_ms, remaining_ms);
156
157 /* If the new deadline is sooner, override any existing
158 * deadline; otherwise schedule without changing any existing
159 * deadline.
160 */
161 if (timeout_ms < remaining_ms) {
162 if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) {
163 k_work_reschedule_for_queue(&settings_work_q, &pending_store,
164 K_MSEC(timeout_ms));
165 } else {
166 k_work_reschedule(&pending_store, K_MSEC(timeout_ms));
167 }
168 } else {
169 if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) {
170 k_work_schedule_for_queue(&settings_work_q, &pending_store,
171 K_MSEC(timeout_ms));
172 } else {
173 k_work_schedule(&pending_store, K_MSEC(timeout_ms));
174 }
175 }
176 }
177
bt_mesh_settings_store_cancel(enum bt_mesh_settings_flag flag)178 void bt_mesh_settings_store_cancel(enum bt_mesh_settings_flag flag)
179 {
180 atomic_clear_bit(pending_flags, flag);
181 }
182
store_pending(struct k_work * work)183 static void store_pending(struct k_work *work)
184 {
185 LOG_DBG("");
186
187 static const struct {
188 void (*handler)(void);
189 } handlers[BT_MESH_SETTINGS_FLAG_COUNT] = {
190 [BT_MESH_SETTINGS_RPL_PENDING] = { bt_mesh_rpl_pending_store_all_nodes },
191 [BT_MESH_SETTINGS_NET_KEYS_PENDING] = { bt_mesh_subnet_pending_store },
192 [BT_MESH_SETTINGS_APP_KEYS_PENDING] = { bt_mesh_app_key_pending_store },
193 [BT_MESH_SETTINGS_NET_PENDING] = { bt_mesh_net_pending_net_store },
194 [BT_MESH_SETTINGS_IV_PENDING] = { bt_mesh_net_pending_iv_store },
195 [BT_MESH_SETTINGS_SEQ_PENDING] = { bt_mesh_net_pending_seq_store },
196 [BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING] = {
197 bt_mesh_net_pending_dev_key_cand_store },
198 [BT_MESH_SETTINGS_HB_PUB_PENDING] = { bt_mesh_hb_pub_pending_store },
199 [BT_MESH_SETTINGS_CFG_PENDING] = { bt_mesh_cfg_pending_store },
200 [BT_MESH_SETTINGS_COMP_PENDING] = { bt_mesh_comp_data_pending_clear },
201 [BT_MESH_SETTINGS_MOD_PENDING] = { bt_mesh_model_pending_store },
202 [BT_MESH_SETTINGS_VA_PENDING] = { bt_mesh_va_pending_store },
203 [BT_MESH_SETTINGS_CDB_PENDING] = {
204 IS_ENABLED(CONFIG_BT_MESH_CDB) ?
205 bt_mesh_cdb_pending_store : NULL },
206 [BT_MESH_SETTINGS_SRPL_PENDING] = {
207 IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) ?
208 bt_mesh_srpl_pending_store : NULL },
209 [BT_MESH_SETTINGS_SSEQ_PENDING] = {
210 IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) ?
211 bt_mesh_sseq_pending_store : NULL },
212 [BT_MESH_SETTINGS_BRG_PENDING] = {
213 IS_ENABLED(CONFIG_BT_MESH_BRG_CFG_SRV) ?
214 bt_mesh_brg_cfg_pending_store : NULL },
215 };
216
217 for (int i = 0; i < ARRAY_SIZE(handlers); i++) {
218 if (!handlers[i].handler) {
219 continue;
220 }
221
222 if (atomic_test_and_clear_bit(pending_flags, i)) {
223 handlers[i].handler();
224 }
225 }
226 }
227
bt_mesh_settings_init(void)228 void bt_mesh_settings_init(void)
229 {
230 if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) {
231 k_work_queue_start(&settings_work_q, settings_work_stack,
232 K_THREAD_STACK_SIZEOF(settings_work_stack),
233 K_PRIO_COOP(SETTINGS_WORKQ_PRIO), NULL);
234 k_thread_name_set(&settings_work_q.thread, "BT Mesh settings workq");
235 }
236
237 k_work_init_delayable(&pending_store, store_pending);
238 }
239
bt_mesh_settings_store_pending(void)240 void bt_mesh_settings_store_pending(void)
241 {
242 (void)k_work_cancel_delayable(&pending_store);
243
244 store_pending(&pending_store.work);
245 }
246