From 00322a24b4f5bf0dff768db965200295f52e32d7 Mon Sep 17 00:00:00 2001 From: Maxim Menshikov <maxim.menshikov@iopsys.eu> Date: Fri, 23 Feb 2024 14:55:04 +0000 Subject: [PATCH] Introduce and use new fragmentation scheme selection API --- src/cmdu.h | 5 +++++ src/cmdufrag.c | 16 +++++++++++----- src/cmdufrag.h | 2 +- src/config.c | 7 ++++--- src/i1905.c | 26 ++++++++++++++++++++++---- src/i1905.h | 1 + src/i1905_ubus.c | 27 ++++++++++++++++++--------- 7 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/cmdu.h b/src/cmdu.h index 29efefdc..b266b031 100644 --- a/src/cmdu.h +++ b/src/cmdu.h @@ -54,6 +54,11 @@ struct cmdu_frag { struct list_head list; }; +enum cmdu_frag_scheme { + CMDU_FRAG_SCHEME_BOUNDARY_TLV, + CMDU_FRAG_SCHEME_BOUNDARY_OCTET, +}; + /** * @struct cmdu_buff * @brief Control structure for a CMDU buffer diff --git a/src/cmdufrag.c b/src/cmdufrag.c index c1ea20bf..ecffdfe5 100644 --- a/src/cmdufrag.c +++ b/src/cmdufrag.c @@ -54,8 +54,7 @@ static struct cmdu_buff *alloc_cmdu(size_t size) return cmdu; } -#ifndef IEEE1905_CMDU_FRAGMENT_TLV_BOUNDARY -struct cmdu_buff *cmdu_fragment(uint8_t *data, int datalen) +struct cmdu_buff *cmdu_fragment_octet(uint8_t *data, int datalen) { struct cmdu_buff *cmdu = NULL; struct cmdu_frag *frag = NULL; @@ -97,8 +96,7 @@ out_free: return NULL; } -#else -struct cmdu_buff *cmdu_fragment(uint8_t *data, int datalen) +struct cmdu_buff *cmdu_fragment_tlv(uint8_t *data, int datalen) { struct cmdu_frag *nextfrag = NULL; size_t rem = FRAG_DATA_SIZE_TLV; @@ -225,7 +223,15 @@ out_free: cmdu_free(cmdu); return NULL; } -#endif /* IEEE1905_CMDU_FRAGMENT_TLV_BOUNDARY */ + +struct cmdu_buff *cmdu_fragment(uint8_t *data, int datalen, int scheme) +{ + if (scheme == CMDU_FRAG_SCHEME_BOUNDARY_TLV) { + return cmdu_fragment_tlv(data, datalen); + } + + return cmdu_fragment_octet(data, datalen); +} static int getcurrtime(struct timeval *out) { diff --git a/src/cmdufrag.h b/src/cmdufrag.h index 2458eb9e..02552ade 100644 --- a/src/cmdufrag.h +++ b/src/cmdufrag.h @@ -27,7 +27,7 @@ #define FRAG_DATA_SIZE (FRAG_DATA_SIZE_TLV - TLV_HLEN) -struct cmdu_buff *cmdu_fragment(uint8_t *data, int datalen); +struct cmdu_buff *cmdu_fragment(uint8_t *data, int datalen, int scheme); struct cmdu_buff *cmdu_defrag(void *rxfq, struct cmdu_buff *lastfrag); diff --git a/src/config.c b/src/config.c index 899a24b5..a63ea4e5 100644 --- a/src/config.c +++ b/src/config.c @@ -31,7 +31,7 @@ #include "util.h" #include "config.h" #include "i1905_wsc.h" - +#include "cmdu.h" static void uci_add_option(struct uci_context *ctx, struct uci_package *p, struct uci_section *s, const char *option, @@ -447,7 +447,8 @@ static int i1905_config_get_base(struct i1905_config *cfg, struct uci_section *s const char *val = tb[I1905_FRAGMENT_SCHEME]->v.string; int frag_scheme = atoi(val); - if (frag_scheme == 0 || frag_scheme == 1) + if (frag_scheme == CMDU_FRAG_SCHEME_BOUNDARY_TLV || + frag_scheme == CMDU_FRAG_SCHEME_BOUNDARY_OCTET) cfg->frag_scheme = frag_scheme; } @@ -1010,7 +1011,7 @@ int i1905_dump_config(struct i1905_config *cfg) } } fprintf(stderr, " CMDU fragmentation scheme : %s boundary\n", - cfg->frag_scheme == 0 ? "TLV" : "Octet"); + cfg->frag_scheme == CMDU_FRAG_SCHEME_BOUNDARY_TLV ? "TLV" : "Octet"); fprintf(stderr, "---\n"); return 0; diff --git a/src/i1905.c b/src/i1905.c index 4623b6e7..ec33d98b 100644 --- a/src/i1905.c +++ b/src/i1905.c @@ -521,14 +521,31 @@ struct i1905_interface *i1905_ifname_to_interface(struct i1905_private *priv, return NULL; } +int i1905_get_fragment_scheme(struct i1905_private *priv, uint8_t *dst) +{ + struct i1905_selfdevice *self = &priv->dm.self; + + if (hwaddr_equal(dst, self->aladdr)) { + return self->frag_scheme; + } else { + struct i1905_device *rdev = NULL; + + list_for_each_entry(rdev, &self->topology.devlist, list) { + if (hwaddr_equal(rdev->aladdr, dst)) { + return rdev->frag_scheme; + } + } + } + + return -1; +} int i1905_set_fragment_scheme(struct i1905_private *priv, uint8_t *dst, - uint8_t scheme) + uint8_t scheme) { struct i1905_selfdevice *self = &priv->dm.self; struct i1905_config *cfg = &priv->cfg; - if (hwaddr_equal(dst, self->aladdr)) { self->frag_scheme = scheme; cfg->frag_scheme = scheme; @@ -738,7 +755,7 @@ int i1905_cmdu_fragment_and_tx(struct i1905_interface_private *ifpriv, uint16_t uint16_t resp_type; int ret = 0; int i = 0; - + int scheme; priv = (struct i1905_private *)ifpriv->i1905private; iface = i1905_interface_priv(ifpriv); @@ -770,7 +787,8 @@ int i1905_cmdu_fragment_and_tx(struct i1905_interface_private *ifpriv, uint16_t } #endif - frm = cmdu_fragment(data, datalen); + scheme = i1905_get_fragment_scheme(priv, dst); + frm = cmdu_fragment(data, datalen, scheme); if (!frm) { err("%s: -ENOMEM\n", __func__); return -1; diff --git a/src/i1905.h b/src/i1905.h index 3736199f..76646fe3 100644 --- a/src/i1905.h +++ b/src/i1905.h @@ -143,6 +143,7 @@ int i1905_rebind_interface(struct i1905_private *priv, struct i1905_interface *i void i1905_print_interfaces(struct i1905_private *priv); +int i1905_get_fragment_scheme(struct i1905_private *priv, uint8_t *dst); int i1905_set_fragment_scheme(struct i1905_private *priv, uint8_t *dst, uint8_t scheme); diff --git a/src/i1905_ubus.c b/src/i1905_ubus.c index 82980380..d781ccd1 100644 --- a/src/i1905_ubus.c +++ b/src/i1905_ubus.c @@ -828,15 +828,13 @@ int i1905_ubus_cmdu_fragment_scheme(struct ubus_context *ctx, struct blob_attr *msg) { struct i1905_private *p = container_of(obj, struct i1905_private, obj); - struct i1905_selfdevice *self = &p->dm.self; struct blob_attr *tb[NUM_CMDU_FRAG_POLICY]; - struct i1905_config *cfg = &p->cfg; + struct blob_buf bb; char dst_macstr[18] = {0}; uint8_t dst[6] = {0}; - uint8_t scheme = 0; + uint8_t scheme; int ret; - blobmsg_parse(cmdu_frag_policy, NUM_CMDU_FRAG_POLICY, tb, blob_data(msg), blob_len(msg)); @@ -855,13 +853,24 @@ int i1905_ubus_cmdu_fragment_scheme(struct ubus_context *ctx, return -EINVAL; } - if (tb[CMDU_FRAG_SCHEME]) + if (tb[CMDU_FRAG_SCHEME]) { scheme = (uint8_t)blobmsg_get_u32(tb[CMDU_FRAG_SCHEME]); - + } else { +#if (EASYMESH_VERSION >= 3) + scheme = CMDU_FRAG_SCHEME_BOUNDARY_OCTET; +#else + scheme = CMDU_FRAG_SCHEME_BOUNDARY_TLV; +#endif + } ret = i1905_set_fragment_scheme(p, dst, scheme); -done: + + memset(&bb, 0, sizeof(bb)); /* reply with status */ - blobmsg_add_string(bb, "status", ret == 0 ? "ok" : "fail"); + blob_buf_init(&bb, 0); + blobmsg_add_string(&bb, "status", ret == 0 ? "ok" : "fail"); + + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); return ret; } @@ -1000,7 +1009,7 @@ int i1905_publish_object(struct i1905_private *p, const char *objname) struct ubus_object_type *obj_type; struct ubus_method *obj_methods; int ret; - struct ubus_method m[17] = { + struct ubus_method m[18] = { UBUS_METHOD_NOARG("id", i1905_ubus_aladdr), UBUS_METHOD_NOARG("start", i1905_ubus_start), UBUS_METHOD_NOARG("stop", i1905_ubus_stop), -- GitLab