msg[n++] = ttl;
msg[n++] = period;
msg[n++] = retransmit;
+
if (mod_id < 0x10000 || mod_id > VENDOR_ID_MASK) {
l_put_le16(mod_id, msg + n);
n += 2;
n += 2;
}
- mesh_model_send(node, dst, src,
- APP_IDX_DEV, DEFAULT_TTL, msg, n);
+ mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n);
}
static bool config_pub_get(struct mesh_node *node, uint16_t src, uint16_t dst,
int status;
bool cred_flag, b_virt = false;
bool vendor = false;
- struct mesh_model_pub *pub;
- uint8_t ele_idx;
switch (size) {
default:
vendor = true;
break;
}
+
ele_addr = l_get_le16(pkt);
pub_addr = pkt + 2;
goto done;
}
- if (status != MESH_STATUS_SUCCESS)
- goto done;
-
- ele_idx = node_get_element_idx(node, ele_addr);
- pub = mesh_model_pub_get(node, ele_idx, mod_id, &status);
-
- if (pub) {
+ if (status == MESH_STATUS_SUCCESS) {
struct mesh_db_pub db_pub = {
.virt = b_virt,
.addr = ota,
.idx = idx,
.ttl = ttl,
- .credential = pub->credential,
+ .credential = cred_flag,
.period = period,
- .count = pub->retransmit >> 5,
- .interval = ((0x1f & pub->retransmit) + 1) * 50
+ .count = retransmit >> 5,
+ .interval = ((0x1f & retransmit) + 1) * 50
};
if (b_virt)
uint16_t ele_addr;
uint32_t mod_id;
uint16_t n = 0;
- int ret = 0;
- uint8_t *status;
+ int status;
+ uint8_t *msg_status;
uint16_t buf_size;
uint8_t msg[5 + sizeof(uint16_t) * MAX_GRP_PER_MOD];
case 4:
mod_id = l_get_le16(pkt + 2);
n = mesh_model_opcode_set(OP_CONFIG_MODEL_SUB_LIST, msg);
- status = msg + n;
+ msg_status = msg + n;
msg[n++] = 0;
l_put_le16(ele_addr, msg + n);
n += 2;
mod_id = l_get_le16(pkt + 2) << 16;
mod_id |= l_get_le16(pkt + 4);
n = mesh_model_opcode_set(OP_CONFIG_VEND_MODEL_SUB_LIST, msg);
- status = msg + n;
+ msg_status = msg + n;
msg[n++] = 0;
l_put_le16(ele_addr, msg + n);
n += 2;
}
buf_size = sizeof(uint16_t) * MAX_GRP_PER_MOD;
- ret = mesh_model_sub_get(node, ele_addr, mod_id, msg + n, buf_size,
+ status = mesh_model_sub_get(node, ele_addr, mod_id, msg + n, buf_size,
&size);
- if (!ret)
+ if (status == MESH_STATUS_SUCCESS)
n += size;
- else if (ret > 0)
- *status = ret;
+
+ *msg_status = (uint8_t) status;
mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n);
return true;
{
uint16_t grp, ele_addr;
bool unreliable = !!(opcode & OP_UNRELIABLE);
- uint32_t mod_id, func;
+ uint32_t mod_id;
const uint8_t *addr = NULL;
- int status = 0;
+ int status = MESH_STATUS_SUCCESS;
bool vendor = false;
switch (size) {
mod_id |= l_get_le16(pkt + 20);
break;
}
+
ele_addr = l_get_le16(pkt);
if (opcode != OP_CONFIG_MODEL_SUB_DELETE_ALL) {
} else
grp = UNASSIGNED_ADDRESS;
- func = opcode & ~OP_UNRELIABLE;
- switch (func) {
+ switch (opcode & ~OP_UNRELIABLE) {
default:
- l_debug("Bad opcode: %x", func);
+ l_debug("Bad opcode: %x", opcode);
return;
case OP_CONFIG_MODEL_SUB_DELETE_ALL:
models = node_get_element_models(node, ele_idx, status);
if (!models) {
- *status = MESH_STATUS_INVALID_ADDRESS;
+ *status = MESH_STATUS_INVALID_MODEL;
return NULL;
}
}
static struct mesh_model *find_model(struct mesh_node *node, uint16_t addr,
- uint32_t mod_id, int *fail)
+ uint32_t mod_id, int *status)
{
int ele_idx;
ele_idx = node_get_element_idx(node, addr);
if (ele_idx < 0) {
- if (fail)
- *fail = MESH_STATUS_INVALID_ADDRESS;
+ *status = MESH_STATUS_INVALID_ADDRESS;
return NULL;
}
- return get_model(node, (uint8_t) ele_idx, mod_id, fail);
+ return get_model(node, (uint8_t) ele_idx, mod_id, status);
}
static uint32_t pub_period_to_ms(uint8_t pub_period)
}
}
-static bool pub_frnd_cred(struct mesh_node *node, uint16_t src, uint32_t mod_id)
-{
- struct mesh_model *mod = find_model(node, src, mod_id, NULL);
-
- if (!mod || !mod->pub)
- return false;
-
- return (mod->pub->credential != 0);
-}
-
static bool msg_send(struct mesh_node *node, bool credential, uint16_t src,
uint32_t dst, uint8_t key_id, const uint8_t *key,
uint8_t *aad, uint8_t ttl, const void *msg, uint16_t msg_len)
iv_index = mesh_net_get_iv_index(net);
seq_num = mesh_net_get_seq_num(net);
- if (!mesh_crypto_payload_encrypt(aad, msg, out, msg_len,
- src, dst, key_id,
- seq_num, iv_index,
- szmic, key)) {
+ if (!mesh_crypto_payload_encrypt(aad, msg, out, msg_len, src, dst,
+ key_id, seq_num, iv_index, szmic, key)) {
l_error("Failed to Encrypt Payload");
goto done;
}
/* print_packet("Encrypted with", key, 16); */
- ret = mesh_net_app_send(net, credential,
- src, dst, key_id, ttl,
- seq_num, iv_index,
- szmic,
- out, out_len,
- cmplt, NULL);
+ ret = mesh_net_app_send(net, credential, src, dst, key_id, ttl,
+ seq_num, iv_index, szmic, out, out_len,
+ cmplt, NULL);
done:
l_free(out);
return ret;
l_free(mod->pub);
mod->pub = NULL;
- /*
- * TODO: Instead of reporting period of 0, report publication
- * address as unassigned
- */
if (!mod->cbs)
/* External models */
config_update_model_pub_period(node, mod->ele_idx, mod->id, 0);
}
static int update_binding(struct mesh_node *node, uint16_t addr, uint32_t id,
- uint16_t app_idx, bool unbind)
+ uint16_t app_idx, bool unbind)
{
- int fail;
+ int status;
struct mesh_model *mod;
bool is_present;
- mod = find_model(node, addr, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod) {
l_debug("Model not found");
- return fail;
+ return status;
}
id = (id >= VENDOR_ID_MASK) ? (id & 0xffff) : id;
uint8_t key_id;
const uint8_t *key;
bool result;
+ int status;
/* print_packet("Mod Tx", msg, msg_len); */
if (src == 0)
src = mesh_net_get_address(net);
- mod = find_model(node, src, mod_id, NULL);
+ mod = find_model(node, src, mod_id, &status);
if (!mod) {
l_debug("model %x not found", mod_id);
return MESH_ERROR_NOT_FOUND;
l_debug("(%x) %p", mod->pub->idx, key);
l_debug("key_id %x", key_id);
- result = msg_send(node, pub_frnd_cred(node, src, mod_id), src,
+ result = msg_send(node, mod->pub->credential != 0, src,
dst, key_id, key, aad, ttl, msg, msg_len);
return result ? MESH_ERROR_NONE : MESH_ERROR_FAILED;
uint8_t ttl, uint8_t period, uint8_t retransmit,
bool b_virt, uint16_t *dst)
{
- int fail = MESH_STATUS_SUCCESS;
- int ele_idx;
struct mesh_model *mod;
- int result;
-
- ele_idx = node_get_element_idx(node, addr);
-
- if (ele_idx < 0) {
- fail = MESH_STATUS_INVALID_ADDRESS;
- return false;
- }
+ int status;
- mod = get_model(node, (uint8_t) ele_idx, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod)
- return fail;
+ return status;
if (id == CONFIG_SRV_MODEL || id == CONFIG_CLI_MODEL)
return MESH_STATUS_INVALID_PUB_PARAM;
if (!appkey_have_key(node_get_net(node), idx))
return MESH_STATUS_INVALID_APPKEY;
- result = set_pub(mod, mod_addr, idx, cred_flag, ttl, period, retransmit,
+ status = set_pub(mod, mod_addr, idx, cred_flag, ttl, period, retransmit,
b_virt, dst);
- if (result != MESH_STATUS_SUCCESS)
- return result;
+ if (status != MESH_STATUS_SUCCESS)
+ return status;
/*
* If the publication address is set to unassigned address value,
- * remove publication
+ * remove the publication
*/
if (IS_UNASSIGNED(*dst))
remove_pub(node, mod);
}
/* External model */
- config_update_model_pub_period(node, ele_idx, id,
+ config_update_model_pub_period(node, mod->ele_idx, id,
pub_period_to_ms(period));
return MESH_STATUS_SUCCESS;
}
-struct mesh_model_pub *mesh_model_pub_get(struct mesh_node *node,
- uint8_t ele_idx, uint32_t mod_id, int *status)
+struct mesh_model_pub *mesh_model_pub_get(struct mesh_node *node, uint16_t addr,
+ uint32_t mod_id, int *status)
{
struct mesh_model *mod;
- mod = get_model(node, ele_idx, mod_id, status);
+ mod = find_model(node, addr, mod_id, status);
if (!mod)
return NULL;
if (l_queue_isempty(mod->bindings) || !mod->cbs->bind) {
for (b = l_queue_get_entries(mod->bindings); b; b = b->next) {
if (cbs->bind(L_PTR_TO_UINT(b->data), ACTION_ADD) !=
- MESH_STATUS_SUCCESS)
+ MESH_STATUS_SUCCESS)
break;
}
}
int mesh_model_get_bindings(struct mesh_node *node, uint16_t addr, uint32_t id,
uint8_t *buf, uint16_t buf_size, uint16_t *size)
{
- int fail;
+ int status;
struct mesh_model *mod;
const struct l_queue_entry *entry;
uint16_t n;
uint32_t idx_pair;
int i;
- mod = find_model(node, addr, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod) {
*size = 0;
- return fail;
+ return status;
}
entry = l_queue_get_entries(mod->bindings);
} else {
idx_pair <<= 12;
idx_pair += app_idx;
+
/* Unlikely, but check for overflow*/
if ((n + 3) > buf_size) {
l_warn("Binding list too large");
goto done;
}
+
l_put_le32(idx_pair, buf);
buf += 3;
n += 3;
done:
*size = n;
-
return MESH_STATUS_SUCCESS;
}
int mesh_model_sub_get(struct mesh_node *node, uint16_t addr, uint32_t id,
uint8_t *buf, uint16_t buf_size, uint16_t *size)
{
- int fail = MESH_STATUS_SUCCESS;
+ int status;
int16_t n;
struct mesh_model *mod;
const struct l_queue_entry *entry;
- mod = find_model(node, addr, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod)
- return fail;
+ return status;
entry = l_queue_get_entries(mod->subs);
*size = 0;
int mesh_model_sub_add(struct mesh_node *node, uint16_t addr, uint32_t id,
const uint8_t *group, bool b_virt, uint16_t *dst)
{
- int fail = MESH_STATUS_SUCCESS;
- int ele_idx = -1;
+ int status;
struct mesh_model *mod;
- ele_idx = node_get_element_idx(node, addr);
-
- if (!node || ele_idx < 0) {
- fail = MESH_STATUS_INVALID_ADDRESS;
- return false;
- }
-
- mod = get_model(node, (uint8_t) ele_idx, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod)
- return fail;
+ return status;
return add_sub(node_get_net(node), mod, group, b_virt, dst);
- /* TODO: communicate to registered models that sub has changed */
}
int mesh_model_sub_ovr(struct mesh_node *node, uint16_t addr, uint32_t id,
const uint8_t *group, bool b_virt, uint16_t *dst)
{
- int fail = MESH_STATUS_SUCCESS;
+ int status;
struct l_queue *virtuals, *subs;
struct mesh_virtual *virt;
struct mesh_model *mod;
- mod = find_model(node, addr, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod)
- return fail;
+ return status;
subs = mod->subs;
virtuals = mod->virtuals;
}
}
- fail = mesh_model_sub_add(node, addr, id, group, b_virt, dst);
+ status = mesh_model_sub_add(node, addr, id, group, b_virt, dst);
- if (fail) {
- /* Adding new group failed, so revert to old list */
+ if (status != MESH_STATUS_SUCCESS) {
+ /* Adding new group failed, so revert to old lists */
l_queue_destroy(mod->subs, NULL);
mod->subs = subs;
l_queue_destroy(mod->virtuals, unref_virt);
mesh_net_dst_unreg(net,
(uint16_t) L_PTR_TO_UINT(entry->data));
+ /* Destroy old lists */
l_queue_destroy(subs, NULL);
l_queue_destroy(virtuals, unref_virt);
}
- return fail;
+ return status;
}
int mesh_model_sub_del(struct mesh_node *node, uint16_t addr, uint32_t id,
const uint8_t *group, bool b_virt, uint16_t *dst)
{
- int fail = MESH_STATUS_SUCCESS;
+ int status;
uint16_t grp;
struct mesh_model *mod;
- mod = find_model(node, addr, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod)
- return fail;
+ return status;
if (b_virt) {
struct mesh_virtual *virt;
int mesh_model_sub_del_all(struct mesh_node *node, uint16_t addr, uint32_t id)
{
- int fail = MESH_STATUS_SUCCESS;
+ int status;
struct mesh_model *mod;
const struct l_queue_entry *entry;
struct mesh_net *net = node_get_net(node);
- mod = find_model(node, addr, id, &fail);
+ mod = find_model(node, addr, id, &status);
if (!mod)
- return fail;
+ return status;
entry = l_queue_get_entries(mod->subs);
l_queue_destroy(mod->virtuals, unref_virt);
mod->virtuals = l_queue_new();
- return fail;
+ return MESH_STATUS_SUCCESS;
}
struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
bool mesh_model_register(struct mesh_node *node, uint8_t ele_idx,
uint32_t mod_id, const struct mesh_model_ops *cbs,
void *user_data);
+struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
+ void *data);
struct mesh_model_pub *mesh_model_pub_get(struct mesh_node *node,
- uint8_t ele_idx, uint32_t mod_id, int *status);
+ 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,
uint8_t ttl, uint8_t period, uint8_t retransmit,
bool b_virt, uint16_t *dst);
-struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
- void *data);
int mesh_model_binding_add(struct mesh_node *node, uint16_t addr, uint32_t id,
- uint16_t app_idx);
+ uint16_t idx);
int mesh_model_binding_del(struct mesh_node *node, uint16_t addr, uint32_t id,
- uint16_t idx);
+ uint16_t idx);
int mesh_model_get_bindings(struct mesh_node *node, uint16_t addr, uint32_t id,
uint8_t *buf, uint16_t buf_len, uint16_t *size);
int mesh_model_sub_add(struct mesh_node *node, uint16_t addr, uint32_t id,
- const uint8_t *grp, bool b_virt,
- uint16_t *dst);
+ const uint8_t *grp, bool b_virt, uint16_t *dst);
int mesh_model_sub_del(struct mesh_node *node, uint16_t addr, uint32_t id,
- const uint8_t *grp, bool b_virt,
- uint16_t *dst);
+ const uint8_t *grp, bool b_virt, uint16_t *dst);
int mesh_model_sub_del_all(struct mesh_node *node, uint16_t addr, uint32_t id);
int mesh_model_sub_ovr(struct mesh_node *node, uint16_t addr, uint32_t id,
- const uint8_t *grp, bool b_virt,
- uint16_t *dst);
+ const uint8_t *grp, bool b_virt, uint16_t *dst);
int mesh_model_sub_get(struct mesh_node *node, uint16_t addr, uint32_t id,
uint8_t *buf, uint16_t buf_size, uint16_t *size);
uint16_t mesh_model_cfg_blk(uint8_t *pkt);
-bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target,
+bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t dst,
uint16_t app_idx, uint8_t ttl,
const void *msg, uint16_t msg_len);
-int mesh_model_publish(struct mesh_node *node, uint32_t mod_id,
- uint16_t src, uint8_t ttl,
- const void *msg, uint16_t msg_len);
+int mesh_model_publish(struct mesh_node *node, uint32_t mod_id, uint16_t src,
+ uint8_t ttl, const void *msg, uint16_t msg_len);
bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
uint32_t seq, uint32_t iv_index, uint8_t ttl,
uint16_t src, uint16_t dst, uint8_t key_id,
void mesh_model_del_virtual(struct mesh_node *node, uint32_t va24);
void mesh_model_list_virtual(struct mesh_node *node);
uint16_t mesh_model_opcode_set(uint32_t opcode, uint8_t *buf);
-bool mesh_model_opcode_get(const uint8_t *buf, uint16_t size,
- uint32_t *opcode, uint16_t *n);
+bool mesh_model_opcode_get(const uint8_t *buf, uint16_t size, uint32_t *opcode,
+ uint16_t *n);
void model_build_config(void *model, void *msg_builder);
void mesh_model_init(void);