Message ID | 20200820054132.110483-1-inga.stotland@intel.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | [BlueZ] mesh: Use correct retransmit parameters for publications | expand |
Applied On Wed, 2020-08-19 at 22:41 -0700, Inga Stotland wrote: > This adds previously missing retransmit count and interval values > specific to model publications. The values are configured by Config CLient > and may be different to each model. > --- > mesh/cfgmod-server.c | 26 +++++++++++------- > mesh/mesh-config-json.c | 36 ++++++++++++------------- > mesh/mesh-config.h | 4 +-- > mesh/model.c | 59 +++++++++++++++++++++++------------------ > mesh/model.h | 9 ++++--- > mesh/net.c | 42 ++++++++++++++++++----------- > mesh/net.h | 6 ++--- > 7 files changed, 104 insertions(+), 78 deletions(-) > > diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c > index 90ebdf046..239ea889d 100644 > --- a/mesh/cfgmod-server.c > +++ b/mesh/cfgmod-server.c > @@ -48,7 +48,7 @@ static uint8_t msg[MAX_MSG_LEN]; > > static uint16_t set_pub_status(uint8_t status, uint16_t ele_addr, uint32_t id, > uint16_t pub_addr, uint16_t idx, bool cred_flag, > - uint8_t ttl, uint8_t period, uint8_t retransmit) > + uint8_t ttl, uint8_t period, uint8_t rtx) > { > size_t n; > > @@ -61,7 +61,7 @@ static uint16_t set_pub_status(uint8_t status, uint16_t ele_addr, uint32_t id, > n += 6; > msg[n++] = ttl; > msg[n++] = period; > - msg[n++] = retransmit; > + msg[n++] = rtx; > > if (!IS_VENDOR(id)) { > l_put_le16(MODEL_ID(id), msg + n); > @@ -80,6 +80,7 @@ static uint16_t config_pub_get(struct mesh_node *node, const uint8_t *pkt, > { > uint32_t id; > uint16_t ele_addr; > + uint8_t rtx; > struct mesh_model_pub *pub; > int status; > > @@ -88,10 +89,12 @@ static uint16_t config_pub_get(struct mesh_node *node, const uint8_t *pkt, > > pub = mesh_model_pub_get(node, ele_addr, id, &status); > > + rtx = pub->rtx.cnt + (((pub->rtx.interval / 50) - 1) << 3); > + > if (pub && status == MESH_STATUS_SUCCESS) > return set_pub_status(status, ele_addr, id, pub->addr, pub->idx, > pub->credential, pub->ttl, pub->period, > - pub->retransmit); > + rtx); > else > return set_pub_status(status, ele_addr, id, 0, 0, 0, 0, 0, 0); > } > @@ -102,7 +105,7 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, > uint32_t id; > uint16_t ele_addr, idx, pub_dst; > const uint8_t *pub_addr; > - uint8_t ttl, period, retransmit; > + uint8_t ttl, period, rtx, cnt, interval; > int status; > bool cred_flag; > > @@ -124,12 +127,15 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, > idx &= APP_IDX_MASK; > ttl = pkt[6]; > period = pkt[7]; > - retransmit = pkt[8]; > + rtx = pkt[8]; > id = CFG_GET_ID(vendor, pkt + 9); > > + cnt = rtx & 0x7; > + interval = ((rtx >> 3) + 1) * 50; > + > status = mesh_model_pub_set(node, ele_addr, id, pub_addr, idx, > - cred_flag, ttl, period, retransmit, > - virt, &pub_dst); > + cred_flag, ttl, period, cnt, > + interval, virt, &pub_dst); > > l_debug("pub_set: status %d, ea %4.4x, ota: %4.4x, id: %x, idx: %3.3x", > status, ele_addr, pub_dst, id, idx); > @@ -153,8 +159,8 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, > .ttl = ttl, > .credential = cred_flag, > .period = period, > - .count = retransmit & 0x7, > - .interval = ((retransmit >> 3) + 1) * 50 > + .cnt = cnt, > + .interval = interval > }; > > if (virt) > @@ -168,7 +174,7 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, > } > > return set_pub_status(status, ele_addr, id, pub_dst, idx, cred_flag, > - ttl, period, retransmit); > + ttl, period, rtx); > } > > static uint16_t cfg_sub_get_msg(struct mesh_node *node, const uint8_t *pkt, > diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c > index a145388d6..63b6c3988 100644 > --- a/mesh/mesh-config-json.c > +++ b/mesh/mesh-config-json.c > @@ -1021,7 +1021,7 @@ static struct mesh_config_pub *parse_model_publication(json_object *jpub) > > if (!get_int(jvalue, "count", &value)) > goto fail; > - pub->count = (uint8_t) value; > + pub->cnt = (uint8_t) value; > > if (!get_int(jvalue, "interval", &value)) > goto fail; > @@ -1339,20 +1339,20 @@ static bool parse_composition(json_object *jcomp, struct mesh_config_node *node) > > static bool read_net_transmit(json_object *jobj, struct mesh_config_node *node) > { > - json_object *jretransmit, *jvalue; > + json_object *jrtx, *jvalue; > uint16_t interval; > uint8_t cnt; > > - if (!json_object_object_get_ex(jobj, "retransmit", &jretransmit)) > + if (!json_object_object_get_ex(jobj, "retransmit", &jrtx)) > return true; > > - if (!json_object_object_get_ex(jretransmit, "count", &jvalue)) > + if (!json_object_object_get_ex(jrtx, "count", &jvalue)) > return false; > > /* TODO: add range checking */ > cnt = (uint8_t) json_object_get_int(jvalue); > > - if (!json_object_object_get_ex(jretransmit, "interval", &jvalue)) > + if (!json_object_object_get_ex(jrtx, "interval", &jvalue)) > return false; > > interval = (uint16_t) json_object_get_int(jvalue); > @@ -1566,30 +1566,30 @@ bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode, > bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt, > uint16_t interval) > { > - json_object *jnode, *jretransmit; > + json_object *jnode, *jrtx; > > if (!cfg) > return false; > > jnode = cfg->jnode; > > - jretransmit = json_object_new_object(); > - if (!jretransmit) > + jrtx = json_object_new_object(); > + if (!jrtx) > return false; > > - if (!write_int(jretransmit, "count", cnt)) > + if (!write_int(jrtx, "count", cnt)) > goto fail; > > - if (!write_int(jretransmit, "interval", interval)) > + if (!write_int(jrtx, "interval", interval)) > goto fail; > > json_object_object_del(jnode, "retransmit"); > - json_object_object_add(jnode, "retransmit", jretransmit); > + json_object_object_add(jnode, "retransmit", jrtx); > > return save_config(cfg->jnode, cfg->node_dir_path); > > fail: > - json_object_put(jretransmit); > + json_object_put(jrtx); > return false; > > } > @@ -1841,7 +1841,7 @@ bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t ele_addr, > uint32_t mod_id, bool vendor, > struct mesh_config_pub *pub) > { > - json_object *jnode, *jmodel, *jpub, *jretransmit; > + json_object *jnode, *jmodel, *jpub, *jrtx; > bool res; > int ele_idx; > > @@ -1885,17 +1885,17 @@ bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t ele_addr, > pub->credential ? 1 : 0)) > goto fail; > > - jretransmit = json_object_new_object(); > - if (!jretransmit) > + jrtx = json_object_new_object(); > + if (!jrtx) > goto fail; > > - if (!write_int(jretransmit, "count", pub->count)) > + if (!write_int(jrtx, "count", pub->cnt)) > goto fail; > > - if (!write_int(jretransmit, "interval", pub->interval)) > + if (!write_int(jrtx, "interval", pub->interval)) > goto fail; > > - json_object_object_add(jpub, "retransmit", jretransmit); > + json_object_object_add(jpub, "retransmit", jrtx); > json_object_object_add(jmodel, "publish", jpub); > > return save_config(jnode, cfg->node_dir_path); > diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h > index 50a55d51e..738cff9dd 100644 > --- a/mesh/mesh-config.h > +++ b/mesh/mesh-config.h > @@ -34,10 +34,10 @@ struct mesh_config_pub { > uint32_t period; > uint16_t addr; > uint16_t idx; > + uint16_t interval; > uint8_t ttl; > uint8_t credential; > - uint8_t count; > - uint8_t interval; > + uint8_t cnt; > uint8_t virt_addr[16]; > }; > > diff --git a/mesh/model.c b/mesh/model.c > index 961391f13..eb5142503 100644 > --- a/mesh/model.c > +++ b/mesh/model.c > @@ -508,10 +508,11 @@ static int virt_packet_decrypt(struct mesh_net *net, const uint8_t *data, > return -1; > } > > -static bool msg_send(struct mesh_node *node, bool credential, uint16_t src, > - uint32_t dst, uint16_t app_idx, uint16_t net_idx, > - uint8_t *label, uint8_t ttl, bool segmented, > - const void *msg, uint16_t msg_len) > +static bool msg_send(struct mesh_node *node, bool cred, uint16_t src, > + uint16_t dst, uint16_t app_idx, uint16_t net_idx, > + uint8_t *label, uint8_t ttl, uint8_t cnt, > + uint16_t interval, bool segmented, const void *msg, > + uint16_t msg_len) > { > uint8_t dev_key[16]; > uint32_t iv_index, seq_num; > @@ -562,9 +563,9 @@ static bool msg_send(struct mesh_node *node, bool credential, uint16_t src, > goto done; > } > > - ret = mesh_net_app_send(net, credential, src, dst, key_aid, net_idx, > - ttl, seq_num, iv_index, segmented, > - szmic, out, out_len); > + ret = mesh_net_app_send(net, cred, src, dst, key_aid, net_idx, ttl, > + cnt, interval, seq_num, iv_index, > + segmented, szmic, out, out_len); > done: > l_free(out); > return ret; > @@ -705,7 +706,7 @@ static struct mesh_virtual *add_virtual(const uint8_t *v) > > static int set_pub(struct mesh_model *mod, uint16_t pub_addr, > uint16_t idx, bool cred_flag, uint8_t ttl, > - uint8_t period, uint8_t retransmit) > + uint8_t period, uint8_t cnt, uint16_t interval) > { > if (!mod->pub) > mod->pub = l_new(struct mesh_model_pub, 1); > @@ -715,14 +716,15 @@ static int set_pub(struct mesh_model *mod, uint16_t pub_addr, > mod->pub->idx = idx; > mod->pub->ttl = ttl; > mod->pub->period = period; > - mod->pub->retransmit = retransmit; > + mod->pub->rtx.cnt = cnt; > + mod->pub->rtx.interval = interval; > > return MESH_STATUS_SUCCESS; > } > > static int set_virt_pub(struct mesh_model *mod, const uint8_t *label, > uint16_t idx, bool cred_flag, uint8_t ttl, > - uint8_t period, uint8_t retransmit) > + uint8_t period, uint8_t cnt, uint16_t interval) > { > struct mesh_virtual *virt = NULL; > > @@ -734,8 +736,8 @@ static int set_virt_pub(struct mesh_model *mod, const uint8_t *label, > mod->pub = l_new(struct mesh_model_pub, 1); > > mod->pub->virt = virt; > - return set_pub(mod, virt->addr, idx, cred_flag, ttl, period, > - retransmit); > + return set_pub(mod, virt->addr, idx, cred_flag, ttl, period, cnt, > + interval); > } > > static int add_virt_sub(struct mesh_net *net, struct mesh_model *mod, > @@ -1058,9 +1060,10 @@ int mesh_model_publish(struct mesh_node *node, uint32_t id, uint16_t src, > > net_idx = appkey_net_idx(net, mod->pub->idx); > > - result = msg_send(node, mod->pub->credential != 0, src, > - mod->pub->addr, mod->pub->idx, net_idx, > - label, mod->pub->ttl, false, msg, msg_len); > + result = msg_send(node, mod->pub->credential != 0, src, mod->pub->addr, > + mod->pub->idx, net_idx, label, mod->pub->ttl, > + mod->pub->rtx.cnt, mod->pub->rtx.interval, > + false, msg, msg_len); > > return result ? MESH_ERROR_NONE : MESH_ERROR_FAILED; > } > @@ -1070,6 +1073,10 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t dst, > uint8_t ttl, bool segmented, > const void *msg, uint16_t msg_len) > { > + struct mesh_net *net = node_get_net(node); > + uint8_t cnt; > + uint16_t interval; > + > /* If SRC is 0, use the Primary Element */ > if (src == 0) > src = node_get_primary(node); > @@ -1079,14 +1086,16 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t dst, > if (IS_UNASSIGNED(dst)) > return false; > > - return msg_send(node, false, src, dst, app_idx, net_idx, > - NULL, ttl, segmented, msg, msg_len); > + mesh_net_transmit_params_get(net, &cnt, &interval); > + > + return msg_send(node, false, src, dst, app_idx, net_idx, NULL, ttl, cnt, > + interval, segmented, msg, msg_len); > } > > int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id, > const uint8_t *pub_addr, uint16_t idx, bool cred_flag, > - uint8_t ttl, uint8_t period, uint8_t retransmit, > - bool is_virt, uint16_t *pub_dst) > + uint8_t ttl, uint8_t period, uint8_t cnt, > + uint16_t interval, bool is_virt, uint16_t *pub_dst) > { > struct mesh_model *mod; > int status, ele_idx = node_get_element_idx(node, addr); > @@ -1124,10 +1133,10 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id, > > if (!is_virt) { > status = set_pub(mod, l_get_le16(pub_addr), idx, cred_flag, > - ttl, period, retransmit); > + ttl, period, cnt, interval); > } else > status = set_virt_pub(mod, pub_addr, idx, cred_flag, ttl, > - period, retransmit); > + period, cnt, interval); > > *pub_dst = mod->pub->addr; > > @@ -1703,15 +1712,13 @@ static struct mesh_model *model_setup(struct mesh_net *net, uint8_t ele_idx, > > /* Add publication if enabled and present */ > if (mod->pub_enabled && pub) { > - uint8_t retransmit = pub->count + > - ((pub->interval / 50 - 1) << 3); > if (pub->virt) > set_virt_pub(mod, pub->virt_addr, pub->idx, > - pub->credential, pub->ttl, > - pub->period, retransmit); > + pub->credential, pub->ttl, pub->period, > + pub->cnt, pub->interval); > else if (!IS_UNASSIGNED(pub->addr)) > set_pub(mod, pub->addr, pub->idx, pub->credential, > - pub->ttl, pub->period, retransmit); > + pub->ttl, pub->period, pub->cnt, pub->interval); > } > > mod->sub_enabled = db_mod->sub_enabled; > diff --git a/mesh/model.h b/mesh/model.h > index 147a02279..a1afedd19 100644 > --- a/mesh/model.h > +++ b/mesh/model.h > @@ -40,10 +40,13 @@ struct mesh_model_pub { > struct mesh_virtual *virt; > uint16_t addr; > uint16_t idx; > + struct { > + uint16_t interval; > + uint8_t cnt; > + } rtx; > uint8_t ttl; > uint8_t credential; > uint8_t period; > - uint8_t retransmit; > }; > > typedef void (*mesh_model_unregister)(void *user_data); > @@ -78,8 +81,8 @@ struct mesh_model_pub *mesh_model_pub_get(struct mesh_node *node, > uint32_t id, int *status); > int mesh_model_pub_set(struct mesh_node *node, uint16_t ele_addr, uint32_t id, > const uint8_t *addr, uint16_t idx, bool cred_flag, > - uint8_t ttl, uint8_t period, uint8_t retransmit, > - bool is_virt, uint16_t *dst); > + uint8_t ttl, uint8_t period, uint8_t rtx_cnt, > + uint16_t rtx_interval, bool is_virt, uint16_t *dst); > > int mesh_model_binding_add(struct mesh_node *node, uint16_t ele_addr, > uint32_t id, uint16_t idx); > diff --git a/mesh/net.c b/mesh/net.c > index 26440b02d..93307e70c 100644 > --- a/mesh/net.c > +++ b/mesh/net.c > @@ -212,6 +212,8 @@ struct net_queue_data { > > struct oneshot_tx { > struct mesh_net *net; > + uint16_t interval; > + uint8_t cnt; > uint8_t size; > uint8_t packet[30]; > }; > @@ -1399,7 +1401,8 @@ static void friend_ack_rxed(struct mesh_net *net, uint32_t iv_index, > l_queue_foreach(net->friends, enqueue_friend_pkt, &frnd_ack); > } > > -static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t seg); > +static bool send_seg(struct mesh_net *net, uint8_t cnt, uint16_t interval, > + struct mesh_sar *msg, uint8_t seg); > > static void send_frnd_ack(struct mesh_net *net, uint16_t src, uint16_t dst, > uint32_t hdr, uint32_t flags) > @@ -1593,7 +1596,7 @@ static void ack_received(struct mesh_net *net, bool timeout, > l_debug("Resend Seg %d net:%p dst:%x app_idx:%3.3x", > i, net, outgoing->remote, outgoing->app_idx); > > - send_seg(net, outgoing, i); > + send_seg(net, net->tx_cnt, net->tx_interval, outgoing, i); > } > > l_timeout_remove(outgoing->seg_timeout); > @@ -2143,8 +2146,8 @@ static void send_msg_pkt_oneshot(void *user_data) > > tx->packet[0] = MESH_AD_TYPE_NETWORK; > info.type = MESH_IO_TIMING_TYPE_GENERAL; > - info.u.gen.interval = net->tx_interval; > - info.u.gen.cnt = net->tx_cnt; > + info.u.gen.interval = tx->interval; > + info.u.gen.cnt = tx->cnt; > info.u.gen.min_delay = DEFAULT_MIN_DELAY; > /* No extra randomization when sending regular mesh messages */ > info.u.gen.max_delay = DEFAULT_MIN_DELAY; > @@ -2153,11 +2156,14 @@ static void send_msg_pkt_oneshot(void *user_data) > l_free(tx); > } > > -static void send_msg_pkt(struct mesh_net *net, uint8_t *packet, uint8_t size) > +static void send_msg_pkt(struct mesh_net *net, uint8_t cnt, uint16_t interval, > + uint8_t *packet, uint8_t size) > { > struct oneshot_tx *tx = l_new(struct oneshot_tx, 1); > > tx->net = net; > + tx->interval = interval; > + tx->cnt = cnt; > tx->size = size; > memcpy(tx->packet, packet, size); > > @@ -2872,7 +2878,8 @@ bool mesh_net_dst_unreg(struct mesh_net *net, uint16_t dst) > return true; > } > > -static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t segO) > +static bool send_seg(struct mesh_net *net, uint8_t cnt, uint16_t interval, > + struct mesh_sar *msg, uint8_t segO) > { > struct mesh_subnet *subnet; > uint8_t seg_len; > @@ -2927,7 +2934,7 @@ static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t segO) > return false; > } > > - send_msg_pkt(net, packet, packet_len + 1); > + send_msg_pkt(net, cnt, interval, packet, packet_len + 1); > > msg->last_seg = segO; > > @@ -2967,7 +2974,8 @@ void mesh_net_send_seg(struct mesh_net *net, uint32_t net_key_id, > return; > } > > - send_msg_pkt(net, packet, packet_len + 1); > + send_msg_pkt(net, net->tx_cnt, net->tx_interval, packet, > + packet_len + 1); > > l_debug("TX: Friend Seg-%d %04x -> %04x : len %u) : TTL %d : SEQ %06x", > segO, src, dst, packet_len, ttl, seq); > @@ -2977,9 +2985,9 @@ void mesh_net_send_seg(struct mesh_net *net, uint32_t net_key_id, > > bool mesh_net_app_send(struct mesh_net *net, bool frnd_cred, uint16_t src, > uint16_t dst, uint8_t key_aid, uint16_t net_idx, > - uint8_t ttl, uint32_t seq, uint32_t iv_index, > - bool segmented, bool szmic, > - const void *msg, uint16_t msg_len) > + uint8_t ttl, uint8_t cnt, uint16_t interval, > + uint32_t seq, uint32_t iv_index, bool segmented, > + bool szmic, const void *msg, uint16_t msg_len) > { > struct mesh_sar *payload = NULL; > uint8_t seg, seg_max; > @@ -3054,11 +3062,12 @@ bool mesh_net_app_send(struct mesh_net *net, bool frnd_cred, uint16_t src, > > for (i = 0; i < 4; i++) { > for (seg = 0; seg <= seg_max && result; seg++) > - result = send_seg(net, payload, seg); > + result = send_seg(net, cnt, interval, payload, > + seg); > } > } else { > for (seg = 0; seg <= seg_max && result; seg++) > - result = send_seg(net, payload, seg); > + result = send_seg(net, cnt, interval, payload, seg); > } > > /* Reliable: Cache; Unreliable: Flush*/ > @@ -3108,7 +3117,7 @@ void mesh_net_ack_send(struct mesh_net *net, uint32_t key_id, uint32_t iv_index, > return; > } > > - send_msg_pkt(net, pkt, pkt_len + 1); > + send_msg_pkt(net, net->tx_cnt, net->tx_interval, pkt, pkt_len + 1); > > l_debug("TX: Friend ACK %04x -> %04x : len %u : TTL %d : SEQ %06x", > src, dst, pkt_len, ttl, seq); > @@ -3182,8 +3191,9 @@ void mesh_net_transport_send(struct mesh_net *net, uint32_t key_id, > return; > } > > - if (dst != 0) > - send_msg_pkt(net, pkt, pkt_len + 1); > + if (!(IS_UNASSIGNED(dst))) > + send_msg_pkt(net, net->tx_cnt, net->tx_interval, pkt, > + pkt_len + 1); > } > > int mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t idx, > diff --git a/mesh/net.h b/mesh/net.h > index 91e07ef78..253185e42 100644 > --- a/mesh/net.h > +++ b/mesh/net.h > @@ -300,9 +300,9 @@ void mesh_net_transport_send(struct mesh_net *net, uint32_t key_id, > > bool mesh_net_app_send(struct mesh_net *net, bool frnd_cred, uint16_t src, > uint16_t dst, uint8_t key_id, uint16_t net_idx, > - uint8_t ttl, uint32_t seq, uint32_t iv_index, > - bool segmented, bool szmic, const void *msg, > - uint16_t msg_len); > + uint8_t ttl, uint8_t cnt, uint16_t interval, > + uint32_t seq, uint32_t iv_index, bool segmented, > + bool szmic, const void *msg, uint16_t msg_len); > void mesh_net_ack_send(struct mesh_net *net, uint32_t key_id, > uint32_t iv_index, uint8_t ttl, uint32_t seq, > uint16_t src, uint16_t dst, bool rly,
diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c index 90ebdf046..239ea889d 100644 --- a/mesh/cfgmod-server.c +++ b/mesh/cfgmod-server.c @@ -48,7 +48,7 @@ static uint8_t msg[MAX_MSG_LEN]; static uint16_t set_pub_status(uint8_t status, uint16_t ele_addr, uint32_t id, uint16_t pub_addr, uint16_t idx, bool cred_flag, - uint8_t ttl, uint8_t period, uint8_t retransmit) + uint8_t ttl, uint8_t period, uint8_t rtx) { size_t n; @@ -61,7 +61,7 @@ static uint16_t set_pub_status(uint8_t status, uint16_t ele_addr, uint32_t id, n += 6; msg[n++] = ttl; msg[n++] = period; - msg[n++] = retransmit; + msg[n++] = rtx; if (!IS_VENDOR(id)) { l_put_le16(MODEL_ID(id), msg + n); @@ -80,6 +80,7 @@ static uint16_t config_pub_get(struct mesh_node *node, const uint8_t *pkt, { uint32_t id; uint16_t ele_addr; + uint8_t rtx; struct mesh_model_pub *pub; int status; @@ -88,10 +89,12 @@ static uint16_t config_pub_get(struct mesh_node *node, const uint8_t *pkt, pub = mesh_model_pub_get(node, ele_addr, id, &status); + rtx = pub->rtx.cnt + (((pub->rtx.interval / 50) - 1) << 3); + if (pub && status == MESH_STATUS_SUCCESS) return set_pub_status(status, ele_addr, id, pub->addr, pub->idx, pub->credential, pub->ttl, pub->period, - pub->retransmit); + rtx); else return set_pub_status(status, ele_addr, id, 0, 0, 0, 0, 0, 0); } @@ -102,7 +105,7 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, uint32_t id; uint16_t ele_addr, idx, pub_dst; const uint8_t *pub_addr; - uint8_t ttl, period, retransmit; + uint8_t ttl, period, rtx, cnt, interval; int status; bool cred_flag; @@ -124,12 +127,15 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, idx &= APP_IDX_MASK; ttl = pkt[6]; period = pkt[7]; - retransmit = pkt[8]; + rtx = pkt[8]; id = CFG_GET_ID(vendor, pkt + 9); + cnt = rtx & 0x7; + interval = ((rtx >> 3) + 1) * 50; + status = mesh_model_pub_set(node, ele_addr, id, pub_addr, idx, - cred_flag, ttl, period, retransmit, - virt, &pub_dst); + cred_flag, ttl, period, cnt, + interval, virt, &pub_dst); l_debug("pub_set: status %d, ea %4.4x, ota: %4.4x, id: %x, idx: %3.3x", status, ele_addr, pub_dst, id, idx); @@ -153,8 +159,8 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, .ttl = ttl, .credential = cred_flag, .period = period, - .count = retransmit & 0x7, - .interval = ((retransmit >> 3) + 1) * 50 + .cnt = cnt, + .interval = interval }; if (virt) @@ -168,7 +174,7 @@ static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt, } return set_pub_status(status, ele_addr, id, pub_dst, idx, cred_flag, - ttl, period, retransmit); + ttl, period, rtx); } static uint16_t cfg_sub_get_msg(struct mesh_node *node, const uint8_t *pkt, diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c index a145388d6..63b6c3988 100644 --- a/mesh/mesh-config-json.c +++ b/mesh/mesh-config-json.c @@ -1021,7 +1021,7 @@ static struct mesh_config_pub *parse_model_publication(json_object *jpub) if (!get_int(jvalue, "count", &value)) goto fail; - pub->count = (uint8_t) value; + pub->cnt = (uint8_t) value; if (!get_int(jvalue, "interval", &value)) goto fail; @@ -1339,20 +1339,20 @@ static bool parse_composition(json_object *jcomp, struct mesh_config_node *node) static bool read_net_transmit(json_object *jobj, struct mesh_config_node *node) { - json_object *jretransmit, *jvalue; + json_object *jrtx, *jvalue; uint16_t interval; uint8_t cnt; - if (!json_object_object_get_ex(jobj, "retransmit", &jretransmit)) + if (!json_object_object_get_ex(jobj, "retransmit", &jrtx)) return true; - if (!json_object_object_get_ex(jretransmit, "count", &jvalue)) + if (!json_object_object_get_ex(jrtx, "count", &jvalue)) return false; /* TODO: add range checking */ cnt = (uint8_t) json_object_get_int(jvalue); - if (!json_object_object_get_ex(jretransmit, "interval", &jvalue)) + if (!json_object_object_get_ex(jrtx, "interval", &jvalue)) return false; interval = (uint16_t) json_object_get_int(jvalue); @@ -1566,30 +1566,30 @@ bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode, bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt, uint16_t interval) { - json_object *jnode, *jretransmit; + json_object *jnode, *jrtx; if (!cfg) return false; jnode = cfg->jnode; - jretransmit = json_object_new_object(); - if (!jretransmit) + jrtx = json_object_new_object(); + if (!jrtx) return false; - if (!write_int(jretransmit, "count", cnt)) + if (!write_int(jrtx, "count", cnt)) goto fail; - if (!write_int(jretransmit, "interval", interval)) + if (!write_int(jrtx, "interval", interval)) goto fail; json_object_object_del(jnode, "retransmit"); - json_object_object_add(jnode, "retransmit", jretransmit); + json_object_object_add(jnode, "retransmit", jrtx); return save_config(cfg->jnode, cfg->node_dir_path); fail: - json_object_put(jretransmit); + json_object_put(jrtx); return false; } @@ -1841,7 +1841,7 @@ bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t ele_addr, uint32_t mod_id, bool vendor, struct mesh_config_pub *pub) { - json_object *jnode, *jmodel, *jpub, *jretransmit; + json_object *jnode, *jmodel, *jpub, *jrtx; bool res; int ele_idx; @@ -1885,17 +1885,17 @@ bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t ele_addr, pub->credential ? 1 : 0)) goto fail; - jretransmit = json_object_new_object(); - if (!jretransmit) + jrtx = json_object_new_object(); + if (!jrtx) goto fail; - if (!write_int(jretransmit, "count", pub->count)) + if (!write_int(jrtx, "count", pub->cnt)) goto fail; - if (!write_int(jretransmit, "interval", pub->interval)) + if (!write_int(jrtx, "interval", pub->interval)) goto fail; - json_object_object_add(jpub, "retransmit", jretransmit); + json_object_object_add(jpub, "retransmit", jrtx); json_object_object_add(jmodel, "publish", jpub); return save_config(jnode, cfg->node_dir_path); diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h index 50a55d51e..738cff9dd 100644 --- a/mesh/mesh-config.h +++ b/mesh/mesh-config.h @@ -34,10 +34,10 @@ struct mesh_config_pub { uint32_t period; uint16_t addr; uint16_t idx; + uint16_t interval; uint8_t ttl; uint8_t credential; - uint8_t count; - uint8_t interval; + uint8_t cnt; uint8_t virt_addr[16]; }; diff --git a/mesh/model.c b/mesh/model.c index 961391f13..eb5142503 100644 --- a/mesh/model.c +++ b/mesh/model.c @@ -508,10 +508,11 @@ static int virt_packet_decrypt(struct mesh_net *net, const uint8_t *data, return -1; } -static bool msg_send(struct mesh_node *node, bool credential, uint16_t src, - uint32_t dst, uint16_t app_idx, uint16_t net_idx, - uint8_t *label, uint8_t ttl, bool segmented, - const void *msg, uint16_t msg_len) +static bool msg_send(struct mesh_node *node, bool cred, uint16_t src, + uint16_t dst, uint16_t app_idx, uint16_t net_idx, + uint8_t *label, uint8_t ttl, uint8_t cnt, + uint16_t interval, bool segmented, const void *msg, + uint16_t msg_len) { uint8_t dev_key[16]; uint32_t iv_index, seq_num; @@ -562,9 +563,9 @@ static bool msg_send(struct mesh_node *node, bool credential, uint16_t src, goto done; } - ret = mesh_net_app_send(net, credential, src, dst, key_aid, net_idx, - ttl, seq_num, iv_index, segmented, - szmic, out, out_len); + ret = mesh_net_app_send(net, cred, src, dst, key_aid, net_idx, ttl, + cnt, interval, seq_num, iv_index, + segmented, szmic, out, out_len); done: l_free(out); return ret; @@ -705,7 +706,7 @@ static struct mesh_virtual *add_virtual(const uint8_t *v) static int set_pub(struct mesh_model *mod, uint16_t pub_addr, uint16_t idx, bool cred_flag, uint8_t ttl, - uint8_t period, uint8_t retransmit) + uint8_t period, uint8_t cnt, uint16_t interval) { if (!mod->pub) mod->pub = l_new(struct mesh_model_pub, 1); @@ -715,14 +716,15 @@ static int set_pub(struct mesh_model *mod, uint16_t pub_addr, mod->pub->idx = idx; mod->pub->ttl = ttl; mod->pub->period = period; - mod->pub->retransmit = retransmit; + mod->pub->rtx.cnt = cnt; + mod->pub->rtx.interval = interval; return MESH_STATUS_SUCCESS; } static int set_virt_pub(struct mesh_model *mod, const uint8_t *label, uint16_t idx, bool cred_flag, uint8_t ttl, - uint8_t period, uint8_t retransmit) + uint8_t period, uint8_t cnt, uint16_t interval) { struct mesh_virtual *virt = NULL; @@ -734,8 +736,8 @@ static int set_virt_pub(struct mesh_model *mod, const uint8_t *label, mod->pub = l_new(struct mesh_model_pub, 1); mod->pub->virt = virt; - return set_pub(mod, virt->addr, idx, cred_flag, ttl, period, - retransmit); + return set_pub(mod, virt->addr, idx, cred_flag, ttl, period, cnt, + interval); } static int add_virt_sub(struct mesh_net *net, struct mesh_model *mod, @@ -1058,9 +1060,10 @@ int mesh_model_publish(struct mesh_node *node, uint32_t id, uint16_t src, net_idx = appkey_net_idx(net, mod->pub->idx); - result = msg_send(node, mod->pub->credential != 0, src, - mod->pub->addr, mod->pub->idx, net_idx, - label, mod->pub->ttl, false, msg, msg_len); + result = msg_send(node, mod->pub->credential != 0, src, mod->pub->addr, + mod->pub->idx, net_idx, label, mod->pub->ttl, + mod->pub->rtx.cnt, mod->pub->rtx.interval, + false, msg, msg_len); return result ? MESH_ERROR_NONE : MESH_ERROR_FAILED; } @@ -1070,6 +1073,10 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t dst, uint8_t ttl, bool segmented, const void *msg, uint16_t msg_len) { + struct mesh_net *net = node_get_net(node); + uint8_t cnt; + uint16_t interval; + /* If SRC is 0, use the Primary Element */ if (src == 0) src = node_get_primary(node); @@ -1079,14 +1086,16 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t dst, if (IS_UNASSIGNED(dst)) return false; - return msg_send(node, false, src, dst, app_idx, net_idx, - NULL, ttl, segmented, msg, msg_len); + mesh_net_transmit_params_get(net, &cnt, &interval); + + return msg_send(node, false, src, dst, app_idx, net_idx, NULL, ttl, cnt, + interval, segmented, msg, msg_len); } int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id, const uint8_t *pub_addr, uint16_t idx, bool cred_flag, - uint8_t ttl, uint8_t period, uint8_t retransmit, - bool is_virt, uint16_t *pub_dst) + uint8_t ttl, uint8_t period, uint8_t cnt, + uint16_t interval, bool is_virt, uint16_t *pub_dst) { struct mesh_model *mod; int status, ele_idx = node_get_element_idx(node, addr); @@ -1124,10 +1133,10 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id, if (!is_virt) { status = set_pub(mod, l_get_le16(pub_addr), idx, cred_flag, - ttl, period, retransmit); + ttl, period, cnt, interval); } else status = set_virt_pub(mod, pub_addr, idx, cred_flag, ttl, - period, retransmit); + period, cnt, interval); *pub_dst = mod->pub->addr; @@ -1703,15 +1712,13 @@ static struct mesh_model *model_setup(struct mesh_net *net, uint8_t ele_idx, /* Add publication if enabled and present */ if (mod->pub_enabled && pub) { - uint8_t retransmit = pub->count + - ((pub->interval / 50 - 1) << 3); if (pub->virt) set_virt_pub(mod, pub->virt_addr, pub->idx, - pub->credential, pub->ttl, - pub->period, retransmit); + pub->credential, pub->ttl, pub->period, + pub->cnt, pub->interval); else if (!IS_UNASSIGNED(pub->addr)) set_pub(mod, pub->addr, pub->idx, pub->credential, - pub->ttl, pub->period, retransmit); + pub->ttl, pub->period, pub->cnt, pub->interval); } mod->sub_enabled = db_mod->sub_enabled; diff --git a/mesh/model.h b/mesh/model.h index 147a02279..a1afedd19 100644 --- a/mesh/model.h +++ b/mesh/model.h @@ -40,10 +40,13 @@ struct mesh_model_pub { struct mesh_virtual *virt; uint16_t addr; uint16_t idx; + struct { + uint16_t interval; + uint8_t cnt; + } rtx; uint8_t ttl; uint8_t credential; uint8_t period; - uint8_t retransmit; }; typedef void (*mesh_model_unregister)(void *user_data); @@ -78,8 +81,8 @@ struct mesh_model_pub *mesh_model_pub_get(struct mesh_node *node, uint32_t id, int *status); int mesh_model_pub_set(struct mesh_node *node, uint16_t ele_addr, uint32_t id, const uint8_t *addr, uint16_t idx, bool cred_flag, - uint8_t ttl, uint8_t period, uint8_t retransmit, - bool is_virt, uint16_t *dst); + uint8_t ttl, uint8_t period, uint8_t rtx_cnt, + uint16_t rtx_interval, bool is_virt, uint16_t *dst); int mesh_model_binding_add(struct mesh_node *node, uint16_t ele_addr, uint32_t id, uint16_t idx); diff --git a/mesh/net.c b/mesh/net.c index 26440b02d..93307e70c 100644 --- a/mesh/net.c +++ b/mesh/net.c @@ -212,6 +212,8 @@ struct net_queue_data { struct oneshot_tx { struct mesh_net *net; + uint16_t interval; + uint8_t cnt; uint8_t size; uint8_t packet[30]; }; @@ -1399,7 +1401,8 @@ static void friend_ack_rxed(struct mesh_net *net, uint32_t iv_index, l_queue_foreach(net->friends, enqueue_friend_pkt, &frnd_ack); } -static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t seg); +static bool send_seg(struct mesh_net *net, uint8_t cnt, uint16_t interval, + struct mesh_sar *msg, uint8_t seg); static void send_frnd_ack(struct mesh_net *net, uint16_t src, uint16_t dst, uint32_t hdr, uint32_t flags) @@ -1593,7 +1596,7 @@ static void ack_received(struct mesh_net *net, bool timeout, l_debug("Resend Seg %d net:%p dst:%x app_idx:%3.3x", i, net, outgoing->remote, outgoing->app_idx); - send_seg(net, outgoing, i); + send_seg(net, net->tx_cnt, net->tx_interval, outgoing, i); } l_timeout_remove(outgoing->seg_timeout); @@ -2143,8 +2146,8 @@ static void send_msg_pkt_oneshot(void *user_data) tx->packet[0] = MESH_AD_TYPE_NETWORK; info.type = MESH_IO_TIMING_TYPE_GENERAL; - info.u.gen.interval = net->tx_interval; - info.u.gen.cnt = net->tx_cnt; + info.u.gen.interval = tx->interval; + info.u.gen.cnt = tx->cnt; info.u.gen.min_delay = DEFAULT_MIN_DELAY; /* No extra randomization when sending regular mesh messages */ info.u.gen.max_delay = DEFAULT_MIN_DELAY; @@ -2153,11 +2156,14 @@ static void send_msg_pkt_oneshot(void *user_data) l_free(tx); } -static void send_msg_pkt(struct mesh_net *net, uint8_t *packet, uint8_t size) +static void send_msg_pkt(struct mesh_net *net, uint8_t cnt, uint16_t interval, + uint8_t *packet, uint8_t size) { struct oneshot_tx *tx = l_new(struct oneshot_tx, 1); tx->net = net; + tx->interval = interval; + tx->cnt = cnt; tx->size = size; memcpy(tx->packet, packet, size); @@ -2872,7 +2878,8 @@ bool mesh_net_dst_unreg(struct mesh_net *net, uint16_t dst) return true; } -static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t segO) +static bool send_seg(struct mesh_net *net, uint8_t cnt, uint16_t interval, + struct mesh_sar *msg, uint8_t segO) { struct mesh_subnet *subnet; uint8_t seg_len; @@ -2927,7 +2934,7 @@ static bool send_seg(struct mesh_net *net, struct mesh_sar *msg, uint8_t segO) return false; } - send_msg_pkt(net, packet, packet_len + 1); + send_msg_pkt(net, cnt, interval, packet, packet_len + 1); msg->last_seg = segO; @@ -2967,7 +2974,8 @@ void mesh_net_send_seg(struct mesh_net *net, uint32_t net_key_id, return; } - send_msg_pkt(net, packet, packet_len + 1); + send_msg_pkt(net, net->tx_cnt, net->tx_interval, packet, + packet_len + 1); l_debug("TX: Friend Seg-%d %04x -> %04x : len %u) : TTL %d : SEQ %06x", segO, src, dst, packet_len, ttl, seq); @@ -2977,9 +2985,9 @@ void mesh_net_send_seg(struct mesh_net *net, uint32_t net_key_id, bool mesh_net_app_send(struct mesh_net *net, bool frnd_cred, uint16_t src, uint16_t dst, uint8_t key_aid, uint16_t net_idx, - uint8_t ttl, uint32_t seq, uint32_t iv_index, - bool segmented, bool szmic, - const void *msg, uint16_t msg_len) + uint8_t ttl, uint8_t cnt, uint16_t interval, + uint32_t seq, uint32_t iv_index, bool segmented, + bool szmic, const void *msg, uint16_t msg_len) { struct mesh_sar *payload = NULL; uint8_t seg, seg_max; @@ -3054,11 +3062,12 @@ bool mesh_net_app_send(struct mesh_net *net, bool frnd_cred, uint16_t src, for (i = 0; i < 4; i++) { for (seg = 0; seg <= seg_max && result; seg++) - result = send_seg(net, payload, seg); + result = send_seg(net, cnt, interval, payload, + seg); } } else { for (seg = 0; seg <= seg_max && result; seg++) - result = send_seg(net, payload, seg); + result = send_seg(net, cnt, interval, payload, seg); } /* Reliable: Cache; Unreliable: Flush*/ @@ -3108,7 +3117,7 @@ void mesh_net_ack_send(struct mesh_net *net, uint32_t key_id, uint32_t iv_index, return; } - send_msg_pkt(net, pkt, pkt_len + 1); + send_msg_pkt(net, net->tx_cnt, net->tx_interval, pkt, pkt_len + 1); l_debug("TX: Friend ACK %04x -> %04x : len %u : TTL %d : SEQ %06x", src, dst, pkt_len, ttl, seq); @@ -3182,8 +3191,9 @@ void mesh_net_transport_send(struct mesh_net *net, uint32_t key_id, return; } - if (dst != 0) - send_msg_pkt(net, pkt, pkt_len + 1); + if (!(IS_UNASSIGNED(dst))) + send_msg_pkt(net, net->tx_cnt, net->tx_interval, pkt, + pkt_len + 1); } int mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t idx, diff --git a/mesh/net.h b/mesh/net.h index 91e07ef78..253185e42 100644 --- a/mesh/net.h +++ b/mesh/net.h @@ -300,9 +300,9 @@ void mesh_net_transport_send(struct mesh_net *net, uint32_t key_id, bool mesh_net_app_send(struct mesh_net *net, bool frnd_cred, uint16_t src, uint16_t dst, uint8_t key_id, uint16_t net_idx, - uint8_t ttl, uint32_t seq, uint32_t iv_index, - bool segmented, bool szmic, const void *msg, - uint16_t msg_len); + uint8_t ttl, uint8_t cnt, uint16_t interval, + uint32_t seq, uint32_t iv_index, bool segmented, + bool szmic, const void *msg, uint16_t msg_len); void mesh_net_ack_send(struct mesh_net *net, uint32_t key_id, uint32_t iv_index, uint8_t ttl, uint32_t seq, uint16_t src, uint16_t dst, bool rly,