From af944ff6657b7e51e85a483689652d3e6abb3bf6 Mon Sep 17 00:00:00 2001 From: Trond Einar Snekvik Date: Fri, 7 Aug 2020 10:16:13 +0200 Subject: [PATCH] Bluetooth: Mesh: Heartbeat period starts at tx Starts the periodic heartbeat publish period at the end of the publication, instead of at the ordering time. This ensures that the heartbeat period doesn't get shortened by other enqueued messages. Signed-off-by: Trond Einar Snekvik --- subsys/bluetooth/mesh/cfg_srv.c | 46 ++++++++++++++++++++++--------- subsys/bluetooth/mesh/lpn.c | 4 +-- subsys/bluetooth/mesh/transport.c | 8 +++--- subsys/bluetooth/mesh/transport.h | 2 +- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index 652b8d0bc57..ea735f308ca 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -779,7 +779,7 @@ static void gatt_proxy_set(struct bt_mesh_model *model, } if (cfg->hb_pub.feat & BT_MESH_FEAT_PROXY) { - bt_mesh_heartbeat_send(); + (void)bt_mesh_heartbeat_send(NULL, NULL); } send_status: @@ -885,7 +885,7 @@ static void relay_set(struct bt_mesh_model *model, BT_MESH_TRANSMIT_INT(cfg->relay_retransmit)); if ((cfg->hb_pub.feat & BT_MESH_FEAT_RELAY) && change) { - bt_mesh_heartbeat_send(); + (void)bt_mesh_heartbeat_send(NULL, NULL); } } else { BT_WARN("Invalid Relay value 0x%02x", buf->data[0]); @@ -2710,7 +2710,7 @@ static void friend_set(struct bt_mesh_model *model, } if (cfg->hb_pub.feat & BT_MESH_FEAT_FRIEND) { - bt_mesh_heartbeat_send(); + (void)bt_mesh_heartbeat_send(NULL, NULL); } send_status: @@ -3196,13 +3196,39 @@ const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = { BT_MESH_MODEL_OP_END, }; +static void hb_publish_end_cb(int err, void *cb_data) +{ + struct bt_mesh_cfg_srv *cfg = cb_data; + uint16_t period_ms; + + period_ms = hb_pwr2(cfg->hb_pub.period, 1) * 1000U; + if (period_ms && cfg->hb_pub.count > 1) { + k_delayed_work_submit(&cfg->hb_pub.timer, K_MSEC(period_ms)); + } + + if (cfg->hb_pub.count != 0xffff) { + cfg->hb_pub.count--; + } +} + +static void hb_publish_start_cb(uint16_t duration, int err, void *cb_data) +{ + if (err) { + hb_publish_end_cb(err, cb_data); + } +} + static void hb_publish(struct k_work *work) { + static const struct bt_mesh_send_cb publish_cb = { + .start = hb_publish_start_cb, + .end = hb_publish_end_cb, + }; struct bt_mesh_cfg_srv *cfg = CONTAINER_OF(work, struct bt_mesh_cfg_srv, hb_pub.timer.work); struct bt_mesh_subnet *sub; - uint16_t period_ms; + int err; BT_DBG("hb_pub.count: %u", cfg->hb_pub.count); @@ -3218,15 +3244,9 @@ static void hb_publish(struct k_work *work) return; } - period_ms = hb_pwr2(cfg->hb_pub.period, 1) * 1000U; - if (period_ms && cfg->hb_pub.count > 1) { - k_delayed_work_submit(&cfg->hb_pub.timer, K_MSEC(period_ms)); - } - - bt_mesh_heartbeat_send(); - - if (cfg->hb_pub.count != 0xffff) { - cfg->hb_pub.count--; + err = bt_mesh_heartbeat_send(&publish_cb, cfg); + if (err) { + hb_publish_end_cb(err, cfg); } } diff --git a/subsys/bluetooth/mesh/lpn.c b/subsys/bluetooth/mesh/lpn.c index 0aa9979b0fe..795ee660a21 100644 --- a/subsys/bluetooth/mesh/lpn.c +++ b/subsys/bluetooth/mesh/lpn.c @@ -248,7 +248,7 @@ static void clear_friendship(bool force, bool disable) lpn->groups_changed = 1U; if (cfg->hb_pub.feat & BT_MESH_FEAT_LOW_POWER) { - bt_mesh_heartbeat_send(); + (void)bt_mesh_heartbeat_send(NULL, NULL); } if (disable) { @@ -966,7 +966,7 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, BT_INFO("Friendship established with 0x%04x", lpn->frnd); if (cfg->hb_pub.feat & BT_MESH_FEAT_LOW_POWER) { - bt_mesh_heartbeat_send(); + (void)bt_mesh_heartbeat_send(NULL, NULL); } if (lpn_cb) { diff --git a/subsys/bluetooth/mesh/transport.c b/subsys/bluetooth/mesh/transport.c index 645fe743fd4..86999fdb504 100644 --- a/subsys/bluetooth/mesh/transport.c +++ b/subsys/bluetooth/mesh/transport.c @@ -1859,7 +1859,7 @@ void bt_mesh_rpl_clear(void) (void)memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); } -void bt_mesh_heartbeat_send(void) +int bt_mesh_heartbeat_send(const struct bt_mesh_send_cb *cb, void *cb_data) { struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); uint16_t feat = 0U; @@ -1882,7 +1882,7 @@ void bt_mesh_heartbeat_send(void) /* Do nothing if heartbeat publication is not enabled */ if (cfg->hb_pub.dst == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } hb.init_ttl = cfg->hb_pub.ttl; @@ -1907,8 +1907,8 @@ void bt_mesh_heartbeat_send(void) BT_DBG("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); - bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), - NULL, NULL); + return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), + cb, cb_data); } int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, diff --git a/subsys/bluetooth/mesh/transport.h b/subsys/bluetooth/mesh/transport.h index 422ae957778..55042075a0c 100644 --- a/subsys/bluetooth/mesh/transport.h +++ b/subsys/bluetooth/mesh/transport.h @@ -101,7 +101,7 @@ void bt_mesh_trans_init(void); void bt_mesh_rpl_clear(void); -void bt_mesh_heartbeat_send(void); +int bt_mesh_heartbeat_send(const struct bt_mesh_send_cb *cb, void *cb_data); int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, uint16_t addr, const uint8_t **key, uint8_t *aid);