Fix the svace issue (DEREF_OF_NULL)
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-mesh-dbus-handler.c
index cfa12e8..0b9f872 100644 (file)
@@ -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},
@@ -420,6 +425,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);
@@ -489,7 +509,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 +523,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");
@@ -1398,6 +1419,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 +1468,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 +1478,13 @@ 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 +1495,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)
@@ -1664,6 +1698,36 @@ meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
        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_create_net_reply(
                struct l_dbus_proxy *proxy,
                        struct l_dbus_message *msg, void *user_data)
@@ -1731,6 +1795,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) {
@@ -2249,6 +2315,91 @@ 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_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: Create New 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)
 {