Bluetooth: Mesh: Fix Heartbeat Pub/Sub Count/Period Log calculation

Mesh Profile Specification Errata 11737 specifies that
Period/Count Log value 0x11 is not defined Log field
transformation in Table 4.1.

Errata 11737 adds value 0x11 to Log field transformation
table with 2-octet value equal to 0x10000 which does not fit into
two octets. This patch changes period calculation to 32-bit precision.
There is also a special case for publication count. If the
log value is equal to 0x11 then the publication count value
should be 0xfffe. When sending Hearbeat Publication Status
message we should return the same value as the one received
in Publication Set so we have to add a case in hb_pub_count_log().

Co-authored-by: Alperen Sener <alperen.sener@nordicsemi.no>
Signed-off-by: Michał Narajowski <michal.narajowski@codecoup.pl>
Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
This commit is contained in:
Michał Narajowski 2020-07-16 14:16:46 +02:00 committed by Carles Cufí
commit 91fa9194f0
3 changed files with 35 additions and 9 deletions

View file

@ -2240,12 +2240,23 @@ static int krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
return send_krp_status(model, ctx, idx, phase, status);
}
static uint8_t hb_sub_count_log(uint32_t val)
{
if (val == 0xffff) {
return 0xff;
} else {
return bt_mesh_hb_log(val);
}
}
static uint8_t hb_pub_count_log(uint16_t val)
{
if (!val) {
return 0x00;
} else if (val == 0x01) {
return 0x01;
} else if (val == 0xfffe) {
return 0x11;
} else if (val == 0xffff) {
return 0xff;
} else {
@ -2312,8 +2323,19 @@ static int heartbeat_pub_set(struct bt_mesh_model *model,
LOG_DBG("src 0x%04x", ctx->addr);
pub.dst = sys_le16_to_cpu(param->dst);
pub.count = bt_mesh_hb_pwr2(param->count_log);
pub.period = bt_mesh_hb_pwr2(param->period_log);
if (param->count_log == 0x11) {
/* Special case defined in Mesh Profile Errata 11737 */
pub.count = 0xfffe;
} else {
pub.count = bt_mesh_hb_pwr2(param->count_log);
}
if (param->period_log == 0x11) {
pub.period = 0x10000;
} else {
pub.period = bt_mesh_hb_pwr2(param->period_log);
}
pub.ttl = param->ttl;
pub.feat = sys_le16_to_cpu(param->feat);
pub.net_idx = sys_le16_to_cpu(param->net_idx);
@ -2329,7 +2351,7 @@ static int heartbeat_pub_set(struct bt_mesh_model *model,
goto rsp;
}
if (param->period_log > 0x10) {
if (param->period_log > 0x11) {
status = STATUS_CANNOT_SET;
goto rsp;
}
@ -2364,7 +2386,7 @@ static int hb_sub_send_status(struct bt_mesh_model *model,
net_buf_simple_add_le16(&msg, sub->src);
net_buf_simple_add_le16(&msg, sub->dst);
net_buf_simple_add_u8(&msg, bt_mesh_hb_log(sub->remaining));
net_buf_simple_add_u8(&msg, bt_mesh_hb_log(sub->count));
net_buf_simple_add_u8(&msg, hb_sub_count_log(sub->count));
net_buf_simple_add_u8(&msg, sub->min_hops);
net_buf_simple_add_u8(&msg, sub->max_hops);
@ -2411,7 +2433,11 @@ static int heartbeat_sub_set(struct bt_mesh_model *model,
return -EINVAL;
}
period = bt_mesh_hb_pwr2(period_log);
if (period_log == 0x11) {
period = 0x10000;
} else {
period = bt_mesh_hb_pwr2(period_log);
}
status = bt_mesh_hb_sub_set(sub_src, sub_dst, period);
if (status != STATUS_SUCCESS) {