Fix coverty issues
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-mesh-dbus-handler.c
index cfa12e8..be91742 100644 (file)
@@ -63,7 +63,7 @@ static struct l_dbus_proxy *net_proxy = NULL;
 static struct l_dbus_message *agent_msg;
 
 static handle_stack_msg mesh_event_cb = NULL;
-
+static uint32_t iv_index;
 
 struct subnet_key_request {
        uint16_t idx;
@@ -99,6 +99,11 @@ struct mesh_provision_auth_action {
        bt_hal_mesh_auth_variant_e auth_type;
 };
 
+struct mesh_remote_node_info {
+       uint16_t unicast;
+       uint8_t num_elements;
+};
+
 static struct mesh_provision_auth_action auth_table[] = {
        { "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
        { "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
@@ -353,6 +358,12 @@ static void __bt_hal_mesh_destroy_app_object(gpointer data)
                                g_slist_length(app->elements));
                g_slist_free_full(app->elements, __mesh_hal_free_elements);
        }
+
+       if (app->scan_timer_id > 0) {
+               INFO("Mesh: Remove timer if already running");
+               g_source_remove(app->scan_timer_id);
+               app->scan_timer_id = 0;
+       }
        g_free(app);
 }
 
@@ -392,21 +403,32 @@ static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
        char *app_uuid_path;
        const meshcfg_app *app = (meshcfg_app*) data;
        char *path = (char *) user_data;
-       INFO("Mesh: proxy path compare: path [%s]", path);
-       INFO("Mesh: App Path  path [%s]", app->path);
        if (!path)
                return -1;
 
        app_uuid_path = l_util_hexstring(app->uuid, 16);
-       INFO("Mesh:App UUID string [%s]", app_uuid_path);
        char **strings =  g_strsplit(path, "node", 2);
 
-       INFO("Mesh:String 0 [%s]", strings[0]);
-       INFO("Mesh:String 1 [%s]", strings[1]);
        ret = g_strcmp0(strings[1], app_uuid_path);
-       g_free(strings[0]);
-       g_free(strings[1]);
+
+       g_strfreev(strings);
        l_free(app_uuid_path);
+
+       return ret;
+}
+
+static gint __compare_dbus_path(gconstpointer data, gconstpointer user_data)
+{
+       int ret = 0;
+       const meshcfg_app *app = (meshcfg_app*) data;
+       char *path = (char *) user_data;
+       if (!path) {
+               INFO("Mesh: NULL dbus path");
+               return -1;
+       }
+       char **strings =  g_strsplit(path, "/elem", 2);
+       ret = g_strcmp0(strings[0], app->path);
+       g_strfreev(strings);
        return ret;
 }
 
@@ -420,6 +442,21 @@ static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
        return (elem->index == elem_index ? 0 : -1);
 }
 
+static void __send_network_destroy_event(void *param, uint8_t status)
+{
+       struct hal_ev_mesh_network_destroyed ev;
+       meshcfg_app *app = (meshcfg_app*)param;
+
+       memset(&ev, 0, sizeof(ev));
+       memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
+       memcpy(ev.token, app->token.u8, 8);
+
+       ev.status = status;
+       if (mesh_event_cb)
+               mesh_event_cb(HAL_EV_MESH_NETWORK_DESTROYED,
+                       (void*)&ev, sizeof(ev));
+}
+
 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
 {
        const char *interface = l_dbus_proxy_get_interface(proxy);
@@ -428,11 +465,22 @@ static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
        INFO("MESH: Proxy added: %s (%s)\n", interface, path);
 
        if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
+               struct hal_ev_mesh_network_proxy_added ev;
                INFO("Mesh: Network Proxy added");
+
                /* Save Global proxy */
                net_proxy = proxy;
                if (net_proxy)
                        INFO("Mesh: Net Proxy [%p]", net_proxy);
+
+               memset(&ev, 0, sizeof(ev));
+               ev.status = BT_STATUS_SUCCESS;
+
+               /* Send event cb */
+               if (mesh_event_cb)
+                       mesh_event_cb(HAL_EV_MESH_NETWORK_PROXY_ADDED,
+                               (void*)&ev, sizeof(ev));
+
                return;
        }
 
