Mesh: Implement Mesh CAPI 50/238850/1
authorAnupam Roy <anupam.r@samsung.com>
Sun, 28 Jun 2020 14:00:50 +0000 (19:30 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Sun, 19 Jul 2020 13:21:53 +0000 (18:51 +0530)
This patch primarily handles following
- Create Local node & its elements & models
- Create & configure Local Provisioner Network
- Scan & Provision device
- Configure Keys in local Network
- Configure provisioned nodes
- Create & configure Mesh Groups
- Configure Keys in provisioned nodes

TODO:
- Events from mesh service
- Node Reset functionality

Change-Id: I4ccc70a5a904da1e8e2ba62425230b5a87a931b7
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
AUTHORS
CMakeLists.txt
include/bluetooth_internal.h
include/bluetooth_private.h
include/bluetooth_type_internal.h
src/bluetooth-common.c
src/bluetooth-mesh.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index 46d1687..2b5c658 100755 (executable)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
 Jinmin Jung <jinmin@samsung.com>
 DoHyun Pyun <dh79.pyun@samsung.com>
+Anupam Roy <anupam.r@samsung.com>
index 8318ff5..61f17c7 100644 (file)
@@ -51,6 +51,7 @@ src/bluetooth-proximity.c
 src/bluetooth-tds.c
 src/bluetooth-otp.c
 src/bluetooth-hrp.c
+src/bluetooth-mesh.c
 )
 
 LIST(APPEND SOURCES src/bluetooth-proximity.c)
