* [PATCH 1/7] meshd: Shared private meshd interfaces
2018-04-25 14:20 [PATCH 0/7] Bluetooth Mesh Daemon Brian Gix
@ 2018-04-25 14:20 ` Brian Gix
2018-04-25 14:20 ` [PATCH 3/7] meshd: Header files for mesh access layer and utilities Brian Gix
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Brian Gix @ 2018-04-25 14:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Brian Gix
---
meshd/src/crypto.h | 164 ++++++++++++++++++
meshd/src/display.h | 29 ++++
meshd/src/friend.h | 57 +++++++
meshd/src/hci.h | 56 +++++++
meshd/src/mesh-io-api.h | 58 +++++++
meshd/src/mesh-io-generic.h | 20 +++
meshd/src/mesh-io.h | 99 +++++++++++
meshd/src/net.h | 392 ++++++++++++++++++++++++++++++++++++++++++++
meshd/src/prov.h | 162 ++++++++++++++++++
meshd/src/provision.h | 30 ++++
10 files changed, 1067 insertions(+)
create mode 100644 meshd/src/crypto.h
create mode 100644 meshd/src/display.h
create mode 100644 meshd/src/friend.h
create mode 100644 meshd/src/hci.h
create mode 100644 meshd/src/mesh-io-api.h
create mode 100644 meshd/src/mesh-io-generic.h
create mode 100644 meshd/src/mesh-io.h
create mode 100644 meshd/src/net.h
create mode 100644 meshd/src/prov.h
create mode 100644 meshd/src/provision.h
diff --git a/meshd/src/crypto.h b/meshd/src/crypto.h
new file mode 100644
index 000000000..251b2cc7f
--- /dev/null
+++ b/meshd/src/crypto.h
@@ -0,0 +1,164 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
+ const uint8_t *aad, uint16_t aad_len,
+ const uint8_t *msg, uint16_t msg_len,
+ uint8_t *out_msg,
+ void *out_mic, size_t mic_size);
+bool mesh_crypto_aes_ccm_decrypt(const uint8_t nonce[13], const uint8_t key[16],
+ const uint8_t *aad, uint16_t aad_len,
+ const uint8_t *enc_msg, uint16_t enc_msg_len,
+ uint8_t *out_msg,
+ void *out_mic, size_t mic_size);
+bool mesh_aes_ecb_one(const uint8_t key[16],
+ const uint8_t plaintext[16], uint8_t encrypted[16]);
+bool mesh_crypto_nkik(const uint8_t network_key[16], uint8_t identity_key[16]);
+bool mesh_crypto_nkbk(const uint8_t network_key[16], uint8_t beacon_key[16]);
+bool mesh_crypto_nkpk(const uint8_t network_key[16], uint8_t proxy_key[16]);
+bool mesh_crypto_identity(const uint8_t net_key[16], uint16_t addr,
+ uint8_t id[16]);
+bool mesh_crypto_beacon_cmac(const uint8_t encryption_key[16],
+ const uint8_t network_id[16],
+ uint32_t iv_index, bool kr,
+ bool iu, uint64_t *cmac);
+bool mesh_crypto_network_nonce(bool frnd, uint8_t ttl, uint32_t seq,
+ uint16_t src, uint32_t iv_index,
+ uint8_t nonce[13]);
+bool mesh_crypto_network_encrypt(bool ctl, uint8_t ttl,
+ uint32_t seq, uint16_t src,
+ uint32_t iv_index,
+ const uint8_t net_key[16],
+ const uint8_t *enc_msg, uint8_t enc_msg_len,
+ uint8_t *out, void *net_mic);
+bool mesh_crypto_network_decrypt(bool frnd, uint8_t ttl,
+ uint32_t seq, uint16_t src,
+ uint32_t iv_index,
+ const uint8_t net_key[16],
+ const uint8_t *enc_msg, uint8_t enc_msg_len,
+ uint8_t *out, void *net_mic, size_t mic_size);
+bool mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
+ uint16_t dst, uint32_t iv_index,
+ bool aszmic, uint8_t nonce[13]);
+bool mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
+ uint16_t dst, uint32_t iv_index,
+ bool aszmic, uint8_t nonce[13]);
+bool mesh_crypto_application_encrypt(uint8_t akf, uint32_t seq, uint16_t src,
+ uint16_t dst, uint32_t iv_index,
+ const uint8_t app_key[16],
+ const uint8_t *aad, uint8_t aad_len,
+ const uint8_t *msg, uint8_t msg_len,
+ uint8_t *out,
+ void *app_mic, size_t mic_size);
+bool mesh_crypto_application_decrypt(uint8_t akf, uint32_t seq, uint16_t src,
+ uint16_t dst, uint32_t iv_index,
+ const uint8_t app_key[16],
+ const uint8_t *aad, uint8_t aad_len,
+ const uint8_t *enc_msg, uint8_t enc_msg_len,
+ uint8_t *out, void *app_mic, size_t mic_size);
+bool mesh_crypto_device_key(const uint8_t secret[32],
+ const uint8_t salt[16],
+ uint8_t device_key[16]);
+bool mesh_crypto_virtual_addr(const uint8_t virtual_label[16],
+ uint16_t *v_addr);
+bool mesh_crypto_nonce(const uint8_t secret[32],
+ const uint8_t salt[16],
+ uint8_t nonce[13]);
+bool mesh_crypto_k1(const uint8_t ikm[16], const uint8_t salt[16],
+ const void *info, size_t info_len, uint8_t okm[16]);
+bool mesh_crypto_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
+ uint8_t net_id[1],
+ uint8_t enc_key[16],
+ uint8_t priv_key[16]);
+bool mesh_crypto_k3(const uint8_t n[16], uint8_t out64[8]);
+bool mesh_crypto_k4(const uint8_t a[16], uint8_t out5[1]);
+bool mesh_crypto_s1(const void *info, size_t len, uint8_t salt[16]);
+bool mesh_crypto_prov_prov_salt(const uint8_t conf_salt[16],
+ const uint8_t prov_rand[16],
+ const uint8_t dev_rand[16],
+ uint8_t prov_salt[16]);
+bool mesh_crypto_prov_conf_key(const uint8_t secret[32],
+ const uint8_t salt[16],
+ uint8_t conf_key[16]);
+bool mesh_crypto_session_key(const uint8_t secret[32],
+ const uint8_t salt[16],
+ uint8_t session_key[16]);
+bool mesh_crypto_privacy_counter(uint32_t iv_index,
+ const uint8_t *payload,
+ uint8_t privacy_counter[16]);
+bool mesh_crypto_network_obfuscate(const uint8_t privacy_key[16],
+ const uint8_t privacy_counter[16],
+ bool ctl, uint8_t ttl, uint32_t seq,
+ uint16_t src, uint8_t *out);
+bool mesh_crypto_network_clarify(const uint8_t privacy_key[16],
+ const uint8_t privacy_counter[16],
+ const uint8_t net_hdr[6],
+ bool *ctl, uint8_t *ttl,
+ uint32_t *seq, uint16_t *src);
+
+bool mesh_crypto_packet_build(bool ctl, uint8_t ttl,
+ uint32_t seq,
+ uint16_t src, uint16_t dst,
+ uint8_t opcode,
+ bool segmented, uint8_t key_id,
+ bool szmic, bool relay, uint16_t seqZero,
+ uint8_t segO, uint8_t segN,
+ const uint8_t *payload, uint8_t payload_len,
+ uint8_t *packet, uint8_t *packet_len);
+bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
+ bool *ctl, uint8_t *ttl, uint32_t *seq,
+ uint16_t *src, uint16_t *dst,
+ uint32_t *cookie, uint8_t *opcode,
+ bool *segmented, uint8_t *key_id,
+ bool *szmic, bool *relay, uint16_t *seqZero,
+ uint8_t *segO, uint8_t *segN,
+ const uint8_t **payload, uint8_t *payload_len);
+bool mesh_crypto_payload_encrypt(uint8_t *aad, const uint8_t *payload,
+ uint8_t *out, uint16_t payload_len,
+ uint16_t src, uint16_t dst, uint8_t key_id,
+ uint32_t seq_num, uint32_t iv_index,
+ bool aszmic,
+ const uint8_t application_key[16]);
+bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
+ const uint8_t *payload, uint16_t payload_len,
+ bool szmict,
+ uint16_t src, uint16_t dst, uint8_t key_id,
+ uint32_t seq_num, uint32_t iv_index,
+ uint8_t *out,
+ const uint8_t application_key[16]);
+bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
+ const uint8_t network_key[16],
+ uint32_t iv_index,
+ const uint8_t privacy_key[16]);
+bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
+ bool proxy, uint8_t *out, uint32_t iv_index,
+ const uint8_t network_key[16],
+ const uint8_t privacy_key[16]);
+bool mesh_crypto_packet_label(uint8_t *packet, uint8_t packet_len,
+ uint16_t iv_index, uint8_t network_id);
+
+uint8_t mesh_crypto_compute_fcs(const uint8_t *packet, uint8_t packet_len);
+bool mesh_crypto_check_fcs(const uint8_t *packet, uint8_t packet_len,
+ uint8_t received_fcs);
+bool mesh_crypto_aes_cmac(const uint8_t key[16], const uint8_t *msg,
+ size_t msg_len, uint8_t res[16]);
+
diff --git a/meshd/src/display.h b/meshd/src/display.h
new file mode 100644
index 000000000..d43292741
--- /dev/null
+++ b/meshd/src/display.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#define COLOR_OFF "\x1B[0m"
+#define COLOR_RED "\x1B[0;91m"
+#define COLOR_GREEN "\x1B[0;92m"
+#define COLOR_YELLOW "\x1B[0;93m"
+#define COLOR_BLUE "\x1B[0;94m"
+
+unsigned int num_columns(void);
+
+void print_packet(const char *label, const void *data, uint16_t size);
+
diff --git a/meshd/src/friend.h b/meshd/src/friend.h
new file mode 100644
index 000000000..1fa6ec92a
--- /dev/null
+++ b/meshd/src/friend.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#define OP_FRND_REQUEST 0x8040
+#define OP_FRND_INQUIRY 0x8041
+#define OP_FRND_CONFIRM 0x8042
+#define OP_FRND_SUB_LIST_ADD 0x8043
+#define OP_FRND_SUB_LIST_CONFIRM 0x8044
+#define OP_FRND_SUB_LIST_REMOVE 0x8045
+#define OP_FRND_NEGOTIATE 0x8046
+#define OP_FRND_CLEAR 0x8047
+
+void friend_poll(struct mesh_net *net, uint16_t src, bool seq,
+ struct mesh_friend *frnd);
+void friend_request(struct mesh_net *net, uint16_t src, uint8_t minReq,
+ uint8_t delay, uint32_t timeout, uint16_t prev,
+ uint8_t num_elements, uint16_t cntr, int8_t rssi);
+void friend_clear_confirm(struct mesh_net *net, uint16_t src, uint16_t lpn,
+ uint16_t lpnCounter);
+void friend_clear(struct mesh_net *net, uint16_t src, uint16_t lpn,
+ uint16_t lpnCounter, struct mesh_friend *frnd);
+void friend_sub_add(struct mesh_net *net, struct mesh_friend *frnd,
+ const uint8_t *pkt, uint8_t len);
+void friend_sub_del(struct mesh_net *net, struct mesh_friend *frnd,
+ const uint8_t *pkt, uint8_t len);
+void mesh_friend_relay_init(struct mesh_net *net, uint16_t addr);
+
+/* Low-Power-Node role */
+void frnd_sub_add(struct mesh_net *net, uint32_t parms[7]);
+void frnd_sub_del(struct mesh_net *net, uint32_t parms[7]);
+void frnd_poll(struct mesh_net *net, bool retry);
+void frnd_clear(struct mesh_net *net);
+void frnd_ack_poll(struct mesh_net *net);
+void frnd_poll_cancel(struct mesh_net *net);
+void frnd_request_friend(struct mesh_net *net, uint8_t cache,
+ uint8_t offer_delay, uint8_t delay, uint32_t timeout);
+void frnd_offer(struct mesh_net *net, uint16_t src, uint8_t window,
+ uint8_t cache, uint8_t sub_list_size,
+ int8_t r_rssi, int8_t l_rssi, uint16_t fn_cnt);
+void frnd_key_refresh(struct mesh_net *net, uint8_t phase);
+struct mesh_key_set *frnd_get_key(struct mesh_net *net);
diff --git a/meshd/src/hci.h b/meshd/src/hci.h
new file mode 100644
index 000000000..a1362b76a
--- /dev/null
+++ b/meshd/src/hci.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+struct bt_hci;
+
+typedef void (*bt_hci_destroy_func_t)(void *user_data);
+
+struct bt_hci *bt_hci_new(int fd);
+struct bt_hci *bt_hci_new_user_channel(uint16_t index);
+struct bt_hci *bt_hci_new_raw_device(uint16_t index);
+
+struct bt_hci *bt_hci_ref(struct bt_hci *hci);
+void bt_hci_unref(struct bt_hci *hci);
+
+bool bt_hci_set_close_on_unref(struct bt_hci *hci, bool do_close);
+
+typedef void (*bt_hci_callback_func_t)(const void *data, uint8_t size,
+ void *user_data);
+
+unsigned int bt_hci_send(struct bt_hci *hci, uint16_t opcode,
+ const void *data, uint8_t size,
+ bt_hci_callback_func_t callback,
+ void *user_data, bt_hci_destroy_func_t destroy);
+bool bt_hci_cancel(struct bt_hci *hci, unsigned int id);
+bool bt_hci_flush(struct bt_hci *hci);
+
+unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
+ bt_hci_callback_func_t callback,
+ void *user_data, bt_hci_destroy_func_t destroy);
+bool bt_hci_unregister(struct bt_hci *hci, unsigned int id);
+
+typedef void (*bt_hci_receive_func_t)(uint16_t handle, uint8_t flags,
+ const void *data, uint16_t size,
+ void *user_data);
+
+bool bt_hci_receive(struct bt_hci *hci, bt_hci_receive_func_t callback,
+ void *user_data, bt_hci_destroy_func_t destroy);
+
+bool bt_hci_write(struct bt_hci *hci, uint16_t handle, uint8_t flags,
+ const void *data, uint16_t size);
diff --git a/meshd/src/mesh-io-api.h b/meshd/src/mesh-io-api.h
new file mode 100644
index 000000000..f69fceeb2
--- /dev/null
+++ b/meshd/src/mesh-io-api.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+struct mesh_io_private;
+
+typedef bool (*mesh_io_init_t)(uint16_t index, struct mesh_io *io);
+typedef bool (*mesh_io_destroy_t)(struct mesh_io *io);
+typedef bool (*mesh_io_caps_t)(struct mesh_io *io, struct mesh_io_caps *caps);
+typedef bool (*mesh_io_send_t)(struct mesh_io *io,
+ struct mesh_io_send_info *info,
+ const uint8_t *data, uint16_t len);
+typedef bool (*mesh_io_register_t)(struct mesh_io *io, uint8_t filter_id,
+ mesh_io_recv_func_t cb, void *user_data);
+typedef bool (*mesh_io_deregister_t)(struct mesh_io *io, uint8_t filter_id);
+typedef bool (*mesh_io_filter_set_t)(struct mesh_io *io,
+ uint8_t filter_id, const uint8_t *data, uint8_t len,
+ mesh_io_status_func_t callback, void *user_data);
+typedef bool (*mesh_io_tx_cancel_t)(struct mesh_io *io, uint8_t *pattern,
+ uint8_t len);
+
+struct mesh_io_api {
+ mesh_io_init_t init;
+ mesh_io_destroy_t destroy;
+ mesh_io_caps_t caps;
+ mesh_io_send_t send;
+ mesh_io_register_t reg;
+ mesh_io_deregister_t dereg;
+ mesh_io_filter_set_t set;
+ mesh_io_tx_cancel_t cancel;
+};
+
+struct mesh_io {
+ enum mesh_io_type type;
+ uint16_t index;
+ const struct mesh_io_api *api;
+ struct mesh_io_private *pvt;
+};
+
+struct mesh_io_table {
+ enum mesh_io_type type;
+ const struct mesh_io_api *api;
+};
diff --git a/meshd/src/mesh-io-generic.h b/meshd/src/mesh-io-generic.h
new file mode 100644
index 000000000..4bf4d5cb7
--- /dev/null
+++ b/meshd/src/mesh-io-generic.h
@@ -0,0 +1,20 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+extern const struct mesh_io_api mesh_io_generic;
diff --git a/meshd/src/mesh-io.h b/meshd/src/mesh-io.h
new file mode 100644
index 000000000..754f6129c
--- /dev/null
+++ b/meshd/src/mesh-io.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+struct mesh_io;
+
+#define MESH_IO_FILTER_BEACON 1
+#define MESH_IO_FILTER_PROV 2
+#define MESH_IO_FILTER_NET 3
+
+#define MESH_IO_TX_COUNT_UNLIMITED 0
+
+enum mesh_io_type {
+ MESH_IO_TYPE_NONE = 0,
+ MESH_IO_TYPE_GENERIC
+};
+
+enum mesh_io_timing_type {
+ MESH_IO_TIMING_TYPE_GENERAL = 1,
+ MESH_IO_TIMING_TYPE_POLL,
+ MESH_IO_TIMING_TYPE_POLL_RSP
+};
+
+struct mesh_io_recv_info {
+ uint32_t instant;
+ uint8_t chan;
+ int8_t rssi;
+};
+
+struct mesh_io_send_info {
+ enum mesh_io_timing_type type;
+ union {
+ struct {
+ uint16_t interval;
+ uint8_t cnt;
+ uint8_t min_delay;
+ uint8_t max_delay;
+ } gen;
+
+ struct {
+ uint16_t scan_duration;
+ uint8_t scan_delay;
+ uint8_t filter_ids[2];
+ uint8_t min_delay;
+ uint8_t max_delay;
+ } poll;
+
+ struct {
+ uint32_t instant;
+ uint8_t delay;
+ } poll_rsp;
+
+ } u;
+};
+
+struct mesh_io_caps {
+ uint8_t max_num_filters;
+ uint8_t window_accuracy;
+};
+
+typedef void (*mesh_io_recv_func_t)(void *user_data,
+ struct mesh_io_recv_info *info,
+ const uint8_t *data, uint16_t len);
+
+typedef void (*mesh_io_status_func_t)(void *user_data, int status,
+ uint8_t filter_id);
+
+struct mesh_io *mesh_io_new(uint16_t index, enum mesh_io_type type);
+void mesh_io_destroy(struct mesh_io *io);
+
+bool mesh_io_get_caps(struct mesh_io *io, struct mesh_io_caps *caps);
+
+bool mesh_io_register_recv_cb(struct mesh_io *io, uint8_t filter_id,
+ mesh_io_recv_func_t cb, void *user_data);
+
+bool mesh_io_deregister_recv_cb(struct mesh_io *io, uint8_t filter_id);
+
+bool mesh_set_filter(struct mesh_io *io, uint8_t filter_id,
+ const uint8_t *data, uint8_t len,
+ mesh_io_status_func_t cb, void *user_data);
+
+bool mesh_io_send(struct mesh_io *io, struct mesh_io_send_info *info,
+ const uint8_t *data, uint16_t len);
+bool mesh_io_send_cancel(struct mesh_io *io, uint8_t *pattern, uint8_t len);
diff --git a/meshd/src/net.h b/meshd/src/net.h
new file mode 100644
index 000000000..e48380314
--- /dev/null
+++ b/meshd/src/net.h
@@ -0,0 +1,392 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+struct mesh_io;
+struct mesh_node;
+
+#define DEV_ID 0
+
+#define UNUSED_KEY_IDX 0xffff
+
+#define APP_ID_DEV 0
+#define APP_ID_ANY ((unsigned int) -1)
+#define NET_ID_ANY (APP_ID_ANY - 1)
+
+#define CTL 0x80
+#define TTL_MASK 0x7f
+#define SEQ_MASK 0xffffff
+
+#define CREDFLAG_MASK 0x1000
+#define APP_IDX_MASK 0x0fff
+#define APP_IDX_DEV 0x7fff
+#define APP_IDX_ANY 0x8000
+#define APP_IDX_NET 0xffff
+
+#define NET_IDX_INVALID 0xffff
+#define NET_NID_INVALID 0xff
+
+#define KEY_CACHE_SIZE 64
+#define FRND_CACHE_MAX 32
+
+#define MAX_UNSEG_LEN 15 /* msg_len == 11 + sizeof(MIC) */
+#define MAX_SEG_LEN 12 /* UnSeg length - 3 octets overhead */
+#define SEG_MAX(len) (((len) <= MAX_UNSEG_LEN) ? 0 : \
+ (((len) - 1) / MAX_SEG_LEN))
+#define SEG_OFF(seg) ((seg) * MAX_SEG_LEN)
+#define MAX_SEG_TO_LEN(seg) ((seg) ? SEG_OFF((seg) + 1) : MAX_UNSEG_LEN)
+
+#define SEGMENTED 0x80
+#define UNSEGMENTED 0x00
+#define SEG_HDR_SHIFT 31
+#define IS_SEGMENTED(hdr) (!!((hdr) & (true << SEG_HDR_SHIFT)))
+
+#define KEY_ID_MASK 0x7f
+#define KEY_AID_MASK 0x3f
+#define KEY_ID_AKF 0x40
+#define KEY_AID_SHIFT 0
+#define AKF_HDR_SHIFT 30
+#define KEY_HDR_SHIFT 24
+#define HAS_APP_KEY(hdr) (!!((hdr) & (true << AKF_HDR_SHIFT)))
+
+#define OPCODE_MASK 0x7f
+#define OPCODE_HDR_SHIFT 24
+#define RELAY 0x80
+#define RELAY_HDR_SHIFT 23
+#define SZMIC 0x80
+#define SZMIC_HDR_SHIFT 23
+#define SEQ_ZERO_MASK 0x1fff
+#define SEQ_ZERO_HDR_SHIFT 10
+#define IS_RELAYED(hdr) (!!((hdr) & (true << RELAY_HDR_SHIFT)))
+#define HAS_MIC64(hdr) (!!((hdr) & (true << SZMIC_HDR_SHIFT)))
+
+#define SEG_MASK 0x1f
+#define SEGO_HDR_SHIFT 5
+#define SEGN_HDR_SHIFT 0
+#define SEG_TOTAL(hdr) (((hdr) >> SEGN_HDR_SHIFT) & SEG_MASK)
+
+/* Mask of Hdr bits which must be constant over entire incoming SAR message */
+/* (SEG || AKF || AID || SZMIC || SeqZero || SegN) */
+#define HDR_KEY_MASK ((true << SEG_HDR_SHIFT) | \
+ (KEY_ID_MASK << KEY_HDR_SHIFT) | \
+ (true << SZMIC_HDR_SHIFT) | \
+ (SEQ_ZERO_MASK << SEQ_ZERO_HDR_SHIFT) | \
+ (SEG_MASK << SEGN_HDR_SHIFT))
+
+#define HDR_ACK_MASK ((OPCODE_MASK << OPCODE_HDR_SHIFT) | \
+ (SEQ_ZERO_MASK << SEQ_ZERO_HDR_SHIFT))
+
+
+
+#define MSG_CACHE_SIZE 70
+#define REPLAY_CACHE_SIZE 10
+
+/* Proxy Configuration Opcodes */
+#define PROXY_OP_SET_FILTER_TYPE 0x00
+#define PROXY_OP_FILTER_ADD 0x01
+#define PROXY_OP_FILTER_DEL 0x02
+#define PROXY_OP_FILTER_STATUS 0x03
+
+/* Proxy Filter Defines */
+#define PROXY_FILTER_WHITELIST 0x00
+#define PROXY_FILTER_BLACKLIST 0x01
+
+/* Network Tranport Opcodes */
+#define NET_OP_SEG_ACKNOWLEDGE 0x00
+#define NET_OP_FRND_POLL 0x01
+#define NET_OP_FRND_UPDATE 0x02
+#define NET_OP_FRND_REQUEST 0x03
+#define NET_OP_FRND_OFFER 0x04
+#define NET_OP_FRND_CLEAR 0x05
+#define NET_OP_FRND_CLEAR_CONFIRM 0x06
+
+#define NET_OP_PROXY_SUB_ADD 0x07
+#define NET_OP_PROXY_SUB_REMOVE 0x08
+#define NET_OP_PROXY_SUB_CONFIRM 0x09
+#define NET_OP_HEARTBEAT 0x0a
+
+#define FRND_OPCODE(x) \
+ ((x) >= NET_OP_FRND_POLL && (x) <= NET_OP_FRND_CLEAR_CONFIRM)
+
+struct mesh_net_addr_range {
+ uint16_t low;
+ uint16_t high;
+ uint16_t next;
+};
+
+struct mesh_net_prov_caps {
+ uint8_t num_ele;
+ uint16_t algorithms;
+ uint8_t pub_type;
+ uint8_t static_type;
+ uint8_t output_size;
+ uint16_t output_action;
+ uint8_t input_size;
+ uint16_t input_action;
+} __packed;
+
+struct mesh_net_heartbeat {
+ struct l_timeout *pub_timer;
+ struct l_timeout *sub_timer;
+ struct timeval sub_time;
+ bool sub_enabled;
+ uint32_t pub_period;
+ uint32_t sub_period;
+ uint32_t sub_start;
+ uint16_t pub_dst;
+ uint16_t pub_count;
+ uint16_t pub_features;
+ uint16_t features;
+ uint16_t pub_net_idx;
+ uint16_t sub_src;
+ uint16_t sub_dst;
+ uint16_t sub_count;
+ uint8_t pub_ttl;
+ uint8_t sub_min_hops;
+ uint8_t sub_max_hops;
+};
+
+struct mesh_key_set {
+ bool frnd;
+ uint8_t nid;
+ uint8_t enc_key[16];
+ uint8_t privacy_key[16];
+};
+
+struct mesh_friend {
+ struct mesh_net *net;
+ struct l_queue *pkt_cache;
+ struct l_timeout *timeout;
+ void *pkt;
+ uint16_t *grp_list;
+ uint32_t poll_timeout;
+ uint32_t last_hdr;
+ uint16_t dst; /* Primary Element unicast addr */
+ uint16_t fn_cnt;
+ uint16_t lp_cnt;
+ int16_t grp_cnt;
+ struct mesh_key_set key_set;
+ struct mesh_key_set new_key_set;
+ uint8_t ele_cnt;
+ uint8_t frd;
+ uint8_t frw;
+ bool seq;
+ bool last;
+};
+
+struct mesh_frnd_pkt {
+ uint32_t iv_index;
+ uint32_t seq;
+ uint16_t src;
+ uint16_t dst;
+ uint16_t size;
+ uint8_t segN;
+ uint8_t segO;
+ uint8_t ttl;
+ uint8_t tc;
+ bool szmict;
+ union {
+ struct {
+ uint8_t key_id;
+ } m;
+ struct {
+ uint16_t seq0;
+ } a;
+ struct {
+ uint8_t opcode;
+ } c;
+ } u;
+ uint8_t data[];
+};
+
+struct mesh_friend_seg_one {
+ uint32_t hdr;
+ uint32_t seq;
+ bool sent;
+ bool md;
+ uint8_t data[15];
+};
+
+struct mesh_friend_seg_12 {
+ uint32_t hdr;
+ uint32_t seq;
+ bool sent;
+ bool md;
+ uint8_t data[12];
+};
+
+struct mesh_friend_msg {
+ uint32_t iv_index;
+ uint32_t flags;
+ uint16_t src;
+ uint16_t dst;
+ uint8_t ttl;
+ uint8_t cnt_in;
+ uint8_t cnt_out;
+ uint8_t last_len;
+ bool done;
+ bool ctl;
+ union {
+ struct mesh_friend_seg_one one[1]; /* Single segment */
+ struct mesh_friend_seg_12 s12[0]; /* Array of segments */
+ } u;
+};
+
+typedef void (*mesh_status_func_t)(void *user_data, bool result);
+typedef void (*mesh_net_status_func_t)(uint16_t remote, uint8_t status,
+ void *data, uint16_t size,
+ void *user_data);
+
+struct mesh_net *mesh_net_new(uint16_t index);
+struct mesh_net *mesh_net_ref(struct mesh_net *net);
+void mesh_net_unref(struct mesh_net *net);
+void mesh_net_flush_msg_queues(struct mesh_net *net);
+void mesh_net_set_iv_index(struct mesh_net *net, uint32_t index, bool update);
+bool mesh_net_iv_index_update(struct mesh_net *net);
+bool mesh_net_set_seq_num(struct mesh_net *net, uint32_t number);
+uint32_t mesh_net_get_seq_num(struct mesh_net *net);
+uint32_t mesh_net_next_seq_num(struct mesh_net *net);
+bool mesh_net_set_default_ttl(struct mesh_net *net, uint8_t ttl);
+uint8_t mesh_net_get_default_ttl(struct mesh_net *net);
+bool mesh_net_get_frnd_seq(struct mesh_net *net);
+void mesh_net_set_frnd_seq(struct mesh_net *net, bool seq);
+uint16_t mesh_net_get_address(struct mesh_net *net);
+bool mesh_net_register_unicast(struct mesh_net *net,
+ uint16_t unicast, uint8_t num_ele);
+bool mesh_net_set_friend(struct mesh_net *net, uint16_t friend_addr);
+uint16_t mesh_net_get_friend(struct mesh_net *net);
+uint8_t mesh_net_get_num_ele(struct mesh_net *net);
+bool mesh_net_set_beacon_mode(struct mesh_net *net, bool enable);
+bool mesh_net_set_proxy_mode(struct mesh_net *net, bool enable);
+bool mesh_net_set_relay_mode(struct mesh_net *net, bool enable, uint8_t cnt,
+ uint8_t interval);
+bool mesh_net_set_friend_mode(struct mesh_net *net, bool enable);
+bool mesh_net_add_keyset(struct mesh_net *net, struct mesh_key_set *key_set);
+bool mesh_net_remove_keyset(struct mesh_net *net, struct mesh_key_set *key_set);
+int mesh_net_del_key(struct mesh_net *net, uint16_t net_idx);
+int mesh_net_add_key(struct mesh_net *net, bool update,
+ uint16_t net_idx, const void *key);
+uint32_t mesh_net_get_iv_index(struct mesh_net *net);
+void mesh_net_get_snb_state(struct mesh_net *net,
+ uint8_t *flags, uint32_t *iv_index);
+bool mesh_net_get_key(struct mesh_net *net, bool new_key, uint16_t idx,
+ uint8_t key[16]);
+bool mesh_net_attach(struct mesh_net *net, struct mesh_io *io);
+struct mesh_io *mesh_net_detach(struct mesh_net *net);
+struct l_queue *mesh_net_get_app_keys(struct mesh_net *net);
+
+bool mesh_net_flush(struct mesh_net *net);
+void mesh_net_transport_send(struct mesh_net *net, struct mesh_key_set *key_set,
+ bool fast, uint32_t iv_index, uint8_t ttl,
+ uint32_t seq, uint16_t src, uint16_t dst,
+ const uint8_t *msg, uint16_t msg_len);
+
+unsigned int mesh_net_app_send(struct mesh_net *net, bool frnd_cred,
+ uint16_t src, uint16_t dst, uint8_t key_id,
+ uint8_t ttl, uint32_t seq, uint32_t iv_index,
+ bool szmic, const void *msg, uint16_t msg_len,
+ mesh_net_status_func_t status_func,
+ void *user_data);
+void mesh_net_app_send_cancel(struct mesh_net *net, unsigned int id);
+void mesh_net_ack_send(struct mesh_net *net, struct mesh_key_set *key_set,
+ uint32_t iv_index, uint8_t ttl, uint32_t seq,
+ uint16_t src, uint16_t dst, bool rly,
+ uint16_t seqZero, uint32_t ack_flags);
+struct mesh_net_prov_caps *mesh_net_prov_caps_get(struct mesh_net *net);
+uint8_t *mesh_net_priv_key_get(struct mesh_net *net);
+bool mesh_net_priv_key_set(struct mesh_net *net, uint8_t key[32]);
+uint8_t *mesh_net_prov_rand(struct mesh_net *net);
+uint16_t mesh_net_prov_uni(struct mesh_net *net, uint8_t ele_cnt);
+bool mesh_net_id_uuid_set(struct mesh_net *net, uint8_t uuid[16]);
+uint8_t *mesh_net_test_addr(struct mesh_net *net);
+int mesh_net_get_identity_mode(struct mesh_net *net, uint16_t idx,
+ uint8_t *mode);
+char *mesh_net_id_name(struct mesh_net *net);
+bool mesh_net_test_mode(struct mesh_net *net);
+bool mesh_net_dst_reg(struct mesh_net *net, uint16_t dst);
+bool mesh_net_dst_unreg(struct mesh_net *net, uint16_t dst);
+struct mesh_friend *mesh_friend_new(struct mesh_net *net, uint16_t dst,
+ uint8_t ele_cnt, uint8_t frd,
+ uint8_t frw, uint32_t fpt,
+ uint16_t fn_cnt, uint16_t lp_cnt);
+void mesh_friend_free(void *frnd);
+bool mesh_friend_clear(struct mesh_net *net, struct mesh_friend *frnd);
+void mesh_friend_sub_add(struct mesh_net *net, uint16_t lpn, uint8_t ele_cnt,
+ uint8_t grp_cnt,
+ const uint8_t *list);
+void mesh_friend_sub_del(struct mesh_net *net, uint16_t lpn, uint8_t cnt,
+ const uint8_t *del_list);
+uint8_t mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t net_idx,
+ uint8_t transition);
+uint8_t mesh_net_key_refresh_phase_get(struct mesh_net *net, uint16_t net_idx,
+ uint8_t *phase);
+int mesh_net_kr_phase_one(struct mesh_net *net, uint16_t net_idx,
+ const uint8_t *key);
+int mesh_net_key_refresh_phase_two(struct mesh_net *net, uint16_t net_idx);
+int mesh_net_key_refresh_finish(struct mesh_net *net, uint16_t net_idx);
+void mesh_net_send_seg(struct mesh_net *net, struct mesh_key_set *key_set,
+ uint32_t iv_index, uint8_t ttl, uint32_t seq,
+ uint16_t src, uint16_t dst, uint32_t hdr,
+ const void *seg, uint16_t seg_len);
+uint16_t mesh_net_get_features(struct mesh_net *net);
+struct mesh_net_heartbeat *mesh_net_heartbeat_get(struct mesh_net *net);
+void mesh_net_heartbeat_init(struct mesh_net *net);
+void mesh_net_heartbeat_send(struct mesh_net *net);
+void mesh_net_uni_range_set(struct mesh_net *net,
+ struct mesh_net_addr_range *range);
+struct mesh_net_addr_range mesh_net_uni_range_get(struct mesh_net *net);
+void mesh_net_provisioner_mode_set(struct mesh_net *net, bool mode);
+bool mesh_net_provisioner_mode_get(struct mesh_net *net);
+bool mesh_net_key_list_get(struct mesh_net *net, uint8_t *buf, uint16_t *count);
+uint16_t mesh_net_get_primary_idx(struct mesh_net *net);
+void mesh_net_sub_list_add(struct mesh_net *net, uint16_t addr);
+void mesh_net_sub_list_del(struct mesh_net *net, uint16_t addr);
+uint32_t mesh_net_friend_timeout(struct mesh_net *net, uint16_t addr);
+struct mesh_io *mesh_net_get_io(struct mesh_net *net);
+bool mesh_net_local_node_set(struct mesh_net *net, struct mesh_node *node,
+ bool provisioner);
+struct mesh_node *mesh_net_local_node_get(struct mesh_net *net);
+bool mesh_net_set_crpl(struct mesh_net *net, uint16_t crpl);
+uint16_t mesh_net_get_crpl(struct mesh_net *net);
+bool mesh_net_have_key(struct mesh_net *net, uint16_t net_idx);
+bool mesh_net_jconfig_set(struct mesh_net *net, void *jconfig);
+void *mesh_net_jconfig_get(struct mesh_net *net);
+bool mesh_net_cfg_file_set(struct mesh_net *net, const char *cfg);
+bool mesh_net_cfg_file_get(struct mesh_net *net, const char **cfg);
+bool mesh_net_is_local_address(struct mesh_net *net, uint16_t addr);
+void mesh_net_set_window_accuracy(struct mesh_net *net, uint8_t accuracy);
+void mesh_net_transmit_params_set(struct mesh_net *net, uint8_t count,
+ uint16_t interval);
+void mesh_net_transmit_params_get(struct mesh_net *net, uint8_t *count,
+ uint16_t *interval);
+struct mesh_prov *mesh_net_get_prov(struct mesh_net *net);
+void mesh_net_set_prov(struct mesh_net *net, struct mesh_prov *prov);
+void mesh_net_provisioned_set(struct mesh_net *net, bool provisioned);
+bool mesh_net_provisioned_get(struct mesh_net *net);
+bool mesh_net_provisioned_new(struct mesh_net *net, uint8_t device_key[16],
+ uint16_t net_idx, uint8_t net_key[16],
+ uint16_t unicast, uint16_t snb_flags,
+ uint32_t iv_index, mesh_status_func_t cb,
+ void *user_data);
diff --git a/meshd/src/prov.h b/meshd/src/prov.h
new file mode 100644
index 000000000..09fe6c3cd
--- /dev/null
+++ b/meshd/src/prov.h
@@ -0,0 +1,162 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+struct mesh_net;
+struct mesh_dev;
+
+enum mesh_trans {
+ MESH_TRANS_IDLE,
+ MESH_TRANS_TX,
+ MESH_TRANS_RX,
+};
+
+enum mesh_bearer {
+ MESH_BEARER_IDLE,
+ MESH_BEARER_ADV,
+};
+
+enum mesh_prov_mode {
+ MESH_PROV_MODE_NONE,
+ MESH_PROV_MODE_INITIATOR,
+ MESH_PROV_MODE_GATT_ACCEPTOR,
+ MESH_PROV_MODE_ADV_ACCEPTOR,
+ MESH_PROV_MODE_GATT_CLIENT,
+ MESH_PROV_MODE_MESH_SERVER,
+ MESH_PROV_MODE_MESH_CLIENT,
+ MESH_PROV_MODE_MESH_GATT_CLIENT,
+};
+
+struct mesh_prov;
+typedef void (*mesh_prov_open_func_t)(struct mesh_prov *prov);
+typedef void (*mesh_prov_close_func_t)(struct mesh_prov *prov, uint8_t reason);
+typedef void (*mesh_prov_send_func_t)(bool success, struct mesh_prov *prov);
+typedef void (*mesh_prov_receive_func_t)(const void *data, uint16_t size,
+ struct mesh_prov *prov);
+
+struct prov_invite {
+ uint8_t attention;
+} __packed;
+
+struct prov_start {
+ uint8_t algorithm;
+ uint8_t pub_key;
+ uint8_t auth_method;
+ uint8_t auth_action;
+ uint8_t auth_size;
+} __packed;
+
+struct conf_input {
+ struct prov_invite invite;
+ struct mesh_net_prov_caps caps;
+ struct prov_start start;
+ uint8_t prv_pub_key[64];
+ uint8_t dev_pub_key[64];
+} __packed;
+
+struct mesh_prov {
+ int ref_count;
+ struct mesh_dev *dev;
+ struct mesh_net *net;
+ enum mesh_prov_mode mode;
+ enum mesh_trans trans;
+ enum mesh_bearer bearer;
+ uint8_t uuid[16];
+ uint8_t caps[12];
+
+ uint32_t conn_id;
+ uint16_t net_idx;
+ uint16_t remote;
+ uint16_t addr;
+ uint16_t expected_len;
+ uint16_t packet_len;
+ uint8_t local_msg_num;
+ uint8_t peer_msg_num;
+ uint8_t last_peer_msg_num;
+ uint8_t got_segs;
+ uint8_t expected_segs;
+ uint8_t expected_fcs;
+ uint8_t packet_buf[80];
+ uint8_t peer_buf[80];
+ struct timeval tx_start;
+ struct l_timeout *tx_timeout;
+
+ /* Provisioning credentials and crypto material */
+ struct conf_input conf_inputs;
+ uint8_t dev_key[16];
+ uint8_t conf_salt[16];
+ uint8_t s_key[16];
+ uint8_t s_nonce[13];
+ uint8_t conf_key[16];
+ uint8_t conf[16];
+ uint8_t r_conf[16];
+ uint8_t rand_auth[32];
+ uint8_t prov_salt[16];
+ uint8_t secret[32];
+ uint8_t r_public[64];
+ uint8_t l_public[64];
+ /* End Provisioning credentials and crypto material */
+
+ mesh_prov_open_func_t open_callback;
+ mesh_prov_close_func_t close_callback;
+ mesh_prov_receive_func_t receive_callback;
+ void *receive_data;
+ mesh_prov_send_func_t send_callback;
+ void *send_data;
+};
+
+struct mesh_prov *mesh_prov_new(struct mesh_net *net, uint16_t remote);
+
+struct mesh_prov *mesh_prov_ref(struct mesh_prov *prov);
+void mesh_prov_unref(struct mesh_prov *prov);
+
+bool mesh_prov_gatt_client(struct mesh_prov *prov, struct mesh_dev *dev,
+ uint8_t uuid[16],
+ mesh_prov_open_func_t open_callback,
+ mesh_prov_close_func_t close_callback,
+ mesh_prov_receive_func_t recv_callback,
+ void *user_data);
+
+bool mesh_prov_listen(struct mesh_net *net, uint8_t uuid[16], uint8_t caps[12],
+ mesh_prov_open_func_t open_callback,
+ mesh_prov_close_func_t close_callback,
+ mesh_prov_receive_func_t recv_callback,
+ void *user_data);
+
+bool mesh_prov_connect(struct mesh_prov *prov, struct mesh_dev *dev,
+ uint16_t net_idx, uint8_t uuid[16],
+ mesh_prov_open_func_t open_callback,
+ mesh_prov_close_func_t close_callback,
+ mesh_prov_receive_func_t recv_callback,
+ void *user_data);
+
+unsigned int mesh_prov_send(struct mesh_prov *prov,
+ const void *data, uint16_t size,
+ mesh_prov_send_func_t send_callback,
+ void *user_data);
+bool mesh_prov_cancel(struct mesh_prov *prov, unsigned int id);
+
+bool mesh_prov_close(struct mesh_prov *prov, uint8_t reason);
+void mesh_prov_set_addr(struct mesh_prov *prov, uint16_t addr);
+uint16_t mesh_prov_get_addr(struct mesh_prov *prov);
+void mesh_prov_set_idx(struct mesh_prov *prov, uint16_t net_idx);
+uint16_t mesh_prov_get_idx(struct mesh_prov *prov);
diff --git a/meshd/src/provision.h b/meshd/src/provision.h
new file mode 100644
index 000000000..0c59bf037
--- /dev/null
+++ b/meshd/src/provision.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+struct mesh_prov;
+struct l_queue;
+
+void initiator_prov_open(struct mesh_prov *prov);
+void initiator_prov_close(struct mesh_prov *prov, uint8_t reason);
+void initiator_prov_receive(const void *pkt, uint16_t size,
+ struct mesh_prov *prov);
+void acceptor_prov_open(struct mesh_prov *prov);
+void acceptor_prov_close(struct mesh_prov *prov, uint8_t reason);
+void acceptor_prov_receive(const void *pkt, uint16_t size,
+ struct mesh_prov *prov);
--
2.14.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/7] meshd: Header files for mesh access layer and utilities
2018-04-25 14:20 [PATCH 0/7] Bluetooth Mesh Daemon Brian Gix
2018-04-25 14:20 ` [PATCH 1/7] meshd: Shared private meshd interfaces Brian Gix
@ 2018-04-25 14:20 ` Brian Gix
2018-04-25 14:20 ` [PATCH 5/7] meshd: Read and write mesh configuration in JSON format Brian Gix
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Brian Gix @ 2018-04-25 14:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Inga Stotland
From: Inga Stotland <inga.stotland@intel.com>
This adds initial implementation of Mesh access layer functionality
---
meshd/common/agent.h | 42 ++++++++++++++
meshd/common/mesh-defs.h | 84 +++++++++++++++++++++++++++
meshd/common/util.h | 25 ++++++++
meshd/src/appkey.h | 43 ++++++++++++++
meshd/src/cfgmod.h | 98 +++++++++++++++++++++++++++++++
meshd/src/mesh.h | 32 +++++++++++
meshd/src/model.h | 146 +++++++++++++++++++++++++++++++++++++++++++++++
meshd/src/node.h | 80 ++++++++++++++++++++++++++
meshd/src/storage.h | 51 +++++++++++++++++
9 files changed, 601 insertions(+)
create mode 100644 meshd/common/agent.h
create mode 100644 meshd/common/mesh-defs.h
create mode 100644 meshd/common/util.h
create mode 100644 meshd/src/appkey.h
create mode 100644 meshd/src/cfgmod.h
create mode 100644 meshd/src/mesh.h
create mode 100644 meshd/src/model.h
create mode 100644 meshd/src/node.h
create mode 100644 meshd/src/storage.h
diff --git a/meshd/common/agent.h b/meshd/common/agent.h
new file mode 100644
index 000000000..6fb475691
--- /dev/null
+++ b/meshd/common/agent.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2017 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+#define MAX_HEXADECIMAL_OOB_LEN 128
+#define DECIMAL_OOB_LEN 4
+#define MAX_ASCII_OOB_LEN 16
+
+enum oob_type {
+ NONE,
+ HEXADECIMAL,
+ DECIMAL,
+ ASCII,
+ OUTPUT,
+} oob_type_t;
+
+typedef void (*agent_input_cb)(enum oob_type type, void *input, uint16_t len,
+ void *user_data);
+bool agent_input_request(enum oob_type type, uint16_t max_len,
+ agent_input_cb cb, void *user_data);
+
+bool agent_output_request(const char *str);
+void agent_output_request_cancel(void);
+bool agent_completion(void);
+bool agent_input(const char *input);
+void agent_release(void);
diff --git a/meshd/common/mesh-defs.h b/meshd/common/mesh-defs.h
new file mode 100644
index 000000000..d40fc43e8
--- /dev/null
+++ b/meshd/common/mesh-defs.h
@@ -0,0 +1,84 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+#define MESH_AD_TYPE_PROVISION 0x29
+#define MESH_AD_TYPE_NETWORK 0x2A
+#define MESH_AD_TYPE_BEACON 0x2B
+
+#define FEATURE_RELAY 1
+#define FEATURE_PROXY 2
+#define FEATURE_FRIEND 4
+#define FEATURE_LPN 8
+
+#define MESH_MODE_DISABLED 0
+#define MESH_MODE_ENABLED 1
+#define MESH_MODE_UNSUPPORTED 2
+
+#define KEY_REFRESH_PHASE_NONE 0x00
+#define KEY_REFRESH_PHASE_ONE 0x01
+#define KEY_REFRESH_PHASE_TWO 0x02
+#define KEY_REFRESH_PHASE_THREE 0x03
+
+#define DEFAULT_TTL 0xff
+
+/* Supported algorithms for provisioning */
+#define ALG_FIPS_256_ECC 0x0001
+
+/* Input OOB action bit flags */
+#define OOB_IN_PUSH 0x0001
+#define OOB_IN_TWIST 0x0002
+#define OOB_IN_NUMBER 0x0004
+#define OOB_IN_ALPHA 0x0008
+
+/* Output OOB action bit flags */
+#define OOB_OUT_BLINK 0x0001
+#define OOB_OUT_BEEP 0x0002
+#define OOB_OUT_VIBRATE 0x0004
+#define OOB_OUT_NUMBER 0x0008
+#define OOB_OUT_ALPHA 0x0010
+
+#define UNASSIGNED_ADDRESS 0x0000
+#define PROXIES_ADDRESS 0xfffc
+#define FRIENDS_ADDRESS 0xfffd
+#define RELAYS_ADDRESS 0xfffe
+#define ALL_NODES_ADDRESS 0xffff
+#define VIRTUAL_ADDRESS_LOW 0x8000
+#define VIRTUAL_ADDRESS_HIGH 0xbfff
+#define GROUP_ADDRESS_LOW 0xc000
+#define GROUP_ADDRESS_HIGH 0xff00
+
+#define NODE_IDENTITY_STOPPED 0x00
+#define NODE_IDENTITY_RUNNING 0x01
+#define NODE_IDENTITY_NOT_SUPPORTED 0x02
+
+#define PRIMARY_ELE_IDX 0x00
+
+#define VENDOR_ID_MASK 0xffff0000
+
+#define MAX_KEY_IDX 0x0fff
+
+#define IS_UNASSIGNED(x) ((x) == UNASSIGNED_ADDRESS)
+#define IS_UNICAST(x) (((x) > UNASSIGNED_ADDRESS) && \
+ ((x) < VIRTUAL_ADDRESS_LOW))
+#define IS_VIRTUAL(x) (((x) >= VIRTUAL_ADDRESS_LOW) && \
+ ((x) <= VIRTUAL_ADDRESS_HIGH))
+#define IS_GROUP(x) (((x) >= GROUP_ADDRESS_LOW) && \
+ ((x) <= GROUP_ADDRESS_HIGH))
+#define IS_ALL_NODES(x) ((x) == ALL_NODES_ADDRESS)
diff --git a/meshd/common/util.h b/meshd/common/util.h
new file mode 100644
index 000000000..ed880bce7
--- /dev/null
+++ b/meshd/common/util.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+uint32_t get_timestamp_secs(void);
+bool str2hex(const char *str, uint16_t in_len, uint8_t *out,
+ uint16_t out_len);
+size_t hex2str(uint8_t *in, size_t in_len, char *out, size_t out_len);
+
diff --git a/meshd/src/appkey.h b/meshd/src/appkey.h
new file mode 100644
index 000000000..8fce3dcd0
--- /dev/null
+++ b/meshd/src/appkey.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+/* TODO: get this number from configuration */
+#define MAX_APP_KEYS 32
+
+bool appkey_key_init(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
+ uint8_t *key_value, uint8_t *new_key_value);
+void appkey_key_free(void *data);
+int appkey_packet_decrypt(struct mesh_net *net, bool szmict, uint32_t seq,
+ uint32_t iv_index, uint16_t src, uint16_t dst,
+ uint8_t *virt, uint16_t virt_size,
+ uint8_t key_id, const uint8_t *data,
+ uint16_t data_size, uint8_t *out);
+bool appkey_msg_in_replay_cache(struct mesh_net *net, uint16_t idx,
+ uint16_t src, uint16_t crpl, uint32_t seq,
+ uint32_t iv_index);
+const uint8_t *appkey_get_key(struct mesh_net *net, uint16_t app_idx,
+ uint8_t *key_id);
+bool appkey_have_key(struct mesh_net *net, uint16_t app_idx);
+int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
+ const uint8_t *new_key, bool update);
+int appkey_key_delete(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx);
+void appkey_delete_bound_keys(struct mesh_net *net, uint16_t net_idx);
+uint8_t appkey_list(struct mesh_net *net, uint16_t net_idx, uint8_t *buf,
+ uint16_t buf_size, uint16_t *size);
diff --git a/meshd/src/cfgmod.h b/meshd/src/cfgmod.h
new file mode 100644
index 000000000..bedb0c6f6
--- /dev/null
+++ b/meshd/src/cfgmod.h
@@ -0,0 +1,98 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+#define CONFIG_SRV_MODEL (VENDOR_ID_MASK | 0x0000)
+#define CONFIG_CLI_MODEL (VENDOR_ID_MASK | 0x0001)
+
+/* New List */
+#define OP_APPKEY_ADD 0x00
+#define OP_APPKEY_DELETE 0x8000
+#define OP_APPKEY_GET 0x8001
+#define OP_APPKEY_LIST 0x8002
+#define OP_APPKEY_STATUS 0x8003
+#define OP_APPKEY_UPDATE 0x01
+#define OP_DEV_COMP_GET 0x8008
+#define OP_DEV_COMP_STATUS 0x02
+#define OP_CONFIG_BEACON_GET 0x8009
+#define OP_CONFIG_BEACON_SET 0x800A
+#define OP_CONFIG_BEACON_STATUS 0x800B
+#define OP_CONFIG_DEFAULT_TTL_GET 0x800C
+#define OP_CONFIG_DEFAULT_TTL_SET 0x800D
+#define OP_CONFIG_DEFAULT_TTL_STATUS 0x800E
+#define OP_CONFIG_FRIEND_GET 0x800F
+#define OP_CONFIG_FRIEND_SET 0x8010
+#define OP_CONFIG_FRIEND_STATUS 0x8011
+#define OP_CONFIG_PROXY_GET 0x8012
+#define OP_CONFIG_PROXY_SET 0x8013
+#define OP_CONFIG_PROXY_STATUS 0x8014
+#define OP_CONFIG_KEY_REFRESH_PHASE_GET 0x8015
+#define OP_CONFIG_KEY_REFRESH_PHASE_SET 0x8016
+#define OP_CONFIG_KEY_REFRESH_PHASE_STATUS 0x8017
+#define OP_CONFIG_MODEL_PUB_GET 0x8018
+#define OP_CONFIG_MODEL_PUB_SET 0x03
+#define OP_CONFIG_MODEL_PUB_STATUS 0x8019
+#define OP_CONFIG_MODEL_PUB_VIRT_SET 0x801A
+#define OP_CONFIG_MODEL_SUB_ADD 0x801B
+#define OP_CONFIG_MODEL_SUB_DELETE 0x801C
+#define OP_CONFIG_MODEL_SUB_DELETE_ALL 0x801D
+#define OP_CONFIG_MODEL_SUB_OVERWRITE 0x801E
+#define OP_CONFIG_MODEL_SUB_STATUS 0x801F
+#define OP_CONFIG_MODEL_SUB_VIRT_ADD 0x8020
+#define OP_CONFIG_MODEL_SUB_VIRT_DELETE 0x8021
+#define OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE 0x8022
+#define OP_CONFIG_NETWORK_TRANSMIT_GET 0x8023
+#define OP_CONFIG_NETWORK_TRANSMIT_SET 0x8024
+#define OP_CONFIG_NETWORK_TRANSMIT_STATUS 0x8025
+#define OP_CONFIG_RELAY_GET 0x8026
+#define OP_CONFIG_RELAY_SET 0x8027
+#define OP_CONFIG_RELAY_STATUS 0x8028
+#define OP_CONFIG_MODEL_SUB_GET 0x8029
+#define OP_CONFIG_MODEL_SUB_LIST 0x802A
+#define OP_CONFIG_VEND_MODEL_SUB_GET 0x802B
+#define OP_CONFIG_VEND_MODEL_SUB_LIST 0x802C
+#define OP_CONFIG_POLL_TIMEOUT_LIST 0x802D
+#define OP_CONFIG_POLL_TIMEOUT_STATUS 0x802E
+/* Health opcodes in health-mod.h */
+#define OP_CONFIG_HEARTBEAT_PUB_GET 0x8038
+#define OP_CONFIG_HEARTBEAT_PUB_SET 0x8039
+#define OP_CONFIG_HEARTBEAT_PUB_STATUS 0x06
+#define OP_CONFIG_HEARTBEAT_SUB_GET 0x803A
+#define OP_CONFIG_HEARTBEAT_SUB_SET 0x803B
+#define OP_CONFIG_HEARTBEAT_SUB_STATUS 0x803C
+#define OP_MODEL_APP_BIND 0x803D
+#define OP_MODEL_APP_STATUS 0x803E
+#define OP_MODEL_APP_UNBIND 0x803F
+#define OP_NETKEY_ADD 0x8040
+#define OP_NETKEY_DELETE 0x8041
+#define OP_NETKEY_GET 0x8042
+#define OP_NETKEY_LIST 0x8043
+#define OP_NETKEY_STATUS 0x8044
+#define OP_NETKEY_UPDATE 0x8045
+#define OP_NODE_IDENTITY_GET 0x8046
+#define OP_NODE_IDENTITY_SET 0x8047
+#define OP_NODE_IDENTITY_STATUS 0x8048
+#define OP_NODE_RESET 0x8049
+#define OP_NODE_RESET_STATUS 0x804A
+#define OP_MODEL_APP_GET 0x804B
+#define OP_MODEL_APP_LIST 0x804C
+#define OP_VEND_MODEL_APP_GET 0x804C
+#define OP_VEND_MODEL_APP_LIST 0x804E
+
+void mesh_config_srv_init(struct mesh_net *net, uint8_t ele_idx);
diff --git a/meshd/src/mesh.h b/meshd/src/mesh.h
new file mode 100644
index 000000000..7cd1e6158
--- /dev/null
+++ b/meshd/src/mesh.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+struct bt_mesh;
+struct mesh_net;
+
+struct bt_mesh *mesh_create(uint16_t index);
+struct bt_mesh *mesh_ref(struct bt_mesh *mesh);
+void mesh_unref(struct bt_mesh *mesh);
+bool mesh_load_config(struct bt_mesh *mesh, const char *in_config_name);
+bool mesh_set_output(struct bt_mesh *mesh, const char *out_config_name);
+const char *mesh_status_str(uint8_t err);
+
+/* Command line testing */
+struct mesh_net *mesh_get_net(struct bt_mesh *mesh);
diff --git a/meshd/src/model.h b/meshd/src/model.h
new file mode 100644
index 000000000..3a41bd722
--- /dev/null
+++ b/meshd/src/model.h
@@ -0,0 +1,146 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+#include <ell/ell.h>
+
+struct mesh_model;
+
+#define OP_UNRELIABLE 0x0100
+
+#define MAX_BINDINGS 10
+#define MAX_GRP_PER_MOD 10
+
+#define VIRTUAL_BASE 0x10000
+
+#define MESH_MAX_ACCESS_PAYLOAD 380
+
+#define MESH_STATUS_SUCCESS 0x00
+#define MESH_STATUS_INVALID_ADDRESS 0x01
+#define MESH_STATUS_INVALID_MODEL 0x02
+#define MESH_STATUS_INVALID_APPKEY 0x03
+#define MESH_STATUS_INVALID_NETKEY 0x04
+#define MESH_STATUS_INSUFF_RESOURCES 0x05
+#define MESH_STATUS_IDX_ALREADY_STORED 0x06
+#define MESH_STATUS_INVALID_PUB_PARAM 0x07
+#define MESH_STATUS_NOT_SUB_MOD 0x08
+#define MESH_STATUS_STORAGE_FAIL 0x09
+#define MESH_STATUS_FEATURE_NO_SUPPORT 0x0a
+#define MESH_STATUS_CANNOT_UPDATE 0x0b
+#define MESH_STATUS_CANNOT_REMOVE 0x0c
+#define MESH_STATUS_CANNOT_BIND 0x0d
+#define MESH_STATUS_UNABLE_CHANGE_STATE 0x0e
+#define MESH_STATUS_CANNOT_SET 0x0f
+#define MESH_STATUS_UNSPECIFIED_ERROR 0x10
+#define MESH_STATUS_INVALID_BINDING 0x11
+
+#define OP_MODEL_TEST 0x8000fffe
+#define OP_MODEL_INVALID 0x8000ffff
+
+#define USE_PUB_VALUE 0x00
+
+#define ACTION_ADD 1
+#define ACTION_UPDATE 2
+#define ACTION_DELETE 3
+
+struct mesh_model_pub {
+ uint32_t addr;
+ uint16_t idx;
+ uint8_t ttl;
+ uint8_t credential;
+ uint8_t period;
+ uint8_t retransmit;
+};
+
+typedef void (*mesh_model_unregister)(void *user_data);
+typedef bool (*mesh_model_recv_cb)(uint16_t src, uint32_t dst, uint16_t unicast,
+ uint16_t app_idx, const uint8_t *data,
+ uint16_t len, uint8_t ttl,
+ const void *user_data);
+typedef int (*mesh_model_bind_cb)(uint16_t app_idx, int action);
+typedef int (*mesh_model_pub_cb)(struct mesh_model_pub *pub);
+typedef int (*mesh_model_sub_cb)(uint16_t sub_addr, int action);
+
+struct mesh_model_ops {
+ mesh_model_unregister unregister;
+ mesh_model_recv_cb recv;
+ mesh_model_bind_cb bind;
+ mesh_model_pub_cb pub;
+ mesh_model_sub_cb sub;
+};
+
+struct mesh_model *mesh_model_new(uint8_t ele_idx, uint32_t id, bool vendor);
+void mesh_model_free(void *data);
+uint32_t mesh_model_get_model_id(const struct mesh_model *model);
+bool mesh_model_vendor_register(struct mesh_net *net, uint8_t ele_idx,
+ uint32_t mod_id,
+ const struct mesh_model_ops *cbs,
+ void *user_data);
+bool mesh_model_register(struct mesh_net *net, uint8_t ele_idx, uint32_t mod_id,
+ const struct mesh_model_ops *cbs,
+ void *user_data);
+struct mesh_model_pub *mesh_model_pub_get(struct mesh_net *net, uint8_t ele_idx,
+ uint32_t mod_id, int *status);
+int mesh_model_pub_set(struct mesh_net *net, 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_init(struct mesh_net *net, uint8_t ele_idx,
+ struct mesh_db_model *db_mod);
+
+int mesh_model_binding_add(struct mesh_net *net, uint16_t addr, uint32_t id,
+ uint16_t app_idx);
+int mesh_model_binding_del(struct mesh_net *net, uint16_t addr, uint32_t id,
+ uint16_t idx);
+int mesh_model_get_bindings(struct mesh_net *net, uint16_t addr, uint32_t id,
+ uint8_t *buf, uint16_t buf_len, uint16_t *size);
+int mesh_model_sub_add(struct mesh_net *net, uint16_t addr, uint32_t id,
+ const uint8_t *grp, bool b_virt,
+ uint16_t *dst);
+int mesh_model_sub_del(struct mesh_net *net, uint16_t addr, uint32_t id,
+ const uint8_t *grp, bool b_virt,
+ uint16_t *dst);
+int mesh_model_sub_del_all(struct mesh_net *net, uint16_t addr, uint32_t id);
+int mesh_model_sub_ovr(struct mesh_net *net, uint16_t addr, uint32_t id,
+ const uint8_t *grp, bool b_virt,
+ uint16_t *dst);
+int mesh_model_sub_get(struct mesh_net *net, 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);
+unsigned int mesh_model_send(struct mesh_net *net, uint32_t mod_id,
+ uint16_t src, uint32_t target,
+ uint16_t app_idx, uint8_t ttl,
+ const void *msg, uint16_t msg_len);
+
+bool mesh_model_rx(struct mesh_net *net, 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,
+ const uint8_t *data, uint16_t size);
+
+void mesh_model_app_key_generate_new(struct mesh_net *net, uint16_t net_idx);
+void mesh_model_app_key_delete(struct mesh_net *net, struct l_queue *models,
+ uint16_t idx);
+struct l_queue *mesh_model_get_appkeys(struct mesh_net *net);
+void *mesh_model_get_local_node_data(struct mesh_net *net);
+void mesh_model_add_virtual(struct mesh_net *net, const uint8_t *v);
+void mesh_model_del_virtual(struct mesh_net *net, uint32_t va24);
+void mesh_model_list_virtual(struct mesh_net *net);
+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);
diff --git a/meshd/src/node.h b/meshd/src/node.h
new file mode 100644
index 000000000..8ebb41941
--- /dev/null
+++ b/meshd/src/node.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+#include "meshd/mesh-json/mesh-db.h"
+
+struct mesh_net;
+struct mesh_node;
+
+/* To prevent local node JSON cache thrashing, minimum update times */
+#define MIN_SEQ_TRIGGER 32
+#define MIN_SEQ_CACHE (2*MIN_SEQ_TRIGGER)
+#define MIN_SEQ_CACHE_TIME (5*60)
+
+struct mesh_node *node_new(void);
+void node_free(struct mesh_node *node);
+uint8_t *node_uuid_get(struct mesh_node *node);
+struct mesh_node *node_find_by_addr(uint16_t addr);
+struct mesh_node *node_find_by_uuid(uint8_t uuid[16]);
+bool node_is_provisioned(struct mesh_node *node);
+bool node_app_key_delete(struct mesh_net *net, uint16_t addr,
+ uint16_t net_idx, uint16_t idx);
+bool node_net_key_delete(struct mesh_node *node, uint16_t index);
+bool node_set_primary(struct mesh_node *node, uint16_t unicast);
+uint16_t node_get_primary(struct mesh_node *node);
+uint16_t node_get_primary_net_idx(struct mesh_node *node);
+bool node_set_device_key(struct mesh_node *node, uint8_t key[16]);
+const uint8_t *node_get_device_key(struct mesh_node *node);
+void node_set_num_elements(struct mesh_node *node, uint8_t num_ele);
+uint8_t node_get_num_elements(struct mesh_node *node);
+bool node_parse_composition(struct mesh_node *node, uint8_t *buf, uint16_t len);
+struct l_queue *node_get_net_keys(struct mesh_node *node);
+struct l_queue *node_get_app_keys(struct mesh_node *node);
+bool node_add_binding(struct mesh_node *node, uint8_t ele_idx,
+ uint32_t model_id, uint16_t app_idx);
+bool node_del_binding(struct mesh_node *node, uint8_t ele_idx,
+ uint32_t model_id, uint16_t app_idx);
+uint8_t node_default_ttl_get(struct mesh_node *node);
+bool node_default_ttl_set(struct mesh_node *node, uint8_t ttl);
+bool node_set_sequence_number(struct mesh_node *node, uint32_t seq);
+uint32_t node_get_sequence_number(struct mesh_node *node);
+int node_get_element_idx(struct mesh_node *node, uint16_t ele_addr);
+struct l_queue *node_get_element_models(struct mesh_node *node, uint8_t ele_idx,
+ int *status);
+struct mesh_model *node_get_model(struct mesh_node *node, uint8_t ele_idx,
+ uint32_t id, int *status);
+uint16_t node_get_crpl(struct mesh_node *node);
+struct mesh_node *node_create_from_storage(struct mesh_net *net,
+ struct mesh_db_node *db_node,
+ bool local);
+uint16_t node_generate_comp(struct mesh_node *node, uint8_t *buf, uint16_t sz);
+uint8_t node_lpn_mode_get(struct mesh_node *node);
+bool node_relay_mode_set(struct mesh_node *node, bool enable, uint8_t cnt,
+ uint16_t interval);
+uint8_t node_relay_mode_get(struct mesh_node *node, uint8_t *cnt,
+ uint16_t *interval);
+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);
+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);
+uint32_t node_seq_cache(struct mesh_node *node);
+void node_cleanup(struct mesh_net *net);
diff --git a/meshd/src/storage.h b/meshd/src/storage.h
new file mode 100644
index 000000000..341932dba
--- /dev/null
+++ b/meshd/src/storage.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2017-2918 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+struct mesh_net;
+
+bool storage_parse_config(struct mesh_net *net, const char *config_name);
+bool storage_save_config(struct mesh_net *net, const char *config_name,
+ bool no_wait, mesh_status_func_t cb, void *user_data);
+bool storage_save_new_config(struct mesh_net *net, const char *config_name,
+ mesh_status_func_t cb, void *user_data);
+void storage_release(struct mesh_net *net);
+
+bool storage_model_bind(struct mesh_net *net, uint16_t addr, uint32_t id,
+ uint16_t app_idx, bool unbind);
+
+bool storage_local_set_ttl(struct mesh_net *net, uint8_t ttl);
+bool storage_local_set_relay(struct mesh_net *net, bool enable, uint8_t count,
+ uint8_t interval);
+bool storage_local_set_transmit_params(struct mesh_net *net, uint8_t count,
+ uint8_t interval);
+bool storage_local_set_mode(struct mesh_net *net, uint8_t mode,
+ const char *mode_name);
+bool storage_local_net_key_add(struct mesh_net *net, uint16_t net_idx,
+ const uint8_t key[16], int phase);
+bool storage_local_net_key_del(struct mesh_net *net, uint16_t net_idx);
+bool storage_local_app_key_add(struct mesh_net *net, uint16_t net_idx,
+ uint16_t app_idx, const uint8_t key[16], bool update);
+bool storage_local_app_key_del(struct mesh_net *net, uint16_t net_idx,
+ uint16_t app_idx);
+bool storage_local_write_sequence_number(struct mesh_net *net, uint32_t seq);
+bool storage_local_set_iv_index(struct mesh_net *net, uint32_t iv_index,
+ bool update);
+bool storage_local_set_device_key(struct mesh_net *net, uint8_t dev_key[16]);
+bool storage_local_set_unicast(struct mesh_net *net, uint16_t unicast);
--
2.14.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/7] meshd: Read and write mesh configuration in JSON format
2018-04-25 14:20 [PATCH 0/7] Bluetooth Mesh Daemon Brian Gix
2018-04-25 14:20 ` [PATCH 1/7] meshd: Shared private meshd interfaces Brian Gix
2018-04-25 14:20 ` [PATCH 3/7] meshd: Header files for mesh access layer and utilities Brian Gix
@ 2018-04-25 14:20 ` Brian Gix
2018-04-25 14:20 ` [PATCH 6/7] meshd: Sample device composition in JSON fromat Brian Gix
2018-04-25 14:20 ` [PATCH 7/7] Makefile for meshd and configure.ac Brian Gix
4 siblings, 0 replies; 6+ messages in thread
From: Brian Gix @ 2018-04-25 14:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Inga Stotland
From: Inga Stotland <inga.stotland@intel.com>
This adds implementation for parsing and writing Mesh configuration
into JSON format. Alos, parse stored unprovisioned device composiotion.
---
meshd/mesh-json/mesh-db.c | 1360 +++++++++++++++++++++++++++++++++++++++++++++
meshd/mesh-json/mesh-db.h | 144 +++++
2 files changed, 1504 insertions(+)
create mode 100644 meshd/mesh-json/mesh-db.c
create mode 100644 meshd/mesh-json/mesh-db.h
diff --git a/meshd/mesh-json/mesh-db.c b/meshd/mesh-json/mesh-db.c
new file mode 100644
index 000000000..6d894a920
--- /dev/null
+++ b/meshd/mesh-json/mesh-db.c
@@ -0,0 +1,1360 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <ell/ell.h>
+
+#include "meshd/common/mesh-defs.h"
+#include "meshd/common/util.h"
+
+#include "meshd/mesh-json/mesh-db.h"
+
+#define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095))
+
+static bool get_int(json_object *jobj, const char *keyword, int *value)
+{
+ json_object *jvalue;
+
+ if (!json_object_object_get_ex(jobj, keyword, &jvalue))
+ return false;
+
+ *value = json_object_get_int(jvalue);
+ if (errno == EINVAL)
+ return false;
+
+ return true;
+}
+
+static bool add_key(json_object *jobject, const char *desc,
+ const uint8_t key[16])
+{
+ json_object *jstring;
+ char hexstr[33];
+
+ hex2str((uint8_t *) key, 16, hexstr, 33);
+ jstring = json_object_new_string(hexstr);
+ if (!jstring)
+ return false;
+
+ json_object_object_add(jobject, desc, jstring);
+ return true;
+}
+
+static json_object *get_element_model(json_object *jnode, int ele_idx,
+ uint32_t mod_id, bool vendor)
+{
+ json_object *jelements, *jelement, *jmodels;
+ int i, num_mods;
+ size_t len;
+ char buf[9];
+
+ if (!vendor)
+ snprintf(buf, 5, "%4.4x", (uint16_t)mod_id);
+ else
+ snprintf(buf, 9, "%8.8x", mod_id);
+
+ json_object_object_get_ex(jnode, "elements", &jelements);
+ if (!jelements)
+ return NULL;
+
+ jelement = json_object_array_get_idx(jelements, ele_idx);
+ if (!jelement)
+ return NULL;
+
+ json_object_object_get_ex(jelement, "models", &jmodels);
+ if (!jmodels)
+ return NULL;
+
+ num_mods = json_object_array_length(jmodels);
+ if (!num_mods)
+ return NULL;
+
+ if (!vendor) {
+ snprintf(buf, 5, "%4.4x", mod_id);
+ len = 4;
+ } else {
+ snprintf(buf, 9, "%8.8x", mod_id);
+ len = 8;
+ }
+
+ for (i = 0; i < num_mods; ++i) {
+ json_object *jmodel, *jvalue;
+ char *str;
+
+ jmodel = json_object_array_get_idx(jmodels, i);
+ json_object_object_get_ex(jmodel, "modelId", &jvalue);
+ if (!jvalue)
+ return NULL;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str)
+ return NULL;
+
+ if (!strncmp(str, buf, len))
+ return jmodel;
+ }
+
+ return NULL;
+}
+
+static bool jarray_has_string(json_object *jarray, char *str, size_t len)
+{
+ int i, sz = json_object_array_length(jarray);
+
+ for (i = 0; i < sz; ++i) {
+ json_object *jentry;
+ char *str_entry;
+
+ jentry = json_object_array_get_idx(jarray, i);
+ str_entry = (char *)json_object_get_string(jentry);
+ if (!str_entry)
+ continue;
+
+ if (!strncmp(str, str_entry, len))
+ return true;
+ }
+
+ return false;
+}
+
+static json_object *jarray_string_del(json_object *jarray, char *str,
+ size_t len)
+{
+ int i, sz = json_object_array_length(jarray);
+ json_object *jarray_new;
+
+ jarray_new = json_object_new_array();
+ if (!jarray_new)
+ return NULL;
+
+ for (i = 0; i < sz; ++i) {
+ json_object *jentry;
+ char *str_entry;
+
+ jentry = json_object_array_get_idx(jarray, i);
+ str_entry = (char *)json_object_get_string(jentry);
+ if (str_entry && !strncmp(str, str_entry, len))
+ continue;
+
+ json_object_array_add(jarray_new, jentry);
+ }
+
+ return jarray_new;
+}
+
+static json_object *get_key_object(json_object *jarray, uint16_t idx)
+{
+ int i, sz = json_object_array_length(jarray);
+
+ for (i = 0; i < sz; ++i) {
+ json_object *jentry, *jvalue;
+ uint32_t jidx;
+
+ jentry = json_object_array_get_idx(jarray, i);
+ if (!json_object_object_get_ex(jentry, "index", &jvalue))
+ return NULL;
+
+ jidx = json_object_get_int(jvalue);
+
+ if (jidx == idx)
+ return jentry;
+ }
+
+ return NULL;
+}
+
+static json_object *jarray_key_del(json_object *jarray, int16_t idx)
+{
+ json_object *jarray_new;
+ int i, sz = json_object_array_length(jarray);
+ char idx_str[5];
+
+ snprintf(idx_str, 5, "%4.4x", idx);
+
+ jarray_new = json_object_new_array();
+ if (!jarray_new)
+ return NULL;
+
+ for (i = 0; i < sz; ++i) {
+ json_object *jentry, *jvalue;
+ char *str;
+
+ jentry = json_object_array_get_idx(jarray, i);
+
+ if (json_object_object_get_ex(jentry, "index", &jvalue)) {
+ str = (char *)json_object_get_string(jvalue);
+ if (str && !strncmp(str, idx_str, 4))
+ continue;
+ }
+
+ json_object_array_add(jarray_new, jentry);
+ }
+
+ return jarray_new;
+}
+
+bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
+{
+ int tmp;
+
+ /* IV index */
+ if (!get_int(jobj, "IVindex", &tmp))
+ return false;
+
+ *idx = (uint32_t) tmp;
+
+ if (!get_int(jobj, "IVupdate", &tmp))
+ return false;
+
+ *update = tmp ? true : false;
+
+ return true;
+}
+
+bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16])
+{
+ json_object *jvalue;
+ char *str;
+
+ if (!key_buf)
+ return false;
+
+ if (!json_object_object_get_ex(jobj, "deviceKey", &jvalue) ||
+ !jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), key_buf, 16))
+ return false;
+
+ return true;
+}
+
+bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
+ void *user_data)
+{
+ json_object *jarray;
+ int len;
+ int i;
+
+ if (!cb)
+ return true;
+
+ json_object_object_get_ex(jobj, "appKeys", &jarray);
+ if (!jarray || (json_object_get_type(jarray) != json_type_array))
+ return false;
+
+ len = json_object_array_length(jarray);
+
+ for (i = 0; i < len; ++i) {
+ json_object *jtemp, *jvalue;
+ int app_idx, net_idx;
+ bool key_refresh = false;
+ char *str;
+ uint8_t key[16];
+ uint8_t new_key[16];
+
+ jtemp = json_object_array_get_idx(jarray, i);
+
+ if (!get_int(jtemp, "index", &app_idx))
+ return false;
+
+ if (!CHECK_KEY_IDX_RANGE(app_idx))
+ return false;
+
+ if (!get_int(jtemp, "boundNetKey", &net_idx))
+ return false;
+
+ if (!CHECK_KEY_IDX_RANGE(net_idx))
+ return false;
+
+ json_object_object_get_ex(jtemp, "oldKey", &jvalue);
+ if (jvalue) {
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), key, 16))
+ return false;
+ key_refresh = true;
+ }
+
+ json_object_object_get_ex(jtemp, "key", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
+ return false;
+
+ if (!cb((uint16_t)net_idx, (uint16_t) app_idx, key,
+ key_refresh ? new_key : NULL, user_data))
+ return false;
+ }
+
+ return true;
+}
+
+bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
+ void *user_data)
+{
+ json_object *jarray;
+ int len;
+ int i;
+
+ if (!cb)
+ return true;
+
+ json_object_object_get_ex(jobj, "netKeys", &jarray);
+ if (!jarray || (json_object_get_type(jarray) != json_type_array))
+ return false;
+
+ len = json_object_array_length(jarray);
+
+ for (i = 0; i < len; ++i) {
+ json_object *jtemp, *jvalue;
+ int idx;
+ char *str;
+ bool key_refresh = false;
+ int phase;
+ uint8_t key[16];
+ uint8_t new_key[16];
+
+ jtemp = json_object_array_get_idx(jarray, i);
+
+ if (!get_int(jtemp, "index", &idx))
+ return false;
+
+ if (!CHECK_KEY_IDX_RANGE(idx))
+ return false;
+
+ json_object_object_get_ex(jtemp, "oldKey", &jvalue);
+ if (jvalue) {
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), key, 16))
+ return false;
+ key_refresh = true;
+ }
+
+ json_object_object_get_ex(jtemp, "key", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
+ return false;
+
+ json_object_object_get_ex(jtemp, "keyRefresh", &jvalue);
+ if (!jvalue)
+ phase = KEY_REFRESH_PHASE_NONE;
+ else
+ phase = json_object_get_int(jvalue);
+
+
+ if (!cb((uint16_t)idx, key, key_refresh ? new_key : NULL, phase,
+ user_data))
+ return false;
+ }
+
+ return true;
+}
+
+bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
+ const uint8_t key[16], int phase)
+{
+ json_object *jarray, *jentry = NULL, *jstring;
+ char buf[5];
+
+ json_object_object_get_ex(jobj, "netKeys", &jarray);
+ if (!jarray && (phase != KEY_REFRESH_PHASE_NONE))
+ return false;
+
+ if (jarray)
+ jentry = get_key_object(jarray, idx);
+
+ /*
+ * The key entry should exist if the key is updated
+ * (i.e., Key Refresh is underway)
+ */
+ if (!jentry && (phase != KEY_REFRESH_PHASE_NONE))
+ return false;
+
+ if (jentry) {
+ uint8_t buf[16];
+ json_object *jvalue;
+ char *str;
+
+ json_object_object_get_ex(jentry, "key", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), buf, sizeof(buf)))
+ return false;
+
+ /* If the same key, return success */
+ if (memcmp(key, buf, 16) == 0)
+ return true;
+
+ return false;
+ }
+
+ if (phase == KEY_REFRESH_PHASE_NONE) {
+ jentry = json_object_new_object();
+ if (!jentry)
+ goto fail;
+
+ snprintf(buf, 5, "%4.4x", idx);
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ goto fail;
+
+ json_object_object_add(jentry, "index", jstring);
+
+ snprintf(buf, 5, "%4.4x", idx);
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ goto fail;
+
+ if (!add_key(jentry, "key", key))
+ goto fail;
+
+ if (!jarray) {
+ jarray = json_object_new_array();
+ if (!jarray)
+ goto fail;
+ json_object_object_add(jobj, "netKeys", jarray);
+ }
+
+ json_object_array_add(jarray, jentry);
+
+ } else {
+
+ if (!json_object_object_get_ex(jentry, "key", &jstring))
+ return false;
+
+ json_object_object_add(jentry, "oldKey", jstring);
+ json_object_object_del(jentry, "key");
+
+ if (!add_key(jentry, "key", key))
+ return false;
+ }
+
+
+ json_object_object_add(jentry, "keyRefresh",
+ json_object_new_int(phase));
+
+ return true;
+fail:
+
+ if (jentry)
+ json_object_put(jentry);
+
+ return false;
+}
+
+bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
+{
+ json_object *jarray, *jarray_new;
+
+ json_object_object_get_ex(jobj, "netKeys", &jarray);
+ if (!jarray)
+ return true;
+
+ /* Check if matching entry exists */
+ if (!get_key_object(jarray, idx))
+ return true;
+
+ if (json_object_array_length(jarray) == 1) {
+ json_object_object_del(jobj, "netKeys");
+ return true;
+ }
+
+ /*
+ * There is no easy way to delete a value from json array.
+ * Create a new copy without specified element and
+ * then remove old array.
+ */
+ jarray_new = jarray_key_del(jarray, idx);
+ if (!jarray_new)
+ return false;
+
+ json_object_object_del(jobj, "netKeys");
+ json_object_object_add(jobj, "netKeys", jarray_new);
+
+ return true;
+}
+
+bool mesh_db_write_device_key(json_object *jnode, uint8_t *key)
+{
+ return add_key(jnode, "deviceKey", key);
+}
+
+bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
+ const uint8_t key[16], bool update)
+{
+ json_object *jarray, *jentry = NULL, *jstring = NULL;
+ char buf[5];
+
+ json_object_object_get_ex(jobj, "appKeys", &jarray);
+ if (!jarray && update)
+ return false;
+
+ if (jarray)
+ jentry = get_key_object(jarray, app_idx);
+
+ /* The key entry should exist if the key is updated */
+ if (!jentry && update)
+ return false;
+
+ if (jentry) {
+ uint8_t buf[16];
+ json_object *jvalue;
+ char *str;
+
+ json_object_object_get_ex(jentry, "key", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), buf, sizeof(buf)))
+ return false;
+
+ /* If the same key, return success */
+ if (memcmp(key, buf, 16) == 0)
+ return true;
+
+ return false;
+ }
+
+ if (!update) {
+ jentry = json_object_new_object();
+ if (!jentry)
+ goto fail;
+
+ snprintf(buf, 5, "%4.4x", app_idx);
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ goto fail;
+
+ json_object_object_add(jentry, "index", jstring);
+
+ snprintf(buf, 5, "%4.4x", net_idx);
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ goto fail;
+
+ json_object_object_add(jentry, "boundNetKey", jstring);
+
+ if (!add_key(jentry, "key", key))
+ goto fail;
+
+ if (!jarray) {
+ jarray = json_object_new_array();
+ if (!jarray)
+ goto fail;
+ json_object_object_add(jobj, "appKeys", jarray);
+ }
+
+ json_object_array_add(jarray, jentry);
+
+ } else {
+
+ if (!json_object_object_get_ex(jentry, "key", &jstring))
+ return false;
+
+ json_object_object_add(jentry, "oldKey", jstring);
+ json_object_object_del(jentry, "key");
+
+ if (!add_key(jentry, "key", key))
+ return false;
+ }
+
+ return true;
+fail:
+
+ if (jentry)
+ json_object_put(jentry);
+
+ return false;
+}
+
+bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
+{
+ json_object *jarray, *jarray_new;
+
+ json_object_object_get_ex(jobj, "appKeys", &jarray);
+ if (!jarray)
+ return true;
+
+ /* Check if matching entry exists */
+ if (!get_key_object(jarray, idx))
+ return true;
+
+ if (json_object_array_length(jarray) == 1) {
+ json_object_object_del(jobj, "appKeys");
+ return true;
+ }
+
+ /*
+ * There is no easy way to delete a value from json array.
+ * Create a new copy without specified element and
+ * then remove old array.
+ */
+ jarray_new = jarray_key_del(jarray, idx);
+ if (!jarray_new)
+ return false;
+
+ json_object_object_del(jobj, "appKeys");
+ json_object_object_add(jobj, "appKeys", jarray_new);
+
+ return true;
+}
+
+bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
+ uint32_t mod_id, uint16_t app_idx)
+{
+ json_object *jmodel, *jstring, *jarray;
+ char buf[5];
+
+ jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+ if (!jmodel)
+ return false;
+
+ json_object_object_get_ex(jmodel, "bind", &jarray);
+
+ snprintf(buf, 5, "%4.4x", app_idx);
+
+ if (jarray && jarray_has_string(jarray, buf, 4))
+ return true;
+
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ return false;
+
+ if (!jarray) {
+ jarray = json_object_new_array();
+ if (!jarray) {
+ json_object_put(jstring);
+ return false;
+ }
+ json_object_object_add(jmodel, "bind", jarray);
+ }
+
+ json_object_array_add(jarray, jstring);
+
+ return true;
+}
+
+bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
+ uint32_t mod_id, uint16_t app_idx)
+{
+ json_object *jmodel, *jarray, *jarray_new;
+ char buf[5];
+
+ jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+ if (!jmodel)
+ return false;
+
+ json_object_object_get_ex(jmodel, "bind", &jarray);
+
+ snprintf(buf, 5, "%4.4x", app_idx);
+
+ if (!jarray || !jarray_has_string(jarray, buf, 4))
+ return true;
+
+ if (json_object_array_length(jarray) == 1) {
+ json_object_object_del(jmodel, "bind");
+ return true;
+ }
+
+ /*
+ * There is no easy way to delete a value from json array.
+ * Create a new copy without specified element and
+ * then remove old array.
+ */
+ jarray_new = jarray_string_del(jarray, buf, 4);
+ if (!jarray_new)
+ return false;
+
+ json_object_object_del(jmodel, "bind");
+ json_object_object_add(jmodel, "bind", jarray_new);
+
+ return true;
+}
+
+static void free_model(void *data)
+{
+ struct mesh_db_model *mod = data;
+
+ l_free(mod->bindings);
+ l_free(mod->subs);
+ l_free(mod->pub);
+ l_free(mod);
+}
+
+static void free_element(void *data)
+{
+ struct mesh_db_element *ele = data;
+
+ l_queue_destroy(ele->models, free_model);
+ l_free(ele);
+}
+
+static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)
+{
+ int cnt;
+ int i;
+
+ cnt = json_object_array_length(jbindings);
+ if (cnt > 0xffff)
+ return false;
+
+ mod->num_subs = cnt;
+
+ /* Allow empty bindings list */
+ if (!cnt)
+ return true;
+
+ mod->bindings = l_new(uint16_t, cnt);
+ if (!mod->bindings)
+ return false;
+
+ for (i = 0; i < cnt; ++i) {
+ int idx;
+ json_object *jvalue;
+
+ jvalue = json_object_array_get_idx(jbindings, i);
+ if (!jvalue)
+ return false;
+
+ idx = json_object_get_int(jvalue);
+ if (!CHECK_KEY_IDX_RANGE(idx))
+ return false;
+
+ mod->bindings[i] = (uint16_t) idx;
+ }
+
+ return true;
+}
+
+static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
+{
+ int i, num_models;
+
+ num_models = json_object_array_length(jmodels);
+ if (!num_models)
+ return true;
+
+ for (i = 0; i < num_models; ++i) {
+ json_object *jmodel, *jarray, *jvalue;
+ struct mesh_db_model *mod;
+ uint32_t id;
+ int len;
+ char *str;
+
+ jmodel = json_object_array_get_idx(jmodels, i);
+ if (!jmodel)
+ goto fail;
+
+ mod = l_new(struct mesh_db_model, 1);
+ if (!ele)
+ goto fail;
+
+ json_object_object_get_ex(jmodel, "modelId", &jvalue);
+ str = (char *)json_object_get_string(jvalue);
+
+ len = strlen(str);
+
+ if (len != 4 && len != 8)
+ goto fail;
+
+ if (len == 4) {
+ if (sscanf(str, "%04x", &id) != 1)
+ goto fail;
+
+ id |= VENDOR_ID_MASK;
+ } else if (len == 8) {
+ if (sscanf(str, "%08x", &id) != 1)
+ goto fail;
+ } else
+ goto fail;
+
+ mod->id = id;
+
+ if (len == 8)
+ mod->vendor = true;
+
+ json_object_object_get_ex(jmodel, "bind", &jarray);
+
+ if (jarray && (json_object_get_type(jmodels) != json_type_array
+ || !parse_bindings(jarray, mod)))
+ goto fail;
+
+ /* TODO add pub/sub */
+ l_queue_push_tail(ele->models, mod);
+ }
+
+ return true;
+
+fail:
+ l_queue_destroy(ele->models, free_model);
+ return false;
+}
+
+static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
+{
+ int i, num_ele;
+
+ num_ele = json_object_array_length(jelements);
+ if (!num_ele)
+ /* Allow "empty" nodes */
+ return true;
+
+ node->elements = l_queue_new();
+ if (!node->elements)
+ return false;
+
+ for (i = 0; i < num_ele; ++i) {
+ json_object *jelement;
+ json_object *jmodels;
+ json_object *jvalue;
+ struct mesh_db_element *ele;
+ int index;
+ char *str;
+
+ jelement = json_object_array_get_idx(jelements, i);
+ if (!jelement)
+ goto fail;
+
+ if (!get_int(jelement, "elementIndex", &index) ||
+ index > num_ele)
+ goto fail;
+
+ ele = l_new(struct mesh_db_element, 1);
+ if (!ele)
+ goto fail;
+
+ ele->index = index;
+ ele->models = l_queue_new();
+ if (!ele->models)
+ goto fail;
+
+ json_object_object_get_ex(jelement, "location", &jvalue);
+ str = (char *)json_object_get_string(jvalue);
+ if (sscanf(str, "%04hx", &(ele->location)) != 1)
+ goto fail;
+
+ json_object_object_get_ex(jelement, "models", &jmodels);
+
+ if (jmodels && (json_object_get_type(jmodels) != json_type_array
+ || !parse_models(jmodels, ele)))
+ goto fail;
+
+ l_queue_push_tail(node->elements, ele);
+ }
+
+ return true;
+
+fail:
+ l_queue_destroy(node->elements, free_element);
+ node->elements = NULL;
+
+ return false;
+}
+
+static int get_mode(json_object *jvalue)
+{
+ const char *str;
+
+ str = json_object_get_string(jvalue);
+ if (!str)
+ return 0xffffffff;
+
+ if (!strncasecmp(str, "disabled", strlen("disabled")))
+ return MESH_MODE_DISABLED;
+
+ if (!strncasecmp(str, "enabled", strlen("enabled")))
+ return MESH_MODE_ENABLED;
+
+ if (!strncasecmp(str, "unsupported", strlen("unsupported")))
+ return MESH_MODE_UNSUPPORTED;
+
+ return 0xffffffff;
+}
+
+static void parse_features(json_object *jconfig, struct mesh_db_node *node)
+{
+ json_object *jvalue, *jrelay;
+ int mode, count;
+ uint16_t interval;
+
+ json_object_object_get_ex(jconfig, "proxy", &jvalue);
+ if (jvalue) {
+ mode = get_mode(jvalue);
+ if (mode <= MESH_MODE_UNSUPPORTED)
+ node->modes.proxy = mode;
+ }
+
+ json_object_object_get_ex(jconfig, "friend", &jvalue);
+ if (jvalue) {
+ mode = get_mode(jvalue);
+ if (mode <= MESH_MODE_UNSUPPORTED)
+ node->modes.friend = mode;
+ }
+
+ json_object_object_get_ex(jconfig, "lowPower", &jvalue);
+ if (jvalue) {
+ mode = get_mode(jvalue);
+ if (mode <= MESH_MODE_UNSUPPORTED)
+ node->modes.friend = mode;
+ }
+
+ json_object_object_get_ex(jconfig, "beacon", &jvalue);
+ if (jvalue) {
+ mode = get_mode(jvalue);
+ if (mode <= MESH_MODE_ENABLED)
+ node->modes.beacon = mode;
+ }
+
+ json_object_object_get_ex(jconfig, "relay", &jrelay);
+ if (!jrelay)
+ return;
+
+ json_object_object_get_ex(jrelay, "mode", &jvalue);
+ if (jvalue) {
+ mode = get_mode(jvalue);
+ if (mode <= MESH_MODE_UNSUPPORTED)
+ node->modes.relay.state = mode;
+ else
+ return;
+ } else
+ return;
+
+ json_object_object_get_ex(jrelay, "count", &jvalue);
+ if (!jvalue)
+ return;
+
+ /* TODO: check range */
+ count = json_object_get_int(jvalue);
+ node->modes.relay.cnt = count;
+
+ json_object_object_get_ex(jrelay, "interval", &jvalue);
+ if (!jvalue)
+ return;
+
+ /* TODO: check range */
+ interval = json_object_get_int(jvalue);
+ node->modes.relay.interval = interval;
+}
+
+static bool parse_composition(json_object *jcomp, struct mesh_db_node *node)
+{
+ json_object *jvalue;
+ char *str;
+
+ /* All the fields in node composition are mandatory */
+ json_object_object_get_ex(jcomp, "cid", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (sscanf(str, "%04hx", &node->cid) != 1)
+ return false;
+
+ json_object_object_get_ex(jcomp, "pid", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (sscanf(str, "%04hx", &node->pid) != 1)
+ return false;
+
+ json_object_object_get_ex(jcomp, "vid", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (sscanf(str, "%04hx", &node->vid) != 1)
+ return false;
+
+ json_object_object_get_ex(jcomp, "crpl", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (sscanf(str, "%04hx", &node->crpl) != 1)
+ return false;
+
+ return true;
+}
+
+static uint16_t get_prov_flags(json_object *jarray, uint16_t max_value)
+{
+ int i, cnt;
+ uint16_t result = 0;
+
+ cnt = json_object_array_length(jarray);
+ if (!cnt)
+ return 0;
+
+ for (i = 0; i < cnt; ++i) {
+ json_object *jvalue;
+ int value;
+
+ jvalue = json_object_array_get_idx(jarray, i);
+ value = json_object_get_int(jvalue);
+ if (value > 16)
+ continue;
+
+ if ((1 << value) > max_value)
+ continue;
+
+ result |= (1 << value);
+ }
+
+ return result;
+}
+
+bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
+{
+ struct mesh_db_node node;
+ json_object *jvalue;
+ char *str;
+
+ if (!cb) {
+ l_info("Node read callback is required");
+ return false;
+ }
+
+ memset(&node, 0, sizeof(node));
+
+ if (!parse_composition(jnode, &node)) {
+ l_info("Failed to parse local node composition");
+ return false;
+ }
+
+ parse_features(jnode, &node);
+
+ json_object_object_get_ex(jnode, "unicastAddress", &jvalue);
+ if (!jvalue) {
+ l_info("Bad config: Unicast address must be present");
+ return false;
+ }
+
+ str = (char *)json_object_get_string(jvalue);
+ if (sscanf(str, "%04hx", &node.unicast) != 1)
+ return false;
+
+ json_object_object_get_ex(jnode, "defaultTTL", &jvalue);
+ if (jvalue) {
+ int ttl = json_object_get_int(jvalue);
+
+ if (ttl < 0 || ttl == 1 || ttl > DEFAULT_TTL)
+ return false;
+ node.ttl = (uint8_t) ttl;
+ }
+
+ json_object_object_get_ex(jnode, "sequenceNumber", &jvalue);
+ if (jvalue)
+ node.seq_number = json_object_get_int(jvalue);
+
+ json_object_object_get_ex(jnode, "elements", &jvalue);
+ if (jvalue && json_object_get_type(jvalue) == json_type_array) {
+ if (!parse_elements(jvalue, &node))
+ return false;
+ }
+
+ return cb(&node, user_data);
+}
+
+bool mesh_db_read_unprovisioned_device(json_object *jnode, mesh_db_node_cb cb,
+ void *user_data)
+{
+ struct mesh_db_node node;
+ json_object *jvalue;
+ char *str;
+
+ if (!cb) {
+ l_info("Device read callback is required");
+ return false;
+ }
+
+ memset(&node, 0, sizeof(node));
+
+ if (!parse_composition(jnode, &node)) {
+ l_info("Failed to parse local device composition");
+ return false;
+ }
+
+ parse_features(jnode, &node);
+
+ json_object_object_get_ex(jnode, "elements", &jvalue);
+ if (jvalue && json_object_get_type(jvalue) == json_type_array) {
+ if (!parse_elements(jvalue, &node))
+ return false;
+ }
+
+ json_object_object_get_ex(jnode, "UUID", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), node.uuid, 16))
+ return false;
+
+ return cb(&node, user_data);
+}
+
+bool mesh_db_read_prov_info(json_object *jnode, struct mesh_db_prov *prov)
+{
+ json_object *jprov, *jarray, *jvalue, *jobj;
+ int value;
+ char *str;
+
+ if (!prov)
+ return false;
+
+ json_object_object_get_ex(jnode, "provision", &jprov);
+ if (!jprov)
+ return false;
+
+ json_object_object_get_ex(jprov, "algorithms", &jarray);
+ if (!jarray || json_object_get_type(jarray) != json_type_array)
+ return false;
+
+ prov->algorithm = get_prov_flags(jarray, ALG_FIPS_256_ECC);
+ if (!prov->algorithm) {
+ l_info("At least one algorithm must be indicated");
+ return false;
+ }
+
+ json_object_object_get_ex(jprov, "outputOOB", &jobj);
+ json_object_object_get_ex(jobj, "size", &jvalue);
+ value = json_object_get_int(jvalue);
+ if (value > 8)
+ return false;
+
+ prov->output_oob.size = (uint8_t) value;
+ json_object_object_get_ex(jobj, "actions", &jarray);
+ if (!jarray || json_object_get_type(jarray) != json_type_array)
+ return false;
+
+ prov->output_oob.actions = get_prov_flags(jarray, OOB_OUT_ALPHA);
+
+ json_object_object_get_ex(jprov, "inputOOB", &jobj);
+ json_object_object_get_ex(jobj, "size", &jvalue);
+ value = json_object_get_int(jvalue);
+ if (value > 8)
+ return false;
+
+ prov->input_oob.size = (uint8_t) value;
+ json_object_object_get_ex(jobj, "actions", &jarray);
+ if (!jarray || json_object_get_type(jarray) != json_type_array)
+ return false;
+
+ prov->input_oob.actions = get_prov_flags(jarray, OOB_IN_ALPHA);
+
+ json_object_object_get_ex(jprov, "publicType", &jvalue);
+ prov->pub_type = (json_object_get_boolean(jvalue)) ? 1 : 0;
+
+ json_object_object_get_ex(jprov, "staticType", &jvalue);
+ prov->static_type = (json_object_get_boolean(jvalue)) ? 1 : 0;
+
+ json_object_object_get_ex(jprov, "privateKey", &jvalue);
+ if (!jvalue)
+ return false;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (!str2hex(str, strlen(str), prov->priv_key, 32))
+ return false;
+
+ return true;
+}
+
+bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
+ uint16_t value)
+{
+ json_object *jstring;
+ char buf[5];
+
+ snprintf(buf, 5, "%4.4x", value);
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ return false;
+
+ json_object_object_add(jobj, desc, jstring);
+ return true;
+}
+
+bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
+{
+ json_object *jvalue;
+
+ json_object_object_del(jobj, keyword);
+
+ jvalue = json_object_new_int(value);
+ if (!jvalue)
+ return false;
+
+ json_object_object_add(jobj, keyword, jvalue);
+ return true;
+}
+
+bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value)
+{
+ json_object *jvalue;
+
+ json_object_object_del(jobj, keyword);
+
+ jvalue = json_object_new_boolean(value);
+ if (!jvalue)
+ return false;
+
+ json_object_object_add(jobj, keyword, jvalue);
+ return true;
+}
+
+bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
+{
+ json_object *jstring;
+
+ switch (value) {
+ case MESH_MODE_DISABLED:
+ jstring = json_object_new_string("disabled");
+ break;
+ case MESH_MODE_ENABLED:
+ jstring = json_object_new_string("enabled");
+ break;
+ case MESH_MODE_UNSUPPORTED:
+ jstring = json_object_new_string("unsupported");
+ break;
+ default:
+ return false;
+ };
+
+ if (!jstring)
+ return false;
+
+ json_object_object_add(jobj, keyword, jstring);
+
+ return true;
+}
+
+bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
+ uint16_t interval)
+{
+ json_object *jrelay;
+
+ json_object_object_del(jnode, "relay");
+
+ jrelay = json_object_new_object();
+ if (jrelay)
+ return false;
+
+ if (!mesh_db_write_mode(jrelay, "mode", mode))
+ goto fail;
+
+ if (!mesh_db_write_int(jrelay, "count", count))
+ goto fail;
+
+ if (!mesh_db_write_int(jrelay, "interval", interval))
+ goto fail;
+
+ json_object_object_add(jnode, "relay", jrelay);
+
+ return true;
+fail:
+ json_object_put(jrelay);
+ return false;
+}
+
+bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
+ uint16_t *interval)
+{
+ json_object *jretransmit, *jvalue;
+
+ json_object_object_get_ex(jobj, "retransmit", &jretransmit);
+ if (!jretransmit)
+ return false;
+
+ json_object_object_get_ex(jretransmit, "count", &jvalue);
+ if (!jvalue)
+ return false;
+
+ *cnt = (uint8_t) json_object_get_int(jvalue);
+
+ json_object_object_get_ex(jretransmit, "interval", &jvalue);
+ if (!jvalue)
+ return false;
+
+ *interval = (uint16_t) json_object_get_int(jvalue);
+
+ return true;
+}
+
+bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
+ uint16_t interval)
+{
+ json_object *jretransmit;
+
+ json_object_object_del(jobj, "retransmit");
+
+ jretransmit = json_object_new_object();
+ if (jretransmit)
+ return false;
+
+ if (!mesh_db_write_int(jretransmit, "count", cnt))
+ goto fail;
+
+ if (!mesh_db_write_int(jretransmit, "interval", interval))
+ goto fail;
+
+ json_object_object_add(jobj, "retransmit", jretransmit);
+
+ return true;
+fail:
+ json_object_put(jretransmit);
+ return false;
+
+}
+
+bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
+{
+ int tmp = update ? 1 : 0;
+
+ if (!mesh_db_write_int(jobj, "IVindex", idx))
+ return false;
+
+ if (!mesh_db_write_int(jobj, "IVupdate", tmp))
+ return false;
+
+ return true;
+}
+
+void mesh_db_remove_property(json_object *jobj, const char *desc)
+{
+ json_object_object_del(jobj, desc);
+}
diff --git a/meshd/mesh-json/mesh-db.h b/meshd/mesh-json/mesh-db.h
new file mode 100644
index 000000000..336302f28
--- /dev/null
+++ b/meshd/mesh-json/mesh-db.h
@@ -0,0 +1,144 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ *
+ */
+
+#include <json-c/json.h>
+
+struct mesh_db_sub {
+ bool virt;
+ union {
+ uint16_t addr;
+ uint8_t virt_addr[16];
+ } src;
+};
+
+struct mesh_db_pub {
+ bool virt;
+ uint16_t addr;
+ uint16_t idx;
+ uint8_t ttl;
+ uint8_t credential;
+ uint8_t period;
+ uint8_t retransmit;
+ uint8_t virt_addr[16];
+};
+
+struct mesh_db_model {
+ struct mesh_db_sub *subs;
+ struct mesh_db_pub *pub;
+ uint16_t *bindings;
+ uint32_t id;
+ bool vendor;
+ uint32_t num_bindings;
+ uint32_t num_subs;
+};
+
+struct mesh_db_element {
+ struct l_queue *models;
+ uint16_t location;
+ uint8_t index;
+};
+
+struct mesh_db_modes {
+ struct {
+ uint16_t interval;
+ uint8_t cnt;
+ uint8_t state;
+ } relay;
+ uint8_t lpn;
+ uint8_t friend;
+ uint8_t proxy;
+ uint8_t beacon;
+};
+
+struct mesh_db_node {
+ bool provisioner;
+ uint32_t seq_number;
+ struct mesh_db_modes modes;
+ uint16_t cid;
+ uint16_t pid;
+ uint16_t vid;
+ uint16_t crpl;
+ uint16_t unicast;
+ uint8_t ttl;
+ struct l_queue *elements;
+ uint8_t uuid[16];
+};
+
+struct mesh_db_prov {
+ uint16_t algorithm;
+ struct {
+ uint16_t actions;
+ uint8_t size;
+ } input_oob;
+ uint8_t pub_type;
+ struct {
+ uint16_t actions;
+ uint8_t size;
+ } output_oob;
+ uint8_t static_type;
+ uint8_t priv_key[32];
+};
+
+typedef bool (*mesh_db_net_key_cb)(uint16_t idx, uint8_t key[16],
+ uint8_t new_key[16], int phase, void *user_data);
+typedef bool (*mesh_db_app_key_cb)(uint16_t idx, uint16_t net_idx,
+ uint8_t key[16], uint8_t new_key[16], void *user_data);
+typedef bool (*mesh_db_node_cb)(struct mesh_db_node *node, void *user_data);
+
+bool mesh_db_read_node(json_object *jobj, mesh_db_node_cb cb, void *user_data);
+bool mesh_db_read_unprovisioned_device(json_object *jnode, mesh_db_node_cb cb,
+ void *user_data);
+bool mesh_db_read_prov_info(json_object *jnode, struct mesh_db_prov *prov);
+bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update);
+bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16]);
+bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
+ uint16_t *interval);
+bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
+ uint16_t interval);
+bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
+ void *user_data);
+bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
+ void *user_data);
+bool mesh_db_write_device_key(json_object *jobj, uint8_t *key);
+bool mesh_db_write_network_key(json_object *jobj, uint16_t idx, uint8_t *key,
+ uint8_t *new_key, int phase);
+bool mesh_db_write_app_key(json_object *jobj, uint16_t net_idx,
+ uint16_t app_idx, uint8_t *key, uint8_t *new_key);
+bool mesh_db_write_int(json_object *jobj, const char *keyword, int value);
+bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
+ uint16_t value);
+bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value);
+bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
+ uint16_t interval);
+bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value);
+bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
+ uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
+ uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_app_key_add(json_object *jnode, uint16_t net_idx, uint16_t app_idx,
+ const uint8_t key[16], bool update);
+bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
+bool mesh_db_net_key_add(json_object *jobj, uint16_t net_idx,
+ const uint8_t key[16], int phase);
+bool mesh_db_net_key_del(json_object *jobj, uint16_t net_idx);
+bool mesh_db_write_kr_phase(json_object *jobj, uint16_t net_idx, int phase);
+bool mesh_db_write_address(json_object *jobj, uint16_t address);
+bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update);
+void mesh_db_remove_property(json_object *jobj, const char *desc);
--
2.14.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6/7] meshd: Sample device composition in JSON fromat
2018-04-25 14:20 [PATCH 0/7] Bluetooth Mesh Daemon Brian Gix
` (2 preceding siblings ...)
2018-04-25 14:20 ` [PATCH 5/7] meshd: Read and write mesh configuration in JSON format Brian Gix
@ 2018-04-25 14:20 ` Brian Gix
2018-04-25 14:20 ` [PATCH 7/7] Makefile for meshd and configure.ac Brian Gix
4 siblings, 0 replies; 6+ messages in thread
From: Brian Gix @ 2018-04-25 14:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Inga Stotland
From: Inga Stotland <inga.stotland@intel.com>
This is a sample unprovisioned device composition described
in JSON format.
---
meshd/config/composition.json | 44 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 meshd/config/composition.json
diff --git a/meshd/config/composition.json b/meshd/config/composition.json
new file mode 100644
index 000000000..20c0d0c3a
--- /dev/null
+++ b/meshd/config/composition.json
@@ -0,0 +1,44 @@
+{
+ "$schema":"file:\/\/\/BlueZ\/MeshD\/local_schema\/mesh.jsonschema",
+ "meshName":"BT Mesh sample node",
+ "UUID":"E0ED0F0200000000203C100200000000",
+ "cid":"0002",
+ "pid":"0010",
+ "vid":"0001",
+ "crpl":"000a",
+ "proxy":"unsupported",
+ "friend":"disabled",
+ "lowPower":"disabled",
+ "relay":{
+ "mode":"enabled"
+ },
+ "elements":[
+ {
+ "elementIndex":0,
+ "location":"0001",
+ "models":[
+ {
+ "modelId":"0000"
+ },
+ {
+ "modelId":"1001"
+ }
+ ]
+ }
+ ],
+ "provision": {
+ "privateKey": "729aa0670d72cd6497502ed473502b037e8803b5c60829a5a3caa219505530ba",
+ "algorithms": [ 0 ],
+ "inputOOB": {
+ "size": 8,
+ "actions": [ 2, 3]
+ },
+ "outputOOB": {
+ "size": 8,
+ "actions": [ 3, 4]
+ },
+ "publicType": false,
+ "staticType": false
+ },
+ }
+}
--
2.14.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 7/7] Makefile for meshd and configure.ac
2018-04-25 14:20 [PATCH 0/7] Bluetooth Mesh Daemon Brian Gix
` (3 preceding siblings ...)
2018-04-25 14:20 ` [PATCH 6/7] meshd: Sample device composition in JSON fromat Brian Gix
@ 2018-04-25 14:20 ` Brian Gix
4 siblings, 0 replies; 6+ messages in thread
From: Brian Gix @ 2018-04-25 14:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Inga Stotland
From: Inga Stotland <inga.stotland@intel.com>
---
Makefile.am | 1 +
Makefile.meshd | 44 ++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 2 +-
3 files changed, 46 insertions(+), 1 deletion(-)
create mode 100644 Makefile.meshd
diff --git a/Makefile.am b/Makefile.am
index daf34b6ca..2a96fa1d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -225,6 +225,7 @@ unit_tests =
include Makefile.tools
include Makefile.obexd
include android/Makefile.am
+include Makefile.meshd
if HID2HCI
rulesdir = @UDEV_DIR@/rules.d
diff --git a/Makefile.meshd b/Makefile.meshd
new file mode 100644
index 000000000..4a9d45a12
--- /dev/null
+++ b/Makefile.meshd
@@ -0,0 +1,44 @@
+if MESH
+mesh_json_sources = meshd/mesh-json/mesh-db.h meshd/mesh-json/mesh-db.c
+mesh_common_sources = meshd/common/mesh-defs.h \
+ meshd/common/util.h meshd/common/util.c
+
+meshd_sources = $(mesh_common_sources) $(mesh_json_sources) \
+ meshd/src/mesh.h meshd/src/mesh.c \
+ meshd/src/mesh-io.h meshd/src/mesh-io.c \
+ meshd/src/mesh-io-api.h meshd/src/bt.h \
+ meshd/src/mesh-io-generic.h \
+ meshd/src/mesh-io-generic.c \
+ meshd/src/hci.h meshd/src/hci.c \
+ meshd/src/storage.h meshd/src/storage.c \
+ meshd/src/net.h meshd/src/net.c \
+ meshd/src/display.h meshd/src/display.c \
+ meshd/src/crypto.h meshd/src/crypto.c \
+ meshd/src/friend.h meshd/src/friend.c \
+ meshd/src/appkeys.h meshd/src/appkey.c \
+ meshd/src/node.h meshd/src/node.c \
+ meshd/src/prov.h meshd/src/prov.c \
+ meshd/src/provision.h meshd/src/provision.c \
+ meshd/src/model.h meshd/src/model.c \
+ meshd/src/cfgmod.h meshd/src/cfgmod-server.c
+
+libexec_PROGRAMS += meshd/src/meshd
+
+meshd_src_meshd_SOURCES = $(meshd_sources) \
+ meshd/src/main.c
+
+meshd_src_meshd_LDADD = /usr/lib64/libell.la src/shared/ecc.lo \
+ @DBUS_LIBS@ -lell -ljson-c -ldl
+
+noinst_PROGRAMS += meshd/src/btmesh
+
+meshd_src_btmesh_SOURCES = $(meshd_sources) \
+ meshd/common/agent.h \
+ meshd/common/agent.c \
+ meshd/src/btmesh.c
+
+meshd_src_btmesh_LDADD = /usr/lib64/libell.la src/shared/ecc.lo \
+ src/libshared-mainloop.la \
+ -lreadline -lell -ljson-c -ldl
+
+endif
diff --git a/configure.ac b/configure.ac
index 5132131f2..f6259c0fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -248,7 +248,7 @@ AC_ARG_ENABLE(btpclient, AC_HELP_STRING([--enable-btpclient],
[enable BTP client]), [enable_btpclient=${enableval}])
AM_CONDITIONAL(BTPCLIENT, test "${enable_btpclient}" = "yes")
-if (test "${enable_btpclient}" = "yes"); then
+if (test "${enable_btpclient}" = "yes" || test "${enable_mesh}" == "yes"); then
PKG_CHECK_MODULES(ELL, ell >= 0.3, dummy=yes,
AC_MSG_ERROR(ell library >= 0.3 is required))
AC_SUBST(ELL_CFLAGS)
--
2.14.3
^ permalink raw reply related [flat|nested] 6+ messages in thread