This patch implements D-Bus DevKeySend() method of org.bluez.mesh.Node1
interface, allowing the application to send messages encrypted using
a known remote device key.
At the moment the call ignores net_index argument and sends messages
using the primary subnet.
Also, it's no longer possible to use 'magic' key_index value 0x7fff
(denoting local device key) when calling regular Send(). Applications
should use DevKeySend() instead.
---
mesh/model.c | 9 +++++++-
mesh/node.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/mesh/model.c b/mesh/model.c
index 598615c5e..aae913d92 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -39,6 +39,7 @@
#include "mesh/dbus.h"
#include "mesh/util.h"
#include "mesh/model.h"
+#include "mesh/keyring.h"
/* Divide and round to ceiling (up) to calculate segment count */
#define CEILDIV(val, div) (((val) + (div) - 1) / (div))
@@ -941,6 +942,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target,
const void *msg, uint16_t msg_len)
{
uint8_t key_id;
+ uint8_t dev_key[16];
const uint8_t *key;
/* print_packet("Mod Tx", msg, msg_len); */
@@ -959,7 +961,12 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target,
if (!key)
return false;
- l_debug("(%x)", app_idx);
+ key_id = APP_ID_DEV;
+ } else if (app_idx == APP_IDX_DEV_REMOTE) {
+ if (!keyring_get_remote_dev_key(node, target, dev_key))
+ return false;
+
+ key = dev_key;
key_id = APP_ID_DEV;
} else {
key = appkey_get_key(node_get_net(node), app_idx, &key_id);
diff --git a/mesh/node.c b/mesh/node.c
index 9acf153d9..316b889e8 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -1959,7 +1959,11 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus,
return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
"Incorrect data");
- if (!mesh_model_send(node, src, dst, app_idx,
+ if ((app_idx & APP_IDX_MASK) != app_idx)
+ return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
+ "Invalid key_index");
+
+ if (!mesh_model_send(node, src, dst, app_idx & APP_IDX_MASK,
mesh_net_get_default_ttl(node->net), data, len))
return dbus_error(msg, MESH_ERROR_FAILED, NULL);
@@ -1969,6 +1973,53 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus,
return reply;
}
+static struct l_dbus_message *dev_key_send_call(struct l_dbus *dbus,
+ struct l_dbus_message *msg,
+ void *user_data)
+{
+ struct mesh_node *node = user_data;
+ const char *sender, *ele_path;
+ struct l_dbus_message_iter iter_data;
+ struct node_element *ele;
+ uint16_t dst, net_idx, src;
+ uint8_t *data;
+ uint32_t len;
+ struct l_dbus_message *reply;
+
+ l_debug("DevKeySend");
+
+ sender = l_dbus_message_get_sender(msg);
+
+ if (strcmp(sender, node->owner))
+ return dbus_error(msg, MESH_ERROR_NOT_AUTHORIZED, NULL);
+
+ if (!l_dbus_message_get_arguments(msg, "oqqay", &ele_path, &dst,
+ &net_idx, &iter_data))
+ return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);
+
+ ele = l_queue_find(node->elements, match_element_path, ele_path);
+ if (!ele)
+ return dbus_error(msg, MESH_ERROR_NOT_FOUND,
+ "Element not found");
+
+ src = node_get_primary(node) + ele->idx;
+
+ if (!l_dbus_message_iter_get_fixed_array(&iter_data, &data, &len) ||
+ !len || len > MESH_MAX_ACCESS_PAYLOAD)
+ return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
+ "Incorrect data");
+
+ /* TODO: use net_idx */
+ if (!mesh_model_send(node, src, dst, APP_IDX_DEV_REMOTE,
+ mesh_net_get_default_ttl(node->net), data, len))
+ return dbus_error(msg, MESH_ERROR_NOT_FOUND, NULL);
+
+ reply = l_dbus_message_new_method_return(msg);
+ l_dbus_message_set_arguments(reply, "");
+
+ return reply;
+}
+
static struct l_dbus_message *publish_call(struct l_dbus *dbus,
struct l_dbus_message *msg,
void *user_data)
@@ -2074,7 +2125,11 @@ static void setup_node_interface(struct l_dbus_interface *iface)
{
l_dbus_interface_method(iface, "Send", 0, send_call, "", "oqqay",
"element_path", "destination",
- "key", "data");
+ "key_index", "data");
+ l_dbus_interface_method(iface, "DevKeySend", 0, dev_key_send_call,
+ "", "oqqay", "element_path",
+ "destination", "net_index",
+ "data");
l_dbus_interface_method(iface, "Publish", 0, publish_call, "", "oqay",
"element_path", "model_id", "data");
l_dbus_interface_method(iface, "VendorPublish", 0, vendor_publish_call,
--
2.19.1