index 5eff9aa..1d87d29 100644 (file)
@@ -4292,6 +4292,896 @@ int bt_gatt_enable_data_batching(const char *remote_address, int packet_threshol
  */
 int bt_gatt_disable_data_batching(const char *remote_address);
 
+/* Mesh API */
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Initializes the Mesh API
+ *
+ * @remarks This function must be called before starting use BT Mesh API's.
+ * You must free all resources of the BT Mesh service by
+ * calling bt_mesh_deinitialize()
+ * if Mesh service is no longer needed.
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_initialize(void);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Must be called if BT Mesh service is no longer needed
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_deinitialize(void);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief API to create a arbitrary node.
+ * Primary element is mandatory element for any node
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_create(bt_mesh_node_features_s *features,
+               bt_mesh_node_h *node_handle);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Destroys the locally created mesh node
+ * & all resources contained in it
+ *
+ * @remarks: It is not allowed to arbitrarily destroy a locally created node,
+ * if it is part of a mesh network already.
+ * @remarks: Destroying a remote node is not supported.
+ * @remarks: In order to reset a remote provisioned node, use bt_mesh_node_reset() API
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_destroy(bt_mesh_node_h node_handle);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief API to create a mesh element. In case of Mesh Provisioner,
+ * it will serve as a element of the local node  of a Mesh Provisioner.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_create_element(bt_mesh_node_h node_handle,
+               bt_mesh_element_h *element_handle);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Destroys the locally created mesh element &
+ * all resources contained in it (Ex: models)
+ *
+ * @remarks: It is not allowed to arbitrarily destroy a
+ * locally created element, if it is part of a mesh network already.
+ * @remarks: Destroying element of a remote node is not supported.
+ * @remarks: In order to reset a remote provisioned node,
+ * use bt_mesh_node_reset() API
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_element_destroy(bt_mesh_element_h element_handle);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief API to create a mesh Model instance.
+ * In case of Mesh Provisioner, it will serve as a
+ * Model of one of the elements of the local node of a Mesh Provisioner.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_element_create_model(bt_mesh_element_h element_handle,
+               bt_mesh_model_id_s *model_id,
+                               bt_mesh_model_h *model_handle);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Destroys the locally created mesh Model
+ *
+ * @remarks: It is not allowed to arbitrarily destroy a locally created model,
+ * if it is part of a mesh network already.
+ * @remarks: Destroying model of a remote element is not supported.
+ * @remarks: In order to reset a remote provisioned node,
+ * use bt_mesh_node_reset() API
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_destroy(bt_mesh_model_h model);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief API to get Model ID from handle.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_get_id(bt_mesh_model_h model,
+               bt_mesh_model_id_s *model_id);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get Network instance in which node is contained.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_get_network(bt_mesh_node_h node,
+               bt_mesh_network_h *netkwork);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get node instance in which element is contained.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_element_get_node(bt_mesh_element_h element,
+               bt_mesh_node_h *node);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get element instance in which model is contained.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_get_element(bt_mesh_model_h model,
+               bt_mesh_element_h *element);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get Network instance in which node is contained.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_appkey_get_netkey(bt_mesh_appkey_h appkey,
+               bt_mesh_netkey_h *netkey);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to create a fresh Local Mesh Provisioner.
+ * Each Mesh Network will be characterisized
+ * by only one Mesh Provisioner. Mesh Provisioner will
+ * contain a Mesh Node which be called "local node".
+ * CAPI user(application) can create multiple Mesh Network.
+ * Each network will have a unique Mesh Provisioner
+ *
+ * @param: in: config_client, local Mesh Provisioner node
+ * @param: in: network_name, Mesh Network user friendly Name
+ * @param: out: token, The token parameter is a hexadecimal string
+ * of 8 bytes has been assigned to
+ * the application when it first got provisioned/joined mesh.
+ * order to authenticate itself and attach to the network as a mesh node.
+ * @param: out: network, created Mesh Network instance
+ *
+ * Note: Once the Mesh Network is successfully created
+ * OR the 'local Node' is attached, it is *NOT* allowed to
+ * change Local Node Hierarchy (Add/Delete Element(s), Add/Delete Model(s) etc.)
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_create(bt_mesh_node_h config_client,
+               const char *network_name,
+                       bt_mesh_network_h *network,
+                               char **token);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to load a previously created Local Mesh Provisioner.
+ * Each Mesh Network will be characterisized
+ * by only one Mesh Provisioner. Mesh Provisioner will contain a
+ * Mesh Config Node which be called "local node".
+ * CAPI user(application) can create multiple Mesh Network.
+ * Each network will have a unique Mesh Provisioner
+ *
+ * @param: in: token, The token parameter is a 8 byte hexadecimal
+ * string that has been assigned to the application when it first
+ * got provisioned/joined mesh. The API will use the token to
+ * authenticate itself and attach to the network as a mesh node.
+ * Application should use a valid token to authenticate itself
+ * as a Mesh Network Provisioner.
+ * @param: out: network, created Mesh Network instance
+ *
+ * Note: Once the Mesh Network is successfully created OR the
+ * 'local Node' is attached,
+ * it is *NOT* allowed to change Local Node Hierarchy
+ * (Add/Delete Element(s), Add/Delete Model(s) etc.)
+ *
+ * @see bt_mesh_network_create
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_load(const char *token,
+               bt_mesh_network_h *network);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Set Mesh Network's user fiendly name.
+ *
+ * @see bt_mesh_network_create
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_set_name(bt_mesh_network_h network,
+               const char *network_name);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get Mesh Network's user fiendly name.
+ *
+ * @see bt_mesh_network_create
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_get_name(bt_mesh_network_h network,
+               char **network_name);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to create and associate a mesh Network Key to Mesh Network
+ *
+ * @see bt_mesh_network_create
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_add_netkey(bt_mesh_network_h network,
+               bt_mesh_netkey_h *netkey);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get all NetKey(s) attached to the Local Network.
+ *
+ * @see bt_mesh_network_create
+ * @see bt_mesh_network_add_netkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_foreach_netkeys(bt_mesh_network_h network,
+               bt_mesh_network_netkey_info_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get global Netkey index from NetKey instance
+ *
+ * @see bt_mesh_network_add_netkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_netkey_get_index(bt_mesh_netkey_h netkey,
+               uint16_t *index);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to update a mesh Network Key.
+ *
+ * @see bt_mesh_network_add_netkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_netkey_update(bt_mesh_netkey_h netkey);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to delete a mesh Network Key.
+ *
+ * @remarks It is not allowed to destroy a netkey if it is already
+ * added to any of nodes in the Mesh Network
+ *
+ * @see bt_mesh_network_add_netkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_netkey_delete(bt_mesh_netkey_h netkey);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to create & associate a Application Key to a Network Key
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_netkey_add_appkey(bt_mesh_netkey_h netkey,
+               bt_mesh_appkey_h *appkey);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get all appkeys associated with a NetKey.
+ *
+ * @see bt_mesh_netkey_add_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_netkey_foreach_appkeys(bt_mesh_netkey_h netkey,
+               bt_mesh_appkey_info_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Get global AppKey index from AppKey instance.
+ *
+ * @see bt_mesh_netkey_add_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_appkey_get_index(bt_mesh_appkey_h netkey,
+               uint16_t *index);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to update a mesh Network Key.
+ *
+ * @see bt_mesh_netkey_add_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_appkey_update(bt_mesh_appkey_h appkey);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to delete a mesh Application Key.
+ *
+ * @remarks It is not allowed to destroy an AppKey if it is already
+ * added to any of nodes in the Mesh Network
+ *
+ * @see bt_mesh_netkey_add_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_appkey_delete(bt_mesh_appkey_h appkey);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to get all devices attached to the network.
+ * Node handle along with its primary unicast address will be returned
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_foreach_devices(bt_mesh_network_h network,
+               bt_mesh_network_device_info_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Call to get primary unicast address of the node from its handle
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_get_primary_address(bt_mesh_node_h node,
+               uint16_t *primary_address);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Find each element present in a node
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_foreach_element(bt_mesh_node_h node,
+               bt_mesh_node_element_info_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Find each models present in an element
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_element_foreach_models(bt_mesh_element_h element,
+               bt_mesh_element_model_info_cb callback,
+                       void *user_data);
+
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to discover unprovisioned device.
+ * Each unprovisioned device will advertise itself with a unique Device UUID
+ *
+ * @remarks scan result will be NULL when scan state is started or finished.
+ * scan result is valid only when scan state is 'device found'
+ *
+ * @see bt_mesh_scanning_state_e
+ * @see bt_mesh_network_scan_unprovisioned_device_result_cb
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_unprovisioned_device_scan(bt_mesh_network_h network,
+               bt_mesh_scan_params_s *scan_params,
+                       bt_mesh_network_scan_unprovisioned_device_result_cb callback,
+                               void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Stop discovring unprovisioned device.
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_stop_unprovisioned_device_scan(bt_mesh_network_h network);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Set capabilities of a provisioner application.
+ * Provisioning capabilities will as per Input/Output capabilities of the
+ * device/application creating the provisioner.
+ * For e.g, if device/application has Wi-Fi/NFC connectivity and can
+ * procure Provisioning keys Out-Of-Band over Wi-Fi network/Remote Web URL/NFC Connectivity,
+ * then following capabilities can be set to true, otherwise left false
+ *     a/ bool public_oob b/ bool static_oob
+ * Above capabilities indicate whether, Public Key for ECC exchange & Static Key for
+ * authentication can be procured out-of-band or not
+ *
+ * @param: in: network Mesh network instance which represents a provisioner node
+ * @param: in: capabilities Provisioner capabilities structure
+ *
+ * @remarks: A single provisioner network can provision multiple remote devices.
+ * During security provisioning, capabilities are selected  *By Provisioner*
+ * based on combination of supported capabilities of provisioner & remote nodes together.
+ *
+ * @remarks: A mesh network instance represents a single Mesh provisioning node
+ * & multiple remote provisioned nodes.
+ * Therefore, setting capabilities one time, for a network or a provisioner node is sufficient.
+ * Normally, Input/output capabilities do not change over time for a device
+ * or an application. Incase, it is changed, application is free to refresh the
+ * capabilities of the Provisioner at any point of time.
+ * The next provisioning process will automatically consider the refreshed capabilities.
+ * @remarks: Capabilities can be set one time after local provisioner node is attached to a network.
+ *
+ * @see: bt_mesh_provisioner_capabilities_s structure
+ * @see: bt_mesh_network_create()
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_set_provisioning_capabilities(
+               bt_mesh_network_h network,
+                       bt_mesh_provisioner_capabilities_s *capabilities);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to provision a device to the Mesh Network
+ *
+ * @remarks: In Tizen, only one provisioning process is allowed,
+ * irrespective of Provisioner or node role.
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_provision_device(bt_mesh_network_h network,
+               const char *dev_uuid,
+                       bt_mesh_network_device_provision_cb callback,
+                               void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Registers a callback that will be invoked when remote
+ * device requests authentication, during the provisioning process.
+ *
+ * @pre Either bt_mesh_network_provision_device() in case of Provisioner role
+ * or bt_mesh_node_network_join() in case of Node role must be
+ * called (Node role API is not defined yet)
+ *
+ * @param[in] callback  callback function which is set, for receiving
+ * authentication request during provisioning process.
+ * @param[in] user_data data from application which will be provided in callback.
+ *
+ * @remarks: This method is designed common for both Provisioner & Node role.
+ * @remarks: This callback is not invoked without the local device initiating the process
+ * of either Provisioning(in case of local provisioner) or
+ * Joining Network(in case of local node role).
+ * Therefore, application will be completely aware, when the callback is invoked.
+ * @remarks: In Tizen, only one provisioning process is allowed, irrespective of Provisioner or node role.
+ * Therefore, when the callback is invoked, aplication exactly knows following
+ *   a/ whether the process is for provisioner role trying to provision a remote device
+ *   b/ Or process if for local node role, which is inviting remote provisioners
+ * to join itself to a Mesh Network
+ *
+ * @see bt_network_provision_device()
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_authentication_set_request_cb(
+               bt_mesh_authentication_request_cb callback,
+                       void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Un-registers a callback that will be invoked when
+ * remote device requests authentication,during the provisioning process
+ *
+ * @param[in] callback  callback function to be set when
+ * authentication request is received.
+ *
+ * @remarks: This method is designed common for both Provisioner & Node role.
+ * @see bt_mesh_authentication_set_request_cb()
+ * @see bt_mesh_authentication_request_cb()
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_authentication_unset_request_cb(
+               bt_mesh_authentication_request_cb callback);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  API to reply authentication request.
+ * @remarks  This function can be called by application when remote
+ * device requests authentication due to either of following process
+ * a/ Local provisioner role trying to provision a remote device
+ * b/ Local node role, inviting remote provisioners to join itself to a Mesh Network
+ * @param[in]  auth_type   Specific authentiation type, for which reply is being sent
+ * @param[in]  value       Reply string corresponding to authentication type
+ * @param[in]  auth_reply  Accept or cancel ongoing provisioning process
+ * @pre  This function can only be called when application receieves authentication
+ *       callback bt_mesh_authentication_request_cb
+ * @remarks: value string is valid, when autnetication type is of following
+ *          a/ BT_MESH_AUTH_REQ_ALPHANUMERIC_INPUT
+ *           b/ BT_MESH_AUTH_REQ_NUMERIC_INPUT
+ *           c/ BT_MESH_AUTH_REQ_BLINK_COUNT_INPUT
+ *           d/ BT_MESH_AUTH_REQ_BEEP_COUNT_INPUT
+ *           e/ BT_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT
+ *           f/ BT_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT
+ *           g/ BT_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT
+ *
+ * @remarks: This method is designed common for both Provisioner & Node role.
+ * @see  bt_mesh_authentication_set_request_cb()
+ * @see  bt_mesh_authentication_request_cb()
+ * @see bt_mesh_authentication_type_e
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_authentication_reply(
+               bt_mesh_authentication_type_e auth_type,
+                       const char *value,  bool auth_reply);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to identify the newly provisioned device
+ *
+ * @remarks: After provisioning is done, device must be
+ * discovered first of all in order to
+ * use it. If device is successfully discovered, node handle
+ * will be returned in the callback.
+ * @see bt_mesh_network_provision_device
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_discover_node(bt_mesh_network_h network,
+               const char *dev_uuid,
+                       bt_mesh_node_discover_status_cb callback,
+                               void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to browse the features of a node.
+ * Features of the node are returned in callback
+ *
+ * @see bt_mesh_network_provision_device
+ * @see bt_mesh_network_discover_node
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_get_features(bt_mesh_node_h node,
+               bt_mesh_node_features_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to Add/Update/Delete a NetKey to a node
+ *
+ * @see bt_mesh_network_add_netkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_configure_netkey(bt_mesh_node_h node,
+               bt_mesh_node_key_configuration_e netkey_op,
+                       bt_mesh_netkey_h netkey,
+                               bt_mesh_netkey_status_cb callback,
+                                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to add/update/delete an Application to a node
+ *
+ * @see bt_mesh_netkey_add_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_configure_appkey(bt_mesh_node_h node,
+               bt_mesh_node_key_configuration_e appkey_op,
+                       bt_mesh_appkey_h appkey,
+                               bt_mesh_appkey_status_cb callback,
+                                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Find all NetKey(s) attached to a node
+ *
+ * @see bt_mesh_node_configure_netkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_foreach_netkeys(bt_mesh_node_h node,
+               bt_mesh_node_netkey_info_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Find all AppKey(s) bound to a NetKey in a node
+ *
+ * @see bt_mesh_node_configure_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node,
+               bt_mesh_netkey_h netkey,
+                       bt_mesh_node_appkey_info_cb callback,
+                               void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Query TTL set to a node in the network
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_get_ttl(bt_mesh_node_h node,
+               bt_mesh_node_ttl_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Query TTL set to a node in the network
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_node_set_ttl(bt_mesh_node_h node, uint8_t ttl,
+               bt_mesh_node_ttl_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to bind a locally created application key
+ * to a Model of a node
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_bind_appkey(bt_mesh_model_h model,
+               bt_mesh_appkey_h appkey, bt_mesh_model_bind_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to Unbind a locally created application key
+ * to a Model of a node
+ *
+ * @see bt_mesh_model_bind_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_unbind_appkey(bt_mesh_model_h model,
+               bt_mesh_appkey_h appkey,
+                       bt_mesh_model_unbind_cb callback,
+                               void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Async call to find all AppKey(s) bound to a model of a node
+ *
+ * @see bt_mesh_model_bind_appkey
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_get_appkey_list(bt_mesh_model_h model,
+        bt_mesh_model_appkey_list_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Create a Mesh group with a given group address in the Local Network
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_create_group(bt_mesh_network_h network,
+               uint16_t group_addr,
+                       bt_mesh_group_h *group);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Create a Mesh Virtual group in the Local Network.
+ *
+ * @remarks Virtual group label (128-bit UUID) is internally managed by Framework.
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_create_virtual_group(bt_mesh_network_h network,
+               bt_mesh_group_h *group);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Remove a create Mesh group in the Local Network.
+ *
+ * @see bt_mesh_network_create_group
+ * @see bt_mesh_network_create_virtual_group
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_remove_group(bt_mesh_group_h group);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Find all Mesh group(s), that are created in the Local Network.
+ *
+ * @remarks Group handles will be returned for each created group.
+ * @see bt_mesh_network_create_group
+ * @see bt_mesh_network_create_virtual_group
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_network_foreach_groups(bt_mesh_network_h network,
+               bt_mesh_network_group_info_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Subscription Add/Delete/Overwrite request to a Model of an element.
+ *
+ * @param: in: model_op: Add/Delete/Overwrite
+ * @param: in: model Model on which subscription operation will be applied
+ * @param: in: group Mesh Group handle.
+ * @param: in: callback result of model subscription operation
+ * request from remote node
+ * @param: in: user_data async callback data
+ *
+ * @see bt_mesh_network_create_group
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_configure_group_subscription(
+               bt_mesh_model_subscription_op_e model_op,
+                       bt_mesh_model_h model, bt_mesh_group_h group,
+                               bt_mesh_model_subscription_op_cb callback,
+                                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Subscription Add/Delete/Overwrite request of a
+ * Virtual Group, to Model of an element.
+ *
+ * @param: in: model_op: Add/Delete/Overwrite
+ * @param: in: model Model on which subscription operation will be applied
+ * @param: in: group Mesh Group handle.
+ * @param: in: callback result of model subscription operation
+ * request from remote node
+ * @param: in: user_data async callback data
+ *
+ * @see bt_mesh_network_create_virtual_group
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_configure_virtual_group_subscription(
+               bt_mesh_model_subscription_op_e model_op,
+                       bt_mesh_model_h model, bt_mesh_group_h group,
+                               bt_mesh_model_subscription_op_cb callback,
+                                       void *user_data);
+
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Find all Subscription list of a model in a node.
+ * A List of all groups handles will be returned in callback, if success
+ *
+ * @remarks Group handles will be returned for each created group.
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_get_subscription_list(bt_mesh_model_h model,
+               bt_mesh_model_subscription_list_cb callback,
+                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Add a publiation to a Model of a node.
+ *
+ * @param: in: model Model which will generate the Publication message
+ * @param: in: appkey application key handle which will be used to
+ * encrypt publication message
+ * @param: in: group Mesh Group handle.
+ * @param: in: param Model Publication Parameters
+ * @param: in: callback result of model publication set request,
+ * from remote node
+ * @param: in: user_data async callback data
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_set_publication(bt_mesh_model_h model,
+               bt_mesh_appkey_h appkey, bt_mesh_group_h group,
+                       bt_mesh_model_pub_params_s *params,
+                               bt_mesh_model_publication_status_cb callback,
+                                       void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Find Publication, set in model of a node, attached to a Network.
+ * Publication group handle will be returned in callback, if success
+ *
+ * @since_tizen 6.0
+ * @privlevel platform
+ */
+int bt_mesh_model_get_publication(bt_mesh_model_h model,
+               bt_mesh_model_publication_status_cb callback,
+                       void *user_data);
+
 /**
  * @}
  */
index 9715b95..df3e9db 100644 (file)
@@ -36,6 +36,8 @@
 #include <bluetooth-gatt-client-api.h>
 #endif
 
+#include <bluetooth-mesh-api.h>
+
 #include "bluetooth.h"
 #include "bluetooth_internal.h"
 
@@ -50,6 +52,9 @@ extern "C" {
 #define BT_DBG(fmt, args...) SLOGD(fmt, ##args)
 #define BT_ERR(fmt, args...) SLOGE(fmt, ##args)
 
+#define FUNC_ENTRY BT_DBG("+")
+#define FUNC_EXIT BT_DBG("-")
+
 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
 #define MAP_UUID "00001134-0000-1000-8000-00805f9b34fb"
 
@@ -168,6 +173,19 @@ typedef enum {
        BT_EVENT_TDS_ACTIVATION_REQUESTED, /**< TDS - transport activation requested event */
        BT_EVENT_TDS_PROVIDER_FOUND_RESULT, /**< TDS - CUSTOM Provider */
        BT_EVENT_OTP_SERVER_STATE_CHANGED, /**< OTP - Server Status */
+       BT_EVENT_MESH_NETWORK_SCAN_STATE_CHANGED, /**< Mesh - Scan state chanegd  event */
+       BT_EVENT_MESH_AUTHENTICATION_REQUEST, /**< Mesh - Authentication Request event */
+       BT_EVENT_MESH_NETWORK_PROVISIONING_RESULT, /**< Mesh - Provisioning Result event */
+       BT_EVENT_MESH_NODE_BROWSING_COMPLETED, /**< Mesh -  Node browsing event */
+       BT_EVENT_MESH_NODE_VENDOR_FEATURES, /**< Mesh -  Node Features event */
+       BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, /**< Mesh -  Node Key Configuration event */
+       BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, /**< Mesh -  Node TTL Get/Set event */
+       BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, /**< Mesh -  Node Model Bind AppKey */
+       BT_EVENT_MESH_NODE_MODEL_APPKEY_LIST, /**< Mesh -  Model AppKey List  */
+       BT_EVENT_MESH_NODE_MODEL_SUB_LIST, /**< Mesh -  Model Subscription List  */
+       BT_EVENT_MESH_NODE_MODEL_GROUP_SUB, /**< Mesh -   Model Virtual Subscription - Add/Delete/overwrite/DeleteAll  */
+       BT_EVENT_MESH_NODE_MODEL_GROUP_VIR_SUB, /**< Mesh -  Model Virtual Subscription - Add/Delete/overwrite/DeleteAll  */
+       BT_EVENT_MESH_NODE_MODEL_PUBLICATION, /**< Mesh -  Model Publication Status event index */
        BT_EVENT_MAX
 } bt_event_e;
 
@@ -586,6 +604,7 @@ typedef enum {
        BT_FEATURE_LE,
        BT_FEATURE_LE_5_0,
        BT_FEATURE_IPSP,
+       BT_FEATURE_MESH,
        BT_FEATURE_AUDIO_CALL,
        BT_FEATURE_AUDIO_MEDIA,
        BT_FEATURE_AUDIO_CONTROLLER,
@@ -752,6 +771,12 @@ char* _bt_convert_uuid_to_uuid128(const char *uuid);
 
 /**
  * @internal
+ * @brief Fill random hex bytes of size num_bytes
+ */
+bool _bt_get_random_bytes(void *buf, size_t num_bytes);
+
+/**
+ * @internal
  * @brief Convert the visibility mode
  */
 bt_adapter_visibility_mode_e _bt_get_bt_visibility_mode_e(bluetooth_discoverable_mode_t mode);
@@ -864,6 +889,72 @@ void _bt_gatt_client_event_proxy(int event,
                gatt_client_event_param_t *param, void *user_data);
 #endif
 
+/* BT MESH Event handler */
+void _bt_mesh_event_proxy(int event, mesh_event_param_t *param, void *user_data);
+
+typedef struct {
+       bool is_local;
+       bool is_attached;
+} bt_mesh_common_handle_s;
+
+typedef struct {
+       bool is_local;                                  /**< Is it a provisioner network >*/
+       bool is_discovered;                             /**< Are all provisioned nodes discovered >*/
+       char uuid[BT_MESH_UUID_STRING_LEN +1 ];  /** < Network's unique identifier, also the UUID of the local node */
+       char token[BT_MESH_TOKEN_STRING_LEN + 1]; /** < Toke of the local node */
+       char name[BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1]; /** < name of the enwtork */
+       uint16_t num_nodes;                             /**< including local node */
+       GSList *nodes;                                  /**< All nodes attached to the network */
+       GSList *netkeys;                                /**< All netkeys which are created in the local key database by the provisioner */
+       GSList *groups;                                 /**< All iGroups created within the network */
+} bt_mesh_network_s;
+
+typedef struct {
+       bt_mesh_network_s *parent;
+       uint16_t addr;
+       char label_uuid[BT_MESH_UUID_STRING_LEN + 1];
+       bool is_virtual;
+       int ref_count;
+} bt_mesh_group_s;
+
+typedef struct {
+       bool is_local;
+       bool is_attached;
+       bt_mesh_network_s *parent;
+       char uuid[BT_MESH_UUID_STRING_LEN + 1];
+       uint16_t unicast;
+       bool is_provisioner;
+       bt_mesh_node_features_s features;
+       GSList *elements;
+       GSList *netkeys;
+       GSList *appkeys;
+} bt_mesh_node_s;
+
+typedef struct {
+       bool is_local;
+       bt_mesh_node_s *parent;
+       uint16_t index;
+       GSList *models;
+} bt_mesh_element_s;
+
+typedef struct {
+       bool is_local;
+       bt_mesh_element_s *parent;
+       uint32_t id;
+       uint16_t pub_addr;
+} bt_mesh_model_s;
+
+typedef struct {
+       bt_mesh_network_s *parent;
+       uint16_t netkey_index;
+       GSList *appkeys;
+} bt_mesh_netkey_s;
+
+typedef struct {
+       bt_mesh_netkey_s *parent;
+       uint16_t appkey_index;
+} bt_mesh_appkey_s;
+
 
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_LE_MODULE
@@ -1037,6 +1128,147 @@ void _bt_otc_connection_state_changed(int result, bluetooth_otc_info_t *otc_info
  */
 void _bt_otp_check_service_changed(char *address, bt_gatt_service_change_t *service_change);
 
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets Mesh network object from network UUID
+ * @since_tizen 6.0
+ */
+bt_mesh_network_s * _bt_mesh_get_network_handle_info(char *net_uuid);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Sets node info and return node object.
+ * @since_tizen 6.0
+ */
+bt_mesh_node_s *_bt_mesh_remote_node_browsed(
+               char *net_uuid, char *dev_uuid,
+                       uint16_t unicast, int count);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Handle Net Key configure for node.
+ * @since_tizen 6.0
+ */
+bt_mesh_netkey_s *_bt_mesh_handle_node_netkey_configure(
+               bt_mesh_network_s *network_s,
+                       bt_mesh_node_s *node_s, uint16_t netkey_idx,
+                               bt_mesh_node_key_configuration_e op);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Handle App Key configure for node.
+ * @since_tizen 6.0
+ */
+bt_mesh_appkey_s *_bt_mesh_handle_node_appkey_configure(
+               bt_mesh_network_s *network_s,
+                       bt_mesh_node_s *node_s,
+                               uint16_t netkey_idx, uint16_t appkey_idx,
+                                        bt_mesh_node_key_configuration_e op);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets node info from node prinary unicast address.
+ * @since_tizen 6.0
+ */
+bt_mesh_node_s *_bt_mesh_get_node_from_unicast(char *net_uuid,
+               uint16_t unicast);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets element object from element index in a node.
+ * @since_tizen 6.0
+ */
+bt_mesh_element_s* _bt_mesh_get_element_from_index(
+               bt_mesh_node_s *node_s,
+                       int element_index);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets model object from model ID in an element.
+ * @since_tizen 6.0
+ */
+bt_mesh_model_s* _bt_mesh_get_model_from_modelid(
+               bt_mesh_element_s *element_s,
+                       uint32_t modelid);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets Mesh group object, corresponding to group address
+ * @since_tizen 6.0
+ */
+bt_mesh_group_s* _bt_mesh_network_get_group(
+               bt_mesh_network_s *network_s,
+                       uint16_t group_addr);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets AppKey object corresponding to AppKey index.
+ * @since_tizen 6.0
+ */
+bt_mesh_appkey_s* _bt_mesh_network_get_appkey_from_index(
+               bt_mesh_network_s *network_s,
+                       uint16_t appkey_idx);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets Mesh Authentication request string from auth numeric Value.
+ * @since_tizen 6.0
+ */
+char * _bt_mesh_get_auth_string_from_value(int auth);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets Appkey Object attahced to a node, from appkey index.
+ * @since_tizen 6.0
+ */
+bt_mesh_appkey_s* _bt_mesh_node_get_appkey(
+               bt_mesh_node_s *node_s,
+                       uint16_t appkey_idx);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets element object from node's primary unicast & element index information.
+ * @since_tizen 6.0
+ */
+bt_mesh_element_s * _bt_mesh_get_node_get_element_from_index(
+               char *net_uuid,
+                       uint16_t unicast, int elem_idx);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Gets model object, from element information.
+ * @since_tizen 6.0
+ */
+bt_mesh_model_s *_bt_mesh_get_node_get_model_from_element(
+               char *net_uuid, uint16_t unicast,
+                       int elem_idx, uint32_t model);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Getsgroups handle from subsciprion address.
+ * @since_tizen 6.0
+ */
+bt_mesh_group_s * _bt_mesh_get_group_from_sub(
+               bt_mesh_network_s *network_s,
+                       bt_mesh_model_s *model_s,
+                               bt_mesh_model_subscription_op_e op,
+                                       uint16_t sub_addr);
+
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE
  * @brief  Called when the battery level of the remote device is changed.
index d03eb7c..68383d7 100644 (file)
@@ -1336,6 +1336,494 @@ typedef enum {
        BT_ADAPTER_LE_ADVERTISING_TX_POWER_ULTRA_LOW = -23  /**< Lowst transmission power level */
 } bt_adapter_le_advertising_tx_power_level_e;
 
+/* Mesh Start */
+#define BT_MESH_MAX_UNPROVISIONED_DEVICE_SCAN_TIME 300
+#define BT_MESH_NETWORK_NAME_STRING_MAX_LEN 100
+#define BT_MESH_MAX_PUBISH_PERIOD_STEPS 0x3F
+#define BT_MESH_UUID_STRING_LEN 32
+#define BT_MESH_TOKEN_STRING_LEN 16
+
+/* Intervals for retransmission of a Publish message: value * 50 msec */
+#define BT_MESH_MAX_PUBISH_RETRANSMIT_INTERVAL_STEPS 0x1F
+
+/* How many times, restransmission is allowed for a publish message */
+#define BT_MESH_MAX_PUBISH_RETRANSMIT_COUNT 0x7
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  Enumerations for the BT SIG Mesh Models
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_MODEL_ID_CFG_SRV                          = 0x0000,
+       BT_MESH_MODEL_ID_CFG_CLIENT                       = 0x0001,
+       BT_MESH_MODEL_ID_HEALTH_SRV                       = 0x0002,
+       BT_MESH_MODEL_ID_HEALTH_CLIENT                    = 0x0003,
+       BT_MESH_MODEL_ID_GEN_ONOFF_SRV                    = 0x1000,
+       BT_MESH_MODEL_ID_GEN_ONOFF_CLIENT                 = 0x1001,
+       BT_MESH_MODEL_ID_GEN_LEVEL_SRV                    = 0x1002,
+       BT_MESH_MODEL_ID_GEN_LEVEL_CLI                    = 0x1003,
+       BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV           = 0x1004,
+       BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI           = 0x1005,
+       BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV              = 0x1006,
+       BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV        = 0x1007,
+       BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI              = 0x1008,
+       BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV              = 0x1009,
+       BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV        = 0x100a,
+       BT_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI              = 0x100b,
+       BT_MESH_MODEL_ID_GEN_BATTERY_SRV                  = 0x100c,
+       BT_MESH_MODEL_ID_GEN_BATTERY_CLI                  = 0x100d,
+       BT_MESH_MODEL_ID_GEN_LOCATION_SRV                 = 0x100e,
+       BT_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV            = 0x100f,
+       BT_MESH_MODEL_ID_GEN_LOCATION_CLI                 = 0x1010,
+       BT_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV               = 0x1011,
+       BT_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV        = 0x1012,
+       BT_MESH_MODEL_ID_GEN_USER_PROP_SRV                = 0x1013,
+       BT_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV              = 0x1014,
+       BT_MESH_MODEL_ID_GEN_PROP_CLI                     = 0x1015,
+       BT_MESH_MODEL_ID_SENSOR_SRV                       = 0x1100,
+       BT_MESH_MODEL_ID_SENSOR_SETUP_SRV                 = 0x1101,
+       BT_MESH_MODEL_ID_SENSOR_CLI                       = 0x1102,
+       BT_MESH_MODEL_ID_TIME_SRV                         = 0x1200,
+       BT_MESH_MODEL_ID_TIME_SETUP_SRV                   = 0x1201,
+       BT_MESH_MODEL_ID_TIME_CLI                         = 0x1202,
+       BT_MESH_MODEL_ID_SCENE_SRV                        = 0x1203,
+       BT_MESH_MODEL_ID_SCENE_SETUP_SRV                  = 0x1204,
+       BT_MESH_MODEL_ID_SCENE_CLI                        = 0x1205,
+       BT_MESH_MODEL_ID_SCHEDULER_SRV                    = 0x1206,
+       BT_MESH_MODEL_ID_SCHEDULER_SETUP_SRV              = 0x1207,
+       BT_MESH_MODEL_ID_SCHEDULER_CLI                    = 0x1208,
+       BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV              = 0x1300,
+       BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV        = 0x1301,
+       BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI              = 0x1302,
+       BT_MESH_MODEL_ID_LIGHT_CTL_SRV                    = 0x1303,
+       BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV              = 0x1304,
+       BT_MESH_MODEL_ID_LIGHT_CTL_CLI                    = 0x1305,
+       BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV               = 0x1306,
+       BT_MESH_MODEL_ID_LIGHT_HSL_SRV                    = 0x1307,
+       BT_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV              = 0x1308,
+       BT_MESH_MODEL_ID_LIGHT_HSL_CLI                    = 0x1309,
+       BT_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV                = 0x130a,
+       BT_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV                = 0x130b,
+       BT_MESH_MODEL_ID_LIGHT_XYL_SRV                    = 0x130c,
+       BT_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV              = 0x130d,
+       BT_MESH_MODEL_ID_LIGHT_XYL_CLI                    = 0x130e,
+       BT_MESH_MODEL_ID_LIGHT_LC_SRV                     = 0x130f,
+       BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV                = 0x1310,
+       BT_MESH_MODEL_ID_LIGHT_LC_CLI                     = 0x1311,
+       BT_MESH_MODEL_MAX                                 = 0xFFFF,
+} bt_mesh_sig_model_id_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  Enumerations of the Provisioning error codes.
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_PROV_ERR_INTERNAL               = -1,
+       BT_MESH_PROV_ERR_SUCCESS                = 0x00,
+       BT_MESH_PROV_ERR_INVALID_PDU            = 0x01,
+       BT_MESH_PROV_ERR_INVALID_FORMAT         = 0x02,
+       BT_MESH_PROV_ERR_UNEXPECTED_PDU         = 0x03,
+       BT_MESH_PROV_ERR_CONFIRM_FAILED         = 0x04,
+       BT_MESH_PROV_ERR_INSUF_RESOURCE         = 0x05,
+       BT_MESH_PROV_ERR_DECRYPT_FAILED         = 0x06,
+       BT_MESH_PROV_ERR_UNEXPECTED_ERR         = 0x07,
+       BT_MESH_PROV_ERR_CANT_ASSIGN_ADDR       = 0x08,
+       /* Internally generated  by Stack */
+       BT_MESH_PROV_ERR_TIMEOUT                = 0xFF,
+} bt_mesh_prov_error_codes_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Enumerations of the Unprovisioned scanning  state of Provisioner device.
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_SCANNING_STARTED, /**< Scanning is started */
+       BT_MESH_SCANNING_FINISHED, /**< Scanning is finished */
+       BT_MESH_SCAN_DEVICE_FOUND, /**< The remote Unprovisioned device is found */
+} bt_mesh_scanning_state_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Enumerations of 2 octet OOB Information field,
+ * per Table 3.54, Mesh profile Specification
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_OOB_INFO_OTHER                          = 0x01,
+       BT_MESH_OOB_INFO_ELECTRONIC_OR_URI              = 0x02,
+       BT_MESH_OOB_INFO_2D_MACHINE_READABLE_CODE       = 0x04,
+       BT_MESH_OOB_INFO_BAR_CODE                       = 0x08,
+       BT_MESH_OOB_INFO_NEAR_FIELD_COMMUNICATION       = 0x10,
+       BT_MESH_OOB_INFO_NUMBER                         = 0x20,
+       BT_MESH_OOB_INFO_STRING                         = 0x40,
+       /* bit 7 ~ 10 : RFU */
+       BT_MESH_OOB_INFO_ON_BOX                         = 0x800,
+       BT_MESH_OOB_INFO_INSIDE_BOX                     = 0x1000,
+       BT_MESH_OOB_INFO_ON_PIECE_OF_PAPER              = 0x2000,
+       BT_MESH_OOB_INFO_INSIDE_MANUAL                  = 0x4000,
+       BT_MESH_OOB_INFO_ON_DEVICE                      = 0x8000,
+} bt_mesh_oob_info_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Enumerations of 2 octet OUT OOB Actions
+ * per Table 5.22, Mesh profile Specification
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_OUT_OOB_METHOD_BLINK            = 0x01,
+       BT_MESH_OUT_OOB_METHOD_BEEP             = 0x02,
+       BT_MESH_OUT_OOB_METHOD_VIBRATE          = 0x04,
+       BT_MESH_OUT_OOB_METHOD_NUMERIC          = 0x08,
+       BT_MESH_OUT_OOB_METHOD_ALPHANUMERIC     = 0x10,
+       /* bit 5 ~ 15 : RFU */
+} bt_mesh_output_oob_action_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Enumerations of 2 octet IN OOB Actions
+ * per Table 5.24, Mesh profile Specification
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_IN_OOB_METHOD_PUSH              = 0x01,
+       BT_MESH_IN_OOB_METHOD_TWIST             = 0x02,
+       BT_MESH_IN_OOB_METHOD_NUMERIC           = 0x04,
+       BT_MESH_IN_OOB_METHOD_ALPHANUMERIC      = 0x08,
+       /* bit 4 ~ 15 : RFU */
+} bt_mesh_input_oob_action_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Enumerations of Authentication Types(Input, Output, OOB Keys)
+ * @since_tizen 6.0
+ */
+typedef enum {
+       /*< Output authentication request types */
+       BT_MESH_AUTH_ALPHANUMERIC_DISPLAY = 0,
+       BT_MESH_AUTH_NUMERIC_DISPLAY,
+       BT_MESH_AUTH_PUSH_COUNT_DISPLAY,
+       BT_MESH_AUTH_TWIST_COUNT_DISPLAY,
+
+       /*< Input authentication request types */
+       BT_MESH_AUTH_REQ_ALPHANUMERIC_INPUT,
+       BT_MESH_AUTH_REQ_NUMERIC_INPUT,
+       BT_MESH_AUTH_REQ_BLINK_COUNT_INPUT,
+       BT_MESH_AUTH_REQ_BEEP_COUNT_INPUT,
+       BT_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT,
+
+       /**< OOB Key Inputs */
+       BT_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT,
+       BT_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT
+} bt_mesh_authentication_type_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  Enumerations for the Step Resolution for Period of Publication message
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_PUBLICATION_STEP_RES_100_MSEC,
+       BT_MESH_PUBLICATION_STEP_RES_1_SECOND,
+       BT_MESH_PUBLICATION_STEP_RES_10_SECONDS,
+       BT_MESH_PUBLICATION_STEP_RES_10_MINS,
+} bt_mesh_publish_resolution_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  Enumerations for the Model Subscription operations
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_MODEL_SUBSCRIPTION_ADD,
+       BT_MESH_MODEL_SUBSCRIPTION_DELETE,
+       BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL,
+       BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE,
+} bt_mesh_model_subscription_op_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  Enumerations for the Mesh features
+ * per Table 4.3, Mesh profile Specification
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_FEATURE_RELAY           = 0x01,
+       BT_MESH_FEATURE_PROXY           = 0x02,
+       BT_MESH_FEATURE_FRIEND          = 0x04,
+       BT_MESH_FEATURE_LOWPOWER        = 0x08,
+       /* bit 4 ~ 15 : RFU */
+} bt_mesh_features_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  Enumerations for the TTL operation for a node in a network
+ * @since_tizen 6.0
+ */
+typedef enum {
+       BT_MESH_TTL_GET,
+       BT_MESH_TTL_SET,
+} bt_mesh_node_ttl_operation_e;
+
+
+typedef enum {
+       BT_MESH_NODE_KEY_ADD,
+       BT_MESH_NODE_KEY_UPDATE,
+       BT_MESH_NODE_KEY_DELETE,
+} bt_mesh_node_key_configuration_e;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  structure of Model ID
+ * @since_tizen 6.0
+ */
+typedef struct {
+       uint16_t company_id; /** < 0xFFFF in case of BT SIG Model ID */
+       uint16_t model_id;
+} bt_mesh_model_id_s;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief  structure of Model Publication parameters
+ * @since_tizen 6.0
+ */
+typedef struct {
+       uint8_t ttl;
+       uint8_t num_steps;
+       bt_mesh_publish_resolution_e per_res;
+       uint8_t retrans_cnt;
+       uint8_t retrans_step;
+       //uint16_t pub_addr;
+} bt_mesh_model_pub_params_s;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief The handle of a BLE Mesh provisioner or a Mesh Network instance.
+ * @since_tizen 6.0
+ */
+typedef void *bt_mesh_network_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief The handle of a BLE Mesh Network group.
+ * @since_tizen 6.0
+ */
+typedef void *bt_mesh_group_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief The handle of a BLE Mesh node (Local or Remote)
+ * @since_tizen 6.0
+ */
+typedef void *bt_mesh_node_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief The handle of a BLE Mesh element contained in a node.
+ * @since_tizen 6.0
+ */
+typedef void *bt_mesh_element_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief The handle of a BLE Mesh Model (BT SIG or vendor Model)
+ * @since_tizen 6.0
+ */
+typedef void *bt_mesh_model_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief The handle of a BLE Mesh Network or subnetwork Key.
+ * @since_tizen 6.0
+ */
+typedef void *bt_mesh_netkey_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief The handle of a BLE Mesh Application key.
+ * @since_tizen 6.0
+ */
+typedef void *bt_mesh_appkey_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Structure of a BLE Mesh Scan result (From a Unprovisioned Device Beacon)
+ * @since_tizen 6.0
+ * @see bt_mesh_network_create()
+ */
+typedef struct {
+       char *uuid;  /**< Unprovisioned Device UUID */
+       int rssi;    /**< RSSI signal strength */
+       bt_mesh_oob_info_e oob_info; /**< Indicates various method via which OOB Data can be exported by remote node */
+       /* TODO Currently mesh daemon does not support  URI Hash data.
+          The structure will be expanded once it is available from stack */
+} bt_mesh_scan_result_s;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Structure of a BLE Mesh Provisioner Capabilities
+ * @since_tizen 6.0
+ * @see bt_mesh_network_set_provisioning_capabilities()
+ */
+typedef struct {
+       bool public_oob;                        /**< Indicates Public Key for ECC Key exchange, can be fetched Out Of Band,  */
+       bool static_oob;                        /**< Indicates Static Key for authentication, can be fetched Out-Of-Band*/
+       bt_mesh_output_oob_action_e out_oob;    /**< Indicates suport for bitmap combination of OUT-OOB actions */
+       bt_mesh_input_oob_action_e  in_oob;     /**< Indicates suport for bitmap combination of IN-OOB actions */
+} bt_mesh_provisioner_capabilities_s;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Structure of a BLE Mesh Unprovisioned Device Scan parameters
+ * @since_tizen 6.0
+ * @see bt_mesh_network_unprovisioned_device_scan()
+ * @see MAX_UNPROVISIONED_DEVICE_SCAN_TIME
+ */
+typedef struct {
+       uint16_t seconds; /**< Current maximum is 300 seconds or 5 minutes */
+       /* More parameters to add in future */
+} bt_mesh_scan_params_s;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MESH_MODULE
+ * @brief Structure of a BLE Mesh Node feature
+ * @since_tizen 6.0
+ * @see bt_mesh_node_get_features()
+ * @see MAX_UNPROVISIONED_DEVICE_SCAN_TIME
+ */
+typedef struct {
+       uint16_t cid;                   /**< Contains a 16-bit company identifier assigned by the Bluetooth SIG */
+       uint16_t pid;                   /**< Contains a 16-bit vendor-assigned product identifier */
+       uint16_t vid;                   /**< Contains a 16-bit vendor-assigned product version identifier*/
+       uint16_t crpl;                  /**< Contains a 16-bit value representing the minimum number of replay protection list entries in a device*/
+       bt_mesh_features_e features;    /**< Bit map of Mesh features supported by the node */
+} bt_mesh_node_features_s;
+
+/* Mesh Callback Signatures */
+typedef void (*bt_mesh_network_create_cb)
+               (int result, bt_mesh_network_h network,
+                       const char *network_name, void *user_data);
+
+
+typedef void (*bt_mesh_network_load_cb)
+               (int result, bt_mesh_network_h network, const char *token,
+                       const char *network_name, void *user_data);
+
+
+typedef void (*bt_mesh_network_scan_unprovisioned_device_result_cb)
+               (int result, bt_mesh_network_h network,
+                       bt_mesh_scanning_state_e state,
+                               bt_mesh_scan_result_s *scan_res,
+                                       void *user_data);
+
+typedef void (*bt_mesh_network_device_provision_cb)
+               (int result, bt_mesh_network_h network,
+                       const char *dev_uuid, void *user_data);
+
+
+typedef void (*bt_mesh_authentication_request_cb)
+               (int result, bt_mesh_authentication_type_e auth_type,
+                       char *auth_value, void *user_data);
+
+
+typedef void (*bt_mesh_network_node_reset_cb)
+               (int result, bt_mesh_network_h network,
+                       const char *dev_uuid, void *user_data);
+
+
+typedef void (*bt_mesh_node_ttl_cb)
+               (int result, bt_mesh_node_h node,
+                       bt_mesh_node_ttl_operation_e ttl_op,
+                               uint8_t ttl, void *user_data);
+
+typedef void (*bt_mesh_node_discover_status_cb)
+               (int result, bt_mesh_network_h network, bt_mesh_node_h node,
+                       void *user_data);
+
+typedef void (*bt_mesh_node_features_cb)
+               (int result, bt_mesh_node_h node,
+                       bt_mesh_node_features_s *features, void *user_data);
+
+typedef bool (*bt_mesh_node_netkey_info_cb)
+               (int result, bt_mesh_node_h node, int total,
+                       bt_mesh_netkey_h netkey,
+                               uint16_t netkey_index, void *user_data);
+
+typedef bool (*bt_mesh_node_appkey_info_cb)
+               (int result, bt_mesh_node_h node, int total,
+                       bt_mesh_netkey_h netkey, bt_mesh_appkey_h appkey,
+                               uint16_t appkey_index, void *user_data);
+
+typedef bool (*bt_mesh_network_netkey_info_cb)
+               (int result, bt_mesh_network_h network,
+                       int total, bt_mesh_netkey_h netkey,
+                               uint16_t netkey_index, void *user_data);
+
+typedef bool (*bt_mesh_appkey_info_cb)
+               (int result, bt_mesh_network_h network, int total,
+                       bt_mesh_netkey_h netkey, bt_mesh_appkey_h appkey,
+                               uint16_t appkey_index, void *user_data);
+
+typedef bool (*bt_mesh_network_device_info_cb)
+               (int result, bt_mesh_network_h network, int total,
+                       const char *dev_uuid, uint16_t primary_unicast,
+                               void *user_data);
+
+typedef bool (*bt_mesh_node_element_info_cb)
+               (int result, bt_mesh_node_h node, int total,
+                       bt_mesh_element_h element,
+                               int elem_index, uint16_t element_addr,
+                                       void *user_data);
+
+typedef bool (*bt_mesh_element_model_info_cb)
+               (int result, bt_mesh_element_h element, int total,
+                       bt_mesh_model_h model, bt_mesh_model_id_s *model_id,
+                               void *user_data);
+
+typedef void (*bt_mesh_appkey_status_cb)
+               (int result, bt_mesh_node_key_configuration_e op,
+                       bt_mesh_node_h node, bt_mesh_netkey_h netkey,
+                               bt_mesh_appkey_h appkey, void *user_data);
+
+typedef void (*bt_mesh_netkey_status_cb)
+               (int result, bt_mesh_node_key_configuration_e op, bt_mesh_node_h node,
+                       bt_mesh_netkey_h netkey, void *user_data);
+
+typedef void (*bt_mesh_model_bind_cb)
+               (int result, bt_mesh_model_h model, bt_mesh_appkey_h appkey,
+                       void *user_data);
+
+typedef void (*bt_mesh_model_unbind_cb)
+               (int result, bt_mesh_model_h model, bt_mesh_appkey_h appkey,
+                       void *user_data);
+
+typedef void (*bt_mesh_model_appkey_list_cb)
+               (int result, bt_mesh_model_h model, int total,
+                       const GSList *appkeylist,
+                               void *user_data);
+
+typedef void (*bt_mesh_model_subscription_op_cb)
+               (int result, bt_mesh_model_subscription_op_e op,
+                       bt_mesh_model_h model, bt_mesh_group_h group,
+                               void *user_data);
+
+
+typedef bool (*bt_mesh_model_subscription_list_cb)
+               (int result, bt_mesh_model_h model, int total,
+                       const GSList *sub_addr,
+                               void *user_data);
+
+typedef void (*bt_mesh_model_publication_status_cb)
+               (int result, bt_mesh_model_h model, bt_mesh_group_h group,
+                       bt_mesh_appkey_h appkey, void *user_data);
+
+typedef bool (*bt_mesh_network_group_info_cb)
+               (int result, bt_mesh_network_h network, int total,
+                       bt_mesh_group_h group, void *user_data);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 34aa11c..f2274a1 100644 (file)
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <fcntl.h>
+#include <unistd.h>
 #include <glib.h>
 #include <string.h>
 #include <stdlib.h>
@@ -670,6 +672,25 @@ char *_bt_convert_error_to_string(int error)
        return "UNKNOWN"; /* LCOV_EXCL_LINE */
 }
 
+bool _bt_get_random_bytes(void *buf, size_t num_bytes)
+{
+       ssize_t len;
+       int fd;
+
+       fd = open("/dev/urandom", O_RDONLY);
+       if (fd < 0)
+               return false;
+
+       len = read(fd, buf, num_bytes);
+
+       close(fd);
+
+       if (len < 0)
+               return false;
+
+       return true;
+}
+
 /* LCOV_EXCL_START */
 char *_bt_convert_uuid_to_uuid128(const char *uuid)
 {
@@ -1251,6 +1272,18 @@ static bt_gatt_server_notification_sent_cb __bt_gatt_attribute_get_notification_
 }
 #endif
 
+void _bt_mesh_event_proxy(int event, mesh_event_param_t *param, void *user_data)
+{
+       if (!param)
+               return;
+       bluetooth_event_param_t new_param;
+       new_param.event = param->event;
+       new_param.param_data = param->param_data;
+       new_param.result = param->result;
+       new_param.user_data = NULL;
+       __bt_event_proxy(event, &new_param, user_data);
+}
+
 static void __bt_free_bt_device_connection_info_s(bt_device_connection_info_s *conn_info)
 {
        if (conn_info == NULL)
diff --git a/src/bluetooth-mesh.c b/src/bluetooth-mesh.c
new file mode 100644 (file)
index 0000000..a848b26
--- /dev/null
@@ -0,0 +1,3311 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * @author: Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <dlog.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <arpa/inet.h>
+#include <bluetooth-api.h>
+
+#include "bluetooth.h"
+#include "bluetooth_internal.h"
+#include "bluetooth_private.h"
+#include "bluetooth-mesh-api.h"
+
+#define BT_MESH_MAX_NETWORKS 5
+#define BT_MESH_MAX_ELEMENTS 32767
+#define BT_MESH_MAX_MODELS 32767
+#define BT_MESH_MAX_NODES 32767
+#define BT_MESH_MAX_SUBNETS 4096
+
+static bool is_mesh_initialized = false;
+
+/**< List of Local handles >*/
+GSList *networks;
+GSList *node_list;
+GSList *element_list;
+GSList *model_list;
+GSList *appkey_list;
+GSList *netkey_list;
+GSList *group_list;
+
+
+#define BT_CHECK_MESH_SUPPORT() \
+{ \
+       BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
+       BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \
+       BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_MESH); \
+}
+
+#define BT_CHECK_MESH_INIT_STATUS() \
+       if (__bt_check_mesh_init_status() == BT_ERROR_NOT_INITIALIZED) { \
+               LOGE("[%s] NOT_INITIALIZED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_INITIALIZED); \
+               return BT_ERROR_NOT_INITIALIZED; \
+       }
+
+
+#define BT_CHECK_MESH_REMOTE(handle) \
+{      if (handle->is_local) return BT_ERROR_OPERATION_FAILED; }
+
+
+#define BT_CHECK_MESH_LOCAL(handle) \
+{      if (!handle->is_local) return BT_ERROR_OPERATION_FAILED; }
+
+
+#define BT_CHECK_MESH_IS_ATTACHED(handle) \
+{      if (handle->is_attached) return BT_ERROR_OPERATION_FAILED; }
+
+#define BT_MESH_VALIDATE_HANDLE(h1, list) \
+{ \
+       GSList *l; \
+       bool valid = FALSE; \
+       for (l = list; l; l = g_slist_next(l)) { \
+               void *h2 = (void *)l->data; \
+               if (h1 == h2) { \
+                       BT_INFO("Handle matched [%p]", h2); \
+                       valid = TRUE; break; \
+               } \
+       } \
+       if (valid == FALSE) { \
+               BT_ERR("Handle [%p] did not match with any stored handles!!", h1); \
+               return BT_ERROR_INVALID_PARAMETER; \
+       } \
+} \
+
+size_t __bt_mesh_util_convert_hex_to_string(uint8_t *in,
+               size_t in_len, char *out, size_t out_len)
+{
+       static const char hexdigits[] = "0123456789abcdef";
+       size_t i;
+
+       if (in_len * 2 > (out_len - 1))
+               return 0;
+
+       for (i = 0; i < in_len; i++) {
+               out[i * 2] = hexdigits[in[i] >> 4];
+               out[i * 2 + 1] = hexdigits[in[i] & 0xf];
+       }
+
+       out[in_len * 2] = '\0';
+       return i;
+}
+
+static int __compare_node_primary_unicast(gconstpointer a, gconstpointer b)
+{
+       const bt_mesh_node_s *node = a;
+       uint16_t index = GPOINTER_TO_UINT(b);
+
+       return (node->unicast - index);
+}
+
+static int __compare_node_element_index(gconstpointer a, gconstpointer b)
+{
+       const bt_mesh_element_s *element = a;
+       int index = GPOINTER_TO_UINT(b);
+
+       return (element->index - index);
+}
+
+static int __compare_network_group_address(gconstpointer a, gconstpointer b)
+{
+       const bt_mesh_group_s *group = a;
+       uint16_t group_addr = GPOINTER_TO_UINT(b);
+
+       return (group->addr - group_addr);
+}
+
+static int __compare_model_id(gconstpointer a, gconstpointer b)
+{
+       const bt_mesh_model_s *model_s = a;
+       uint32_t model = GPOINTER_TO_UINT(b);
+
+       return (model_s->id - model);
+}
+
+static int __compare_netkey_index(gconstpointer a, gconstpointer b)
+{
+       const bt_mesh_netkey_s *nk = a;
+       uint16_t netkey_index = GPOINTER_TO_UINT(b);
+
+       return (nk->netkey_index - netkey_index);
+}
+
+static int __simple_compare(gconstpointer a, gconstpointer b)
+{
+       if (a == b)
+               return 0;
+       else
+               return 1;
+}
+
+static int __compare_appkey_index(gconstpointer a, gconstpointer b)
+{
+       const bt_mesh_appkey_s *ak = a;
+       uint16_t appkey_index = GPOINTER_TO_UINT(b);
+
+       return (ak->appkey_index - appkey_index);
+}
+
+static int __compare_element_index(gconstpointer a, gconstpointer b)
+{
+       const bt_mesh_element_s *elem = a;
+       uint16_t element_index = GPOINTER_TO_UINT(b);
+
+       return (elem->index - element_index);
+}
+
+static bt_mesh_netkey_s * __bt_mesh_network_is_netkey_added(
+               bt_mesh_network_s *network_s, uint16_t netkey_idx)
+{
+       GSList *l;
+
+       l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
+                       (GCompareFunc)__compare_netkey_index);
+       if (!l)
+               return NULL;
+
+       return (bt_mesh_netkey_s*) l->data;
+}
+
+bt_mesh_element_s *_bt_mesh_get_element_from_index(
+               bt_mesh_node_s *node_s, int element_index)
+{
+       GSList *l;
+
+       l = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(element_index),
+                       (GCompareFunc)__compare_element_index);
+       if (!l)
+               return NULL;
+
+       return (bt_mesh_element_s*) l->data;
+}
+
+bt_mesh_appkey_s *_bt_mesh_network_get_appkey_from_index(
+               bt_mesh_network_s *network_s, uint16_t appkey_idx)
+{
+       GSList *l, *l1;
+
+       for (l = network_s->netkeys; l; l = l->next) {
+               bt_mesh_netkey_s *netkey_s = l->data;
+
+               l1 = g_slist_find_custom(netkey_s->appkeys, GUINT_TO_POINTER(appkey_idx),
+                               (GCompareFunc)__compare_appkey_index);
+
+               if (l1)
+                       return l1->data;
+       }
+       return NULL;
+}
+
+bt_mesh_model_s *_bt_mesh_get_model_from_modelid(
+               bt_mesh_element_s *element_s, uint32_t modelid)
+{
+       GSList *l;
+
+       l = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(modelid),
+                       (GCompareFunc)__compare_model_id);
+       if (!l)
+               return NULL;
+
+       return (bt_mesh_model_s*) l->data;
+}
+
+bt_mesh_group_s* _bt_mesh_network_get_group(
+               bt_mesh_network_s *network_s, uint16_t group_addr)
+{
+       GSList *l;
+       bt_mesh_group_s *group_s = NULL;
+
+       /* Unassigned address */
+       if (group_addr == 0x0000)
+               return NULL;
+
+       l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(group_addr),
+                       (GCompareFunc) __compare_network_group_address);
+       if (!l) {
+               group_s = g_malloc0(sizeof(bt_mesh_group_s));
+               group_s->addr = group_addr;
+               if (group_addr >= 0x8000 && group_addr <= 0xbfff)
+                       group_s->is_virtual = true;
+               else
+                       group_s->is_virtual = false;
+               group_s->parent = network_s;
+
+               if (g_slist_append(network_s->groups, group_s))
+                       BT_INFO("Mesh: Group created");
+
+               group_list = g_slist_append(group_list, group_s);
+       } else
+               group_s = l->data;
+
+       return group_s;
+}
+
+bt_mesh_appkey_s* _bt_mesh_node_get_appkey(
+               bt_mesh_node_s *node_s, uint16_t appkey_idx)
+{
+       GSList *l;
+
+       l = g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(appkey_idx),
+                       (GCompareFunc)__compare_appkey_index);
+       if (!l)
+               return NULL;
+
+       return (bt_mesh_appkey_s*) l->data;
+}
+
+static bt_mesh_appkey_s *__bt_mesh_network_is_appkey_added(
+               bt_mesh_network_s *network_s,
+                       uint16_t netkey_idx,
+                               uint16_t appkey_idx)
+{
+       GSList *l, *l1;
+       const bt_mesh_netkey_s *netkey;
+
+       l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
+                       (GCompareFunc)__compare_netkey_index);
+       if (!l)
+               return NULL;
+       netkey = l->data;
+
+       l1 = g_slist_find_custom(netkey->appkeys, GUINT_TO_POINTER(appkey_idx),
+                       (GCompareFunc)__compare_appkey_index);
+       if (!l1)
+               return NULL;
+
+       return (bt_mesh_appkey_s*) l1->data;
+}
+
+int __bt_check_mesh_init_status(void)
+{
+       if (is_mesh_initialized != true) {
+               BT_ERR("NOT_INITIALIZED(0x%08x)", BT_ERROR_NOT_INITIALIZED);
+               return BT_ERROR_NOT_INITIALIZED;
+       }
+
+       return BT_ERROR_NONE;
+}
+
+/* Local static */
+static void __bt_mesh_free_models(void *data)
+{
+       bt_mesh_model_s *model = (bt_mesh_model_s*)data;
+       model_list = g_slist_remove(model_list, model);
+       g_free(model);
+}
+
+static void __bt_mesh_free_elements(void *data)
+{
+       bt_mesh_element_s *elem = (bt_mesh_element_s*)data;
+       element_list = g_slist_remove(element_list, elem);
+       g_slist_free_full(elem->models, __bt_mesh_free_models);
+       g_free(elem);
+}
+
+static gint __bt_mesh_compare_net_uuid(gpointer *a, gpointer *b)
+{
+       bt_mesh_network_s *net = (bt_mesh_network_s *)a;
+       char *net_uuid = (char *)b;
+       return g_strcmp0(net->uuid, net_uuid);
+}
+
+
+static void __bt_mesh_insert_elements_in_node(
+               bt_mesh_node_s *node, uint16_t unicast,
+                       int num_elements, bool is_local)
+{
+       bt_mesh_element_s *element_s;
+
+       for (int i = 0; i < num_elements; i++) {
+               element_s = g_malloc0(sizeof(bt_mesh_element_s));
+               element_s->is_local = is_local;
+               element_s->parent = node;
+               element_s->index = i;
+               node->elements = g_slist_append(node->elements, element_s);
+               element_list = g_slist_append(element_list, element_s);
+       }
+}
+
+bt_mesh_appkey_s *_bt_mesh_handle_node_appkey_configure(
+               bt_mesh_network_s *network_s,
+                       bt_mesh_node_s *node_s, uint16_t netkey_idx,
+                               uint16_t appkey_idx,
+                                       bt_mesh_node_key_configuration_e op)
+{
+       bt_mesh_appkey_s *appkey_s;
+
+       appkey_s = __bt_mesh_network_is_appkey_added(
+                       network_s, netkey_idx, appkey_idx);
+
+       /* AppKey with index not found in network */
+       if (!appkey_s) {
+               BT_ERR("Mesh: Exceptional case: AppKey not found in Network");
+               return NULL;
+       }
+
+       if (op == BT_MESH_NODE_KEY_ADD) {
+               if (!g_slist_find_custom(node_s->appkeys,(gconstpointer) appkey_s,
+                                       (GCompareFunc)__simple_compare)) {
+                       node_s->appkeys = g_slist_append(node_s->appkeys, appkey_s);
+               } else
+                       BT_INFO("Mesh: AppKey Already added");
+               return appkey_s;
+       } else  if (op == BT_MESH_NODE_KEY_DELETE) {
+               node_s->appkeys = g_slist_remove(node_s->appkeys, appkey_s);
+               return NULL;
+       } else  /* Node NetKey update */
+               return appkey_s;
+}
+
+bt_mesh_netkey_s *_bt_mesh_handle_node_netkey_configure(
+               bt_mesh_network_s *network_s,
+                       bt_mesh_node_s *node_s, uint16_t netkey_idx,
+                               bt_mesh_node_key_configuration_e op)
+{
+       bt_mesh_netkey_s *netkey_s;
+
+       netkey_s = __bt_mesh_network_is_netkey_added(network_s, netkey_idx);
+
+       /* Netkey with index not found in network */
+       if (!netkey_s) {
+               BT_ERR("Mesh: Exceptional case: Netkey not found in Network");
+               return NULL;
+       }
+
+       if (op == BT_MESH_NODE_KEY_ADD) {
+               if (!g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_s,
+                                       (GCompareFunc)__simple_compare)) {
+                       node_s->netkeys = g_slist_append(node_s->netkeys, netkey_s);
+               } else
+                       BT_INFO("Mesh: NetKey Already added");
+               return netkey_s;
+       } else if (op == BT_MESH_NODE_KEY_DELETE) {
+               node_s->netkeys = g_slist_remove(node_s->netkeys, netkey_s);
+               return NULL;
+       } else  /* Node NetKey update */
+               return netkey_s;
+}
+
+bt_mesh_group_s * _bt_mesh_get_group_from_sub(
+               bt_mesh_network_s *network_s, bt_mesh_model_s *model_s,
+                       bt_mesh_model_subscription_op_e op, uint16_t sub_addr)
+{
+       GSList *l;
+       bt_mesh_group_s *group_s = NULL;
+       l  = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(sub_addr),
+                       (GCompareFunc) __compare_network_group_address);
+       if (l)
+               group_s = l->data;
+
+       if (op ==  BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
+               BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL");
+       if (op == BT_MESH_MODEL_SUBSCRIPTION_ADD)
+               BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_ADD");
+       if (op == BT_MESH_MODEL_SUBSCRIPTION_DELETE)
+               BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE");
+       if (op == BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE)
+               BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE");
+
+       return group_s;
+}
+
+bt_mesh_model_s *_bt_mesh_get_node_get_model_from_element(
+               char *net_uuid, uint16_t unicast,
+                       int elem_idx, uint32_t model)
+{
+       GSList *l, *l1, *l2, *l3;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_element_s *element_s;
+
+       l = g_slist_find_custom(networks, net_uuid,
+               (GCompareFunc)__bt_mesh_compare_net_uuid);
+       if (!l)
+               return NULL;
+
+       network_s = l->data;
+
+       l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
+                       (GCompareFunc)__compare_node_primary_unicast);
+       if (!l1)
+               return NULL;
+
+       node_s = l1->data;
+
+       l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
+                       (GCompareFunc)__compare_node_element_index);
+       if (!l2)
+               return NULL;
+
+       element_s =  (bt_mesh_element_s*) l->data;
+
+
+       l3 = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(model),
+                       (GCompareFunc) __compare_model_id);
+       if (!l3)
+               return NULL;
+
+       return (bt_mesh_model_s*) l->data;
+}
+
+bt_mesh_element_s * _bt_mesh_get_node_get_element_from_index(char *net_uuid,
+                       uint16_t unicast, int elem_idx)
+{
+       GSList *l, *l1, *l2;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+
+       l = g_slist_find_custom(networks, net_uuid,
+                       (GCompareFunc)__bt_mesh_compare_net_uuid);
+       if (!l)
+               return NULL;
+
+       network_s = l->data;
+
+       l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
+                       (GCompareFunc)__compare_node_primary_unicast);
+       if (!l1)
+               return NULL;
+
+       node_s = l1->data;
+
+       l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
+                       (GCompareFunc)__compare_node_element_index);
+       if (!l2)
+               return NULL;
+
+       return (bt_mesh_element_s*) l->data;
+}
+
+bt_mesh_node_s *_bt_mesh_get_node_from_unicast(char *net_uuid, uint16_t unicast)
+{
+       GSList *l, *l1;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+
+       l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
+       if (!l)
+               return NULL;
+
+       network_s = l->data;
+
+       l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
+                       (GCompareFunc)__compare_node_primary_unicast);
+       if (!l1)
+               return NULL;
+
+       node_s = l1->data;
+       return node_s;
+}
+
+bt_mesh_node_s *_bt_mesh_remote_node_browsed(char *net_uuid, char *dev_uuid,
+                       uint16_t unicast, int count)
+{
+       GSList *l, *l1;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+
+       l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
+       if (!l)
+               return NULL;
+
+       network_s = l->data;
+
+       l1 = g_slist_find_custom(network_s->nodes,  GUINT_TO_POINTER(unicast),
+                       (GCompareFunc)__compare_node_primary_unicast);
+       if (l1) {
+               node_s = l1->data;
+               g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
+       } else {
+               node_s = g_malloc0(sizeof(bt_mesh_node_s));
+               node_s->parent = network_s;
+               node_s->unicast = unicast;
+               node_s->is_attached = true;
+               if (node_s->unicast == 0x0001) {
+                       node_s->is_local = true;
+                       node_s->is_provisioner = true;
+               }
+               g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
+               __bt_mesh_insert_elements_in_node(node_s, unicast,
+                               count, node_s->is_local? true : false);
+               network_s->nodes = g_slist_append(network_s->nodes, node_s);
+               node_list = g_slist_append(node_list, node_s);
+       }
+       return node_s;
+}
+
+bt_mesh_network_s * _bt_mesh_get_network_handle_info(char *net_uuid)
+{
+       GSList *l;
+
+       l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
+       if (!l)
+               return NULL;
+
+       return (bt_mesh_network_s*)l->data;
+}
+
+char * _bt_mesh_get_auth_string_from_value(int auth)
+{
+       switch(auth) {
+       case BT_MESH_AUTH_ALPHANUMERIC_DISPLAY:
+               BT_INFO("Mesh: ALPHANUMERIC_DISPLAY");
+               return "ALPHANUMERIC_DISPLAY";
+       case BT_MESH_AUTH_NUMERIC_DISPLAY:
+               BT_INFO("Mesh: NUMERIC_DISPLAY");
+               return "NUMERIC_DISPLAY";
+       case BT_MESH_AUTH_PUSH_COUNT_DISPLAY:
+               BT_INFO("Mesh: PUSH_COUNT_DISPLAY");
+               return "PUSH_COUNT_DISPLAY";
+       case BT_MESH_AUTH_TWIST_COUNT_DISPLAY:
+               BT_INFO("Mesh: TWIST_COUNT_DISPLAY");
+               return "TWIST_COUNT_DISPLAY";
+
+               /*< Input authentication request types */
+       case BT_MESH_AUTH_REQ_ALPHANUMERIC_INPUT:
+               BT_INFO("Mesh: REQ_ALPHANUMERIC_INPUT");
+               return "REQ_ALPHANUMERIC_INPUT";
+       case BT_MESH_AUTH_REQ_NUMERIC_INPUT:
+               BT_INFO("Mesh: REQ_NUMERIC_INPUT");
+               return "REQ_NUMERIC_INPUT";
+       case BT_MESH_AUTH_REQ_BLINK_COUNT_INPUT:
+               BT_INFO("Mesh: REQ_BLINK_COUNT_INPUT");
+               return "REQ_BLINK_COUNT_INPUT";
+       case BT_MESH_AUTH_REQ_BEEP_COUNT_INPUT:
+               BT_INFO("Mesh: REQ_BEEP_COUNT_INPUT");
+               return "REQ_BEEP_COUNT_INPUT";
+       case BT_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT:
+               BT_INFO("Mesh: REQ_VIBRATE_COUNT_INPUT");
+               return "REQ_VIBRATE_COUNT_INPUT";
+
+               /**< OOB Key Inputs */
+       case BT_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT:
+               BT_INFO("Mesh: OOB_PUBLIC_KEY_INPUT");
+               return "OOB_PUBLIC_KEY_INPUT";
+       case BT_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT:
+               BT_INFO("Mesh: OOB_STATIC_KEY_INPUT");
+               return "OOB_STATIC_KEY_INPUT";
+       default:
+               return "";
+       }
+}
+
+/* Mesh API */
+int bt_mesh_initialize(void)
+{
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+
+       int ret = BT_ERROR_NONE;
+
+       BT_INFO("Is Mesh initialized:[%s]",
+               is_mesh_initialized ? "TRUE": "FALSE");
+
+       if (is_mesh_initialized) {
+               BT_ERR("Mesh is initialized");
+               return BT_ERROR_NONE;
+       }
+
+       if (!is_mesh_initialized) {
+               ret = _bt_get_error_code(bluetooth_mesh_init(
+                               _bt_mesh_event_proxy, NULL));
+
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("%s(0x%08x)",
+                                       _bt_convert_error_to_string(ret), ret);
+                       return BT_ERROR_OPERATION_FAILED;
+               }
+
+               is_mesh_initialized = true;
+               return BT_ERROR_NONE;
+       }
+
+       BT_INFO("Mesh is already initialized");
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_deinitialize(void)
+{
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       int error;
+
+       error = bluetooth_mesh_deinit();
+       error = _bt_get_error_code(error);
+       if (BT_ERROR_NONE != error)
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error);
+
+       is_mesh_initialized = false;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_create(bt_mesh_node_features_s *features,
+               bt_mesh_node_h *node_handle)
+{
+       FUNC_ENTRY;
+       bt_mesh_node_s *node = NULL;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node_handle);
+       BT_CHECK_INPUT_PARAMETER(features);
+
+       node = g_malloc0(sizeof(bt_mesh_node_s));
+       if (!node) {
+               BT_ERR("g_malloc0 failed");
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       node->is_local = true;
+       node->features = *features;
+       node->unicast = 0x0001;
+
+       node_list = g_slist_append(node_list, node);
+       *node_handle = (bt_mesh_node_h)node;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_destroy(bt_mesh_node_h node_handle)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node_handle);
+
+       bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
+
+       BT_MESH_VALIDATE_HANDLE(node, node_list);
+
+       /* It is NOT allowed to destroy attached node: Do Reset */
+       BT_CHECK_MESH_IS_ATTACHED(node);
+
+       node_list = g_slist_remove(node_list, node);
+       g_slist_free_full(node->elements, __bt_mesh_free_elements);
+       g_free(node);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+static void __bt_mesh_generate_element(bt_mesh_node_s *node_s,
+               bt_mesh_element_s *elem_s)
+{
+       GSList *l;
+       uint16_t index = 0;
+
+       for (l = node_s->elements; l; l = l->next) {
+               bt_mesh_element_s *el = (bt_mesh_element_s*)l->data;
+               if (el->index != index)
+                       break;
+               index++;
+       }
+       elem_s->index = index;
+       node_s->elements = g_slist_insert(node_s->elements, elem_s, index);
+}
+
+int bt_mesh_node_create_element(bt_mesh_node_h node_handle,
+               bt_mesh_element_h *element_handle)
+{
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node_handle);
+       BT_CHECK_INPUT_PARAMETER(element_handle);
+
+       bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
+       bt_mesh_element_s *element = NULL;
+
+       BT_INFO("Mesh: Element creation request");
+       BT_MESH_VALIDATE_HANDLE(node, node_list);
+
+       /* It is NOT allowed to add an element to a already attached node */
+       BT_CHECK_MESH_IS_ATTACHED(node);
+
+       /* Check num elements already present in the node */
+       if (g_slist_length(node->elements) >= BT_MESH_MAX_ELEMENTS)
+               return BT_ERROR_QUOTA_EXCEEDED;
+
+
+       element = g_malloc0(sizeof(bt_mesh_element_s));
+       if (!element) {
+               BT_ERR("g_malloc0 failed");
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       element->is_local = true;
+       element->parent = node;
+
+       __bt_mesh_generate_element(node, element);
+       element_list = g_slist_append(element_list, element);
+       *element_handle = (bt_mesh_element_h)element;
+
+       BT_INFO("Mesh: Element created successfully: element index [%d]", element->index);
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_element_destroy(bt_mesh_element_h element_handle)
+{
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(element_handle);
+       BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
+
+       bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
+       bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
+
+       /* It is NOT allowed to destroy remote element */
+       BT_CHECK_MESH_LOCAL(node);
+
+       /* It is NOT allowed to destroy an attahced element */
+       BT_CHECK_MESH_IS_ATTACHED(node);
+
+       element_list = g_slist_remove(element_list, element);
+       node->elements = g_slist_remove(node->elements, element);
+
+       g_slist_free_full(element->models, __bt_mesh_free_models);
+       g_free(element);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_element_create_model(
+               bt_mesh_element_h element_handle,
+                       bt_mesh_model_id_s *model_id,
+                               bt_mesh_model_h *model_handle)
+{
+       FUNC_ENTRY;
+       uint32_t mod_id;
+       bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
+       bt_mesh_model_s *model = NULL;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(element_handle);
+       BT_CHECK_INPUT_PARAMETER(model_id);
+       BT_CHECK_INPUT_PARAMETER(model_handle);
+       BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
+
+       bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
+
+       /* It is NOT allowed to add model to a remote element */
+       BT_CHECK_MESH_LOCAL(node);
+
+       /* It is NOT allowed to add a Model to a already attached node */
+       BT_CHECK_MESH_IS_ATTACHED(node);
+
+       BT_INFO("Mesh: Model creation request: Company ID [0x%2.2x] Model ID [0x%2.2x]",
+                       model_id->company_id, model_id->model_id);
+
+       mod_id = model_id->company_id;
+       mod_id <<= 16;
+       mod_id |= model_id->model_id;
+       /* Allow configuration server model only in primary element */
+       if ((model_id->model_id == BT_MESH_MODEL_ID_CFG_SRV) &&
+                       element->index != 0)
+               return BT_ERROR_OPERATION_FAILED;
+
+       /* Check num models already present in the element */
+       if (g_slist_length(element->models) >= BT_MESH_MAX_MODELS)
+               return BT_ERROR_QUOTA_EXCEEDED;
+
+       /* Don't allow multiple instance of same model in an element */
+       if (g_slist_find_custom(element->models, GUINT_TO_POINTER(mod_id),
+               (GCompareFunc)__compare_model_id))
+               return BT_ERROR_ALREADY_DONE;
+
+       model = g_malloc0(sizeof(bt_mesh_model_s));
+       if (!model) {
+               BT_ERR("g_malloc0 failed");
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       model->is_local = true;
+       model->parent = element;
+       model->id = mod_id;
+
+       BT_INFO("Mesh: Model ID [0x%2.2x]", model_id->model_id);
+       BT_INFO("Mesh: Company ID [0x%2.2x]", model_id->company_id);
+       BT_INFO("Mesh: MOD [0x%4.4x]", model->id);
+
+       model_list = g_slist_append(model_list, model);
+       element->models = g_slist_append(element->models, model);
+       *model_handle = (bt_mesh_model_h)model;
+
+       BT_INFO("Mesh: Model created successfully");
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_model_destroy(bt_mesh_model_h model_handle)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model_handle);
+
+       bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)((bt_mesh_model_s*)model_handle)->parent)->parent;
+       bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
+       bt_mesh_element_s *element = model->parent;
+
+       BT_MESH_VALIDATE_HANDLE(model, model_list);
+       BT_MESH_VALIDATE_HANDLE(element, element_list);
+
+       /* It is NOT allowed to destroy remote model */
+       BT_CHECK_MESH_LOCAL(node);
+
+       /* It is NOT allowed to destroy an attahced model */
+       BT_CHECK_MESH_IS_ATTACHED(node);
+
+       model_list = g_slist_remove(model_list, model);
+       element->models = g_slist_remove(element->models, model);
+       g_free(model);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_model_get_id(bt_mesh_model_h model_handle,
+               bt_mesh_model_id_s *model_id)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model_handle);
+       BT_CHECK_INPUT_PARAMETER(model_id);
+
+       bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
+       BT_MESH_VALIDATE_HANDLE(model, model_list);
+
+       BT_INFO("Mesh: Model ID [0x%4.4x]", model->id);
+       model_id->company_id = model->id >> 16;
+       model_id->model_id = model->id;
+       BT_INFO("Mesh: CID [0x%2.2x]",  model_id->company_id);
+       BT_INFO("Mesh: MID [0x%2.2x]",  model_id->model_id);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_get_network(bt_mesh_node_h node_handle, bt_mesh_network_h *network)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node_handle);
+       BT_CHECK_INPUT_PARAMETER(network);
+
+       bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
+       BT_MESH_VALIDATE_HANDLE(node_handle, node_list);
+
+       *network = node->parent;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_element_get_node(bt_mesh_element_h element_handle,
+               bt_mesh_node_h *node)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(element_handle);
+       BT_CHECK_INPUT_PARAMETER(node);
+
+       bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
+       BT_MESH_VALIDATE_HANDLE(element, element_list);
+
+       *node = element->parent;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_model_get_element(bt_mesh_model_h model_handle,
+               bt_mesh_element_h *element)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model_handle);
+       BT_CHECK_INPUT_PARAMETER(element);
+
+       bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
+       BT_MESH_VALIDATE_HANDLE(model, model_list);
+
+       *element = model->parent;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_appkey_get_netkey(bt_mesh_appkey_h appkey_handle,
+               bt_mesh_netkey_h *netkey)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(appkey_handle);
+       BT_CHECK_INPUT_PARAMETER(netkey);
+
+       bt_mesh_appkey_s *appkey = (bt_mesh_appkey_s*)appkey_handle;
+       BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
+
+       *netkey = appkey->parent;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+/* Async API's to bt-service & stack */
+int bt_mesh_network_create(bt_mesh_node_h config_client,
+               const char *network_name,
+                       bt_mesh_network_h *network, char **token)
+{
+       FUNC_ENTRY;
+       int error_code = BT_ERROR_NONE;
+       GSList *l1, *l2;
+       int i, j;
+       int offset = 0;
+       int num_models = 0;
+       bluetooth_mesh_network_t net;
+       bluetooth_mesh_node_t param_node;
+       bluetooth_mesh_model_t **param_model;
+       bt_mesh_network_s *network_s;
+       bt_mesh_netkey_s *netkey_s;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(config_client);
+       BT_CHECK_INPUT_PARAMETER(network_name);
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(token);
+
+       BT_INFO("Mesh: Create Network: Name [%s]", network_name);
+       bt_mesh_node_s *node = (bt_mesh_node_s*)config_client;
+
+       BT_MESH_VALIDATE_HANDLE(node, node_list);
+
+       /* Error if remote node*/
+       BT_CHECK_MESH_LOCAL(node);
+
+       /* It is NOT allowed to create network out of a already attahced node */
+       BT_CHECK_MESH_IS_ATTACHED(node);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       if (strlen(network_name) >= BT_MESH_NETWORK_NAME_STRING_MAX_LEN)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       /* Node in network should contain at-least one element */
+       if (!g_slist_length(node->elements)) {
+               BT_INFO("Mesh: No element present in Node: NOT ALLOWED!!");
+               return BT_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Element in Node should contain at-least one Model */
+       for (l1 = node->elements; l1 != NULL; l1 = l1->next) {
+               bt_mesh_element_s *el = l1->data;
+               int models = 0;
+               models = g_slist_length(el->models);
+               BT_INFO("Mesh: Num models element [%u] has is [%d]", el->index, models);
+               if (!models) {
+                       BT_INFO("Mesh: No Model present in element: NOT ALLOWED!!");
+                       return BT_ERROR_INVALID_PARAMETER;
+               }
+               /* If Primary element does not contain CFG SRV model, create and append */
+               if (el->index == 0x0000) {
+                       uint32_t mod_id = 0xFFFF0000; /* CFG SRV */
+
+                       if (!g_slist_find_custom(el->models, GUINT_TO_POINTER(mod_id),
+                                               (GCompareFunc)__compare_model_id)) {
+                               bt_mesh_model_s *model_s;
+                               BT_ERR("Mesh: Primary element does not contain CFG SRV Model:Add it!");
+                               model_s = g_malloc0(sizeof(bt_mesh_model_s));
+
+                               model_s->is_local = true;
+                               model_s->parent = el;
+                               model_s->id = mod_id;
+
+                               model_list = g_slist_append(model_list, model_s);
+                               el->models = g_slist_append(el->models, model_s);
+                               num_models++;
+                       } else
+                               BT_INFO("Mesh: CFG SRV model is already added in primary element");
+               }
+               num_models += models;
+       }
+
+       /* Check currently created network */
+       if (g_slist_length(networks) >= BT_MESH_MAX_NETWORKS)
+               return BT_ERROR_QUOTA_EXCEEDED;
+
+       memset(&param_node, 0x00, sizeof(bluetooth_mesh_node_t));
+       memcpy(&param_node.vendor_info, &(node->features), sizeof(node->features));
+       param_node.num_elements =  g_slist_length(node->elements);
+       param_node.primary_unicast = 0x0001;
+       _bt_get_random_bytes(param_node.uuid, 16);
+
+       BT_INFO("Mesh: Total Models [%d]", num_models);
+       param_model = (bluetooth_mesh_model_t**)g_malloc0(num_models * sizeof(bluetooth_mesh_model_t*));
+
+       for (l1 = node->elements, i = 0; l1 != NULL; l1 = l1->next, i++) {
+               bt_mesh_element_s *e = l1->data;
+
+               for (l2 = e->models, j = 0; l2 != NULL; l2 = l2->next, j++) {
+                       bt_mesh_model_s *m = l2->data;
+                       param_model[j+offset] = g_malloc0(sizeof(bluetooth_mesh_model_t));
+                       param_model[j+offset]->elem_index = i;
+                       param_model[j+offset]->model_id = m->id;
+
+               }
+               offset += g_slist_length(e->models);
+       }
+
+       BT_INFO("Mesh: Send Network create Request to FRWK");
+       error_code = _bt_get_error_code(bluetooth_mesh_network_create(network_name, &param_node,
+                               num_models, param_model, &net));
+       if (error_code != BT_ERROR_NONE) {
+               BT_INFO("Mesh: Network could not be created!!");
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+
+               /* Cleanup */
+               for (int i = 0; i < num_models; i++)
+                       g_free(param_model[i]);
+
+               return error_code;
+       }
+
+       BT_INFO("Mesh: Network created successfully");
+
+       /* Create Network object & fill data in network */
+       network_s = g_malloc0(sizeof(bt_mesh_network_s));
+       network_s->num_nodes = 1;
+       network_s->is_local = true;
+       network_s->is_discovered = true;
+
+       /* Fill network name, token & UUID */
+       __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid, 16,
+                       network_s->uuid, sizeof(network_s->uuid));
+       g_strlcpy(network_s->token, net.token.token, 17);
+       g_strlcpy(network_s->name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+       network_s->nodes = g_slist_append(network_s->nodes, node);
+       BT_INFO("Mesh: Network Name [%s]", network_s->name);
+       BT_INFO("Mesh: Network Token[%s]", network_s->token);
+       BT_INFO("Mesh: Network UUID [%s]", network_s->uuid);
+
+       /* Create primary Netkey object */
+       netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
+       netkey_s->parent = network_s;
+       netkey_s->netkey_index = 0x0000; /* Primary index */
+       network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
+       netkey_list = g_slist_append(netkey_list, netkey_s);
+
+       /* Fill Config Client Node Data */
+       node->is_attached = true;
+       node->is_provisioner = true;
+       __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid,
+               16, node->uuid, sizeof(node->uuid));
+       node->unicast = 0x0001;
+       node->parent = network_s;
+
+       /* Prepare Out parameters */
+       *token = network_s->token;
+       *network = (bt_mesh_network_h)network_s;
+
+       /* Save network in list */
+       networks = g_slist_append(networks, network_s);
+
+       /* Clean up memory */
+       for (int i = 0; i < num_models; i++)
+               g_free(param_model[i]);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_network_load(const char *token, bt_mesh_network_h *network)
+{
+       int error_code = BT_ERROR_NONE;
+       bluetooth_mesh_network_t net;
+       bt_mesh_network_s *network_s;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(token);
+       BT_CHECK_INPUT_PARAMETER(network);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+       error_code = _bt_get_error_code(bluetooth_mesh_network_load(token, &net));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       /* Create Network object */
+       network_s = g_malloc0(sizeof(bt_mesh_network_s));
+       network_s->is_local = true;
+       g_strlcpy(network_s->uuid, net.uuid, 33);
+       g_strlcpy(network_s->token, token, 17);
+       g_strlcpy(network_s->name, net.name.name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+       networks = g_slist_append(networks, network_s);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_network_get_name(bt_mesh_network_h network, char **network_name)
+{
+       bt_mesh_network_s *network_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(network_name);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       network_s = (bt_mesh_network_s*)network;
+       *network_name = strdup(network_s->name);
+       if (*network_name == NULL) {
+               BT_ERR("OUT_OF_MEMORY(0x%08x)",
+                               BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_network_set_name(bt_mesh_network_h network, const char *network_name)
+{
+       int error_code = BT_ERROR_NONE;
+       bluetooth_mesh_network_t net;
+       bt_mesh_network_s* network_s;
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(network_name);
+
+       network_s = (bt_mesh_network_s*)network;
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       BT_INFO("Mesh: Set Network Name [%s]", network_name);
+       error_code = _bt_get_error_code(bluetooth_mesh_network_set_name(&net));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       BT_INFO("Mesh: Network Name set successfully [%s]", network_name);
+       g_strlcpy(network_s->name, network_name, sizeof(network_s->name));
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_network_add_netkey(bt_mesh_network_h network,
+               bt_mesh_netkey_h *netkey)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_netkey_s *netkey_s;
+       bluetooth_mesh_network_t net;
+       uint16_t netkey_idx;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(netkey);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_add_netkey(&net, &netkey_idx));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       BT_INFO("Mesh: Subnet Key created: Index [%d]", netkey_idx);
+       /* Create Netkey object */
+       netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
+       netkey_s->parent = network_s;
+       netkey_s->netkey_index = netkey_idx;
+       network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
+       netkey_list = g_slist_append(netkey_list, netkey_s);
+       *netkey = (bt_mesh_netkey_h)netkey_s;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_network_foreach_netkeys(bt_mesh_network_h network,
+               bt_mesh_network_netkey_info_cb callback, void *user_data)
+{
+       bluetooth_mesh_network_t net;
+       GPtrArray *netkeys = NULL;
+       GSList *l;
+       int error_code = BT_ERROR_NONE;
+       uint16_t *netkey_idx = NULL;
+       int i;
+       int total;
+       bt_mesh_network_s *network_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       netkeys = g_ptr_array_new();
+       if (netkeys == NULL) {
+               BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_netkey(&net, &netkeys));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               g_ptr_array_free(netkeys, TRUE);
+               return error_code;
+       }
+
+       for (i = 0; i < netkeys->len; i++) {
+               netkey_idx = g_ptr_array_index(netkeys, i);
+               if (netkey_idx) {
+                       /* Create and insert netkey object in list */
+                       if (!__bt_mesh_network_is_netkey_added(network_s, *netkey_idx)) {
+                               bt_mesh_netkey_s *nk;
+                               nk = g_malloc0(sizeof(bt_mesh_netkey_s));
+                               nk->parent = network_s;
+                               nk->netkey_index = *netkey_idx;
+                               network_s->netkeys = g_slist_append(network_s->netkeys, nk);
+                               netkey_list = g_slist_append(netkey_list, nk);
+                       }
+
+               } else {
+                       BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                       BT_ERROR_OPERATION_FAILED);
+                       error_code = BT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+       }
+
+       total = g_slist_length(network_s->netkeys);
+       if (total == 0) {
+               BT_INFO("Mesh: No netkey added in network");
+               callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
+                               NULL, 0xFFFF, user_data);
+       }
+       for (l = network_s->netkeys; l != NULL; l = g_slist_next(l)) {
+               bt_mesh_netkey_s *netkey;
+               netkey = l->data;
+
+               if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
+                                       (bt_mesh_netkey_h) netkey,
+                                       netkey->netkey_index, user_data)) {
+                       break;
+               }
+       }
+
+       g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
+       g_ptr_array_free(netkeys, TRUE);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_netkey_get_index(bt_mesh_netkey_h netkey, uint16_t *index)
+{
+       bt_mesh_netkey_s *netkey_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(netkey);
+       BT_CHECK_INPUT_PARAMETER(index);
+
+       BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
+
+       netkey_s = (bt_mesh_netkey_s*)netkey;
+       *index = netkey_s->netkey_index;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_netkey_update(bt_mesh_netkey_h netkey)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_netkey_s *netkey_s;
+       bluetooth_mesh_network_t net;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(netkey);
+
+       netkey_s = (bt_mesh_netkey_s*)netkey;
+       network_s = netkey_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_update_netkey(
+                               &net, netkey_s->netkey_index));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_netkey_delete(bt_mesh_netkey_h netkey)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_netkey_s *netkey_s;
+       bluetooth_mesh_network_t net;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(netkey);
+
+       netkey_s = (bt_mesh_netkey_s*)netkey;
+       network_s = netkey_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_delete_netkey(&net, netkey_s->netkey_index));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       network_s->netkeys = g_slist_remove(network_s->netkeys, netkey_s);
+       netkey_list = g_slist_remove(netkey_list, netkey_s);
+       g_slist_free_full(netkey_s->appkeys, g_free);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_netkey_add_appkey(bt_mesh_netkey_h netkey,
+               bt_mesh_appkey_h *appkey)
+{
+       int error_code = BT_ERROR_NONE;
+       uint16_t appkey_idx;
+       bt_mesh_network_s *network_s;
+       bt_mesh_netkey_s *netkey_s;
+       bt_mesh_appkey_s *appkey_s;
+       bluetooth_mesh_network_t net;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(netkey);
+       BT_CHECK_INPUT_PARAMETER(appkey);
+
+       netkey_s = (bt_mesh_netkey_s*)netkey;
+       network_s = netkey_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_add_appkey(
+                               &net, netkey_s->netkey_index, &appkey_idx));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       /* Create Appkey object */
+       appkey_s = g_malloc0(sizeof(bt_mesh_appkey_s));
+       appkey_s->parent = netkey_s;
+       appkey_s->appkey_index = appkey_idx;
+       netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_s);
+       appkey_list = g_slist_append(appkey_list, appkey_s);
+       *appkey = (bt_mesh_appkey_h)appkey_s;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_appkey_update(bt_mesh_appkey_h appkey)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_netkey_s *netkey_s;
+       bt_mesh_appkey_s *appkey_s;
+       bluetooth_mesh_network_t net;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(appkey);
+
+       appkey_s = (bt_mesh_appkey_s*)appkey;
+       netkey_s = appkey_s->parent;
+       network_s = netkey_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_update_appkey(
+                               &net, netkey_s->netkey_index, appkey_s->appkey_index));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_appkey_delete(bt_mesh_appkey_h appkey)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_netkey_s *netkey_s;
+       bt_mesh_appkey_s *appkey_s;
+       bluetooth_mesh_network_t net;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(appkey);
+
+       appkey_s = (bt_mesh_appkey_s*)appkey;
+       netkey_s = appkey_s->parent;
+       network_s = netkey_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_delete_appkey(
+                       &net, netkey_s->netkey_index, appkey_s->appkey_index));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       /* Delete Appkey Object */
+       netkey_s->appkeys = g_slist_remove(netkey_s->appkeys, appkey_s);
+       appkey_list = g_slist_remove(appkey_list, appkey_s);
+       g_free(appkey_s);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_netkey_foreach_appkeys(bt_mesh_netkey_h netkey,
+               bt_mesh_appkey_info_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_netkey_s *netkey_s;
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_network_t net;
+       int total;
+       int i;
+       GSList *l;
+       GPtrArray *appkeys = NULL;
+       uint16_t *appkey_idx = NULL;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(netkey);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
+
+       netkey_s = (bt_mesh_netkey_s*)netkey;
+       network_s = netkey_s->parent;
+
+       appkeys = g_ptr_array_new();
+       if (appkeys == NULL) {
+               BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       BT_INFO("Mesh: Find all Appkeys for Netkey : index [%d]", netkey_s->netkey_index);
+       error_code = _bt_get_error_code(bluetooth_mesh_netkey_get_all_appkey(
+                       &net, netkey_s->netkey_index, &appkeys));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               g_ptr_array_free(appkeys, TRUE);
+               return error_code;
+       }
+       for (i = 0; i < appkeys->len; i++) {
+               appkey_idx = g_ptr_array_index(appkeys, i);
+               if (appkey_idx) {
+                       /* Create and insert netkey object in list */
+                       if (!__bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx)) {
+                               bt_mesh_appkey_s *key;
+                               key = g_malloc0(sizeof(bt_mesh_appkey_s));
+                               key->parent = netkey_s;
+                               key->appkey_index = *appkey_idx;
+                               netkey_s->appkeys = g_slist_append(netkey_s->appkeys, key);
+                               appkey_list = g_slist_append(appkey_list, key);
+                       }
+
+               } else {
+                       BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                       BT_ERROR_OPERATION_FAILED);
+                       error_code = BT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+       }
+
+       total = g_slist_length(netkey_s->appkeys);
+       BT_INFO("Mesh: Total appkeys [%d]", total);
+
+       if (!total) {
+               BT_INFO("Mesh: No AppKey added in NetKey yet!");
+               callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
+                               (bt_mesh_netkey_h) netkey_s, NULL,
+                               0xFFFF, user_data);
+               return BT_ERROR_NONE;
+       }
+
+
+       for (l = netkey_s->appkeys; l; l = g_slist_next(l)) {
+               bt_mesh_appkey_s *appkey_s;
+               appkey_s = l->data;
+               if (!callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
+                                       (bt_mesh_netkey_h) netkey_s, (bt_mesh_appkey_h) appkey_s,
+                                       appkey_s->appkey_index, user_data))
+                       break;
+       }
+
+       g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
+       g_ptr_array_free(appkeys, TRUE);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_appkey_get_index(bt_mesh_appkey_h appkey, uint16_t *index)
+{
+       bt_mesh_appkey_s *appkey_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(appkey);
+       BT_CHECK_INPUT_PARAMETER(index);
+
+       BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
+
+       appkey_s = (bt_mesh_appkey_s*)appkey;
+       *index = appkey_s->appkey_index;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+/* Sync API's to bt-service: Discovery API's */
+int bt_mesh_network_foreach_devices(bt_mesh_network_h network,
+               bt_mesh_network_device_info_cb callback, void *user_data)
+{
+       bluetooth_mesh_network_t net;
+       bluetooth_mesh_node_info_t *node_info;
+       GPtrArray *nodes = NULL;
+       int error_code = BT_ERROR_NONE;
+       int i;
+       bt_mesh_network_s *network_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       nodes = g_ptr_array_new();
+       if (nodes == NULL) {
+               BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_nodes(&net, &nodes));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               g_ptr_array_free(nodes, TRUE);
+               return error_code;
+       }
+
+       BT_INFO("Mesh: Total number of Devices found [%d]", nodes->len);
+       for (i = 0; i < nodes->len; i++) {
+               node_info = g_ptr_array_index(nodes, i);
+               if (node_info) {
+                       if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, nodes->len,
+                                       node_info->dev_uuid, node_info->primary_unicast, user_data)) {
+                               break;
+                       }
+               } else {
+                       BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                       BT_ERROR_OPERATION_FAILED);
+                       error_code = BT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+       }
+
+       g_ptr_array_foreach(nodes, (GFunc)g_free, NULL);
+       g_ptr_array_free(nodes, TRUE);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_node_get_primary_address(bt_mesh_node_h node,
+               uint16_t *primary_address)
+{
+       bt_mesh_node_s *node_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(primary_address);
+
+       BT_MESH_VALIDATE_HANDLE(node, node_list);
+
+       node_s = (bt_mesh_node_s*) node;
+       *primary_address = node_s->unicast;
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_foreach_element(bt_mesh_node_h node,
+       bt_mesh_node_element_info_cb callback, void *user_data)
+{
+       bt_mesh_node_s *node_s;
+       int total = 0;
+       GSList *l;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(node, node_list);
+       node_s = (bt_mesh_node_s*) node;
+
+       /* Only for Node which is attached to the Network */
+#if 0
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+#endif
+       total = g_slist_length(node_s->elements);
+       if (!total) {
+               callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
+                       (bt_mesh_element_h) NULL, -1, 0xFFFF,  user_data);
+
+       }
+
+       for (l = node_s->elements; l; l = g_slist_next(l)) {
+               bt_mesh_element_s *element_s;
+               element_s = l->data;
+               if (!callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
+                                       (bt_mesh_element_h)element_s, element_s->index,
+                                       (node_s->unicast + element_s->index), user_data))
+                       break;
+       }
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_element_foreach_models(bt_mesh_element_h element,
+       bt_mesh_element_model_info_cb callback, void *user_data)
+{
+       bluetooth_mesh_network_t net;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_element_s *element_s;
+
+       GPtrArray *models = NULL;
+       uint32_t *model_info;
+       int error_code = BT_ERROR_NONE;
+       int i;
+       int total;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(element);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(element, element_list);
+
+       element_s = (bt_mesh_element_s*) element;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       /* Only for local Node */
+       if (node_s->is_local) {
+               GSList *l;
+               BT_INFO("Mesh: Local element");
+
+               total = g_slist_length(element_s->models);
+               if (!total)
+                       callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, 0,
+                                       (bt_mesh_model_h) NULL, NULL, user_data);
+
+               for (l = element_s->models; l; l = l->next) {
+                       bt_mesh_model_s *model_s = l->data;
+                       bt_mesh_model_id_s modid;
+
+                       modid.company_id = model_s->id >> 16;
+                       modid.model_id = model_s->id;
+
+                       if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
+                                               (bt_mesh_model_h) model_s,
+                                               &modid, user_data)) {
+                               break;
+                       }
+               }
+               FUNC_EXIT;
+               return BT_ERROR_NONE;
+       }
+
+       models = g_ptr_array_new();
+       if (models == NULL) {
+               BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_element_get_all_models(&net,
+                               /* Node identity */node_s->unicast,
+                               /* eleement identity */element_s->index,
+                               /*Output*/ &models));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               g_ptr_array_free(models, TRUE);
+               return error_code;
+       }
+
+       total = models->len;
+       for (i = 0; i < models->len; i++) {
+               model_info = g_ptr_array_index(models, i);
+               if (model_info) {
+                       /* Create and insert model object in list */
+                       bt_mesh_model_s *mod;
+                       bt_mesh_model_id_s modid;
+                       mod = g_malloc0(sizeof(bt_mesh_model_s));
+                       mod->parent = element_s;
+                       if (node_s->unicast == 0x0001) {
+                               mod->is_local = true;
+                       }
+                       mod->id = *model_info;
+                       element_s->models = g_slist_append(element_s->models, mod);
+                       model_list = g_slist_append(model_list, mod);
+
+                       modid.company_id = *model_info >> 16;
+                       modid.model_id = *model_info;
+                       /* Send Callback */
+                       if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
+                                               (bt_mesh_model_h) mod,
+                                               &modid, user_data)) {
+                               break;
+                       }
+               } else {
+                       BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                       BT_ERROR_OPERATION_FAILED);
+                       error_code = BT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+       }
+
+       g_ptr_array_foreach(models, (GFunc)g_free, NULL);
+       g_ptr_array_free(models, TRUE);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+/* Provisioning & capabilities related*/
+int bt_mesh_network_unprovisioned_device_scan(bt_mesh_network_h network,
+               bt_mesh_scan_params_s *scan_params,
+                       bt_mesh_network_scan_unprovisioned_device_result_cb callback,
+                               void *user_data)
+{
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_network_t net;
+       int error_code = BT_ERROR_NONE;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(scan_params);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_scan(
+                       &net, (bluetooth_mesh_scan_param_t*) scan_params));
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       _bt_set_cb(BT_EVENT_MESH_NETWORK_SCAN_STATE_CHANGED, callback, user_data);
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_stop_unprovisioned_device_scan(bt_mesh_network_h network)
+{
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_network_t net;
+       int error_code = BT_ERROR_NONE;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_cancel_scan(&net));
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_network_set_provisioning_capabilities(bt_mesh_network_h network,
+               bt_mesh_provisioner_capabilities_s *capabilities)
+{
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_network_t net;
+       bluetooth_mesh_provisioner_caps_t caps;
+       int error_code = BT_ERROR_NONE;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(capabilities);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+       memset(&caps, 0x00, sizeof(bluetooth_mesh_provisioner_caps_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       caps.public_oob = capabilities->public_oob;
+       caps.static_oob = capabilities->static_oob;
+       caps.out_oob = capabilities->out_oob;
+       caps.in_oob = capabilities->in_oob;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_set_capabilities(
+                                       &net,(bluetooth_mesh_provisioner_caps_t*) &caps));
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_network_provision_device(bt_mesh_network_h network,
+               const char *dev_uuid,
+                       bt_mesh_network_device_provision_cb callback,
+                               void *user_data)
+{
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_provisioning_request_t req;
+       int error_code = BT_ERROR_NONE;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(dev_uuid);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&req, 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       g_strlcpy(req.dev_uuid, dev_uuid, 33);
+
+       BT_INFO("Mesh: Provision Device [%s]", dev_uuid);
+       error_code = _bt_get_error_code(bluetooth_mesh_network_provision_device(&req));
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       _bt_set_cb(BT_EVENT_MESH_NETWORK_PROVISIONING_RESULT, callback, user_data);
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_authentication_set_request_cb(bt_mesh_authentication_request_cb callback, void *user_data)
+{
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       _bt_set_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST, callback, user_data);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_authentication_unset_request_cb(bt_mesh_authentication_request_cb callback)
+{
+       FUNC_ENTRY;
+
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       _bt_unset_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST);
+
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_authentication_reply(bt_mesh_authentication_type_e auth_type, const char *value,  bool auth_reply)
+{
+       int error_code = BT_ERROR_NONE;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(value);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_authentication_reply(auth_type, value, auth_reply));
+       if (error_code != BT_ERROR_NONE)
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_network_discover_node(bt_mesh_network_h network,
+               const char *dev_uuid, bt_mesh_node_discover_status_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_node_discover_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(dev_uuid);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+
+       /* Check if node with dev_uuid is already created */
+       network_s = (bt_mesh_network_s*)network;
+       memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       g_strlcpy(req.dev_uuid, dev_uuid, 33);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_browse_remote_node(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_BROWSING_COMPLETED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_configure_netkey(bt_mesh_node_h node, bt_mesh_node_key_configuration_e netkey_op,
+                                       bt_mesh_netkey_h netkey,  bt_mesh_netkey_status_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_netkey_s *netkey_s;
+       bluetooth_mesh_key_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(netkey);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       node_s = (bt_mesh_node_s*) node;
+       network_s = node_s->parent;
+       netkey_s = (bt_mesh_netkey_s*) netkey;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       /* Return error, if netkey is not present in the specific network */
+       if (netkey_s->parent != network_s)
+               return BT_ERROR_INVALID_PARAMETER;
+
+#if 0
+       /* Return Already done, if netkey is present in the node */
+       if (g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_s,
+                               (GCompareFunc)__simple_compare))
+               return BT_ERROR_ALREADY_DONE;
+#endif
+       memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.netkey_idx = netkey_s->netkey_index;
+       req.is_netkey = true;
+       req.op = (bluetooth_mesh_node_key_conf_e) netkey_op;
+
+       BT_INFO("Mesh: Add NetKey Idx [%d] to node", req.netkey_idx);
+       error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_configure_appkey(bt_mesh_node_h node, bt_mesh_node_key_configuration_e appkey_op,
+                                       bt_mesh_appkey_h appkey, bt_mesh_appkey_status_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_netkey_s *netkey_s;
+       bt_mesh_appkey_s *appkey_s;
+       bluetooth_mesh_key_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(appkey);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       node_s = (bt_mesh_node_s*) node;
+       network_s = node_s->parent;
+       appkey_s = (bt_mesh_appkey_s*) appkey;
+       netkey_s = (bt_mesh_netkey_s*) appkey_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       /* Return error, if netkey is not present in the specific network */
+       if (netkey_s->parent != network_s)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       /* Return Already done, if appkey is present in the node */
+       if (g_slist_find_custom(node_s->appkeys,(gconstpointer) appkey_s,
+                               (GCompareFunc)__simple_compare))
+               return BT_ERROR_ALREADY_DONE;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.netkey_idx = netkey_s->netkey_index;
+       req.appkey_idx = appkey_s->appkey_index;
+       req.is_netkey = false;
+       req.op = (bluetooth_mesh_node_key_conf_e) appkey_op;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+
+/* Remote Node Operations: CONFIG: Non Key */
+int bt_mesh_node_get_features(bt_mesh_node_h node, bt_mesh_node_features_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bluetooth_mesh_node_features_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       node_s = (bt_mesh_node_s*) node;
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_node_features_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.unicast = node_s->unicast;
+       req.elem_count = node_s->unicast;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_node_browse_vendor_features(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_VENDOR_FEATURES, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_get_ttl(bt_mesh_node_h node, bt_mesh_node_ttl_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bluetooth_mesh_node_ttl_info_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       node_s = (bt_mesh_node_s*) node;
+       network_s = node_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.unicast = node_s->unicast;
+       req.is_set = false;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_set_ttl(bt_mesh_node_h node, uint8_t ttl, bt_mesh_node_ttl_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bluetooth_mesh_node_ttl_info_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       node_s = (bt_mesh_node_s*) node;
+       network_s = node_s->parent;
+       BT_CHECK_INPUT_PARAMETER(network_s);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.unicast = node_s->unicast;
+       req.is_set = true;
+       req.ttl = ttl;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_node_foreach_netkeys(bt_mesh_node_h node, bt_mesh_node_netkey_info_cb callback, void *user_data)
+{
+       GPtrArray *netkeys = NULL;
+       GSList *l;
+       int error_code = BT_ERROR_NONE;
+       uint16_t *netkey_idx = NULL;
+       int i;
+       int total;
+       bluetooth_mesh_node_discover_t req;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       node_s = (bt_mesh_node_s*) node;
+       network_s = node_s->parent;
+
+       BT_CHECK_INPUT_PARAMETER(network_s);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       netkeys = g_ptr_array_new();
+       if (netkeys == NULL) {
+               BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.unicast = node_s->unicast;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_netkeys(&req, &netkeys));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               g_ptr_array_free(netkeys, TRUE);
+               return error_code;
+       }
+
+       BT_INFO("Mesh: Total netkeys added in node is [%d]", netkeys->len);
+       for (i = 0; i < netkeys->len; i++) {
+               bt_mesh_netkey_s *netkey_local;
+               netkey_idx = g_ptr_array_index(netkeys, i);
+               BT_INFO("Mesh: NetKey IDX [0x%2.2x]", *netkey_idx);
+               if (netkey_idx) {
+                       /* Check if netkey index is present in network or not */
+                       netkey_local = __bt_mesh_network_is_netkey_added(network_s, *netkey_idx);
+                       if (!netkey_local) {
+                               BT_ERR("Mesh: Network does not contain the netKey index, possibly reloaded");
+                               /* Create Netkey object */
+                               netkey_local = g_malloc0(sizeof(bt_mesh_netkey_s));
+                               netkey_local->parent = network_s;
+                               netkey_local->netkey_index = *netkey_idx;
+                               network_s->netkeys = g_slist_append(network_s->netkeys, netkey_local);
+                               netkey_list = g_slist_append(netkey_list, netkey_local);
+
+                               if (!g_slist_find_custom(node_s->netkeys, GUINT_TO_POINTER(*netkey_idx),
+                                                       (GCompareFunc)__compare_netkey_index))
+                                       node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
+                       } else {
+                               /* Check if netkey index is present in target node or not */
+                               if (!g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_local,
+                                                       (GCompareFunc)__simple_compare)) {
+                                       node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
+                               } else {
+                                       /* DO NOTHING*/
+                                       BT_INFO("Mesh: Netkey is already added in node");
+                               }
+                       }
+               } else {
+                       BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                       BT_ERROR_OPERATION_FAILED);
+                       error_code = BT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+       }
+
+       total = g_slist_length(node_s->netkeys);
+       if (total == 0) {
+               BT_ERR("Mesh: Unexpcted: No netkey added in node!!");
+               callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
+                               NULL, 0xFFFF, user_data);
+       }
+       for (l = node_s->netkeys; l != NULL; l = g_slist_next(l)) {
+               bt_mesh_netkey_s *netkey;
+               netkey = l->data;
+
+               if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
+                                       (bt_mesh_netkey_h) netkey,
+                                       netkey->netkey_index, user_data)) {
+                       break;
+               }
+       }
+
+       g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
+       g_ptr_array_free(netkeys, TRUE);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node, bt_mesh_netkey_h netkey,
+               bt_mesh_node_appkey_info_cb callback, void *user_data)
+{
+       GPtrArray *appkeys = NULL;
+       GSList *l;
+       int error_code = BT_ERROR_NONE;
+       int i;
+       int total;
+       bluetooth_mesh_node_discover_t req;
+       uint16_t *appkey_idx = NULL;
+       bt_mesh_network_s *network_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_netkey_s *netkey_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(node);
+       BT_CHECK_INPUT_PARAMETER(netkey);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       node_s = (bt_mesh_node_s*) node;
+       network_s = node_s->parent;
+       netkey_s = (bt_mesh_netkey_s*) netkey;
+
+       BT_CHECK_INPUT_PARAMETER(network_s);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       appkeys = g_ptr_array_new();
+       if (appkeys == NULL) {
+               BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.unicast = node_s->unicast;
+       req.netkey_idx = netkey_s->netkey_index;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_appkeys(&req, &appkeys));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               g_ptr_array_free(appkeys, TRUE);
+               return error_code;
+       }
+
+       BT_INFO("Mesh: Total appkeys found in Node [%d]", appkeys->len);
+       for (i = 0; i < appkeys->len; i++) {
+               bt_mesh_appkey_s *appkey_local;
+               appkey_idx = g_ptr_array_index(appkeys, i);
+               BT_INFO("Mesh: AppKey index [0x%2.2x]", *appkey_idx);
+               if (appkey_idx) {
+                       /* Check if netkey index is present in network or not */
+                       appkey_local = __bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx);
+
+                       if (!appkey_local) {
+                               BT_ERR("Mesh: Network does not AppKey index, possibly Network reloaded!!");
+                               /* Create Netkey object */
+                               appkey_local = g_malloc0(sizeof(bt_mesh_netkey_s));
+                               appkey_local->parent = netkey_s;
+                               appkey_local->appkey_index = *appkey_idx;
+                               netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_local);
+                               appkey_list = g_slist_append(appkey_list, appkey_local);
+
+                               if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
+                                                       (GCompareFunc)__compare_appkey_index))
+                                       node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
+                       } else {
+                               /* Check if netkey index is present in target node or not */
+                               if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
+                                                       (GCompareFunc)__compare_appkey_index)) {
+                                       node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
+                               } else {
+                                       /* DO NOTHING*/
+                                       BT_INFO("Mesh: AppKey is already added in node");
+                               }
+                       }
+               } else {
+                       BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                       BT_ERROR_OPERATION_FAILED);
+                       error_code = BT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+       }
+
+       total = g_slist_length(node_s->appkeys);
+       if (total == 0) {
+               BT_ERR("Mesh:Possible: No appkey added in node!!");
+               callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
+                               (bt_mesh_netkey_h) netkey_s, NULL, 0xFFFF, user_data);
+       }
+       for (l = node_s->appkeys; l != NULL; l = g_slist_next(l)) {
+               bt_mesh_appkey_s *appkey_s;
+               appkey_s = l->data;
+
+               if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
+                                       (bt_mesh_netkey_h) netkey, (bt_mesh_appkey_h) appkey_s,
+                                       appkey_s->appkey_index, user_data)) {
+                       break;
+               }
+       }
+
+       g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
+       g_ptr_array_free(appkeys, TRUE);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_model_bind_appkey(bt_mesh_model_h model,
+       bt_mesh_appkey_h appkey, bt_mesh_model_bind_cb callback,
+               void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_network_s *network_s;
+       bt_mesh_appkey_s *appkey_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(appkey);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       appkey_s = (bt_mesh_appkey_s*) appkey;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.elem_index = element_s->index;
+       req.model = model_s->id;
+       req.appkey_idx = appkey_s->appkey_index;
+       req.is_bind = true;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_model_unbind_appkey(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
+               bt_mesh_model_unbind_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_appkey_s *appkey_s;
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(appkey);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       appkey_s = (bt_mesh_appkey_s*) appkey;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.elem_index = element_s->index;
+       req.model = model_s->id;
+       req.appkey_idx = appkey_s->appkey_index;
+       req.is_bind = false;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_model_get_appkey_list(bt_mesh_model_h model,
+               bt_mesh_model_appkey_list_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       BT_CHECK_INPUT_PARAMETER(model_s);
+       BT_CHECK_INPUT_PARAMETER(element_s);
+       BT_CHECK_INPUT_PARAMETER(node_s);
+       BT_CHECK_INPUT_PARAMETER(network_s);
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.elem_index = element_s->index;
+       req.model = model_s->id;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_get_all_appkeys(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_APPKEY_LIST, callback, user_data);
+       return error_code;
+}
+
+int bt_mesh_network_foreach_groups(bt_mesh_network_h network,
+               bt_mesh_network_group_info_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bluetooth_mesh_network_t net;
+       bt_mesh_network_s *network_s;
+       GPtrArray *groups = NULL;
+       GSList *l;
+       uint16_t *group_addr = NULL;
+       int i;
+       int total;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_MESH_VALIDATE_HANDLE(network, networks);
+
+       groups = g_ptr_array_new();
+       if (groups == NULL) {
+               BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       network_s = (bt_mesh_network_s*)network;
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_groups(&net, &groups));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               g_ptr_array_free(groups, TRUE);
+               return error_code;
+       }
+
+       for (i = 0; i < groups->len; i++) {
+               group_addr = g_ptr_array_index(groups, i);
+               if (group_addr) {
+                       /* Find or create group in network list */
+                       if (!_bt_mesh_network_get_group(network_s, *group_addr)) {
+                               BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                               BT_ERROR_OPERATION_FAILED);
+                               error_code = BT_ERROR_OPERATION_FAILED;
+                               break;
+                       }
+               } else {
+                       BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
+                                       BT_ERROR_OPERATION_FAILED);
+                       error_code = BT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+       }
+
+       total = g_slist_length(network_s->groups);
+       if (total == 0) {
+               BT_INFO("Mesh: No Groups added in network");
+               callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
+                               NULL, user_data);
+       }
+       for (l = network_s->groups; l != NULL; l = g_slist_next(l)) {
+               bt_mesh_group_s *group_s;
+               group_s = l->data;
+
+               if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
+                                       (bt_mesh_group_h) group_s,
+                                       user_data))
+                       break;
+       }
+
+       g_ptr_array_foreach(groups, (GFunc)g_free, NULL);
+       g_ptr_array_free(groups, TRUE);
+
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_network_create_virtual_group(bt_mesh_network_h network,
+        bt_mesh_group_h *group)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_group_s *group_s;
+       bluetooth_mesh_network_group_info_t req;
+       bluetooth_mesh_network_t net;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+
+       network_s = (bt_mesh_network_s*) network;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+       memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, true, 0x0000, &req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       group_s = g_malloc0(sizeof(bt_mesh_group_s));
+       group_s->addr = req.group_addr;
+       group_s->is_virtual = true;
+       group_s->parent = network_s;
+       if (g_slist_append(network_s->groups, group_s))
+               BT_INFO("Mesh: Group created");
+
+       __bt_mesh_util_convert_hex_to_string((uint8_t *)req.label_uuid, 16,
+                       group_s->label_uuid, sizeof(group_s->label_uuid));
+
+       group_list = g_slist_append(group_list, group_s);
+       *group = (bt_mesh_group_h) group_s;
+       FUNC_EXIT;
+       return error_code;
+}
+
+int bt_mesh_network_remove_group(bt_mesh_group_h group)
+{
+       bt_mesh_network_s *network_s;
+       bt_mesh_group_s *group_s;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_INPUT_PARAMETER(group);
+
+       group_s = (bt_mesh_group_s*) group;
+       network_s = group_s->parent;
+
+       BT_MESH_VALIDATE_HANDLE(group_s, group_list);
+
+       network_s->groups = g_slist_remove(network_s->groups, group_s);
+       group_list = g_slist_remove(group_list, group_s);
+
+       g_free(group_s);
+       FUNC_EXIT;
+       return BT_ERROR_NONE;
+}
+
+int bt_mesh_network_create_group(bt_mesh_network_h network,
+               uint16_t grp_addr, bt_mesh_group_h *group)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_network_s *network_s;
+       bt_mesh_group_s *group_s;
+       bluetooth_mesh_network_t net;
+       bluetooth_mesh_network_group_info_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(network);
+
+       network_s = (bt_mesh_network_s*) network;
+
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+       memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
+
+       /* Fill Network Info */
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, false, grp_addr, &req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       group_s = g_malloc0(sizeof(bt_mesh_group_s));
+       group_s->addr = grp_addr;
+       group_s->is_virtual = false;
+       group_s->parent = network_s;
+       if (g_slist_append(network_s->groups, group_s))
+               BT_INFO("Mesh: Group created");
+
+       group_list = g_slist_append(group_list, group_s);
+       *group = (bt_mesh_group_h) group_s;
+       FUNC_EXIT;
+       return error_code;
+}
+
+
+int bt_mesh_model_configure_group_subscription(bt_mesh_model_subscription_op_e model_op,
+               bt_mesh_model_h model, bt_mesh_group_h group,
+                       bt_mesh_model_subscription_op_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_network_s *network_s;
+       bt_mesh_group_s *group_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(group);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       group_s = (bt_mesh_group_s*) model;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       /* Check group belongs to the same network */
+       if (network_s != group_s->parent)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       /* Check group is non virtual */
+       if (group_s->is_virtual)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       BT_CHECK_INPUT_PARAMETER(element_s);
+       BT_CHECK_INPUT_PARAMETER(node_s);
+       BT_CHECK_INPUT_PARAMETER(network_s);
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(group_s, group_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
+               req.sub_addr = group_s->addr;
+       req.is_virtual_sub = false;
+       req.op = model_op;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_configure_group_sub(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_SUB, callback, user_data);
+       return error_code;
+}
+
+int bt_mesh_model_configure_virtual_group_subscription(bt_mesh_model_subscription_op_e model_op,
+               bt_mesh_model_h model, bt_mesh_group_h group,
+                       bt_mesh_model_subscription_op_cb callback,
+                               void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_network_s *network_s;
+       bt_mesh_group_s *group_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(group);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       group_s = (bt_mesh_group_s*) model;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       /* Check group belongs to the same network */
+       if (network_s != group_s->parent)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       /* Check group is non virtual */
+       if (!group_s->is_virtual)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       BT_CHECK_INPUT_PARAMETER(element_s);
+       BT_CHECK_INPUT_PARAMETER(node_s);
+       BT_CHECK_INPUT_PARAMETER(network_s);
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(group_s, group_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
+               req.sub_addr = group_s->addr;
+
+       req.is_virtual_sub = true;
+       req.op = model_op;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_configure_virtual_group_sub(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_VIR_SUB, callback, user_data);
+       return error_code;
+}
+
+int bt_mesh_model_get_subscription_list(bt_mesh_model_h model,
+                bt_mesh_model_subscription_list_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       BT_CHECK_INPUT_PARAMETER(model_s);
+       BT_CHECK_INPUT_PARAMETER(element_s);
+       BT_CHECK_INPUT_PARAMETER(node_s);
+       BT_CHECK_INPUT_PARAMETER(network_s);
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.elem_index = element_s->index;
+       req.model = model_s->id;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_get_subscriptopn_list(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_APPKEY_LIST, callback, user_data);
+       return error_code;
+}
+
+int bt_mesh_model_set_publication(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
+               bt_mesh_group_h group,
+                        bt_mesh_model_pub_params_s *params,
+                               bt_mesh_model_publication_status_cb callback,
+                                       void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_appkey_s *appkey_s;
+       bt_mesh_network_s *network_s;
+       bt_mesh_group_s *group_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(appkey);
+       BT_CHECK_INPUT_PARAMETER(group);
+       BT_CHECK_INPUT_PARAMETER(params);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       appkey_s = (bt_mesh_appkey_s*) appkey;
+       group_s = (bt_mesh_group_s*) group;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       if (group_s->parent != network_s)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       if (params->num_steps > BT_MESH_MAX_PUBISH_PERIOD_STEPS)
+               return BT_ERROR_INVALID_PARAMETER;
+       if (params->retrans_cnt > BT_MESH_MAX_PUBISH_RETRANSMIT_COUNT)
+               return BT_ERROR_INVALID_PARAMETER;
+       if (params->retrans_step > BT_MESH_MAX_PUBISH_RETRANSMIT_INTERVAL_STEPS)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       BT_CHECK_INPUT_PARAMETER(element_s);
+       BT_CHECK_INPUT_PARAMETER(node_s);
+       BT_CHECK_INPUT_PARAMETER(network_s);
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+       BT_MESH_VALIDATE_HANDLE(group_s, group_list);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.elem_index = element_s->index;
+       req.model = model_s->id;
+       req.appkey_idx = appkey_s->appkey_index;
+       req.pub_addr = group_s->addr;
+
+       req.ttl = params->ttl;
+       req.period = params->num_steps;
+       req.period = req.period << 2;
+       req.period |= params->per_res;
+       req.retransmit = params->retrans_cnt;
+       req.retransmit = req.retransmit << 5;
+       req.retransmit |= params->retrans_step;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_set_publication(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);
+       return error_code;
+}
+
+int bt_mesh_model_get_publication(bt_mesh_model_h model,
+               bt_mesh_model_publication_status_cb callback, void *user_data)
+{
+       int error_code = BT_ERROR_NONE;
+       bt_mesh_model_s *model_s;
+       bt_mesh_element_s *element_s;
+       bt_mesh_node_s *node_s;
+       bt_mesh_network_s *network_s;
+       bluetooth_mesh_model_configure_t req;
+
+       FUNC_ENTRY;
+       BT_CHECK_MESH_SUPPORT();
+       BT_CHECK_MESH_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(model);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       model_s = (bt_mesh_model_s*) model;
+       element_s = (bt_mesh_element_s*) model_s->parent;
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       network_s = (bt_mesh_network_s*) node_s->parent;
+
+       BT_CHECK_INPUT_PARAMETER(model_s);
+       BT_CHECK_INPUT_PARAMETER(element_s);
+       BT_CHECK_INPUT_PARAMETER(node_s);
+       BT_CHECK_INPUT_PARAMETER(network_s);
+
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
+       BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+       BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
+
+       /* Return error, if node is not attached */
+       if (!node_s->is_attached)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
+
+       g_strlcpy(req.net_uuid, network_s->uuid, 33);
+       req.primary_unicast = node_s->unicast;
+       req.elem_index = element_s->index;
+       req.model = model_s->id;
+
+       error_code = _bt_get_error_code(bluetooth_mesh_model_get_publication(&req));
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+               return error_code;
+       }
+
+       FUNC_EXIT;
+       _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);
+       return error_code;
+}