@@ -489,7 +537,8 @@ static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
                l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
                if (l) {
                        app = l->data;
-                       /*TODO: Send event to app about removal of a mesh local node */
+                       /* Send event to app about removal of a mesh local node */
+                       __send_network_destroy_event(app, BT_STATUS_SUCCESS);
                        __bt_hal_mesh_destroy_app_object(app);
                } else {
                        ERR("Mesh: app not found for Mgmt proxy");
@@ -502,8 +551,8 @@ static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
                l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
                if (l) {
                        app = l->data;
-                       /*TODO: Send event to app about removal of
-                       a mesh local node: first send event, then destroy mesh object */
+                       /* Send event to app about removal of a mesh local node */
+                       __send_network_destroy_event(app, BT_STATUS_SUCCESS);
                        __bt_hal_mesh_destroy_app_object(app);
                } else {
                        ERR("Mesh: app not found for Mgmt proxy");
@@ -512,6 +561,43 @@ static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
        }
 }
 
+static void __mesh_property_changed(struct l_dbus_proxy *proxy, const char *name,
+                               struct l_dbus_message *msg, void *user_data)
+{
+       const char *interface = l_dbus_proxy_get_interface(proxy);
+       const char *path = l_dbus_proxy_get_path(proxy);
+       GSList *l;
+       meshcfg_app *app = NULL;
+
+       l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
+       if (l) {
+               app = l->data;
+       } else {
+               ERR("Mesh: app not found for Mgmt proxy");
+       }
+
+       INFO("Property changed: %s %s %s\n", name, path, interface);
+
+       if (!app)
+               return;
+
+       if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
+
+               if (!strcmp(name, "IvIndex")) {
+                       uint32_t ivi;
+
+                       if (!l_dbus_message_get_arguments(msg, "u", &ivi))
+                               return;
+
+                       INFO("New IV Index: %u\n", ivi);
+
+                       iv_index = ivi;
+                       /*TODO: save iv index */
+               }
+       }
+}
+
+
 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
                void *user_data)
 {
@@ -566,7 +652,7 @@ bool _bt_hal_mesh_stack_init(void)
                return false;
        if (!l_dbus_client_set_proxy_handlers(client,
                                __mesh_proxy_added, __mesh_proxy_removed,
-                               NULL, NULL, NULL))
+                               __mesh_property_changed, NULL, NULL))
                return false;
        if (!l_dbus_client_set_ready_handler(client,
                                __mesh_dbus_client_ready, NULL, NULL))
@@ -589,6 +675,12 @@ void _bt_hal_mesh_stack_deinit(void)
                l_dbus_destroy(dbus);
                dbus = NULL;
        }
+
+       /* Reset Globals */
+       net_proxy = NULL;
+       agent_msg = NULL;
+       INFO("Mesh: Number of meshapps present in memory [%d]",
+                       g_slist_length(mesh_apps));
 }
 
 /* To send stack event to hal-mesh handler */
@@ -664,6 +756,7 @@ static void __send_network_attach_event(void *param, uint8_t status)
        memset(&ev, 0, sizeof(ev));
        memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
        memcpy(ev.token, app->token.u8, 8);
+       ev.is_prov = app->is_prov;
 
        ev.status = status;
        if (mesh_event_cb)
@@ -677,6 +770,8 @@ static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
        struct l_dbus_message_iter iter_cfg;
        char *path;
        meshcfg_app *app = (meshcfg_app*) user_data;
+       uint32_t ivi;
+
        INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
                app->path, app->agent_path);
 
@@ -694,6 +789,13 @@ static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
 
        INFO("Mesh: Attached with path %s\n", app->path);
        __send_network_attach_event(app, BT_STATUS_SUCCESS);
+
+       if (l_dbus_proxy_get_property(app->proxy, "IvIndex", "u", &ivi) &&
+                                                       ivi != iv_index) {
+               iv_index = ivi;
+               /* TODO: Save IV index */
+       }
+
        return;
 failed:
        __send_network_attach_event(app, BT_STATUS_FAIL);
