Skip to content

Commit e5b8f60

Browse files
Johan Hedbergjhedberg
authored andcommitted
Bluetooth: Mesh: Add support for suspend/resume
In some cases the Friendship & Low Power Node features aren't available or feasible, however power saving is nevertheless required. This patch introduces two new APIs to suspend and resume the Mesh network. Currently, what this impacts is the LE scanning, the ability to allocate new outgoing buffers, as well as the model publishing, beacon and heartbeat timers. Signed-off-by: Johan Hedberg <[email protected]>
1 parent 3e11177 commit e5b8f60

File tree

6 files changed

+114
-0
lines changed

6 files changed

+114
-0
lines changed

include/bluetooth/mesh/main.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,27 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
279279
*/
280280
void bt_mesh_reset(void);
281281

282+
/** @brief Suspend the Mesh network temporarily.
283+
*
284+
* This API can be used for power saving purposes, but the user should be
285+
* aware that leaving the local node suspended for a long period of time
286+
* may cause it to become permanently disconnected from the Mesh network.
287+
* If at all possible, the Friendship feature should be used instead, to
288+
* make the node into a Low Power Node.
289+
*
290+
* @return 0 on success, or (negative) error code on failure.
291+
*/
292+
int bt_mesh_suspend(void);
293+
294+
/** @brief Resume a suspended Mesh network.
295+
*
296+
* This API resumes the local node, after it has been suspended using the
297+
* bt_mesh_suspend() API.
298+
*
299+
* @return 0 on success, or (negative) error code on failure.
300+
*/
301+
int bt_mesh_resume(void);
302+
282303
/** @brief Provision the local Mesh Node.
283304
*
284305
* This API should normally not be used directly by the application. The

subsys/bluetooth/host/mesh/adv.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
214214
struct bt_mesh_adv *adv;
215215
struct net_buf *buf;
216216

217+
if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
218+
BT_WARN("Refusing to allocate buffer while suspended");
219+
return NULL;
220+
}
221+
217222
buf = net_buf_alloc(pool, timeout);
218223
if (!buf) {
219224
return NULL;

subsys/bluetooth/host/mesh/cfg_srv.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3492,6 +3492,13 @@ struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void)
34923492
return &conf->hb_pub;
34933493
}
34943494

3495+
void bt_mesh_hb_pub_disable(void)
3496+
{
3497+
if (conf) {
3498+
hb_pub_disable(conf);
3499+
}
3500+
}
3501+
34953502
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void)
34963503
{
34973504
return conf;

subsys/bluetooth/host/mesh/foundation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ void bt_mesh_attention(struct bt_mesh_model *model, u8_t time);
127127
u8_t *bt_mesh_label_uuid_get(u16_t addr);
128128

129129
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
130+
void bt_mesh_hb_pub_disable(void);
130131
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void);
131132

132133
u8_t bt_mesh_net_transmit_get(void);

subsys/bluetooth/host/mesh/main.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,85 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
191191
return 0;
192192
}
193193

194+
static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
195+
bool vnd, bool primary, void *user_data)
196+
{
197+
if (mod->pub && mod->pub->update) {
198+
mod->pub->count = 0;
199+
k_delayed_work_cancel(&mod->pub->timer);
200+
}
201+
}
202+
203+
int bt_mesh_suspend(void)
204+
{
205+
int err;
206+
207+
if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
208+
return -EINVAL;
209+
}
210+
211+
if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
212+
return -EALREADY;
213+
}
214+
215+
err = bt_mesh_scan_disable();
216+
if (err) {
217+
atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
218+
BT_WARN("Disabling scanning failed (err %d)", err);
219+
return err;
220+
}
221+
222+
bt_mesh_hb_pub_disable();
223+
224+
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
225+
bt_mesh_beacon_disable();
226+
}
227+
228+
bt_mesh_model_foreach(model_suspend, NULL);
229+
230+
return 0;
231+
}
232+
233+
static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
234+
bool vnd, bool primary, void *user_data)
235+
{
236+
if (mod->pub && mod->pub->update) {
237+
s32_t period_ms = bt_mesh_model_pub_period_get(mod);
238+
239+
if (period_ms) {
240+
k_delayed_work_submit(&mod->pub->timer, period_ms);
241+
}
242+
}
243+
}
244+
245+
int bt_mesh_resume(void)
246+
{
247+
int err;
248+
249+
if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
250+
return -EINVAL;
251+
}
252+
253+
if (!atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
254+
return -EALREADY;
255+
}
256+
257+
err = bt_mesh_scan_enable();
258+
if (err) {
259+
BT_WARN("Re-enabling scanning failed (err %d)", err);
260+
atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
261+
return err;
262+
}
263+
264+
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
265+
bt_mesh_beacon_enable();
266+
}
267+
268+
bt_mesh_model_foreach(model_resume, NULL);
269+
270+
return err;
271+
}
272+
194273
int bt_mesh_init(const struct bt_mesh_prov *prov,
195274
const struct bt_mesh_comp *comp)
196275
{

subsys/bluetooth/host/mesh/net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ struct bt_mesh_lpn {
194194
/* bt_mesh_net.flags */
195195
enum {
196196
BT_MESH_VALID, /* We have been provisioned */
197+
BT_MESH_SUSPENDED, /* Network is temporarily suspended */
197198
BT_MESH_IVU_IN_PROGRESS, /* IV Update in Progress */
198199
BT_MESH_IVU_INITIATOR, /* IV Update initiated by us */
199200
BT_MESH_IVU_TEST, /* IV Update test mode */

0 commit comments

Comments
 (0)