device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
NULL, BT_HAL_BLUEZ_NAME,
device_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
-
if (device_proxy != NULL) {
-
ret = g_dbus_proxy_call_sync(device_proxy, "Get",
g_variant_new("(ss)", BT_HAL_DEVICE_INTERFACE, "Paired"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
+ g_object_unref(device_proxy);
if (error) {
ERR("Getting property failed: [%s]\n", error->message);
g_error_free(error);
} else {
if (!ret) {
ERR("No paired device");
- g_object_unref(device_proxy);
return BT_STATUS_NOT_PAIRED;
}
g_variant_unref(value);
g_variant_unref(ret);
}
- g_object_unref(device_proxy);
}
if (is_paired == FALSE) {
goto fail;
}
-
g_dbus_proxy_call(device_proxy, "DiscoverServices",
g_variant_new("(s)", ""),
G_DBUS_CALL_FLAGS_NONE,
DBG("+");
g_dbus_proxy_call_finish(proxy, res, &err);
-
g_object_unref(proxy);
/* Check event pointer */
g_dbus_proxy_call_finish(proxy, res, &err);
device_path = g_dbus_proxy_get_object_path(proxy);
_bt_hal_convert_device_path_to_address(device_path, dev_address);
+ g_object_unref(proxy);
if (err != NULL) {
g_dbus_error_strip_remote_error(err);
uuid = _bt_convert_service_id_to_uuid_string(rem_svc_id);
DBG("uuid: %s", uuid);
- if (!uuid)
+ if (!uuid) {
+ g_object_unref(device_proxy);
return 0;
+ }
result = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
g_variant_new("(s)", uuid),
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]);
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 */
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)
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;
bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid);
+bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid);
+
bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
uint16_t unicast, uint16_t num_elements);
return _bt_hal_mesh_create_network(node, models, is_prov);
}
+static bt_status_t mesh_release_network(bt_uuid_t *network)
+{
+ DBG("");
+ return _bt_hal_mesh_network_release(network);
+}
+
static bt_status_t mesh_destroy_network(bt_uuid_t *network)
{
DBG("");
.init = init,
.create = mesh_create_network,
.destroy = mesh_destroy_network,
+ .release = mesh_release_network,
.delete_node = mesh_delete_node,
.scan = mesh_scan,
.scan_cancel = mesh_scan_cancel,
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 (*release)(bt_uuid_t *network);
bt_status_t (*delete_node)(bt_uuid_t *network, uint16_t unicast,
uint16_t elem_cnt);
bt_status_t (*scan)(bt_uuid_t *network,
oal_status_t mesh_network_destroy(oal_uuid_t* network_uuid);
/**
+ * @brief Request Stack to release Network resources
+ *
+ * @remarks Stack will remove only yhe DBUS resources of local node
+ *
+ * @pre OAl API should be enabled with mesh_enable().
+ *
+ * @see mesh_enable()
+ * @see mesh_register_node()
+ */
+oal_status_t mesh_network_release(oal_uuid_t* network_uuid);
+
+/**
* @brief Delete Remote Node configuration
*
* @remarks Stack will remove the Remote node entry
return OAL_STATUS_SUCCESS;
}
+oal_status_t mesh_network_release(oal_uuid_t* network_uuid)
+{
+ int ret = BT_STATUS_SUCCESS;
+ API_TRACE();
+ CHECK_OAL_MESH_ENABLED();
+
+ BT_INFO("Mesh: Send Release Network request to stack");
+ ret = mesh_api->release((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_destroy(oal_uuid_t* network_uuid)
{
int ret = BT_STATUS_SUCCESS;
}
case BT_MESH_INIT:
- result = _bt_mesh_init();
+ sender = (char*)g_dbus_method_invocation_get_sender(context);
+ BT_INFO("Mesh: Init by [%s]", sender);
+ result = _bt_mesh_init(sender);
/* Save invocation */
if (result == BLUETOOTH_ERROR_NONE) {
BT_INFO("Mesh: Save Invoation");
break;
case BT_MESH_DEINIT:
- result = _bt_mesh_deinit();
+ sender = (char*)g_dbus_method_invocation_get_sender(context);
+ BT_INFO("Mesh: De-Init by [%s]", sender);
+ result = _bt_mesh_deinit(sender);
break;
case BT_MESH_NETWORK_CREATE: {
requester_unique_creds,
sizeof(network->app_cred));
sender = (char*)g_dbus_method_invocation_get_sender(context);
+ BT_INFO("Mesh: Network Create by [%s]", sender);
_bt_save_invocation_context(context,
result, sender,
function_name, (gpointer)network);
/* Check if RFCOMM app is terminated */
_bt_rfcomm_check_termination(name);
+
+ /* Mesh App Termination */
+ _bt_check_mesh_app_termination(name);
}
static void __bt_service_bus_acquired_handler(GDBusConnection *connection,
typedef struct {
char *cfg_fname;
+ char *owner;
char *app_cred;
json_object *jcfg;
uint8_t token[8];
_bt_mesh_cdb_t * _bt_mesh_conf_database_create(const char *file_name,
const uint8_t uuid[16], const uint8_t token[8],
const char *network_name,
- const char *app_cred);
+ const char *sender, const char *app_cred);
bool _bt_mesh_conf_set_phase_network_key(_bt_mesh_cdb_t *cfg,
uint16_t net_idx, uint8_t phase);
extern "C" {
#endif
-int _bt_mesh_init(void);
+int _bt_mesh_init(const char *sender);
-int _bt_mesh_deinit(void);
+int _bt_mesh_deinit(const char *sender);
+
+void _bt_mesh_handle_app_termination(const char *sender);
#ifdef __cplusplus
}
int _bt_mesh_network_destroy(const char *app_cred,
const char *sender, bluetooth_mesh_network_t *network);
+void _bt_check_mesh_app_termination(const char *name);
+
int _bt_mesh_network_remove_net_configuration(bluetooth_mesh_network_t *net);
void _bt_mesh_network_unload_net_configuration(_bt_mesh_cdb_t *cdb_cfg);
void _bt_mesh_conf_free(_bt_mesh_cdb_t *cfg)
{
g_free(cfg->cfg_fname);
+ g_free(cfg->owner);
g_free(cfg->app_cred);
json_object_put(cfg->jcfg);
g_slist_free_full(cfg->groups, g_free);
_bt_mesh_cdb_t *_bt_mesh_conf_database_create(const char *file_name,
const uint8_t uuid[16],
const uint8_t token[8], const char *network_name,
- const char *app_cred)
+ const char *sender, const char *app_cred)
{
_bt_mesh_cdb_t *cfg;
json_object *jcfg, *jarray;
cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
cfg->jcfg = jcfg;
cfg->cfg_fname = g_strdup(file_name);
+ cfg->owner = g_strdup(sender);
cfg->app_cred = g_strdup(app_cred);
memcpy(&cfg->token, (void*)token, 8);
memcpy(&cfg->uuid, (void*)uuid, 16);
static guint launch_timer = 0;
static guint mesh_app_ref_count;
+static GSList *apps;
+
/* Event handlers */
static void __bt_mesh_handle_pending_request_info(int result,
int service_function, void *param,
BT_INFO("Mesh: Request: BT_MESH_INIT Sender: [%s] result[%d]",
req_info->sender, result);
- if (result == BLUETOOTH_ERROR_NONE)
+ if (result == BLUETOOTH_ERROR_NONE) {
+
+ /* Save Mesh App Owner */
+ char *owner = g_strdup(req_info->sender);
+ BT_INFO("Mesh: Insert Sender Mesh App List[%s]",
+ req_info->sender);
+ apps = g_slist_append(apps, owner);
+
/* Increase mesh app ref count */
mesh_app_ref_count++;
+ }
out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
_bt_service_method_return(req_info->context,
return FALSE;
}
-int _bt_mesh_init(void)
+int _bt_mesh_init(const char *sender)
{
int ret = BLUETOOTH_ERROR_NONE;
BT_INFO("Mesh: Total apps using Mesh: [%d]",
mesh_app_ref_count);
+ BT_INFO("Mesh: Mesh App Sender [%s]", sender);
+
BT_INFO("Mesh: Current Timer ID [%u]", launch_timer);
if (launch_timer > 0) {
BT_INFO("Mesh: BT_MESH_INIT in progress");
if (mesh_app_ref_count) {
BT_INFO("Mesh: Mesh Stack already initialized");
+
+ /* Save Mesh App Owner */
+ apps = g_slist_append(apps, g_strdup(sender));
+
/* Increase mesh app ref count */
mesh_app_ref_count++;
return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
return ret;
}
-int _bt_mesh_deinit(void)
+static gint __bt_mesh_match_sender(gconstpointer a, gconstpointer b)
+{
+ char *owner_a = (char*) a;
+ char *owner_b = (char*) b;
+
+ return g_strcmp0(owner_a, owner_b);
+}
+
+int _bt_mesh_deinit(const char *sender)
{
+ GSList *l = NULL;
+ char *owner = NULL;
oal_status_t status = OAL_STATUS_SUCCESS;
int ret = UNIT_CONTROL_OK;
+ BT_INFO("Mesh: Deinit Request from App [%s]", sender);
+ BT_INFO("Mesh: Total Apps available in list [%d]",
+ g_slist_length(apps));
+
+ /* Find & remove app entry from list */
+ l = g_slist_find_custom(apps, sender,
+ (GCompareFunc)__bt_mesh_match_sender);
+ if (!l) {
+ BT_ERR("Mesh: App is not Mesh App");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ BT_INFO("Mesh: Deinit Mesh: Sender Found: [%s]", sender);
+
if (launch_timer > 0) {
g_source_remove(launch_timer);
launch_timer = 0;
/* Decrease mesh app ref count */
mesh_app_ref_count--;
+ owner = l->data;
+ apps = g_slist_remove(apps, owner);
+ g_free(owner);
+
return BLUETOOTH_ERROR_NONE;
}
+
+void _bt_mesh_handle_app_termination(const char *sender)
+{
+ BT_INFO("Mesh: Handle App termination: dbus app name[%s]",
+ sender);
+
+ _bt_mesh_deinit(sender);
+}
#include "bt-service-mesh-network.h"
#include "bt-service-mesh-cdb.h"
+#include "bt-service-mesh-main.h"
#include "bt-service-mesh-nodes.h"
#include "bt-service-mesh-keys.h"
#include "bt-service-mesh-util.h"
return BLUETOOTH_ERROR_NONE;
}
+void _bt_check_mesh_app_termination(const char *name)
+{
+ GSList *l;
+ _bt_mesh_cdb_t *cdb_cfg = NULL;
+ const char *app_cred = NULL;
+ BT_INFO("Mesh: App terminated [%s]", name);
+
+ /* TODO: Fetch app cred, when support is added */
+
+ for (l = cdb_list; l != NULL;) {
+ cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+ l = g_slist_next(l);
+
+ if (g_strcmp0(cdb_cfg->owner, name) == 0) {
+
+ bluetooth_mesh_network_t network;
+ memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
+
+ _bt_mesh_util_convert_hex_to_string((uint8_t *) cdb_cfg->uuid,
+ 16, network.uuid, sizeof(network.uuid));
+
+ BT_INFO("Mesh: Got Network for unloading: UUID [%s]",
+ network.uuid);
+
+ if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_unload(app_cred, name, &network))
+ BT_ERR("Mesh: Network unloading failed!!");
+ else
+ BT_INFO("Mesh: Network unloading Success!!");
+ }
+ }
+ _bt_mesh_handle_app_termination(name);
+}
+
void _bt_mesh_network_unload_net_configuration(_bt_mesh_cdb_t *cdb_cfg)
{
BT_INFO("Mesh: Unload Network Configuration");
BT_INFO("Mesh: CDB File path[%s]", file_path);
BT_INFO("Mesh: CDB App Cred[%s]", app_creds);
cdb_cfg = _bt_mesh_conf_database_create(file_path, uuid,
- token, network, app_creds);
+ token, network, sender, app_creds);
/* Cleanup */
g_free(dir_path);
const char *sender, bluetooth_mesh_network_t *network)
{
GSList *l;
- uint8_t net_uuid[16];
+ oal_uuid_t net_uuid;
_bt_mesh_cdb_t *cdb_cfg;
+ int ret = OAL_STATUS_SUCCESS;
BT_INFO("Mesh: Unload Network Configuration");
/* If Scanning is going on */
}
_bt_mesh_util_convert_string_to_hex(network->uuid,
- strlen(network->uuid), net_uuid, 16);
+ strlen(network->uuid), net_uuid.uuid, 16);
+
+ /* Release Mesh Network */
+ ret = mesh_network_release(&net_uuid);
+ if (ret != OAL_STATUS_SUCCESS) {
+ BT_ERR("ret: %d", ret);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ BT_INFO("Mesh: Network released");
/* Find CDB */
- l = g_slist_find_custom(cdb_list, net_uuid,
+ l = g_slist_find_custom(cdb_list, net_uuid.uuid,
__mesh_compare_app_network_uuid);
if (!l) {
BT_ERR("Mesh: Could not find Network Entry: unexpected!!");