@@ -36,8 +36,8 @@
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, uint16_t pub_addr,
- uint32_t mod_id, uint16_t idx, bool cred_flag,
+ uint8_t status, uint16_t ele_addr, uint32_t mod_id,
+ uint16_t pub_addr, uint16_t idx, bool cred_flag,
uint8_t ttl, uint8_t period, uint8_t retransmit)
{
uint8_t msg[16];
@@ -56,7 +56,7 @@ static void send_pub_status(struct mesh_node *node, uint16_t net_idx,
msg[n++] = period;
msg[n++] = retransmit;
- if (mod_id < 0x10000 || mod_id > VENDOR_ID_MASK) {
+ if (mod_id >= VENDOR_ID_MASK) {
l_put_le16(mod_id, msg + n);
n += 2;
} else {
@@ -76,8 +76,7 @@ static bool config_pub_get(struct mesh_node *node, uint16_t net_idx,
{
uint32_t mod_id;
uint16_t ele_addr;
- int ele_idx;
- struct mesh_model_pub *pub = NULL;
+ struct mesh_model_pub *pub;
int status;
if (size == 4) {
@@ -90,27 +89,22 @@ static bool config_pub_get(struct mesh_node *node, uint16_t net_idx,
return false;
ele_addr = l_get_le16(pkt);
- ele_idx = node_get_element_idx(node, ele_addr);
-
- if (ele_idx >= 0)
- pub = mesh_model_pub_get(node, ele_addr, mod_id, &status);
- else
- status = MESH_STATUS_INVALID_ADDRESS;
+ pub = mesh_model_pub_get(node, ele_addr, mod_id, &status);
if (pub && status == MESH_STATUS_SUCCESS)
send_pub_status(node, net_idx, src, dst, status, ele_addr,
- pub->addr, mod_id, pub->idx, pub->credential,
+ mod_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, 0,
- mod_id, 0, 0, 0, 0, 0);
+ send_pub_status(node, net_idx, src, dst, status, ele_addr,
+ mod_id, 0, 0, 0, 0, 0, 0);
return true;
}
-static bool config_pub_set(struct mesh_node *node, uint16_t net_idx,
+static void config_pub_set(struct mesh_node *node, uint16_t net_idx,
uint16_t src, uint16_t dst,
- const uint8_t *pkt, uint16_t size,
- bool unreliable)
+ const uint8_t *pkt, uint8_t virt_offset,
+ bool vendor, bool unreliable)
{
uint32_t mod_id;
uint16_t ele_addr, idx, ota = 0;
@@ -119,93 +113,58 @@ static bool config_pub_set(struct mesh_node *node, uint16_t net_idx,
uint8_t ttl, period;
uint8_t retransmit;
int status;
- bool cred_flag, b_virt = false;
- bool vendor = false;
-
- switch (size) {
- default:
- return false;
-
- case 11:
- idx = l_get_le16(pkt + 4);
- ttl = pkt[6];
- period = pkt[7];
- retransmit = pkt[8];
- mod_id = l_get_le16(pkt + 9);
- mod_id |= VENDOR_ID_MASK;
- break;
+ bool cred_flag;
- case 13:
- idx = l_get_le16(pkt + 4);
- ttl = pkt[6];
- period = pkt[7];
- retransmit = pkt[8];
- mod_id = l_get_le16(pkt + 9) << 16;
- mod_id |= l_get_le16(pkt + 11);
- vendor = true;
- break;
+ idx = l_get_le16(pkt + 4 + virt_offset);
+ ttl = pkt[6 + virt_offset];
+ period = pkt[7 + virt_offset];
+ retransmit = pkt[8 + virt_offset];
+ mod_id = l_get_le16(pkt + 9 + virt_offset);
- case 25:
- b_virt = true;
- idx = l_get_le16(pkt + 18);
- ttl = pkt[20];
- period = pkt[21];
- retransmit = pkt[22];
- mod_id = l_get_le16(pkt + 23);
+ if (!vendor)
mod_id |= VENDOR_ID_MASK;
- break;
-
- case 27:
- b_virt = true;
- idx = l_get_le16(pkt + 18);
- ttl = pkt[20];
- period = pkt[21];
- retransmit = pkt[22];
- mod_id = l_get_le16(pkt + 23) << 16;
- mod_id |= l_get_le16(pkt + 25);
- vendor = true;
- break;
- }
+ else
+ mod_id |= l_get_le16(pkt + 11 + virt_offset);
ele_addr = l_get_le16(pkt);
pub_addr = pkt + 2;
- /* Doesn't accept out-of-range TTLs */
- if (ttl > TTL_MASK && ttl != DEFAULT_TTL)
- return false;
+ /* Doesn't accept virtual seeming addresses */
+ test_addr = l_get_le16(pub_addr);
+ if (!virt_offset && IS_VIRTUAL(test_addr))
+ return;
/* Get cred_flag */
cred_flag = !!(CREDFLAG_MASK & idx);
- /* Ignore non-IDX bits */
+ /* Get AppKey index */
idx &= APP_IDX_MASK;
- /* Doesn't accept virtual seeming addresses */
- test_addr = l_get_le16(pub_addr);
- if (!b_virt && test_addr > 0x7fff && test_addr < 0xc000)
- return false;
-
status = mesh_model_pub_set(node, ele_addr, mod_id, pub_addr, idx,
cred_flag, ttl, period, retransmit,
- b_virt, &ota);
+ virt_offset != 0, &ota);
l_debug("pub_set: status %d, ea %4.4x, ota: %4.4x, mod: %x, idx: %3.3x",
status, ele_addr, ota, mod_id, idx);
- if (IS_UNASSIGNED(ota) && !b_virt) {
- ttl = period = idx = 0;
+ if (status != MESH_STATUS_SUCCESS) {
+ if (!unreliable)
+ send_pub_status(node, net_idx, src, dst, status,
+ ele_addr, mod_id, 0, 0, 0, 0, 0, 0);
- /* Remove model publication from config file */
- if (status == MESH_STATUS_SUCCESS)
- mesh_config_model_pub_del(node_config_get(node),
- ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
- vendor);
- goto done;
+ return;
}
- if (status == MESH_STATUS_SUCCESS) {
+ if (IS_UNASSIGNED(ota) && !virt_offset) {
+ ttl = period = idx = 0;
+
+ /* Remove model publication from config file */
+ mesh_config_model_pub_del(node_config_get(node), ele_addr,
+ vendor ? mod_id : mod_id & ~VENDOR_ID_MASK,
+ vendor);
+ } else {
struct mesh_config_pub db_pub = {
- .virt = b_virt,
+ .virt = (virt_offset != 0),
.addr = ota,
.idx = idx,
.ttl = ttl,
@@ -215,21 +174,19 @@ static bool config_pub_set(struct mesh_node *node, uint16_t net_idx,
.interval = ((retransmit >> 3) + 1) * 50
};
- if (b_virt)
+ if (virt_offset)
memcpy(db_pub.virt_addr, pub_addr, 16);
/* Save model publication to config file */
if (!mesh_config_model_pub_add(node_config_get(node), ele_addr,
- vendor ? mod_id : mod_id & 0x0000ffff,
+ vendor ? mod_id : mod_id & ~VENDOR_ID_MASK,
vendor, &db_pub))
status = MESH_STATUS_STORAGE_FAIL;
}
-done:
if (!unreliable)
send_pub_status(node, net_idx, src, dst, status, ele_addr, ota,
mod_id, idx, cred_flag, ttl, period, retransmit);
- return true;
}
static void send_sub_status(struct mesh_node *node, uint16_t net_idx,
@@ -825,7 +782,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst, uint16_t unicast,
if (size != 25 && size != 27)
return true;
- config_pub_set(node, net_idx, src, unicast, pkt, size,
+ config_pub_set(node, net_idx, src, unicast, pkt, 14, size == 27,
!!(opcode & OP_UNRELIABLE));
break;
@@ -833,7 +790,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst, uint16_t unicast,
if (size != 11 && size != 13)
return true;
- config_pub_set(node, net_idx, src, unicast, pkt, size,
+ config_pub_set(node, net_idx, src, unicast, pkt, 0, size == 13,
!!(opcode & OP_UNRELIABLE));
break;