summaryrefslogtreecommitdiff
path: root/mesh/cfgmod-server.c
diff options
context:
space:
mode:
authorInga Stotland <inga.stotland@intel.com>2020-08-06 18:38:28 -0700
committerBrian Gix <brian.gix@intel.com>2020-08-10 14:47:09 -0700
commit14572fe1c508a94da43ed7ab76bd4a754f817c9f (patch)
tree94fe585760fcf709d05298e0ed43e0f7ee996bce /mesh/cfgmod-server.c
parent72f85660fb8b6d74f3d56045601c00751e50af35 (diff)
downloadbluez-14572fe1c508a94da43ed7ab76bd4a754f817c9f.tar.gz
mesh: Clean up handling of config publication messages
This modification allows using a single point for sending out the composed status messages by the Config Server. Also, return Feature Not Supported errror code when credential flag is set, but the node does not support LPN feature
Diffstat (limited to 'mesh/cfgmod-server.c')
-rw-r--r--mesh/cfgmod-server.c99
1 files changed, 41 insertions, 58 deletions
diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 82938dc83..6ed5800c0 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -32,6 +32,8 @@
#include "mesh/mesh-config.h"
#include "mesh/cfgmod.h"
+#define CREDFLAG_MASK 0x1000
+
#define CFG_GET_ID(vendor, pkt) ((vendor) ? \
(SET_ID(l_get_le16((pkt)), l_get_le16((pkt) + 2))) : \
(SET_ID(SIG_VENDOR, l_get_le16(pkt))))
@@ -44,11 +46,9 @@ static const uint8_t supported_pages[] = {
static uint8_t msg[MAX_MSG_LEN];
-static void send_pub_status(struct mesh_node *node, uint16_t net_idx,
- uint16_t src, uint16_t dst,
- 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)
+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)
{
size_t n;
@@ -72,46 +72,36 @@ static void send_pub_status(struct mesh_node *node, uint16_t net_idx,
n += 4;
}
- mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, net_idx, DEFAULT_TTL,
- false, msg, n);
+ return n;
}
-static void config_pub_get(struct mesh_node *node, uint16_t net_idx,
- uint16_t src, uint16_t dst,
- const uint8_t *pkt, uint16_t size)
+static uint16_t config_pub_get(struct mesh_node *node, const uint8_t *pkt,
+ bool vendor)
{
uint32_t id;
uint16_t ele_addr;
struct mesh_model_pub *pub;
int status;
- if (size == 4) {
- id = SET_ID(SIG_VENDOR, l_get_le16(pkt + 2));
- } else if (size == 6) {
- id = SET_ID(l_get_le16(pkt + 2), l_get_le16(pkt + 4));
- } else
- return;
-
ele_addr = l_get_le16(pkt);
+ id = CFG_GET_ID(vendor, pkt + 2);
+
pub = mesh_model_pub_get(node, ele_addr, id, &status);
if (pub && status == MESH_STATUS_SUCCESS)
- send_pub_status(node, net_idx, src, dst, status, ele_addr,
- id, pub->addr, pub->idx, pub->credential,
- pub->ttl, pub->period, pub->retransmit);
+ return set_pub_status(status, ele_addr, id, pub->addr, pub->idx,
+ pub->credential, pub->ttl, pub->period,
+ pub->retransmit);
else
- send_pub_status(node, net_idx, src, dst, status, ele_addr,
- id, 0, 0, 0, 0, 0, 0);
+ return set_pub_status(status, ele_addr, id, 0, 0, 0, 0, 0, 0);
}
-static void config_pub_set(struct mesh_node *node, uint16_t net_idx,
- uint16_t src, uint16_t dst,
- const uint8_t *pkt, bool virt, bool vendor)
+static uint16_t config_pub_set(struct mesh_node *node, const uint8_t *pkt,
+ bool virt, bool vendor)
{
uint32_t id;
- uint16_t ele_addr, idx, ota = UNASSIGNED_ADDRESS;
+ uint16_t ele_addr, idx, pub_dst;
const uint8_t *pub_addr;
- uint16_t test_addr;
uint8_t ttl, period, retransmit;
int status;
bool cred_flag;
@@ -119,42 +109,35 @@ static void config_pub_set(struct mesh_node *node, uint16_t net_idx,
ele_addr = l_get_le16(pkt);
pub_addr = pkt + 2;
- pkt += (virt ? 14 : 0);
+ pub_dst = l_get_le16(pub_addr);
- idx = l_get_le16(pkt + 4);
- ttl = pkt[6];
- period = pkt[7];
- retransmit = pkt[8];
- id = l_get_le16(pkt + 9);
+ if (!virt && IS_VIRTUAL(pub_dst))
+ return 0;
- if (!vendor)
- id = SET_ID(SIG_VENDOR, id);
- else
- id = SET_ID(id, l_get_le16(pkt + 11));
+ pkt += (virt ? 14 : 0);
- /* Don't accept virtual seeming addresses */
- test_addr = l_get_le16(pub_addr);
- if (!virt && IS_VIRTUAL(test_addr))
- return;
+ idx = l_get_le16(pkt + 4);
+ if (idx > CREDFLAG_MASK)
+ return 0;
cred_flag = !!(CREDFLAG_MASK & idx);
idx &= APP_IDX_MASK;
+ ttl = pkt[6];
+ period = pkt[7];
+ retransmit = pkt[8];
+ id = CFG_GET_ID(vendor, pkt + 9);
status = mesh_model_pub_set(node, ele_addr, id, pub_addr, idx,
cred_flag, ttl, period, retransmit,
- virt, &ota);
-
- l_debug("pub_set: status %d, ea %4.4x, ota: %4.4x, mod: %x, idx: %3.3x",
- status, ele_addr, ota, id, idx);
+ virt, &pub_dst);
- if (status != MESH_STATUS_SUCCESS) {
- send_pub_status(node, net_idx, src, dst, status, ele_addr,
- id, 0, 0, 0, 0, 0, 0);
+ l_debug("pub_set: status %d, ea %4.4x, ota: %4.4x, id: %x, idx: %3.3x",
+ status, ele_addr, pub_dst, id, idx);
- return;
- }
+ if (status != MESH_STATUS_SUCCESS)
+ return set_pub_status(status, ele_addr, id, 0, 0, 0, 0, 0, 0);
- if (IS_UNASSIGNED(test_addr) && !virt) {
+ if (IS_UNASSIGNED(pub_dst) && !virt) {
ttl = period = idx = 0;
/* Remove model publication from config file */
@@ -165,7 +148,7 @@ static void config_pub_set(struct mesh_node *node, uint16_t net_idx,
} else {
struct mesh_config_pub db_pub = {
.virt = virt,
- .addr = ota,
+ .addr = pub_dst,
.idx = idx,
.ttl = ttl,
.credential = cred_flag,
@@ -180,12 +163,12 @@ static void config_pub_set(struct mesh_node *node, uint16_t net_idx,
/* Save model publication to config file */
if (!mesh_config_model_pub_add(node_config_get(node), ele_addr,
vendor ? id : MODEL_ID(id),
- vendor, &db_pub))
+ vendor, &db_pub))
status = MESH_STATUS_STORAGE_FAIL;
}
- send_pub_status(node, net_idx, src, dst, status, ele_addr, id, ota,
- idx, cred_flag, ttl, period, retransmit);
+ return set_pub_status(status, ele_addr, id, pub_dst, idx, cred_flag,
+ ttl, period, retransmit);
}
static uint16_t cfg_sub_get_msg(struct mesh_node *node, const uint8_t *pkt,
@@ -667,14 +650,14 @@ static bool cfg_srv_pkt(uint16_t src, uint16_t dst, uint16_t app_idx,
if (!virt && (size != 11 && size != 13))
return true;
- config_pub_set(node, net_idx, src, dst, pkt, virt,
- size == 13 || size == 27);
+ n = config_pub_set(node, pkt, virt, size == 13 || size == 27);
break;
case OP_CONFIG_MODEL_PUB_GET:
if (size != 4 && size != 6)
return true;
- config_pub_get(node, net_idx, src, dst, pkt, size);
+
+ n = config_pub_get(node, pkt, size == 6);
break;
case OP_CONFIG_VEND_MODEL_SUB_GET: