mesh: Fix and clean up model publication code
authorInga Stotland <inga.stotland@intel.com>
Sun, 30 Jun 2019 06:43:55 +0000 (23:43 -0700)
committerAnupam Roy <anupam.r@samsung.com>
Tue, 17 Dec 2019 15:20:03 +0000 (20:50 +0530)
This adds proper checks for model publication removal:
the publication is not virtual and the publication address is set to zero,
i.e., UNASSIGNED_ADDRESS.
Also removes double memory allocation for model publication and
miscellaneous redundancies.

Change-Id: Ib41b16a583de598c38ffd176bca5812f1bf96375
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
mesh/model.c
mesh/model.h

index 205ba01..7401dce 100644 (file)
@@ -593,7 +593,7 @@ static struct mesh_virtual *add_virtual(const uint8_t *v)
        return virt;
 }
 
-static int set_pub(struct mesh_model *mod, const uint8_t *mod_addr,
+static int set_pub(struct mesh_model *mod, const uint8_t *pub_addr,
                        uint16_t idx, bool cred_flag, uint8_t ttl,
                        uint8_t period, uint8_t retransmit, bool b_virt,
                        uint16_t *dst)
@@ -605,11 +605,11 @@ static int set_pub(struct mesh_model *mod, const uint8_t *mod_addr,
                if (b_virt)
                        *dst = 0;
                else
-                       *dst = l_get_le16(mod_addr);
+                       *dst = l_get_le16(pub_addr);
        }
 
        if (b_virt) {
-               virt = add_virtual(mod_addr);
+               virt = add_virtual(pub_addr);
                if (!virt)
                        return MESH_STATUS_STORAGE_FAIL;
 
@@ -634,28 +634,18 @@ static int set_pub(struct mesh_model *mod, const uint8_t *mod_addr,
                grp = virt->addr;
                mod->pub->addr = virt->id;
        } else {
-               grp = l_get_le16(mod_addr);
+               grp = l_get_le16(pub_addr);
                mod->pub->addr = grp;
        }
 
        if (dst)
                *dst = grp;
 
-       if (IS_UNASSIGNED(grp) && mod->pub) {
-               l_free(mod->pub);
-               mod->pub = NULL;
-               /* Remove publication if Pub Addr is 0x0000 */
-       } else {
-
-               if (!mod->pub)
-                       mod->pub = l_new(struct mesh_model_pub, 1);
-
-               mod->pub->credential = cred_flag;
-               mod->pub->idx = idx;
-               mod->pub->ttl = ttl;
-               mod->pub->period = period;
-               mod->pub->retransmit = retransmit;
-       }
+       mod->pub->credential = cred_flag;
+       mod->pub->idx = idx;
+       mod->pub->ttl = ttl;
+       mod->pub->period = period;
+       mod->pub->retransmit = retransmit;
 
        return MESH_STATUS_SUCCESS;
 }
@@ -985,7 +975,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target,
 }
 
 int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,
-                       const uint8_t *mod_addr, uint16_t idx, bool cred_flag,
+                       const uint8_t *pub_addr, uint16_t idx, bool cred_flag,
                        uint8_t ttl, uint8_t period, uint8_t retransmit,
                        bool b_virt, uint16_t *dst)
 {
@@ -1002,28 +992,28 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,
        if (!appkey_have_key(node_get_net(node), idx))
                return MESH_STATUS_INVALID_APPKEY;
 
-       status = set_pub(mod, mod_addr, idx, cred_flag, ttl, period, retransmit,
-                                                               b_virt, dst);
-
-       if (status != MESH_STATUS_SUCCESS)
-               return status;
-
        /*
         * If the publication address is set to unassigned address value,
         * remove the publication
         */
-       if (IS_UNASSIGNED(*dst))
+       if (!b_virt && IS_UNASSIGNED(l_get_le16(pub_addr))) {
                remove_pub(node, mod);
-
-       /* Internal model, call registered callbacks */
-       if (mod->cbs && mod->cbs->pub) {
-               mod->cbs->pub(mod->pub);
                return MESH_STATUS_SUCCESS;
        }
 
-       /* External model */
-       config_update_model_pub_period(node, mod->ele_idx, id,
+       status = set_pub(mod, pub_addr, idx, cred_flag, ttl, period, retransmit,
+                                                               b_virt, dst);
+
+       if (status != MESH_STATUS_SUCCESS)
+               return status;
+
+       if (!mod->cbs)
+               /* External model */
+               config_update_model_pub_period(node, mod->ele_idx, id,
                                                pub_period_to_ms(period));
+       else
+               /* Internal model, call registered callbacks */
+               mod->cbs->pub(mod->pub);
 
        return MESH_STATUS_SUCCESS;
 }
@@ -1373,6 +1363,7 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
        struct mesh_db_model *db_mod = data;
        struct mesh_model *mod;
        struct mesh_net *net;
+       struct mesh_db_pub *pub = db_mod->pub;
        uint32_t i;
 
        if (db_mod->num_bindings > MAX_BINDINGS) {
@@ -1409,8 +1400,7 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
        }
 
        /* Add publication if present */
-       if (db_mod->pub) {
-               struct mesh_db_pub *pub = db_mod->pub;
+       if (pub && (pub->virt || !(IS_UNASSIGNED(pub->addr)))) {
                uint8_t mod_addr[2];
                uint8_t *pub_addr;
                uint8_t retransmit = (pub->count << 5) +
@@ -1418,7 +1408,7 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
 
                /* Add publication */
                l_put_le16(pub->addr, &mod_addr);
-               pub_addr = pub->virt ? pub->virt_addr : (uint8_t *) &mod_addr;
+               pub_addr = pub->virt ? pub->virt_addr : mod_addr;
 
                if (set_pub(mod, pub_addr, pub->idx, pub->credential, pub->ttl,
                        pub->period, retransmit, pub->virt, NULL) !=
index f0f97ee..a695129 100644 (file)
@@ -95,7 +95,7 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
 struct mesh_model_pub *mesh_model_pub_get(struct mesh_node *node,
                                uint16_t addr, uint32_t mod_id, int *status);
 int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,
-                       const uint8_t *mod_addr, uint16_t idx, bool cred_flag,
+                       const uint8_t *pub_addr, uint16_t idx, bool cred_flag,
                        uint8_t ttl, uint8_t period, uint8_t retransmit,
                        bool b_virt, uint16_t *dst);