mesh: Allow short messages to be segmented
PATCH 1/1 mesh: Allow short messages to be segmented
For add reliability, it is legal to send short messages as "single segment" segmented messages, which require transport layer acknowledgement. This feature is intended for heavy usage in the future so I am adding it now.
Further, to support this functionality, an additional queue has been added to allow multiple SAR messages to the same DST to be queued and sent serially.
--- mesh/cfgmod-server.c | 14 +++---- mesh/model.c | 12 +++--- mesh/model.h | 2 +- mesh/net.c | 88 ++++++++++++++++++++++++++++------------- mesh/net.h | 6 ++- mesh/node.c | 8 ++-- unit/test-mesh-crypto.c | 4 +- 7 files changed, 84 insertions(+), 50 deletions(-)
mesh/cfgmod-server.c +7 -7
@@ -67,7 +67,7 @@ static void send_pub_status(struct mesh_node *node, uint16_t net_idx, }mesh_model_send (node, dst, src,APP_IDX_DEV_LOCAL , net_idx,DEFAULT_TTL , - msg, n); + false, msg, n); } static bool config_pub_get(struct mesh_node *node, uint16_t net_idx,
@@ -211,8 +211,8 @@ static void send_sub_status(struct mesh_node *node, uint16_t net_idx, n +=2 ; } -mesh_model_send (node, dst, src,APP_IDX_DEV_LOCAL , net_idx, -DEFAULT_TTL , msg, n); +mesh_model_send (node, dst, src,APP_IDX_DEV_LOCAL , net_idx,DEFAULT_TTL , + false, msg, n); } static bool config_sub_get(struct mesh_node *node, uint16_t net_idx,
@@ -272,7 +272,7 @@ static bool config_sub_get(struct mesh_node *node, uint16_t net_idx, *msg_status = (uint8_t ) status;mesh_model_send (node, dst, src,APP_IDX_DEV_LOCAL , net_idx,DEFAULT_TTL , - msg, n); + false, msg, n);return true; }
@@ -450,7 +450,7 @@ static void send_model_app_status(struct mesh_node *node, uint16_t net_idx, n +=2 ;mesh_model_send (node, dst, src,APP_IDX_DEV_LOCAL , net_idx,DEFAULT_TTL , - msg, n); + false, msg, n); } static void model_app_list(struct mesh_node *node, uint16_t net_idx,
@@ -505,7 +505,7 @@ static void model_app_list(struct mesh_node *node, uint16_t net_idx,if (result >=0 ) { *status = result;mesh_model_send (node, dst, src,APP_IDX_DEV_LOCAL , net_idx, -DEFAULT_TTL , msg, n); +DEFAULT_TTL , false, msg, n); }l_free (msg);
@@ -1234,7 +1234,7 @@ static bool cfg_srv_pkt(uint16_t src, uint16_t dst, uint16_t app_idx,if (n) {/* print_packet("App Tx", long_msg ? long_msg : msg, n); */ mesh_model_send (node, dst, src, -APP_IDX_DEV_LOCAL , net_idx,DEFAULT_TTL , +APP_IDX_DEV_LOCAL , net_idx,DEFAULT_TTL , false, long_msg ? long_msg : msg, n); }l_free (long_msg);
mesh/model.c +6 -6
@@ -540,7 +540,7 @@ static void cmplt(uint16_t remote, uint8_t status,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, +uint8_t *label,uint8_t ttl,bool segmented,const void *msg,uint16_t msg_len) {uint8_t dev_key[16 ];
@@ -597,8 +597,8 @@ static bool msg_send(struct mesh_node *node, bool credential, uint16_t src,/* print_packet("Encrypted with", key, 16); */ ret =mesh_net_app_send (net, credential, src, dst, key_aid, net_idx, - ttl, seq_num, iv_index, szmic, out, - out_len, cmplt,NULL ); + ttl, seq_num, iv_index, segmented, + szmic, out, out_len, cmplt,NULL ); done:l_free (out);return ret;
@@ -1098,14 +1098,14 @@ int mesh_model_publish(struct mesh_node *node, uint32_t mod_id, result =msg_send (node, mod->pub->credential !=0 , src, mod->pub->addr, mod->pub->idx, net_idx, - label, ttl, msg, msg_len); + label, ttl, false, msg, msg_len);return result ?MESH_ERROR_NONE :MESH_ERROR_FAILED ; }bool mesh_model_send (struct mesh_node *node,uint16_t src,uint16_t dst,uint16_t app_idx,uint16_t net_idx, -uint8_t ttl, +uint8_t ttl,bool segmented,const void *msg,uint16_t msg_len) {/* print_packet("Mod Tx", msg, msg_len); */
@@ -1120,7 +1120,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t dst,return false;return msg_send (node, false, src, dst, app_idx, net_idx, -NULL , ttl, msg, msg_len); +NULL , ttl, segmented, msg, msg_len); } int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,
mesh/model.h +1 -1
@@ -95,7 +95,7 @@ int mesh_model_sub_get(struct mesh_node *node, uint16_t addr, uint32_t id,uint16_t mesh_model_cfg_blk (uint8_t *pkt);bool mesh_model_send (struct mesh_node *node,uint16_t src,uint16_t dst,uint16_t app_idx,uint16_t net_idx, -uint8_t ttl, +uint8_t ttl,bool segmented,const void *msg,uint16_t msg_len);int mesh_model_publish (struct mesh_node *node,uint32_t mod_id,uint16_t src,uint8_t ttl,const void *msg,uint16_t msg_len);
mesh/net.c +60 -28
225 lines not on this page · raw message
mesh/net.h +4 -2
@@ -40,8 +40,9 @@ struct mesh_node;#define MAX_UNSEG_LEN 15/* msg_len == 11 + sizeof(MIC) */ #define MAX_SEG_LEN 12/* UnSeg length - 3 octets overhead */ -#define SEG_MAX (len) (((len) <= MAX_UNSEG_LEN) ? 0 : \ +#define SEG_MAX (seg, len) ((!seg && len <= MAX_UNSEG_LEN) ? 0 : \ (((len) - 1) / MAX_SEG_LEN)) +#define SEG_OFF (seg) ((seg) * MAX_SEG_LEN)#define MAX_SEG_TO_LEN (seg) ((seg) ? SEG_OFF((seg) + 1) : MAX_UNSEG_LEN)
@@ -311,7 +312,8 @@ 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 szmic,const void *msg,uint16_t msg_len, +bool segmented,bool szmic, +const void *msg,uint16_t msg_len,mesh_net_status_func_t status_func,void *user_data); void mesh_net_ack_send(struct mesh_net *net, uint32_t key_id,
mesh/node.c +4 -4
@@ -1830,7 +1830,7 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus,return dbus_error (msg,MESH_ERROR_INVALID_ARGS ,"Invalid key_index" ); -if (!mesh_model_send (node, src, dst, app_idx,0 ,DEFAULT_TTL , +if (!mesh_model_send (node, src, dst, app_idx,0 ,DEFAULT_TTL , false, data, len))return dbus_error (msg,MESH_ERROR_FAILED ,NULL );
@@ -1879,7 +1879,7 @@ static struct l_dbus_message *dev_key_send_call(struct l_dbus *dbus, app_idx = remote ?APP_IDX_DEV_REMOTE :APP_IDX_DEV_LOCAL ;if (!mesh_model_send (node, src, dst, app_idx, net_idx,DEFAULT_TTL , - data, len)) + true, data, len))return dbus_error (msg,MESH_ERROR_NOT_FOUND ,NULL );return l_dbus_message_new_method_return (msg);
@@ -1937,7 +1937,7 @@ static struct l_dbus_message *add_netkey_call(struct l_dbus *dbus,l_put_le16 (sub_idx, &data[2 ]);if (!mesh_model_send (node, src, dst,APP_IDX_DEV_REMOTE , net_idx, -DEFAULT_TTL , data,20 )) +DEFAULT_TTL , false, data,20 ))return dbus_error (msg,MESH_ERROR_NOT_FOUND ,NULL );return l_dbus_message_new_method_return (msg);
@@ -2003,7 +2003,7 @@ static struct l_dbus_message *add_appkey_call(struct l_dbus *dbus, data[3 ] = app_idx >>4 ;if (!mesh_model_send (node, src, dst,APP_IDX_DEV_REMOTE , net_idx, -DEFAULT_TTL , data,20 )) +DEFAULT_TTL , false, data,20 ))return dbus_error (msg,MESH_ERROR_NOT_FOUND ,NULL );return l_dbus_message_new_method_return (msg);
unit/test-mesh-crypto.c +2 -2
@@ -1017,7 +1017,7 @@ static void check_encrypt(const struct mesh_crypto_test *keys) app_msg =l_util_from_hexstring (keys->app_msg, &app_msg_len);if (keys->szmic) { - seg_max =SEG_MAX (app_msg_len +8 ); + seg_max =SEG_MAX (keys->segmented, app_msg_len +8 ); enc_msg =l_malloc (app_msg_len +8 ); mesh_crypto_application_encrypt(key_aid, keys->app_seq, keys->net_src, keys->net_dst,
@@ -1028,7 +1028,7 @@ static void check_encrypt(const struct mesh_crypto_test *keys) enc_msg, &app_mic64, sizeof(app_mic64));l_put_be64 (app_mic64, enc_msg + app_msg_len); }else { - seg_max =SEG_MAX (app_msg_len +4 ); + seg_max =SEG_MAX (keys->segmented, app_msg_len +4 ); enc_msg =l_malloc (app_msg_len +4 ); mesh_crypto_application_encrypt(key_aid, keys->app_seq, keys->net_src, keys->net_dst,
Signature · 1 line
2.21.1