Mesh: Implement Network Destroy Request 03/240803/1 accepted/tizen/unified/20200812.143918 submit/tizen/20200811.230110
authorAnupam Roy <anupam.r@samsung.com>
Tue, 11 Aug 2020 14:05:36 +0000 (19:35 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Tue, 11 Aug 2020 14:09:26 +0000 (19:39 +0530)
This patch handles handles destroying the
network, by which local configuration client
will leave the Mesh Network. Both Stack &
FRWK will consequently remove the DB &
other configuration entries.

Change-Id: I58f567664c49633786f31c760a058889ba7d73b6
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
23 files changed:
bt-api/bt-mesh.c
bt-oal/bluez_hal/inc/bt-hal-msg.h
bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c
bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.h
bt-oal/bluez_hal/src/bt-hal-mesh.c
bt-oal/hardware/bt_mesh.h
bt-oal/include/oal-event.h
bt-oal/include/oal-mesh.h
bt-oal/oal-mesh.c
bt-service/services/bt-request-handler.c
bt-service/services/bt-service-event-receiver.c
bt-service/services/include/bt-service-mesh-keys.h
bt-service/services/include/bt-service-mesh-network.h
bt-service/services/include/bt-service-mesh-nodes.h
bt-service/services/include/bt-service-mesh-util.h
bt-service/services/mesh/bt-service-mesh-cdb.c
bt-service/services/mesh/bt-service-mesh-keys.c
bt-service/services/mesh/bt-service-mesh-main.c
bt-service/services/mesh/bt-service-mesh-network.c
bt-service/services/mesh/bt-service-mesh-nodes.c
bt-service/services/mesh/bt-service-mesh-util.c
include/bluetooth-mesh-api.h
include/bt-internal-types.h

index 71f8776..02525a1 100644 (file)
@@ -97,6 +97,25 @@ BT_EXPORT_API int bluetooth_mesh_deinit(void)
        return BLUETOOTH_ERROR_NONE;
 }
 
+BT_EXPORT_API int bluetooth_mesh_network_destroy(bluetooth_mesh_network_t *network)
+{
+       int result;
+
+       BT_CHECK_PARAMETER(network, return);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, network,  sizeof(bluetooth_mesh_network_t));
+
+       BT_INFO("Mesh: Network Destroy");
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_MESH_NETWORK_DESTROY,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
 BT_EXPORT_API int bluetooth_mesh_network_create(
        const char *net_name, bluetooth_mesh_node_t *node,
                uint16_t total_models, bluetooth_mesh_model_t **models,
index ec39475..4872314 100644 (file)
@@ -946,4 +946,11 @@ struct hal_ev_mesh_message_event {
        uint8_t data[0];
 } __attribute__((packed));
 
+#define HAL_EV_MESH_NETWORK_DESTROYED  0xDE
+struct hal_ev_mesh_network_destroyed {
+       uint8_t status;
+       uint8_t uuid[16];
+       uint8_t token[8];
+} __attribute__((packed));
+
 #endif //_BT_HAL_MSG_H_
index cfa12e8..5f995b4 100644 (file)
@@ -420,6 +420,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 +504,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 +518,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");
@@ -1664,6 +1680,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)
@@ -2249,6 +2295,35 @@ bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
        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)
 {
index 4015fc2..19d2cde 100644 (file)
@@ -47,6 +47,8 @@ void _bt_hal_mesh_stack_deinit(void);
 bt_status_t _bt_hal_mesh_create_network(bt_hal_mesh_node_t *node,
                GSList *models, bool is_prov);
 
+bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid);
+
 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
                bt_hal_mesh_scan_param_t *param);
 
index ff1b80d..a0e4467 100644 (file)
@@ -51,6 +51,15 @@ static void __bt_hal_mesh_network_attached(void *buf, uint16_t len)
                                (bt_uuid_t*)&ev->uuid);
 }
 
