mesh: Add internal Mesh Private Beacon model
authorBrian Gix <brian.gix@intel.com>
Thu, 8 Oct 2020 18:05:47 +0000 (11:05 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 5 Jan 2024 10:11:34 +0000 (15:41 +0530)
Adds recgnition that the Mesh Private Beacon model is internal
and foundational, without bindings.

mesh/model.c
mesh/net-keys.c
mesh/net-keys.h
mesh/node.c
mesh/node.h
mesh/prvbeac-server.c

index e2babea..4ccafa1 100644 (file)
@@ -26,6 +26,7 @@
 #include "mesh/cfgmod.h"
 #include "mesh/prov.h"
 #include "mesh/remprv.h"
+#include "mesh/prv-beacon.h"
 #include "mesh/error.h"
 #include "mesh/dbus.h"
 #include "mesh/util.h"
@@ -81,6 +82,9 @@ static bool is_internal(uint32_t id)
        if (id == REM_PROV_SRV_MODEL || id == REM_PROV_CLI_MODEL)
                return true;
 
+       if (id == PRV_BEACON_SRV_MODEL || id == PRV_BEACON_CLI_MODEL)
+               return true;
+
        return false;
 }
 
@@ -647,6 +651,9 @@ static int update_binding(struct mesh_node *node, uint16_t addr, uint32_t id,
        if (id == CONFIG_SRV_MODEL || id == CONFIG_CLI_MODEL)
                return MESH_STATUS_INVALID_MODEL;
 
+       if (id == PRV_BEACON_SRV_MODEL || id == PRV_BEACON_CLI_MODEL)
+               return MESH_STATUS_INVALID_MODEL;
+
        if (!appkey_have_key(node_get_net(node), app_idx))
                return MESH_STATUS_INVALID_APPKEY;
 
@@ -1655,7 +1662,8 @@ static struct mesh_model *model_setup(struct mesh_net *net, uint8_t ele_idx,
                                                SET_ID(SIG_VENDOR, db_mod->id));
 
        /* Implicitly bind config server model to device key */
-       if (db_mod->id == CONFIG_SRV_MODEL) {
+       if (db_mod->id == CONFIG_SRV_MODEL ||
+                                       db_mod->id == PRV_BEACON_SRV_MODEL) {
 
                if (ele_idx != PRIMARY_ELE_IDX) {
                        l_free(mod);
index 0ba051d..57a9df0 100644 (file)
@@ -123,6 +123,7 @@ uint32_t net_key_add(const uint8_t flooding[16])
        key = l_new(struct net_key, 1);
        memcpy(key->flooding, flooding, 16);
        key->ref_cnt++;
+       key->mpb_refresh = NET_MPB_REFRESH_DEFAULT;
        result = mesh_crypto_k2(flooding, p, sizeof(p), &key->nid, key->enc_key,
                                                                key->prv_key);
        if (!result)
@@ -664,6 +665,10 @@ bool net_key_beacon_refresh(uint32_t id, uint32_t ivi, bool kr, bool ivu,
 
        l_debug("Set Beacon: IVI: %8.8x, IVU: %d, KR: %d", ivi, ivu, kr);
 
+       key->ivi = ivi;
+       key->ivu = ivu;
+       key->kr = kr;
+
        /* Propagate changes to all local nodes */
        net_local_beacon(id, ivi, ivu, kr);
 
index a390944..e738124 100644 (file)
@@ -12,6 +12,7 @@
 #define BEACON_TYPE_MPB                0x02
 #define KEY_REFRESH            0x01
 #define IV_INDEX_UPDATE                0x02
+#define NET_MPB_REFRESH_DEFAULT        60
 
 void net_key_cleanup(void);
 bool net_key_confirm(uint32_t id, const uint8_t flooding[16]);
index 7b042f5..a7a8206 100644 (file)
@@ -33,6 +33,7 @@
 #include "mesh/model.h"
 #include "mesh/cfgmod.h"
 #include "mesh/remprv.h"
+#include "mesh/prv-beacon.h"
 #include "mesh/util.h"
 #include "mesh/error.h"
 #include "mesh/dbus.h"
@@ -101,6 +102,8 @@ struct mesh_node {
        uint8_t proxy;
        uint8_t friend;
        uint8_t beacon;
+       uint8_t mpb;
+       uint8_t mpb_period;
 };
 
 struct node_import {
@@ -207,6 +210,8 @@ static void set_defaults(struct mesh_node *node)
 {
        node->lpn = MESH_MODE_UNSUPPORTED;
        node->proxy = MESH_MODE_UNSUPPORTED;
+       node->mpb = MESH_MODE_DISABLED;
+       node->mpb_period = NET_MPB_REFRESH_DEFAULT;
        node->friend = (mesh_friendship_supported()) ? MESH_MODE_DISABLED :
                                                        MESH_MODE_UNSUPPORTED;
        node->beacon = (mesh_beacon_enabled()) ? MESH_MODE_ENABLED :
@@ -420,7 +425,7 @@ static bool init_storage_dir(struct mesh_node *node)
        return rpl_init(node->storage_dir);
 }
 
-static void update_net_settings(struct mesh_node *node)
+static void init_net_settings(struct mesh_node *node)
 {
        struct mesh_net *net = node->net;
 
@@ -432,6 +437,8 @@ static void update_net_settings(struct mesh_node *node)
                                        node->relay.cnt, node->relay.interval);
 
        mesh_net_set_snb_mode(net, node->beacon == MESH_MODE_ENABLED);
+       mesh_net_set_mpb_mode(net, node->mpb == MESH_MODE_ENABLED,
+                                                       node->mpb_period, true);
 }
 
 static bool init_from_storage(struct mesh_config_node *db_node,
@@ -459,6 +466,8 @@ static bool init_from_storage(struct mesh_config_node *db_node,
        node->relay.cnt = db_node->modes.relay.cnt;
        node->relay.interval = db_node->modes.relay.interval;
        node->beacon = db_node->modes.beacon;
+       node->mpb = db_node->modes.mpb;
+       node->mpb_period = db_node->modes.mpb_period;
 
        l_debug("relay %2.2x, proxy %2.2x, lpn %2.2x, friend %2.2x",
                        node->relay.mode, node->proxy, node->lpn, node->friend);
@@ -512,7 +521,7 @@ static bool init_from_storage(struct mesh_config_node *db_node,
        mesh_net_set_seq_num(node->net, node->seq_number);
        mesh_net_set_default_ttl(node->net, node->ttl);
 
-       update_net_settings(node);
+       init_net_settings(node);
 
        /* Initialize configuration server model */
        cfgmod_server_init(node, PRIMARY_ELE_IDX);
@@ -521,6 +530,9 @@ static bool init_from_storage(struct mesh_config_node *db_node,
        remote_prov_server_init(node, PRIMARY_ELE_IDX);
        remote_prov_client_init(node, PRIMARY_ELE_IDX);
 
+       /* Initialize Private Beacon server model */
+       prv_beacon_server_init(node, PRIMARY_ELE_IDX);
+
        node->cfg = cfg;
 
        return true;
@@ -856,6 +868,36 @@ uint8_t node_beacon_mode_get(struct mesh_node *node)
        return node->beacon;
 }
 
+bool node_mpb_mode_set(struct mesh_node *node, bool enable, uint8_t period)
+{
+       bool res;
+       uint8_t beacon;
+
+       if (!node)
+               return false;
+
+       beacon = enable ? MESH_MODE_ENABLED : MESH_MODE_DISABLED;
+       res = mesh_config_write_mpb(node->cfg, beacon, period);
+
+       if (res) {
+               node->mpb = beacon;
+               node->mpb_period = period;
+               mesh_net_set_mpb_mode(node->net, enable, period, false);
+       }
+
+       return res;
+}
+
+uint8_t node_mpb_mode_get(struct mesh_node *node, uint8_t *period)
+{
+       if (!node)
+               return MESH_MODE_DISABLED;
+
+       *period = node->mpb_period;
+
+       return node->mpb;
+}
+
 bool node_friend_mode_set(struct mesh_node *node, bool enable)
 {
        bool res;
@@ -968,6 +1010,8 @@ static void convert_node_to_storage(struct mesh_node *node,
        db_node->modes.relay.cnt = node->relay.cnt;
        db_node->modes.relay.interval = node->relay.interval;
        db_node->modes.beacon = node->beacon;
+       db_node->modes.mpb = node->mpb;
+       db_node->modes.mpb_period = node->mpb_period;
 
        db_node->ttl = node->ttl;
        db_node->seq_number = node->seq_number;
@@ -1190,9 +1234,16 @@ static bool get_sig_models_from_properties(struct mesh_node *node,
        while (l_dbus_message_iter_next_entry(&mods, &m_id, &var)) {
                uint32_t id = SET_ID(SIG_VENDOR, m_id);
 
-               /* Allow Config Server Model only on the primary element */
-               if (ele->idx != PRIMARY_ELE_IDX && id == CONFIG_SRV_MODEL)
-                       return false;
+               /*
+                * Allow Config Server & Private Beacon Models only on
+                * the primary element
+                */
+               if (ele->idx != PRIMARY_ELE_IDX) {
+                       if (id == CONFIG_SRV_MODEL)
+                               return false;
+                       if (id == PRV_BEACON_SRV_MODEL)
+                               return false;
+               }
 
                if (!mesh_model_add(node, ele->models, id, &var))
                        return false;
@@ -1295,6 +1346,7 @@ static bool get_element_properties(struct mesh_node *node, const char *path,
         */
        if (ele->idx == PRIMARY_ELE_IDX) {
                mesh_model_add(node, ele->models, CONFIG_SRV_MODEL, NULL);
+               mesh_model_add(node, ele->models, PRV_BEACON_SRV_MODEL, NULL);
                mesh_model_add(node, ele->models, REM_PROV_SRV_MODEL, NULL);
                if (node->provisioner)
                        mesh_model_add(node, ele->models, REM_PROV_CLI_MODEL,
@@ -1414,13 +1466,16 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 
        l_queue_foreach(node->pages, save_pages, node);
 
-       update_net_settings(node);
+       init_net_settings(node);
 
        /* Initialize internal server models */
        cfgmod_server_init(node, PRIMARY_ELE_IDX);
        remote_prov_server_init(node, PRIMARY_ELE_IDX);
        remote_prov_client_init(node, PRIMARY_ELE_IDX);
 
+       /* Initialize Private Beacon server model */
+       prv_beacon_server_init(node, PRIMARY_ELE_IDX);
+
        node->busy = true;
 
        return true;
index b4a44ee..14f96d7 100644 (file)
@@ -66,6 +66,8 @@ uint8_t node_relay_mode_get(struct mesh_node *node, uint8_t *cnt,
 bool node_proxy_mode_set(struct mesh_node *node, bool enable);
 uint8_t node_proxy_mode_get(struct mesh_node *node);
 bool node_beacon_mode_set(struct mesh_node *node, bool enable);
+bool node_mpb_mode_set(struct mesh_node *node, bool enable, uint8_t period);
+uint8_t node_mpb_mode_get(struct mesh_node *node, uint8_t *period);
 uint8_t node_beacon_mode_get(struct mesh_node *node);
 bool node_friend_mode_set(struct mesh_node *node, bool enable);
 uint8_t node_friend_mode_get(struct mesh_node *node);
index e712778..dd0e4cb 100644 (file)
@@ -43,7 +43,7 @@ static bool prvbec_srv_pkt(uint16_t src, uint16_t dst, uint16_t app_idx,
        uint32_t opcode;
        uint8_t msg[5];
        uint16_t n;
-       uint8_t period = 0;
+       uint8_t period;
 
        if (app_idx != APP_IDX_DEV_LOCAL)
                return false;
@@ -65,18 +65,23 @@ static bool prvbec_srv_pkt(uint16_t src, uint16_t dst, uint16_t app_idx,
 
        case OP_PRIVATE_BEACON_SET:
                if (size == 1)
-                       period = 0xff;
+                       node_mpb_mode_get(node, &period);
                else if (size == 2)
                        period = pkt[1];
                else
                        return true;
 
+               if (pkt[0] > 1)
+                       return true;
+
+               node_mpb_mode_set(node, !!pkt[0], period);
+
                /* fall through */
 
        case OP_PRIVATE_BEACON_GET:
                n = mesh_model_opcode_set(OP_PRIVATE_BEACON_STATUS, msg);
 
-               msg[n++] = NOT_SUPPORTED;
+               msg[n++] = node_mpb_mode_get(node, &period);
                msg[n++] = period;
 
                l_debug("Get/Set Private Beacon (%d)", msg[n-2]);