diff mbox series

[BlueZ] mesh: Use correct retransmit parameters for publications

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

Commit Message

Stotland, Inga Aug. 20, 2020, 5:41 a.m. UTC
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(-)

Comments

Brian Gix Aug. 22, 2020, 2:21 p.m. UTC | #1
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 mbox series

Patch

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,