+static void __bt_hal_mesh_network_destroyed(void *buf, uint16_t len)
+{
+       struct hal_ev_mesh_network_destroyed *ev = buf;
+       if (bt_hal_mesh_cbacks->network_destroyed_cb)
+               bt_hal_mesh_cbacks->network_destroyed_cb(ev->status,
+                       (bt_mesh_token_t*)&ev->token,
+                               (bt_uuid_t*)&ev->uuid);
+}
+
 static void __bt_hal_handle_network_scan_result(void *buf, uint16_t len)
 {
        struct hal_ev_mesh_scan_result *ev = buf;
@@ -172,6 +181,10 @@ static void __bt_hal_handle_mesh_events(int message, void *buf, uint16_t len)
                DBG("Mesh Event: HAL_EV_MESH_NETWORK_ATTACHED");
                __bt_hal_mesh_network_attached(buf, len);
                break;
+       case HAL_EV_MESH_NETWORK_DESTROYED:
+               DBG("Mesh Event: HAL_EV_MESH_NETWORK_DESTROYED");
+               __bt_hal_mesh_network_destroyed(buf, len);
+               break;
        case HAL_EV_MESH_SCAN_STATE_CHANGED:
                DBG("Mesh Event: HAL_EV_MESH_SCAN_STATE_CHANGED");
                __bt_hal_handle_network_scan_status(buf, len);
@@ -227,6 +240,12 @@ static bt_status_t mesh_create_network(bt_hal_mesh_node_t *node,
        return _bt_hal_mesh_create_network(node, models, is_prov);
 }
 
+static bt_status_t mesh_destroy_network(bt_uuid_t *network)
+{
+       DBG("");
+       return _bt_hal_mesh_network_destroy(network);
+}
+
 static bt_status_t mesh_scan(bt_uuid_t *network, bt_hal_mesh_scan_param_t *param)
 {
        DBG("");
@@ -353,6 +372,7 @@ static btmesh_interface_t mesh_if = {
        .size = sizeof(mesh_if),
        .init = init,
        .create = mesh_create_network,
+       .destroy = mesh_destroy_network,
        .scan = mesh_scan,
        .scan_cancel = mesh_scan_cancel,
        .capability = mesh_set_prov_caps,
index fe7b07a..a965f1b 100644 (file)
@@ -134,6 +134,9 @@ typedef enum {
 typedef void (*btmesh_network_attached_callback)(bt_status_t status,
                bt_mesh_token_t *token, bt_uuid_t *uuid);
 
+typedef void (*btmesh_network_destroyed_callback)(bt_status_t status,
+               bt_mesh_token_t *token, bt_uuid_t *uuid);
+
 typedef void (*btmesh_network_scan_status_callback)(
                bt_mesh_scan_state_t scan_state, bt_status_t status,
                        bt_uuid_t *net_uuid);
@@ -176,6 +179,7 @@ typedef struct {
        /** set to sizeof(btmesh_callbacks_t) */
        size_t      size;
        btmesh_network_attached_callback  network_attached_cb;
+       btmesh_network_destroyed_callback  network_destroyed_cb;
        btmesh_network_scan_status_callback  scan_status_cb;
        btmesh_network_scan_result_callback  scan_result_cb;
        btmesh_network_provisioning_status_callback  provisioning_status_cb;
@@ -199,6 +203,7 @@ typedef struct {
        bt_status_t (*init)(btmesh_callbacks_t* callbacks);
        bt_status_t (*create)(bt_hal_mesh_node_t *node,
                GSList *model_list, bool is_prov);
+       bt_status_t (*destroy)(bt_uuid_t *network);
        bt_status_t (*scan)(bt_uuid_t *network,
                bt_hal_mesh_scan_param_t *param);
        bt_status_t (*scan_cancel)(bt_uuid_t *network);
index 20d7e01..9d1a563 100644 (file)
@@ -187,6 +187,7 @@ extern "C" {
        EVENT(OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE)    /* gattc acquire write */\
        EVENT(OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY)    /* gattc acquire notify */\
        EVENT(OAL_EVENT_MESH_NETWORK_ATTACHED)    /* mesh network attached */\
+       EVENT(OAL_EVENT_MESH_NETWORK_DESTROYED)    /* mesh network destroyed */\
        EVENT(OAL_EVENT_MESH_SCAN_STARTED)    /* mesh network scan start status */\
        EVENT(OAL_EVENT_MESH_SCAN_FINISHED)    /* mesh network scan stop status*/\
        EVENT(OAL_EVENT_MESH_SCAN_RESULT)    /* mesh Scan Result */\
index a032e0d..1edbb35 100644 (file)
@@ -147,6 +147,12 @@ typedef struct {
 
 typedef struct {
        oal_status_t status;
+       uint8_t token[8];
+       oal_uuid_t uuid;
+} event_mesh_network_destroyed_t;
+
+typedef struct {
+       oal_status_t status;
        oal_uuid_t net_uuid;
        oal_mesh_scan_result_t result;
 } event_mesh_scan_result_t;
@@ -252,6 +258,19 @@ oal_status_t mesh_disable(void);
 oal_status_t mesh_register_node(oal_mesh_node_t *node,
                GSList *model_list, bool is_provisioner);
 
+
+/**
+ * @brief Destroy or leave Network
+ *
+ * @remarks Stack will remove the local node entry
+ *
+ * @pre OAl API should be enabled with mesh_enable().
+ *
+ * @see  mesh_enable()
+ * @see  mesh_register_node()
+ */
+oal_status_t mesh_network_destroy(oal_uuid_t* network_uuid);
+
 /**
  * @brief UnRegister the BLE Mesh Node
  *
index 63eeb5b..1e476da 100644 (file)
@@ -45,6 +45,8 @@ static const btmesh_interface_t *mesh_api;
 /* Forward declaration: Callbacks from HAL */
 static void mesh_network_attached_callback(bt_status_t status,
                bt_mesh_token_t *token, bt_uuid_t *uuid);
+static void mesh_network_destroyed_callback(bt_status_t status,
+               bt_mesh_token_t *token, bt_uuid_t *uuid);
 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
                bt_status_t status, bt_uuid_t *net_uuid);
 static void mesh_network_scan_result_callback(bt_status_t status,
@@ -75,6 +77,7 @@ static void mesh_message_received_callback(bt_uuid_t *net_uuid,
 static btmesh_callbacks_t sBluetoothMeshCallbacks = {
        .size = sizeof(sBluetoothMeshCallbacks),
        .network_attached_cb = mesh_network_attached_callback,
+       .network_destroyed_cb = mesh_network_destroyed_callback,
        .scan_status_cb = mesh_network_scan_status_callback,
        .scan_result_cb = mesh_network_scan_result_callback,
        .provisioning_status_cb = mesh_network_provisioning_status_callback,
@@ -104,6 +107,22 @@ static void mesh_network_attached_callback(bt_status_t status,
                event, sizeof(event_mesh_network_attached_t), NULL);
 }
 
+static void mesh_network_destroyed_callback(bt_status_t status,
+               bt_mesh_token_t *token, bt_uuid_t *uuid)
+{
+       event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
+
+       event->status = convert_to_oal_status(status);
+       BT_INFO("Mesh Event: Network Destroyed, status: [%s]",
+                       status2string(status));
+
+       memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
+       memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
+
+       send_event_bda_trace(OAL_EVENT_MESH_NETWORK_DESTROYED,
+                       event, sizeof(event_mesh_network_destroyed_t), NULL);
+}
+
 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
                bt_status_t status, bt_uuid_t *net_uuid)
 {
@@ -348,6 +367,21 @@ oal_status_t mesh_register_node(oal_mesh_node_t *node,
        return OAL_STATUS_SUCCESS;
 }
 
+oal_status_t mesh_network_destroy(oal_uuid_t* network_uuid)
+{
+       int ret = BT_STATUS_SUCCESS;
+       API_TRACE();
+       CHECK_OAL_MESH_ENABLED();
+
+       ret = mesh_api->destroy((bt_uuid_t*)network_uuid);
+       if (ret != BT_STATUS_SUCCESS) {
+               BT_ERR("MESH: Network Leave failed: %s", status2string(ret));
+               return convert_to_oal_status(ret);
+       }
+
+       return OAL_STATUS_SUCCESS;
+}
+
 oal_status_t mesh_network_start_scan(oal_uuid_t* network_uuid,
                oal_mesh_scan_params_t *params)
 {
index e1be7cc..c57e89b 100644 (file)
@@ -236,6 +236,7 @@ static gboolean __bt_is_sync_function(int service_function)
                        || service_function == BT_AUDIO_SELECT_ROLE
                        /* Mesh API's */
                        || service_function == BT_MESH_NETWORK_CREATE
+                       || service_function == BT_MESH_NETWORK_DESTROY
                        || service_function == BT_MESH_NETWORK_LOAD
                        || service_function == BT_MESH_NETWORK_SCAN
                        || service_function == BT_MESH_NETWORK_ADD_NETKEY
@@ -3446,6 +3447,31 @@ normal:
                BT_INFO("Mesh: Cleanup Done");
                break;
        }
+       case BT_MESH_NETWORK_DESTROY: {
+               bluetooth_mesh_network_t network;
+               memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
+
+               __bt_service_get_parameters(in_param1,
+                               &network, sizeof(bluetooth_mesh_network_t));
+
+               BT_INFO("Mesh: Destroy Network");
+               result = _bt_mesh_network_destroy(requester_unique_creds,
+                               sender, &network);
+
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       g_array_append_vals(*out_param1,
+                               &network, sizeof(bluetooth_mesh_network_t));
+               } else {
+                       BT_INFO("Mesh: Destroy Network scheduled: add invocation");
+                       bluetooth_mesh_network_t *net =  \
+                                       g_memdup(&network, sizeof(bluetooth_mesh_network_t));
+
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       _bt_save_invocation_context(context, result, sender,
+                                       function_name, (gpointer)net);
+               }
+               break;
+       }
        case BT_MESH_NETWORK_LOAD: {
                char *token = NULL;
                bluetooth_mesh_network_t *network;
@@ -5101,6 +5127,7 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_MESH_INIT:
        case BT_MESH_DEINIT:
        case BT_MESH_NETWORK_CREATE:
+       case BT_MESH_NETWORK_DESTROY:
        case BT_MESH_NETWORK_LOAD:
        case BT_MESH_NETWORK_SCAN:
        case BT_MESH_NETWORK_CANCEL_SCAN:
index 9cdb30e..b4f634e 100644 (file)
@@ -409,6 +409,7 @@ static gboolean __bt_handle_oal_events(gpointer data)
                        adapter_le_cb(event_type, event_data);
                break;
        case OAL_EVENT_MESH_NETWORK_ATTACHED:
+       case OAL_EVENT_MESH_NETWORK_DESTROYED:
        case OAL_EVENT_MESH_SCAN_STARTED:
        case OAL_EVENT_MESH_SCAN_FINISHED:
        case OAL_EVENT_MESH_SCAN_RESULT:
index d0074a2..4937ca8 100644 (file)
@@ -35,7 +35,7 @@ extern "C" {
 
 void _bt_mesh_keys_load_net(uint8_t net_uuid[]);
 
-void _bt_mesh_keys_unload_net(_bt_mesh_cdb_t *cfg);
+void _bt_mesh_keys_unload_net(uint8_t net_uuid[]);
 
 void _bt_mesh_keys_add_net_key(uint8_t net_uuid[],
                uint16_t net_idx);
index 781aa85..341964f 100644 (file)
@@ -35,6 +35,11 @@ int _bt_mesh_network_create(const char *app_key,
                const char *sender, const char *network_name,
                        bluetooth_mesh_node_t *node, GSList *model_list);
 
+int _bt_mesh_network_destroy(const char *app_cred,
+               const char *sender, bluetooth_mesh_network_t *network);
+
+int _bt_mesh_network_remove_net_configuration(bluetooth_mesh_network_t *net);
+
 int _bt_mesh_network_create_cdb(int result,
                const char *sender, const char *app_creds,
                        uint8_t uuid[16], uint8_t token[8],
index 4833ef3..4ec3fc2 100644 (file)
@@ -35,7 +35,7 @@ extern "C" {
 
 void _bt_mesh_node_load_net(uint8_t net_uuid[]);
 
-void _bt_mesh_node_unload_net(_bt_mesh_cdb_t *cfg);
+void _bt_mesh_node_unload_net(uint8_t net_uuid[]);
 
 bool _bt_mesh_node_add_node(uint8_t net_uuid[],
        const uint8_t uuid[16], uint16_t unicast,
index fdb5d69..7e3247b 100644 (file)
@@ -206,6 +206,8 @@ void _bt_mesh_util_print_packet(const char *label,
 
 bool _bt_mesh_util_create_directory(const char *dir_name);
 
+bool _bt_mesh_util_delete_file(const char *filename);
+
 bool _bt_mesh_util_is_directory_exists(const char *dir_path);
 
 uint16_t _bt_mesh_util_opcode_set(uint32_t opcode,
index 743a95f..8137b65 100644 (file)
@@ -459,6 +459,7 @@ void _bt_mesh_conf_free(_bt_mesh_cdb_t *cfg)
        g_free(cfg->cfg_fname);
        g_free(cfg->app_cred);
        json_object_put(cfg->jcfg);
+       g_slist_free_full(cfg->groups, g_free);
        g_free(cfg);
 }
 
index 95dc273..923b57b 100644 (file)
@@ -108,13 +108,13 @@ static bool __mesh_remove_netkey_entry(void *a, void *b)
        return true;
 }
 
-void _bt_mesh_keys_unload_net(_bt_mesh_cdb_t *cfg)
+void _bt_mesh_keys_unload_net(uint8_t net_uuid[])
 {
        struct mesh_network_t *network;
        int numkeys;
        BT_INFO("Mesh:Keys: Unload network with all Keys");
 
-       network = l_queue_find(networks, __mesh_net_uuid_match, cfg->uuid);
+       network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
        if (!network || !network->net_keys)
                return;
 
@@ -122,7 +122,10 @@ void _bt_mesh_keys_unload_net(_bt_mesh_cdb_t *cfg)
                        __mesh_remove_netkey_entry, network);
        BT_INFO("Mesh:Nodes: Unloaded [%d] Keys from the network",
                        numkeys);
+       l_queue_remove(networks, network);
        l_free(network);
+       BT_INFO("Mesh: Current Number of networks [%d]",
+                       l_queue_length(networks));
 }
 
 void _bt_mesh_keys_load_net(uint8_t net_uuid[])
index fc45634..f3dc1e5 100644 (file)
@@ -109,6 +109,36 @@ static void __bt_mesh_handle_pending_request_info(int result,
                        }
                        break;
                }
+               case BT_MESH_NETWORK_DESTROY: {
+                       bluetooth_mesh_network_t *event;
+                       bluetooth_mesh_network_t *network;
+                       ret_if(param == NULL);
+                       BT_INFO("Mesh: Request: BT_MESH_NETWORK_DESTROY Sender: [%s] result[%d]",
+                                       req_info->sender, result);
+
+                       event = (bluetooth_mesh_network_t*) param;
+                       network = (bluetooth_mesh_network_t*)req_info->user_data;
+
+                       BT_INFO("Mesh: Network UUID from event [%s] Net UUID from req [%s]",
+                                       event->uuid, network->uuid);
+
+                       if (!g_strcmp0(network->uuid, event->uuid)) {
+                               BT_INFO("Mesh: BT_MESH_NETWORK_DESTROY Request found uuid [%s]",
+                                       network->uuid);
+
+                               result = _bt_mesh_network_remove_net_configuration(network);
+
+                               BT_INFO("Mesh: Return Invocation for BT_MESH_NETWORK_DESTROY");
+                               out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+                               g_array_append_vals(out_param, network,
+                                       sizeof(bluetooth_mesh_network_t));
+                               _bt_service_method_return(req_info->context,
+                                       out_param, result);
+                               _bt_free_info_from_invocation_list(req_info);
+                               g_array_free(out_param, TRUE);
+                       }
+                       break;
+               }
                case BT_MESH_NETWORK_LOAD: {
                        char token_str[BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1];
                        bluetooth_mesh_node_t *node;
@@ -355,6 +385,32 @@ static void __handle_mesh_network_attached_event(
                        &node, sizeof(bluetooth_mesh_node_t));
 }
 
+static void __handle_mesh_network_destroyed_event(
+               event_mesh_network_destroyed_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bluetooth_mesh_network_t network;
+
+       if (event->status != OAL_STATUS_SUCCESS) {
+               BT_INFO("Mesh: Network Destroyed Event: result is Failed!");
+               result = BLUETOOTH_ERROR_INTERNAL;
+       } else {
+               BT_INFO("Mesh: Network Destroyed Event: result is Success!");
+       }
+
+       memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
+       _bt_mesh_util_convert_hex_to_string(
+                       (uint8_t *) event->uuid.uuid, 16, network.uuid,
+                       BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
+       _bt_mesh_util_convert_hex_to_string(
+                       (uint8_t *) event->token, 8, network.token.token,
+                       BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
+
+       __bt_mesh_handle_pending_request_info(result,
+                       BT_MESH_NETWORK_DESTROY,
+                       &network, sizeof(bluetooth_mesh_network_t));
+}
+
 static void __handle_mesh_network_scan_started_event(
        event_mesh_scan_status_t *event)
 {
@@ -614,6 +670,11 @@ static void __handle_mesh_events(int event_type,
                        (event_mesh_network_attached_t*)event_data);
                BT_PERMANENT_LOG("Mesh: Network attached!!");
                break;
+       case OAL_EVENT_MESH_NETWORK_DESTROYED:
+               __handle_mesh_network_destroyed_event(
+                       (event_mesh_network_destroyed_t*)event_data);
+               BT_PERMANENT_LOG("Mesh: Network Destroyed!!");
+               break;
        case OAL_EVENT_MESH_SCAN_STARTED:
                __handle_mesh_network_scan_started_event(
                        (event_mesh_scan_status_t*)event_data);
index 7a7366a..9b32131 100644 (file)
@@ -188,6 +188,60 @@ int _bt_mesh_network_request_provisioning_data_request(uint8_t net_uuid[],
        return BLUETOOTH_ERROR_NONE;
 }
 
+int _bt_mesh_network_remove_net_configuration(
+               bluetooth_mesh_network_t *net)
+{
+       GSList *l;
+       char *file_path;
+       _bt_mesh_cdb_t *cdb_cfg = NULL;
+       uint8_t net_uuid[16];
+       BT_INFO("Mesh: Remove network Configuration");
+
+       _bt_mesh_util_convert_string_to_hex(net->uuid,
+                       strlen(net->uuid), net_uuid, 16);
+
+       /* Find CDB */
+       l = g_slist_find_custom(cdb_list, net_uuid,
+                       __mesh_compare_app_network_uuid);
+       if (!l) {
+               BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       }
+
+       cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+
+       /* Create the CDB for the network */
+       file_path = g_strdup_printf("%s.bak", cdb_cfg->cfg_fname);
+
+       BT_INFO("Mesh: CDB File path[%s]", cdb_cfg->cfg_fname);
+       BT_INFO("Mesh: CDB Backup File path[%s]", file_path);
+
+       /* Remove the config */
+       if (!_bt_mesh_util_delete_file(cdb_cfg->cfg_fname))
+               return BLUETOOTH_ERROR_INTERNAL;
+
+       /* Remove the config backup */
+       if (!_bt_mesh_util_delete_file(file_path))
+               return BLUETOOTH_ERROR_INTERNAL;
+       BT_INFO("Mesh: Config DB file removed!!");
+
+       cdb_list = g_slist_remove(cdb_list, cdb_cfg);
+       _bt_mesh_conf_free(cdb_cfg);
+       BT_INFO("Mesh: CDB freed from memory");
+
+       /* Cleanup */
+       g_free(file_path);
+
+       /* Unload Network from Keys */
+       _bt_mesh_keys_unload_net(net_uuid);
+
+       /* Unload Network from Nodes */
+       _bt_mesh_node_unload_net(net_uuid);
+
+       BT_INFO("Mesh: Cleanup Done!");
+       return BLUETOOTH_ERROR_NONE;
+}
+
 int _bt_mesh_network_create_cdb(int result,
                const char *sender, const char *app_creds,
                        uint8_t uuid[16], uint8_t token[8],
@@ -299,6 +353,30 @@ int _bt_mesh_network_create_cdb(int result,
        return BLUETOOTH_ERROR_NONE;
 }
 
+int _bt_mesh_network_destroy(const char *app_cred,
+       const char *sender, bluetooth_mesh_network_t *network)
+{
+       int ret = OAL_STATUS_SUCCESS;
+       oal_uuid_t net_uuid;
+
+       /* If Scanning is going on */
+       if (_bt_mesh_is_provisioning() ||
+                       _bt_mesh_is_scanning()) {
+               BT_ERR("Device is buzy..");
+               return BLUETOOTH_ERROR_DEVICE_BUSY;
+       }
+       _bt_mesh_util_convert_string_to_hex(network->uuid,
+                       strlen(network->uuid), net_uuid.uuid, 16);
+       /* Destroy Mesh Network */
+       ret = mesh_network_destroy(&net_uuid);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
 int _bt_mesh_network_scan(const char *app_cred,
        const char *sender,
                bluetooth_mesh_network_t *network,
@@ -1201,14 +1279,14 @@ int _bt_mesh_network_load_cdb(int result, const char *sender,
        /* Create new network for saving network specific Keys */
        _bt_mesh_keys_load_net(cdb_cfg->uuid);
        if (!_bt_mesh_conf_load_all_keys(cdb_cfg)) {
-               _bt_mesh_keys_unload_net(cdb_cfg);
+               _bt_mesh_keys_unload_net(cdb_cfg->uuid);
                goto failed;
        }
 
        /* Create new network for saving network specific nodes */
        _bt_mesh_node_load_net(cdb_cfg->uuid);
        if (!_bt_mesh_conf_load_all_nodes(cdb_cfg)) {
-               _bt_mesh_node_unload_net(cdb_cfg);
+               _bt_mesh_node_unload_net(cdb_cfg->uuid);
                goto failed;
        }
 
index 7a90a63..5bae17f 100644 (file)
@@ -197,22 +197,26 @@ void _bt_mesh_node_load_net(uint8_t net_uuid[])
        l_queue_push_tail(networks, network);
 }
 
-void _bt_mesh_node_unload_net(_bt_mesh_cdb_t *cfg)
+void _bt_mesh_node_unload_net(uint8_t net_uuid[])
 {
        struct mesh_network_t *network;
        int numnodes;
        BT_INFO("Mesh:Nodes: Unload network with all nodes");
 
-       network = l_queue_find(networks, __mesh_net_uuid_match, cfg->uuid);
+       network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
        if (!network || !network->nodes)
                return;
 
        /* Only remove the ndoe from the Local Network object:
           DONT touch configuration file */
        numnodes = l_queue_foreach_remove(network->nodes,
-                       __mesh_remove_node_entry, cfg);
+                       __mesh_remove_node_entry, NULL);
        BT_INFO("Mesh:Nodes: Unloadeded [%d] Nodes from the network", numnodes);
+       l_queue_remove(networks, network);
        l_free(network);
+
+       BT_INFO("Mesh: After unloading, number of networks [%d]",
+               l_queue_length(networks));
 }
 
 bool _bt_mesh_node_get_unicast_from_dev_uuid(uint8_t net_uuid[],
index db3fd53..ccb13e0 100644 (file)
@@ -19,6 +19,7 @@
  *
  */
 #include <dirent.h>
+#include <fcntl.h>
 #include <ftw.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -263,6 +264,36 @@ bool _bt_mesh_util_create_directory(const char *mesh_dir)
        return true;
 }
 
+bool _bt_mesh_util_delete_file(const char *filename)
+{
+       struct stat st;
+       int fd;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0) {
+               BT_ERR("Mesh: Failed to open [%s]", filename);
+               return false;
+       }
+
+       if (fstat(fd, &st) < 0) {
+               BT_ERR("Mesh: Failed to stat [%s]", filename);
+               return false;
+       }
+
+       if (S_ISREG(st.st_mode)) {
+               BT_INFO("Mesh: Failed stat: success [%s]", filename);
+               close(fd);
+               remove(filename);
+               return true;
+       } else {
+               BT_ERR("Mesh: [%s] Is not a regular file", filename);
+       }
+
+       BT_INFO("Mesh: File [%s] deleted", filename);
+       close(fd);
+       return false;
+}
+
 bool _bt_mesh_util_is_directory_exists(const char *dir_path)
 {
        struct stat st;
index 777661b..081bd0b 100644 (file)
@@ -256,6 +256,8 @@ int bluetooth_mesh_network_create(const char *net_name,
                        bluetooth_mesh_model_t **models,
                                bluetooth_mesh_network_t *network);
 
+int bluetooth_mesh_network_destroy(bluetooth_mesh_network_t *network);
+
 /**
  * Load already created Network
  */
index 6dccd25..442c222 100644 (file)
@@ -477,6 +477,7 @@ typedef enum {
        BT_MESH_INIT = BT_FUNC_MESH_BASE,
        BT_MESH_DEINIT,
        BT_MESH_NETWORK_CREATE,
+       BT_MESH_NETWORK_DESTROY,
        BT_MESH_NETWORK_LOAD,
        BT_MESH_NETWORK_SCAN,
        BT_MESH_NETWORK_CANCEL_SCAN,