All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Bluetooth Mesh Daemon
@ 2018-04-25 14:20 Brian Gix
  2018-04-25 14:20 ` [PATCH 1/7] meshd: Shared private meshd interfaces Brian Gix
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Brian Gix @ 2018-04-25 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Brian Gix

This is our starting point for creating a stand-alone Mesh Daemon.

The Mesh Daemon (meshd) is intended to eventually co-exist beside the
Bluetooth Daemon (bluetoothd), and either daemon may exist without the
other. The Mesh Daemon will need full control/ownership of a
BT Controller that supports at least Core Spec revision 4.0 or
greater.  It works strictly over the Advertising bearer, but we
have plans to extend it to support Mesh Proxy Server over GATT, at
which point it will require support from bluetoothd.

The current meshd, and it's companion Non-Background Command-line
version btmesh, exists fully within user-space, but requires an
HCI_USER socket to the kernel controler, and currently requires root
privledges.

This first revision is intended to operate as a standard
(non-provisioner) node.  It includes the Configuration Server model,
and if it cannot find it's Mesh Configuration, will look for it's
Composition data, and start up as unprovisioned, and accept an
incoming PB-ADV provisioning session.

Two of us (Inga and Brian) have been working on this, and will be
the initial supporters and maintainers, and we gladly invite other
interested parties to participate.

Brian Gix (2):
  meshd: Shared private meshd interfaces
  meshd: Upper Transport on down Implementation

Inga Stotland (5):
  meshd: Header files for mesh access layer and utilities
  meshd: Source files for mesh access layer and utilities
  meshd: Read and write mesh configuration in JSON format
  meshd: Sample device composition in JSON fromat
  Makefile for meshd and configure.ac

 Makefile.am                   |    1 +
 Makefile.meshd                |   44 +
 configure.ac                  |    2 +-
 meshd/common/agent.c          |  229 +++
 meshd/common/agent.h          |   42 +
 meshd/common/mesh-defs.h      |   84 +
 meshd/common/util.c           |   71 +
 meshd/common/util.h           |   25 +
 meshd/config/composition.json |   44 +
 meshd/mesh-json/mesh-db.c     | 1360 +++++++++++++
 meshd/mesh-json/mesh-db.h     |  144 ++
 meshd/src/appkey.c            |  538 ++++++
 meshd/src/appkey.h            |   43 +
 meshd/src/btmesh.c            |  176 ++
 meshd/src/cfgmod-server.c     | 1194 ++++++++++++
 meshd/src/cfgmod.h            |   98 +
 meshd/src/crypto.c            | 1607 ++++++++++++++++
 meshd/src/crypto.h            |  164 ++
 meshd/src/display.c           |   67 +
 meshd/src/display.h           |   29 +
 meshd/src/friend.c            | 1116 +++++++++++
 meshd/src/friend.h            |   57 +
 meshd/src/hci.c               |  699 +++++++
 meshd/src/hci.h               |   56 +
 meshd/src/main.c              |  174 ++
 meshd/src/mesh-io-api.h       |   58 +
 meshd/src/mesh-io-generic.c   |  660 +++++++
 meshd/src/mesh-io-generic.h   |   20 +
 meshd/src/mesh-io.c           |  187 ++
 meshd/src/mesh-io.h           |   99 +
 meshd/src/mesh.c              |  184 ++
 meshd/src/mesh.h              |   32 +
 meshd/src/model.c             | 1274 +++++++++++++
 meshd/src/model.h             |  146 ++
 meshd/src/net.c               | 4188 +++++++++++++++++++++++++++++++++++++++++
 meshd/src/net.h               |  392 ++++
 meshd/src/node.c              |  851 +++++++++
 meshd/src/node.h              |   80 +
 meshd/src/prov.c              |  722 +++++++
 meshd/src/prov.h              |  162 ++
 meshd/src/provision.c         | 1159 ++++++++++++
 meshd/src/provision.h         |   30 +
 meshd/src/storage.c           |  673 +++++++
 meshd/src/storage.h           |   51 +
 44 files changed, 19031 insertions(+), 1 deletion(-)
 create mode 100644 Makefile.meshd
 create mode 100644 meshd/common/agent.c
 create mode 100644 meshd/common/agent.h
 create mode 100644 meshd/common/mesh-defs.h
 create mode 100644 meshd/common/util.c
 create mode 100644 meshd/common/util.h
 create mode 100644 meshd/config/composition.json
 create mode 100644 meshd/mesh-json/mesh-db.c
 create mode 100644 meshd/mesh-json/mesh-db.h
 create mode 100644 meshd/src/appkey.c
 create mode 100644 meshd/src/appkey.h
 create mode 100644 meshd/src/btmesh.c
 create mode 100644 meshd/src/cfgmod-server.c
 create mode 100644 meshd/src/cfgmod.h
 create mode 100644 meshd/src/crypto.c
 create mode 100644 meshd/src/crypto.h
 create mode 100644 meshd/src/display.c
 create mode 100644 meshd/src/display.h
 create mode 100644 meshd/src/friend.c
 create mode 100644 meshd/src/friend.h
 create mode 100644 meshd/src/hci.c
 create mode 100644 meshd/src/hci.h
 create mode 100644 meshd/src/main.c
 create mode 100644 meshd/src/mesh-io-api.h
 create mode 100644 meshd/src/mesh-io-generic.c
 create mode 100644 meshd/src/mesh-io-generic.h
 create mode 100644 meshd/src/mesh-io.c
 create mode 100644 meshd/src/mesh-io.h
 create mode 100644 meshd/src/mesh.c
 create mode 100644 meshd/src/mesh.h
 create mode 100644 meshd/src/model.c
 create mode 100644 meshd/src/model.h
 create mode 100644 meshd/src/net.c
 create mode 100644 meshd/src/net.h
 create mode 100644 meshd/src/node.c
 create mode 100644 meshd/src/node.h
 create mode 100644 meshd/src/prov.c
 create mode 100644 meshd/src/prov.h
 create mode 100644 meshd/src/provision.c
 create mode 100644 meshd/src/provision.h
 create mode 100644 meshd/src/storage.c
 create mode 100644 meshd/src/storage.h

-- 
2.14.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [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

end of thread, other threads:[~2018-04-25 14:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 5/7] meshd: Read and write mesh configuration in JSON format 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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.