@@ -759,13 +861,36 @@ static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
        return l_dbus_message_new_method_return(message);
 }
 
+static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
+                const char *key, const char *signature,
+                const void *data)
+{
+        if (!builder)
+                return;
+
+        l_dbus_message_builder_enter_dict(builder, "sv");
+        l_dbus_message_builder_append_basic(builder, 's', key);
+        l_dbus_message_builder_enter_variant(builder, signature);
+        l_dbus_message_builder_append_basic(builder, signature[0], data);
+        l_dbus_message_builder_leave_variant(builder);
+        l_dbus_message_builder_leave_dict(builder);
+}
+
 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
                gpointer user_data)
 {
        struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
        meshcfg_model *model_info = (meshcfg_model*) data;
+       bool pub_enable = true;
+       bool sub_enable = true;
 
+       l_dbus_message_builder_enter_struct(builder, "qa{sv}");
        l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
+       l_dbus_message_builder_enter_array(builder, "{sv}");
+       append_dict_entry_basic(builder, "Subscribe", "b", &sub_enable);
+       append_dict_entry_basic(builder, "Publish", "b", &pub_enable);
+       l_dbus_message_builder_leave_array(builder);
+       l_dbus_message_builder_leave_struct(builder);
 }
 
 static bool __mesh_model_getter(struct l_dbus *dbus,
@@ -775,7 +900,7 @@ static bool __mesh_model_getter(struct l_dbus *dbus,
 {
        meshcfg_el *element = (meshcfg_el*) user_data;
 
-       l_dbus_message_builder_enter_array(builder, "q");
+       l_dbus_message_builder_enter_array(builder, "(qa{sv})");
        g_slist_foreach(element->models,
                __bt_hal_mesh_foreach_model_getter, builder);
 
@@ -790,7 +915,7 @@ static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
                        struct l_dbus_message_builder *builder,
                                void *user_data)
 {
-       l_dbus_message_builder_enter_array(builder, "(qq)");
+       l_dbus_message_builder_enter_array(builder, "(qqa{sv})");
        l_dbus_message_builder_leave_array(builder);
 
        return true;
@@ -868,9 +993,19 @@ static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
        uint32_t n;
        const char *dbus_path;
        uint16_t size;
+       bool is_provisioner = true;
        uint8_t *net_uuid;
        dbus_path =  l_dbus_message_get_path(msg);
-       net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,  MESH_ELEMENT_IFACE);
+       GSList *l = g_slist_find_custom(mesh_apps, dbus_path, __compare_dbus_path);
+       if (l) {
+               meshcfg_app *app = NULL;
+               app = l->data;
+               INFO("Mesh: is Provisioner [%d]", app->is_prov);
+               is_provisioner = app->is_prov;
+       } else {
+               ERR("Mesh: app is NULL");
+       }
+       net_uuid = __mesh_get_net_uuid_from_path(dbus_path, is_provisioner,  MESH_ELEMENT_IFACE);
        uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
        struct hal_ev_mesh_message_event *ev = (void *)buf;
 
@@ -880,6 +1015,7 @@ static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
        size = (uint16_t) sizeof(*ev);
        memcpy(ev->net_uuid, net_uuid, 16);
        g_free(net_uuid);
+       ev->is_prov = is_provisioner;
 
        if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
                                &iter)) {
@@ -917,9 +1053,10 @@ static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
        /* Properties */
        l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
                        NULL);
-       l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
+       l_dbus_interface_property(iface, "VendorModels", 0, "a(qqa{sv})",
                        __mesh_vendor_model_getter, NULL);
-       l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
+       l_dbus_interface_property(iface, "Models", 0, "a(qa{sv})", __mesh_model_getter,
+                                                                       NULL);
 
        /* Methods */
        l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
@@ -1158,12 +1295,13 @@ static struct l_dbus_message *__mesh_node_add_failed(
        INFO("Mesh: Provisioning failed:\n");
        str = l_util_hexstring_upper(uuid, 16);
        INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
-       l_free(str);
 
        ev.status = BT_STATUS_FAIL;
        ev.reason = __bt_mesh_util_get_prov_error_code(str);
        memcpy(ev.dev_uuid, uuid, 16);
 
+       l_free(str);
+
        if (mesh_event_cb)
                mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
                        (void*)&ev, sizeof(ev));
