mesh: Use correct retransmit parameters for publications
authorInga Stotland <inga.stotland@intel.com>
Thu, 20 Aug 2020 05:41:32 +0000 (22:41 -0700)
committerAbhay Agarwal <ay.agarwal@samsung.com>
Mon, 28 Dec 2020 06:20:04 +0000 (11:50 +0530)
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.

Change-Id: I5ee9af88e7ed11f4fc43a18bcf78d97ba7992f39
Signed-off-by: anuj.bhumiya <anuj.bhumiya@samsung.com>
mesh/cfgmod-server.c
mesh/mesh-config-json.c
mesh/mesh-config.h
mesh/model.c
mesh/model.h
mesh/net.c
mesh/net.h

index 8fca756..866d847 100644 (file)
@@ -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,
index 0882a91..374f217 100644 (file)
@@ -1022,7 +1022,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;
@@ -1340,20 +1340,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);
@@ -1567,30 +1567,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;
 
 }
@@ -1842,7 +1842,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;
 
@@ -1886,17 +1886,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);
index 50a55d5..738cff9 100644 (file)
@@ -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];
 };
 
index 9529dfb..c1497de 100644 (file)
@@ -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,
@@ -1038,9 +1040,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;
 }
@@ -1050,6 +1053,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);
@@ -1059,14 +1066,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);
@@ -1104,10 +1113,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;
 
@@ -1683,15 +1692,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;
index 147a022..a1afedd 100644 (file)
@@ -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);
index ab2c2cd..cecf0c8 100644 (file)
@@ -210,6 +210,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];
 };
@@ -1397,7 +1399,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)
@@ -1591,7 +1594,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);
@@ -2150,8 +2153,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;
@@ -2160,11 +2163,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);
 
@@ -2879,7 +2885,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;
@@ -2934,7 +2941,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;
 
@@ -2974,7 +2981,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);
@@ -2984,9 +2992,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;
@@ -3061,11 +3069,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*/
@@ -3115,7 +3124,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);
@@ -3189,8 +3198,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,
index 91e07ef..253185e 100644 (file)
@@ -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,