From 1087f81b3c3249db68fe48d5643499e8e2cf997a Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Tue, 11 Aug 2020 19:35:36 +0530 Subject: [PATCH] Mesh: Implement Network Destroy Request 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 --- bt-api/bt-mesh.c | 19 +++++ bt-oal/bluez_hal/inc/bt-hal-msg.h | 7 ++ bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c | 81 ++++++++++++++++++++- bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.h | 2 + bt-oal/bluez_hal/src/bt-hal-mesh.c | 20 ++++++ bt-oal/hardware/bt_mesh.h | 5 ++ bt-oal/include/oal-event.h | 1 + bt-oal/include/oal-mesh.h | 19 +++++ bt-oal/oal-mesh.c | 34 +++++++++ bt-service/services/bt-request-handler.c | 27 +++++++ bt-service/services/bt-service-event-receiver.c | 1 + bt-service/services/include/bt-service-mesh-keys.h | 2 +- .../services/include/bt-service-mesh-network.h | 5 ++ .../services/include/bt-service-mesh-nodes.h | 2 +- bt-service/services/include/bt-service-mesh-util.h | 2 + bt-service/services/mesh/bt-service-mesh-cdb.c | 1 + bt-service/services/mesh/bt-service-mesh-keys.c | 7 +- bt-service/services/mesh/bt-service-mesh-main.c | 61 ++++++++++++++++ bt-service/services/mesh/bt-service-mesh-network.c | 82 +++++++++++++++++++++- bt-service/services/mesh/bt-service-mesh-nodes.c | 10 ++- bt-service/services/mesh/bt-service-mesh-util.c | 31 ++++++++ include/bluetooth-mesh-api.h | 2 + include/bt-internal-types.h | 1 + 23 files changed, 410 insertions(+), 12 deletions(-) diff --git a/bt-api/bt-mesh.c b/bt-api/bt-mesh.c index 71f8776..02525a1 100644 --- a/bt-api/bt-mesh.c +++ b/bt-api/bt-mesh.c @@ -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, diff --git a/bt-oal/bluez_hal/inc/bt-hal-msg.h b/bt-oal/bluez_hal/inc/bt-hal-msg.h index ec39475..4872314 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-msg.h +++ b/bt-oal/bluez_hal/inc/bt-hal-msg.h @@ -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_ diff --git a/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c b/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c index cfa12e8..5f995b4 100644 --- a/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c +++ b/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c @@ -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) { diff --git a/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.h b/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.h index 4015fc2..19d2cde 100644 --- a/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.h +++ b/bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.h @@ -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); diff --git a/bt-oal/bluez_hal/src/bt-hal-mesh.c b/bt-oal/bluez_hal/src/bt-hal-mesh.c index ff1b80d..a0e4467 100644 --- a/bt-oal/bluez_hal/src/bt-hal-mesh.c +++ b/bt-oal/bluez_hal/src/bt-hal-mesh.c @@ -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, diff --git a/bt-oal/hardware/bt_mesh.h b/bt-oal/hardware/bt_mesh.h index fe7b07a..a965f1b 100644 --- a/bt-oal/hardware/bt_mesh.h +++ b/bt-oal/hardware/bt_mesh.h @@ -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); diff --git a/bt-oal/include/oal-event.h b/bt-oal/include/oal-event.h index 20d7e01..9d1a563 100644 --- a/bt-oal/include/oal-event.h +++ b/bt-oal/include/oal-event.h @@ -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 */\ diff --git a/bt-oal/include/oal-mesh.h b/bt-oal/include/oal-mesh.h index a032e0d..1edbb35 100644 --- a/bt-oal/include/oal-mesh.h +++ b/bt-oal/include/oal-mesh.h @@ -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 * diff --git a/bt-oal/oal-mesh.c b/bt-oal/oal-mesh.c index 63eeb5b..1e476da 100644 --- a/bt-oal/oal-mesh.c +++ b/bt-oal/oal-mesh.c @@ -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) { diff --git a/bt-service/services/bt-request-handler.c b/bt-service/services/bt-request-handler.c index e1be7cc..c57e89b 100644 --- a/bt-service/services/bt-request-handler.c +++ b/bt-service/services/bt-request-handler.c @@ -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: diff --git a/bt-service/services/bt-service-event-receiver.c b/bt-service/services/bt-service-event-receiver.c index 9cdb30e..b4f634e 100644 --- a/bt-service/services/bt-service-event-receiver.c +++ b/bt-service/services/bt-service-event-receiver.c @@ -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: diff --git a/bt-service/services/include/bt-service-mesh-keys.h b/bt-service/services/include/bt-service-mesh-keys.h index d0074a2..4937ca8 100644 --- a/bt-service/services/include/bt-service-mesh-keys.h +++ b/bt-service/services/include/bt-service-mesh-keys.h @@ -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); diff --git a/bt-service/services/include/bt-service-mesh-network.h b/bt-service/services/include/bt-service-mesh-network.h index 781aa85..341964f 100644 --- a/bt-service/services/include/bt-service-mesh-network.h +++ b/bt-service/services/include/bt-service-mesh-network.h @@ -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], diff --git a/bt-service/services/include/bt-service-mesh-nodes.h b/bt-service/services/include/bt-service-mesh-nodes.h index 4833ef3..4ec3fc2 100644 --- a/bt-service/services/include/bt-service-mesh-nodes.h +++ b/bt-service/services/include/bt-service-mesh-nodes.h @@ -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, diff --git a/bt-service/services/include/bt-service-mesh-util.h b/bt-service/services/include/bt-service-mesh-util.h index fdb5d69..7e3247b 100644 --- a/bt-service/services/include/bt-service-mesh-util.h +++ b/bt-service/services/include/bt-service-mesh-util.h @@ -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, diff --git a/bt-service/services/mesh/bt-service-mesh-cdb.c b/bt-service/services/mesh/bt-service-mesh-cdb.c index 743a95f..8137b65 100644 --- a/bt-service/services/mesh/bt-service-mesh-cdb.c +++ b/bt-service/services/mesh/bt-service-mesh-cdb.c @@ -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); } diff --git a/bt-service/services/mesh/bt-service-mesh-keys.c b/bt-service/services/mesh/bt-service-mesh-keys.c index 95dc273..923b57b 100644 --- a/bt-service/services/mesh/bt-service-mesh-keys.c +++ b/bt-service/services/mesh/bt-service-mesh-keys.c @@ -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[]) diff --git a/bt-service/services/mesh/bt-service-mesh-main.c b/bt-service/services/mesh/bt-service-mesh-main.c index fc45634..f3dc1e5 100644 --- a/bt-service/services/mesh/bt-service-mesh-main.c +++ b/bt-service/services/mesh/bt-service-mesh-main.c @@ -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); diff --git a/bt-service/services/mesh/bt-service-mesh-network.c b/bt-service/services/mesh/bt-service-mesh-network.c index 7a7366a..9b32131 100644 --- a/bt-service/services/mesh/bt-service-mesh-network.c +++ b/bt-service/services/mesh/bt-service-mesh-network.c @@ -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; } diff --git a/bt-service/services/mesh/bt-service-mesh-nodes.c b/bt-service/services/mesh/bt-service-mesh-nodes.c index 7a90a63..5bae17f 100644 --- a/bt-service/services/mesh/bt-service-mesh-nodes.c +++ b/bt-service/services/mesh/bt-service-mesh-nodes.c @@ -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[], diff --git a/bt-service/services/mesh/bt-service-mesh-util.c b/bt-service/services/mesh/bt-service-mesh-util.c index db3fd53..ccb13e0 100644 --- a/bt-service/services/mesh/bt-service-mesh-util.c +++ b/bt-service/services/mesh/bt-service-mesh-util.c @@ -19,6 +19,7 @@ * */ #include +#include #include #include #include @@ -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; diff --git a/include/bluetooth-mesh-api.h b/include/bluetooth-mesh-api.h index 777661b..081bd0b 100644 --- a/include/bluetooth-mesh-api.h +++ b/include/bluetooth-mesh-api.h @@ -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 */ diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index 6dccd25..442c222 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -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, -- 2.7.4