@@ -1398,6 +1536,10 @@ static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
 
        l = g_slist_find_custom(mesh_apps, net_uuid,
                        __mesh_compare_network_uuid);
+       if (!l) {
+               g_free(net_uuid);
+               return NULL;
+       }
        app = l->data;
 
        memset(&ev, 0, sizeof(ev));
@@ -1443,7 +1585,7 @@ static struct l_dbus_message *__mesh_agent_prompt_static_request(
        uint8_t *net_uuid;
        const char *dbus_path;
        GSList *l;
-       meshcfg_app *app;
+       meshcfg_app *app = NULL;
 
        dbus_path =  l_dbus_message_get_path(msg);
        net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
@@ -1453,7 +1595,12 @@ static struct l_dbus_message *__mesh_agent_prompt_static_request(
 
        l = g_slist_find_custom(mesh_apps, net_uuid,
                        __mesh_compare_network_uuid);
-       app = l->data;
+
+       if (l)
+               app = l->data;
+       else
+               ERR("Mesh: app not found");
+
 
        memset(&ev, 0, sizeof(ev));
        memcpy(ev.net_uuid, net_uuid, 16);
@@ -1464,7 +1611,10 @@ static struct l_dbus_message *__mesh_agent_prompt_static_request(
 
                struct hal_ev_mesh_provision_finished ev;
                memset(&ev, 0, sizeof(ev));
-               memcpy(ev.net_uuid, app->uuid, 16);
+
+               if (app)
+                       memcpy(ev.net_uuid, app->uuid, 16);
+
                ev.status = BT_STATUS_FAIL;
                ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
                if (mesh_event_cb)
@@ -1559,14 +1709,14 @@ bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
                                __bt_hal_mesh_setup_app_iface, NULL, false)) {
                ERR("Mesh: Failed to register interface %s",
                                BT_HAL_MESH_APPLICATION_INTERFACE);
-               //return false;
+               return false;
        }
 
        if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
                                __bt_hal_mesh_setup_prov_iface, NULL, false)) {
                ERR("Mesh: Failed to register interface %s",
                                BT_HAL_MESH_PROVISIONER_INTERFACE);
-               //return false;
+               return false;
        }
 
        if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
@@ -1584,7 +1734,7 @@ bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
                                __bt_hal_mesh_setup_ele_iface, NULL, false)) {
                ERR("Mesh: Failed to register interface %s",
                                BT_HAL_MESH_ELEMENT_INTERFACE);
-               //return false;
+               return false;
        }
 
        INFO("Mesh: Number of elements to be registsred [%d]",
@@ -1639,6 +1789,7 @@ meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
        char *uuid_str = NULL;
 
        uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
+       INFO("Mesh: Network UUID [%s]", uuid_str);
 
        app = g_malloc0(sizeof(meshcfg_app));
        memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
@@ -1647,6 +1798,7 @@ meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
        app->pid = node->vendor_info.vendorid;
        app->vid =  node->vendor_info.versionid;
        app->crpl = node->vendor_info.crpl;
+       INFO("Mesh: is_prov [%d]", is_prov);
 
        if (is_prov) {
                app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
@@ -1660,10 +1812,70 @@ meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
 
        g_free(uuid_str);
        app->is_prov = is_prov;
+       app->token.u64 = node->token.u64;
+       INFO("Mesh: Token [%llu]", (unsigned long long int)app->token.u64);
        INFO("Mesh: app created");
        return app;
 }
 
+static void __bt_hal_mesh_leave_net_reply(
+               struct l_dbus_proxy *proxy,
+                       struct l_dbus_message *msg, void *user_data)
+{
+       meshcfg_app *app;
+       app = (meshcfg_app*) user_data;
+
+       INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
+       if (l_dbus_message_is_error(msg)) {
+               const char *name;
+
+               l_dbus_message_get_error(msg, &name, NULL);
+               ERR("Mesh: Failed to leave network: %s", name);
+
+               /* Send Network Destroy fail event */
+               __send_network_destroy_event(app, BT_STATUS_FAIL);
+       } else {
+               INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
+       }
+}
+
+static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
+               void *user_data)
+{
+       meshcfg_app *app = (meshcfg_app*) user_data;
+
+       l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
+       INFO("Mesh: Leave Network Setup app path [%s]", app->path);
+}
+
+static void __bt_hal_mesh_release_net_reply(
+               struct l_dbus_proxy *proxy,
+                       struct l_dbus_message *msg, void *user_data)
+{
+       meshcfg_app *app;
+       app = (meshcfg_app*) user_data;
+
+       INFO("Mesh:Release Network Reply from Meshd: app path [%s]", app->path);
+       if (l_dbus_message_is_error(msg)) {
+               const char *name;
+
+               l_dbus_message_get_error(msg, &name, NULL);
+               ERR("Mesh: Failed to Release network: %s", name);
+
+       } else {
+               INFO("Mesh: Release Network: Success, cleanup app after proxy removed");
+       }
+}
+
+static void __bt_hal_mesh_release_net_setup(struct l_dbus_message *msg,
+               void *user_data)
+{
+       meshcfg_app *app = (meshcfg_app*) user_data;
+
+       l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
+       INFO("Mesh: Release Network Setup app path [%s]", app->path);
+}
+
 static void __bt_hal_mesh_create_net_reply(
                struct l_dbus_proxy *proxy,
                        struct l_dbus_message *msg, void *user_data)
@@ -1731,6 +1943,8 @@ void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
        meshcfg_app *app;
        l = g_slist_find_custom(mesh_apps, net_uuid,
                        __mesh_compare_network_uuid);
+       if (!l)
+               return;
        app = l->data;
 
        if (app->scan_timer_id > 0) {
@@ -1778,21 +1992,6 @@ static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
        l_free(net_uuid);
 }
 
-static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
-               const char *key, const char *signature,
-               const void *data)
-{
-       if (!builder)
-               return;
-
-       l_dbus_message_builder_enter_dict(builder, "sv");
-       l_dbus_message_builder_append_basic(builder, 's', key);
-       l_dbus_message_builder_enter_variant(builder, signature);
-       l_dbus_message_builder_append_basic(builder, signature[0], data);
-       l_dbus_message_builder_leave_variant(builder);
-       l_dbus_message_builder_leave_dict(builder);
-}
-
 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
 {
        struct l_dbus_message_builder *builder;
@@ -1872,10 +2071,14 @@ static void __bt_hal_mesh_add_node_reply(
 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
                void *user_data)
 {
-       char *uuid;
+       char *uuid = NULL;
        bt_uuid_t *dev = user_data;
        struct l_dbus_message_builder *builder;
+
        uuid =  l_util_hexstring(dev->uu, 16);
+       if (uuid == NULL)
+               return;
+
        INFO("Mesh: Add Node Setup UUID [%s]", uuid);
 
        builder = l_dbus_message_builder_new(msg);
@@ -1884,6 +2087,8 @@ static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
        l_dbus_message_builder_leave_array(builder);
        l_dbus_message_builder_finalize(builder);
        l_dbus_message_builder_destroy(builder);
+
+       l_free(uuid);
 }
 
 bt_status_t _bt_hal_mesh_provision_device(
@@ -2249,6 +2454,120 @@ bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
        return BT_STATUS_SUCCESS;
 }
 
+static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
+               void *user_data)
+{
+       struct mesh_remote_node_info *node_info = \
+               (struct mesh_remote_node_info*) user_data;
+
+       l_dbus_message_set_arguments(msg, "qy",
+               node_info->unicast, node_info->num_elements);
+       INFO("Mesh: Delete Remote Node Setup params passed");
+}
+
+static void __bt_hal_mesh_delete_node_reply(
+               struct l_dbus_proxy *proxy,
+                       struct l_dbus_message *msg, void *user_data)
+{
+       INFO("Mesh: Delete Remote Node Reply from DBUS");
+}
+
+bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
+               uint16_t unicast, uint16_t num_elements)
+{
+       GSList *l;
+       meshcfg_app *app;
+       struct mesh_remote_node_info *node_info;
+       INFO("Mesh: Delete Remote Node");
+       l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
+       if (l) {
+               app = l->data;
+               if (!__bt_mesh_proxy_check(app)) {
+                       ERR("Mesh: Proxy check failed!!");
+                       return BT_STATUS_FAIL;
+               }
+               INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
+                       unicast, num_elements);
+
+               /* Delete Remote Node Request */
+               node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
+               node_info->unicast = unicast;
+               node_info->num_elements = num_elements;
+
+               if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
+                                       __bt_hal_mesh_delete_node_setup,
+                                       __bt_hal_mesh_delete_node_reply, node_info,
+                                       l_free)) {
+                       ERR("Mesh: Delete Remote Node Request failed!!");
+                       g_free(node_info);
+                       return BT_STATUS_FAIL;
+               }
+       } else {
+               ERR("Mesh: App not found!!");
+               return BT_STATUS_PARM_INVALID;
+       }
+       INFO("Mesh: Delete Remote Node Call issued successfully!!");
+       return BT_STATUS_SUCCESS;
+}
+
+bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid)
+{
+       GSList *l;
+       meshcfg_app *app;
+       INFO("Mesh: Release Network");
+       l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
+       if (l) {
+               app = l->data;
+               if (!__bt_mesh_proxy_check(app)) {
+                       ERR("Mesh: Proxy check failed!!");
+                       return BT_STATUS_FAIL;
+               }
+               INFO("Mesh: Release Network");
+               /* Create CFG Network */
+               if (!l_dbus_proxy_method_call(net_proxy, "Release",
+                                       __bt_hal_mesh_release_net_setup,
+                                       __bt_hal_mesh_release_net_reply, app,
+                                       NULL)) {
+                       ERR("Mesh: Network Release failed!!");
+                       return BT_STATUS_FAIL;
+               }
+       } else {
+               ERR("Mesh: App not found!!");
+               return BT_STATUS_PARM_INVALID;
+       }
+       INFO("Mesh: Network Release Call issued successfully!!");
+       return BT_STATUS_SUCCESS;
+}
+
+bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
+{
+       GSList *l;
+       meshcfg_app *app;
+       INFO("Mesh: Destroy network");
+       l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
+       if (l) {
+               app = l->data;
+               if (!__bt_mesh_proxy_check(app)) {
+                       ERR("Mesh: Proxy check failed!!");
+                       return BT_STATUS_FAIL;
+               }
+               INFO("Mesh: Destroy Network");
+               /* Create CFG Network */
+               if (!l_dbus_proxy_method_call(net_proxy, "Leave",
+                                       __bt_hal_mesh_leave_net_setup,
+                                       __bt_hal_mesh_leave_net_reply, app,
+                                       NULL)) {
+                       ERR("Mesh: Network Leave failed!!");
+                       return BT_STATUS_FAIL;
+               }
+       } else {
+               ERR("Mesh: App not found!!");
+               return BT_STATUS_PARM_INVALID;
+       }
+       INFO("Mesh: Network Leave Call issued successfully!!");
+       return BT_STATUS_SUCCESS;
+}
+
 bt_status_t _bt_hal_mesh_create_network(
                bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
 {
@@ -2268,6 +2587,7 @@ bt_status_t _bt_hal_mesh_create_network(
        INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
        INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
        INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
+       INFO("Mesh: Token [%llu]", (unsigned long long int)node->token.u64);
        /* Create DBUS APP */
        app = __bt_hal_mesh_create_app(node, models, is_prov);
        if (!app)
@@ -2288,7 +2608,7 @@ bt_status_t _bt_hal_mesh_create_network(
                        goto failed;
                }
        } else {
-               INFO("Mesh: Attach Node to Network");
+               INFO("Mesh: Attach Node to Network: Token [%llu]", (unsigned long long int)app->token.u64);
                /* Attach to Network */
                if (!l_dbus_proxy_method_call(net_proxy, "Attach",
                                        __bt_hal_mesh_attach_node_setup,
@@ -2311,6 +2631,81 @@ failed:
        return BT_STATUS_FAIL;
 }
 
+bt_status_t _bt_hal_mesh_join_network(
+               bt_hal_mesh_node_t *node, GSList *models)
+{
+       meshcfg_app *app;
+
+       INFO("Mesh: Join Network Request");
+
+       if (!__bt_mesh_proxy_check(0)) {
+               ERR("Mesh: Proxy check failed!!");
+               return BT_STATUS_FAIL;
+       }
+
+       INFO("Mesh: Node Element count [%d]", node->num_elements);
+       INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
+       INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
+       INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
+       INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
+       INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
+       INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
+       INFO("Mesh: Token [%llu]", (unsigned long long int)node->token.u64);
+       /* Create DBUS APP */
+       app = __bt_hal_mesh_create_app(node, models, false);
+       if (!app)
+               return BT_STATUS_FAIL;
+       /* Register DBUS APP */
+       if (!__bt_hal_mesh_register_application(app))
+               goto failed;
+
+       INFO("Mesh: Create New Network");
+       INFO("Mesh: app is_prov [%d]", app->is_prov);
+       if (!l_dbus_proxy_method_call(net_proxy, "Join",
+                               __bt_hal_mesh_create_net_setup,
+                               __bt_hal_mesh_create_net_reply, app,
+                               NULL)) {
+                ERR("Mesh: Join Network failed!!");
+                goto failed;
+       }
+
+       INFO("Mesh: Node registration request scheudled");
+       INFO("Mesh: Total number of apps in list Before [%d]",
+                       g_slist_length(mesh_apps));
+       mesh_apps = g_slist_append(mesh_apps, app);
+       INFO("Mesh: Total number of apps in list  [%d]",
+                       g_slist_length(mesh_apps));
+       return BT_STATUS_SUCCESS;
+failed:
+       ERR("Mesh: network can not be joined!!");
+       __bt_hal_mesh_destroy_app_object(app);
+       return BT_STATUS_FAIL;
+}
+
+bt_status_t _bt_hal_mesh_join_cancel(bt_uuid_t *node_uuid)
+{
+       GSList *l;
+       meshcfg_app *app;
+       INFO("Mesh: Call cancel join");
+       l = g_slist_last(mesh_apps);
+       if (l) {
+               app = l->data;
+               if (!l_dbus_proxy_method_call(net_proxy, "Cancel",
+                                       NULL,
+                                       NULL, NULL,
+                                       NULL)) {
+                       ERR("Mesh: Cancel Join failed!!");
+                       return BT_STATUS_FAIL;
+               }
+       } else {
+               ERR("Mesh: App not found!!");
+               return BT_STATUS_PARM_INVALID;
+       }
+       INFO("Mesh: Cancel Join request Call issued successfully!!");
+       __bt_hal_mesh_destroy_app_object(app);
+       return BT_STATUS_SUCCESS;
+}
+
 static void __bt_hal_mesh_config_send(
                struct l_dbus_message *msg, void *user_data)
 {
@@ -2325,6 +2720,13 @@ static void __bt_hal_mesh_config_send(
                l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
 
        l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
+
+       /* Options */
+       l_dbus_message_builder_enter_array(builder, "{sv}");
+       l_dbus_message_builder_enter_dict(builder, "sv");
+       l_dbus_message_builder_leave_dict(builder);
+       l_dbus_message_builder_leave_array(builder);
+
        __mesh_append_byte_array(builder, req->data, req->len);
        l_dbus_message_builder_finalize(builder);
        l_dbus_message_builder_destroy(builder);
@@ -2358,6 +2760,13 @@ static void __bt_hal_mesh_model_execute_message(
        l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
        l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
        l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
+
+       /* Options */
+       l_dbus_message_builder_enter_array(builder, "{sv}");
+       l_dbus_message_builder_enter_dict(builder, "sv");
+       l_dbus_message_builder_leave_dict(builder);
+       l_dbus_message_builder_leave_array(builder);
+
        __mesh_append_byte_array(builder, req->data, req->len);
        l_dbus_message_builder_finalize(builder);
        l_dbus_message_builder_destroy(builder);