From d85dbdb8faf6b38ecf634d0059b821cf683faa34 Mon Sep 17 00:00:00 2001 From: "anuj.bhumiya" Date: Fri, 26 Feb 2021 16:45:25 +0530 Subject: [PATCH] Mesh: Implement Mesh Node Role API's This patch implements the Mesh node role for device. Join API create a fresh node and set callbacks for join complete and message execution callbacks. Cancel API destroy the outgoing request initiated by Join API and destroy the node from the application Change-Id: I79fa3c390a08076d84c0e20450f7c32aec1bdf6e Signed-off-by: anuj.bhumiya --- bt-api/bt-event-handler.c | 21 ++++ bt-api/bt-mesh.c | 52 ++++++++++ bt-oal/bluez_hal/inc/bt-hal-msg.h | 2 + bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c | 108 ++++++++++++++++++++- bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.h | 5 + bt-oal/bluez_hal/src/bt-hal-mesh.c | 22 ++++- bt-oal/hardware/bt_mesh.h | 7 +- bt-oal/include/oal-mesh.h | 13 +++ bt-oal/oal-mesh.c | 46 +++++++-- bt-service/services/bt-request-handler.c | 60 ++++++++++++ bt-service/services/bt-service-event-sender.c | 3 + .../services/include/bt-service-mesh-network.h | 7 ++ .../services/mesh/bt-service-mesh-config-client.c | 2 + bt-service/services/mesh/bt-service-mesh-main.c | 34 ++++++- bt-service/services/mesh/bt-service-mesh-model.c | 11 ++- bt-service/services/mesh/bt-service-mesh-network.c | 58 +++++++++++ include/bluetooth-api.h | 1 + include/bluetooth-mesh-api.h | 12 +++ include/bt-internal-types.h | 3 + 19 files changed, 445 insertions(+), 22 deletions(-) diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c index de5e298..1c4f329 100644 --- a/bt-api/bt-event-handler.c +++ b/bt-api/bt-event-handler.c @@ -745,6 +745,27 @@ static void __bt_mesh_event_filter(GDBusConnection *connection, _bt_mesh_event_cb(BLUETOOTH_EVENT_MESH_MODEL_MSG_EXECUTED, result, info, event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_MESH_JOIN_COMPLETED) == 0) { + int result; + GVariant *param = NULL; + GArray *dbus_data = NULL; + BT_INFO("Mesh: JOIN event"); + bluetooth_mesh_network_t *info = NULL; + + g_variant_get(parameters, "(iv)", &result, ¶m); + dbus_data = g_array_new(TRUE, TRUE, sizeof(gchar)); + + __bt_fill_garray_from_variant(param, dbus_data); + g_variant_unref(param); + + info = &g_array_index(dbus_data, bluetooth_mesh_network_t, 0); + + if (!info) + BT_INFO("Mesh: info is null"); + + _bt_mesh_event_cb(BLUETOOTH_EVENT_MESH_JOIN_COMPLETED, + result, info, + event_info->cb, event_info->user_data); } BT_INFO("Mesh event handler Exit <<"); } diff --git a/bt-api/bt-mesh.c b/bt-api/bt-mesh.c index a1e2920..2d64020 100644 --- a/bt-api/bt-mesh.c +++ b/bt-api/bt-mesh.c @@ -224,6 +224,58 @@ BT_EXPORT_API int bluetooth_mesh_network_load( return result; } +BT_EXPORT_API int bluetooth_mesh_network_join( + bluetooth_mesh_node_t *node, uint16_t total_models, + bluetooth_mesh_model_t **models) +{ + int result; + + BT_CHECK_PARAMETER(node, return); + BT_CHECK_PARAMETER(models, return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, node, sizeof(bluetooth_mesh_node_t)); + + for (int i = 0; i < total_models; i++) + g_array_append_vals(in_param2, models[i], + sizeof(bluetooth_mesh_model_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, + BT_MESH_NETWORK_JOIN, + in_param1, in_param2, in_param3, + in_param4, &out_param); + if (result == BLUETOOTH_ERROR_NONE) { + *node = g_array_index(out_param, + bluetooth_mesh_node_t, 0); + } + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_mesh_cancel_join( + bluetooth_mesh_node_info_t *node) +{ + int result; + + BT_CHECK_PARAMETER(node, return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + g_array_append_vals(in_param1, node, sizeof(bluetooth_mesh_node_info_t)); + + BT_INFO("Mesh: Cancel Ongoing Join"); + BT_INFO("Mesh: Node UUID [%s]", node->net_uuid); + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_MESH_CANCEL_JOIN, + 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_scan( bluetooth_mesh_network_t *network, bluetooth_mesh_scan_param_t *scan_param) diff --git a/bt-oal/bluez_hal/inc/bt-hal-msg.h b/bt-oal/bluez_hal/inc/bt-hal-msg.h index 0d1199f..56884ae 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-msg.h +++ b/bt-oal/bluez_hal/inc/bt-hal-msg.h @@ -843,6 +843,7 @@ struct hal_ev_controller_error_recieved { #define HAL_EV_MESH_NETWORK_ATTACHED 0xD2 struct hal_ev_mesh_network_attached { uint8_t status; + bool is_prov; uint8_t uuid[16]; uint8_t token[8]; } __attribute__((packed)); @@ -940,6 +941,7 @@ struct hal_ev_mesh_devkey_message_event { #define HAL_EV_MESH_MESSAGE_EVENT 0xDD struct hal_ev_mesh_message_event { uint8_t net_uuid[16]; + bool is_prov; uint16_t source_addr; uint16_t dest_addr; uint16_t key_idx; 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 1c42379..14b60f2 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 @@ -417,6 +417,20 @@ static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data) 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); + return ret; +} + static gint __compare_element_index(gconstpointer data, gconstpointer user_data) { const meshcfg_el *elem = data; @@ -741,6 +755,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) @@ -865,8 +880,8 @@ static void __bt_hal_mesh_foreach_model_getter(gpointer data, { struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data; meshcfg_model *model_info = (meshcfg_model*) data; - bool pub_enable = false; - bool sub_enable = false; + 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); @@ -977,9 +992,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; @@ -989,6 +1014,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)) { @@ -1771,6 +1797,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); @@ -2603,6 +2630,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) { 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 b22bf40..1a9185b 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 @@ -49,6 +49,11 @@ bt_status_t _bt_hal_mesh_create_network(bt_hal_mesh_node_t *node, bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid); +bt_status_t _bt_hal_mesh_join_network(bt_hal_mesh_node_t *node, + GSList *models); + +bt_status_t _bt_hal_mesh_join_cancel(bt_uuid_t *node_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, diff --git a/bt-oal/bluez_hal/src/bt-hal-mesh.c b/bt-oal/bluez_hal/src/bt-hal-mesh.c index ad5711d..e969538 100644 --- a/bt-oal/bluez_hal/src/bt-hal-mesh.c +++ b/bt-oal/bluez_hal/src/bt-hal-mesh.c @@ -47,8 +47,9 @@ static void __bt_hal_mesh_network_attached(void *buf, uint16_t len) struct hal_ev_mesh_network_attached *ev = buf; if (bt_hal_mesh_cbacks->network_attached_cb) bt_hal_mesh_cbacks->network_attached_cb(ev->status, - (bt_mesh_token_t*)&ev->token, - (bt_uuid_t*)&ev->uuid); + ev->is_prov, + (bt_mesh_token_t*)&ev->token, + (bt_uuid_t*)&ev->uuid); } static void __bt_hal_mesh_network_destroyed(void *buf, uint16_t len) @@ -171,7 +172,7 @@ static void __bt_hal_handle_message_received_event(void *buf, uint16_t len) if (bt_hal_mesh_cbacks->msg_cb) bt_hal_mesh_cbacks->msg_cb((bt_uuid_t*)&ev->net_uuid, - ev->source_addr, + ev->is_prov, ev->source_addr, ev->dest_addr, ev->key_idx, ev->data_len, ev->data); } @@ -263,6 +264,19 @@ static bt_status_t mesh_destroy_network(bt_uuid_t *network) return _bt_hal_mesh_network_destroy(network); } +static bt_status_t mesh_join_network(bt_hal_mesh_node_t *node, + GSList *models) +{ + DBG(""); + return _bt_hal_mesh_join_network(node, models); +} + +static bt_status_t mesh_join_cancel(bt_uuid_t *node_uuid) +{ + DBG(""); + return _bt_hal_mesh_join_cancel(node_uuid); +} + static bt_status_t mesh_delete_node(bt_uuid_t *network, uint16_t unicast, uint16_t num_elements) { @@ -397,6 +411,8 @@ static btmesh_interface_t mesh_if = { .init = init, .create = mesh_create_network, .destroy = mesh_destroy_network, + .join = mesh_join_network, + .cancel = mesh_join_cancel, .release = mesh_release_network, .delete_node = mesh_delete_node, .scan = mesh_scan, diff --git a/bt-oal/hardware/bt_mesh.h b/bt-oal/hardware/bt_mesh.h index 090045e..087c1b0 100644 --- a/bt-oal/hardware/bt_mesh.h +++ b/bt-oal/hardware/bt_mesh.h @@ -138,7 +138,7 @@ typedef enum { typedef void (*btmesh_network_proxy_added_callback)(bt_status_t status); typedef void (*btmesh_network_attached_callback)(bt_status_t status, - bt_mesh_token_t *token, bt_uuid_t *uuid); + bool is_prov, 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); @@ -176,7 +176,7 @@ typedef void (*btmesh_devkey_message_received_callback)(bt_uuid_t *net_uuid, uint16_t source_addr, bool is_devkey_remote, uint16_t netkey_idx, uint16_t data_len, uint8_t *data); -typedef void (*btmesh_message_received_callback)(bt_uuid_t *net_uuid, +typedef void (*btmesh_message_received_callback)(bt_uuid_t *net_uuid, bool is_prov, uint16_t source_addr, uint16_t dest_addr, uint16_t key_idx, uint16_t data_len, uint8_t *data); @@ -211,6 +211,9 @@ typedef struct { 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 (*join)(bt_hal_mesh_node_t *node, + GSList *model_list); + bt_status_t (*cancel)(bt_uuid_t *node); bt_status_t (*release)(bt_uuid_t *network); bt_status_t (*delete_node)(bt_uuid_t *network, uint16_t unicast, uint16_t elem_cnt); diff --git a/bt-oal/include/oal-mesh.h b/bt-oal/include/oal-mesh.h index c84a277..a5d426f 100644 --- a/bt-oal/include/oal-mesh.h +++ b/bt-oal/include/oal-mesh.h @@ -145,6 +145,7 @@ typedef struct { typedef struct { oal_status_t status; + bool is_prov; uint8_t token[8]; oal_uuid_t uuid; } event_mesh_network_attached_t; @@ -220,6 +221,7 @@ typedef struct { typedef struct { oal_uuid_t net_uuid; + bool is_prov; uint16_t source; /* address of remote element which sent msg */ uint16_t dest; /* address of local element which received msg*/ uint16_t key_idx; @@ -276,6 +278,17 @@ oal_status_t mesh_register_node(oal_mesh_node_t *node, oal_status_t mesh_network_destroy(oal_uuid_t* network_uuid); /** + * @brief Cancel ongoing Join Request + * + * @remark Stack will remove the local node entry + * + * @pre OAL API should be enabled with mesh_enable(). + * + * @see mesh_enable() + */ +oal_status_t mesh_cancel_join(oal_uuid_t* node_uuid); + +/** * @brief Request Stack to release Network resources * * @remarks Stack will remove only yhe DBUS resources of local node diff --git a/bt-oal/oal-mesh.c b/bt-oal/oal-mesh.c index 3c88100..e980233 100644 --- a/bt-oal/oal-mesh.c +++ b/bt-oal/oal-mesh.c @@ -45,7 +45,7 @@ static const btmesh_interface_t *mesh_api; /* Forward declaration: Callbacks from HAL */ static void mesh_network_proxy_added_callback(bt_status_t status); static void mesh_network_attached_callback(bt_status_t status, - bt_mesh_token_t *token, bt_uuid_t *uuid); + bool is_prov, 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, @@ -70,9 +70,9 @@ static void mesh_network_appkey_execute_callback(bt_status_t status, static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid, uint16_t source_addr, bool is_remote_devkey, uint16_t netkey_idx, uint16_t ata_len, uint8_t *data); -static void mesh_message_received_callback(bt_uuid_t *net_uuid, +static void mesh_message_received_callback(bt_uuid_t *net_uuid, bool is_prov, uint16_t source_addr, uint16_t dest_addr, - uint16_t key_idx, uint16_t data_len, uint8_t *data); + uint16_t key_idx, uint16_t data_len, uint8_t *data); static btmesh_callbacks_t sBluetoothMeshCallbacks = { @@ -105,7 +105,7 @@ static void mesh_network_proxy_added_callback(bt_status_t status) event, sizeof(event_mesh_network_proxy_added_t), NULL); } -static void mesh_network_attached_callback(bt_status_t status, +static void mesh_network_attached_callback(bt_status_t status, bool is_prov, bt_mesh_token_t *token, bt_uuid_t *uuid) { event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1); @@ -116,6 +116,7 @@ static void mesh_network_attached_callback(bt_status_t status, memcpy(event->token, token->token, sizeof(bt_mesh_token_t)); memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t)); + event->is_prov = is_prov; send_event_bda_trace(OAL_EVENT_MESH_NETWORK_ATTACHED, event, sizeof(event_mesh_network_attached_t), NULL); @@ -299,7 +300,7 @@ static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid, sizeof(event_mesh_devkey_message_t), NULL); } -static void mesh_message_received_callback(bt_uuid_t *net_uuid, +static void mesh_message_received_callback(bt_uuid_t *net_uuid, bool is_prov, uint16_t source_addr, uint16_t dest_addr, uint16_t key_idx, uint16_t data_len, uint8_t *data) { @@ -307,6 +308,7 @@ static void mesh_message_received_callback(bt_uuid_t *net_uuid, BT_INFO("Mesh Event: Model Message Received"); event->source = source_addr; + event->is_prov = is_prov; event->dest = dest_addr; event->key_idx = key_idx; event->data_len = data_len; @@ -370,17 +372,41 @@ oal_status_t mesh_register_node(oal_mesh_node_t *node, API_TRACE(); CHECK_OAL_MESH_ENABLED(); - BT_INFO("Mesh: Send create network request to stack"); - ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner); - if (ret != BT_STATUS_SUCCESS) { - BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret)); - return convert_to_oal_status(ret); + if (is_provisioner) { + BT_INFO("Mesh: Send create network request to stack"); + ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + } else { + BT_INFO("Mesh: Send join network request to stack"); + ret = mesh_api->join((bt_hal_mesh_node_t*)node, model_list); + if (ret != BT_STATUS_SUCCESS) { + return convert_to_oal_status(ret); + } } BT_INFO("Mesh: Request sent to stack"); return OAL_STATUS_SUCCESS; } +oal_status_t mesh_cancel_join(oal_uuid_t* node_uuid) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + BT_INFO("Mesh: Send cancel join request to stack"); + ret = mesh_api->cancel((bt_uuid_t*)node_uuid); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: cancel join failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + oal_status_t mesh_network_release(oal_uuid_t* network_uuid) { int ret = BT_STATUS_SUCCESS; diff --git a/bt-service/services/bt-request-handler.c b/bt-service/services/bt-request-handler.c index ad3562b..232ada1 100644 --- a/bt-service/services/bt-request-handler.c +++ b/bt-service/services/bt-request-handler.c @@ -3643,6 +3643,64 @@ normal: sender, &network); break; } + case BT_MESH_NETWORK_JOIN: { + bluetooth_mesh_node_t node; + GSList *model_list = NULL; + int total_models = 0; + GArray *param2; + int i = 0; + + memset(&node, 0x00, sizeof(bluetooth_mesh_node_t)); + sender = (char*)g_dbus_method_invocation_get_sender(context); + + __bt_service_get_parameters(in_param1, + &node, sizeof(bluetooth_mesh_node_t)); + + param2 = g_array_new(TRUE, TRUE, sizeof(gchar)); + __bt_fill_garray_from_variant(in_param2, param2); + + total_models = (param2->len) / sizeof(bluetooth_mesh_model_t); + for (i = 0; i < total_models; i++) { + bluetooth_mesh_model_t *info = NULL; + bluetooth_mesh_model_t *mod = NULL; + info = &g_array_index(param2, + bluetooth_mesh_model_t, i); + mod = g_memdup(info, sizeof(bluetooth_mesh_model_t)); + + if (mod) + model_list = g_slist_append(model_list, + (gpointer)mod); + } + + BT_INFO("MESH: Network Join bt-service"); + //result = BLUETOOTH_ERROR_NONE; + result = _bt_mesh_network_join(requester_unique_creds, + sender, &node, model_list); + if (result != BLUETOOTH_ERROR_NONE) { + g_array_append_vals(*out_param1, &node, sizeof(bluetooth_mesh_node_t)); + BT_ERR("Mesh: Mesh Join Network schedule failed"); + g_slist_free_full(model_list, g_free); + } + + BT_INFO("return of _bt_mesh_network_join : [%d]", result); + break; + } + case BT_MESH_CANCEL_JOIN: { + bluetooth_mesh_node_info_t node; + memset(&node, 0x00, sizeof(bluetooth_mesh_node_info_t)); + + __bt_service_get_parameters(in_param1, + &node, sizeof(bluetooth_mesh_node_info_t)); + + BT_INFO("Mesh: Cancel Join request"); + result = _bt_mesh_cancel_join(requester_unique_creds, + sender, &node); + if (result != BLUETOOTH_ERROR_NONE) { + g_array_append_vals(*out_param1, + &node, sizeof(bluetooth_mesh_node_t)); + } + break; + } case BT_MESH_NETWORK_SCAN: { bluetooth_mesh_network_t network; bluetooth_mesh_scan_param_t param; @@ -5287,6 +5345,8 @@ gboolean __bt_service_check_privilege(int function_name, case BT_MESH_NETWORK_DESTROY: case BT_MESH_NETWORK_LOAD: case BT_MESH_NETWORK_UNLOAD: + case BT_MESH_NETWORK_JOIN: + case BT_MESH_CANCEL_JOIN: case BT_MESH_NETWORK_SCAN: case BT_MESH_NETWORK_CANCEL_SCAN: case BT_MESH_NETWORK_SET_CAPABILITIES: diff --git a/bt-service/services/bt-service-event-sender.c b/bt-service/services/bt-service-event-sender.c index 63961f1..6b136c5 100644 --- a/bt-service/services/bt-service-event-sender.c +++ b/bt-service/services/bt-service-event-sender.c @@ -574,6 +574,9 @@ int _bt_send_event(int event_type, int event, GVariant *param) case BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS: signal = BT_MESH_MODEL_PUB_STATUS; break; + case BLUETOOTH_EVENT_MESH_JOIN_COMPLETED: + signal = BT_MESH_JOIN_COMPLETED; + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; diff --git a/bt-service/services/include/bt-service-mesh-network.h b/bt-service/services/include/bt-service-mesh-network.h index 9344f71..e7a7d61 100644 --- a/bt-service/services/include/bt-service-mesh-network.h +++ b/bt-service/services/include/bt-service-mesh-network.h @@ -59,6 +59,13 @@ int _bt_mesh_network_load(const char *app_cred, int _bt_mesh_network_unload(const char *app_cred, const char *sender, bluetooth_mesh_network_t *network); +int _bt_mesh_network_join(const char *app_cred, + const char *sender, bluetooth_mesh_node_t *node, + GSList *model_list); + +int _bt_mesh_cancel_join(const char *app_cred, + const char *sender, bluetooth_mesh_node_info_t *node); + int _bt_mesh_network_load_cdb(int result, const char *sender, const char *app_creds, uint8_t uuid[16], uint8_t token[8], char **network); diff --git a/bt-service/services/mesh/bt-service-mesh-config-client.c b/bt-service/services/mesh/bt-service-mesh-config-client.c index 9b57173..6780b86 100644 --- a/bt-service/services/mesh/bt-service-mesh-config-client.c +++ b/bt-service/services/mesh/bt-service-mesh-config-client.c @@ -1287,6 +1287,7 @@ void _bt_mesh_config_client_devkey_msg_handler( BT_INFO("Model ID\t%4.4x\n", mod_id); if (data[0] == MESH_STATUS_SUCCESS) { + BT_INFO("_bt_mesh_network_add_model_subscription called or not"); /* Update cdb */ switch (cmd->opcode) { case MESH_OPCODE_CONFIG_MODEL_SUB_ADD: @@ -1296,6 +1297,7 @@ void _bt_mesh_config_client_devkey_msg_handler( ele_addr - event->source, mod_id, addr)) { BT_INFO("Failed to add model subscription!"); } + BT_INFO("_bt_mesh_network_add_model_subscription called or not"); break; case MESH_OPCODE_CONFIG_MODEL_SUB_DELETE: case MESH_OPCODE_CONFIG_MODEL_SUB_VIRT_DELETE: diff --git a/bt-service/services/mesh/bt-service-mesh-main.c b/bt-service/services/mesh/bt-service-mesh-main.c index bf44116..9c3b2c8 100644 --- a/bt-service/services/mesh/bt-service-mesh-main.c +++ b/bt-service/services/mesh/bt-service-mesh-main.c @@ -55,7 +55,6 @@ static guint mesh_app_ref_count; struct l_timeout *wait_timer; static GSList *apps; - static int __bt_meshd_launch() { int ret = UNIT_CONTROL_OK; @@ -475,6 +474,37 @@ static void __handle_mesh_network_proxy_added_event( NULL, 0); } +static void __handle_mesh_network_join_completed_event( + event_mesh_network_attached_t *event) +{ + GVariant *out_var = NULL, *param = NULL; + GArray *info = NULL; + bluetooth_mesh_node_t node; + int result = BLUETOOTH_ERROR_NONE; + if (event->status != OAL_STATUS_SUCCESS) { + BT_INFO("Mesh: Join Finished: status:: FAILED!"); + result = BLUETOOTH_ERROR_INTERNAL; + } + else + BT_INFO("Mesh: Join Finished: status:: SUCCESS!"); + + if (result == BLUETOOTH_ERROR_NONE) { + memset(&node, 0x00, sizeof(bluetooth_mesh_node_t)); + memcpy(node.uuid, event->uuid.uuid, 16); + info = g_array_new(FALSE, FALSE, sizeof(gchar)); + g_array_append_vals(info, &node, + sizeof(bluetooth_mesh_node_t)); + out_var = g_variant_new_from_data((const GVariantType *)"ay", + info->data, info->len, + TRUE, NULL, NULL); + + param = g_variant_new("(iv)", result, out_var); + _bt_send_event(BT_MESH_EVENT, + BLUETOOTH_EVENT_MESH_JOIN_COMPLETED, + param); + } +} + static void __handle_mesh_network_attached_event( event_mesh_network_attached_t *event) { @@ -495,6 +525,8 @@ static void __handle_mesh_network_attached_event( __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_LOAD, &node, sizeof(bluetooth_mesh_node_t)); + if (!event->is_prov) + __handle_mesh_network_join_completed_event(event); } static void __handle_mesh_network_destroyed_event( diff --git a/bt-service/services/mesh/bt-service-mesh-model.c b/bt-service/services/mesh/bt-service-mesh-model.c index 1e4ce05..0e5d370 100644 --- a/bt-service/services/mesh/bt-service-mesh-model.c +++ b/bt-service/services/mesh/bt-service-mesh-model.c @@ -441,9 +441,14 @@ void _bt_mesh_msg_handler(event_mesh_message_t *event) param.opcode = opcode; BT_INFO("Send response"); - __bt_mesh_handle_pending_msg_request_info(result, - BT_MESH_MODEL_EXECUTE_MSG, ¶m, - sizeof(bluetooth_mesh_model_msg_t)); + if (!event->is_prov) { + BT_DBG("Node role supported is ON"); + __bt_mesh_send_model_msg_event(result, ¶m); + } else { + __bt_mesh_handle_pending_msg_request_info(result, + BT_MESH_MODEL_EXECUTE_MSG, ¶m, + sizeof(bluetooth_mesh_model_msg_t)); + } } diff --git a/bt-service/services/mesh/bt-service-mesh-network.c b/bt-service/services/mesh/bt-service-mesh-network.c index ba5c7c7..d6097ac 100644 --- a/bt-service/services/mesh/bt-service-mesh-network.c +++ b/bt-service/services/mesh/bt-service-mesh-network.c @@ -509,6 +509,7 @@ int _bt_mesh_network_destroy(const char *app_cred, strlen(network->uuid), net_uuid.uuid, 16); /* Destroy Mesh Network */ ret = mesh_network_destroy(&net_uuid); + BT_INFO("Mesh: Network UUID [%s]", network->uuid); if (ret != OAL_STATUS_SUCCESS) { BT_ERR("ret: %d", ret); return BLUETOOTH_ERROR_INTERNAL; @@ -1194,6 +1195,63 @@ int _bt_mesh_network_create(const char *app_cred, const char *sender, return BLUETOOTH_ERROR_NONE; } +int _bt_mesh_network_join(const char *app_cred, const char *sender, + bluetooth_mesh_node_t *node, GSList *model_list) +{ + int ret = OAL_STATUS_SUCCESS; + + BT_INFO("Mesh: App Credential#### [%s] sender [%s]", + app_cred, sender); + + /* TODO Handle Buzy status */ + /* Sanity Check: CDB directory creation */ + if (!_bt_mesh_util_is_directory_exists(MESH_CDB_DEFAULT_DIR_PATH)) { + BT_INFO("MESH: CDB directory does not exist"); + if (!_bt_mesh_util_create_directory(MESH_CDB_DEFAULT_DIR_PATH)) { + BT_ERR("MESH: Fail to create Mesh CDB directory"); + return BLUETOOTH_ERROR_INTERNAL; + } + } + + BT_INFO("Mesh: Send Join Network Request to OAL"); + /* Register Mesh Node */ + ret = mesh_register_node((oal_mesh_node_t*)node, model_list, false); + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("ret: %d", ret); + return BLUETOOTH_ERROR_INTERNAL; + } + + BT_INFO("Mesh: Request Sent to Stack successfully"); + /* Create a temporary node & wait for Join event */ + mesh_local_node_t *temp = g_malloc0(sizeof(mesh_local_node_t)); + memcpy(temp->node_uuid, node->uuid, 16); + temp->num_elems = node->num_elements; + temp->prim_unicast = node->primary_unicast; + temp->sender = g_strdup(sender); + temp->app_cred = g_strdup(app_cred); + temp->vendor_info = node->vendor_info; + temp->model_list = model_list; + temp_nodes = g_slist_append(temp_nodes, temp); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_mesh_cancel_join(const char *app_cred, + const char *sender, bluetooth_mesh_node_info_t *node) +{ + int ret = OAL_STATUS_SUCCESS; + oal_uuid_t node_uuid; + + _bt_mesh_util_convert_string_to_hex(node->net_uuid, + strlen(node->net_uuid), node_uuid.uuid, 16); + /* Destroy Mesh Network */ + ret = mesh_cancel_join(&node_uuid); + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("ret: %d", ret); + return BLUETOOTH_ERROR_INTERNAL; + } + return BLUETOOTH_ERROR_NONE; +} + bool _bt_mesh_network_save_remote_node_appkey( uint8_t net_uuid[], uint16_t remote_unicast, uint16_t netkey_idx, uint16_t appkey_idx) diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index aa5ae3b..a4c74bb 100644 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -962,6 +962,7 @@ typedef enum { BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED, BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED, BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, + BLUETOOTH_EVENT_MESH_JOIN_COMPLETED } bluetooth_event_type_t; /** diff --git a/include/bluetooth-mesh-api.h b/include/bluetooth-mesh-api.h index 464b668..0dd41a1 100644 --- a/include/bluetooth-mesh-api.h +++ b/include/bluetooth-mesh-api.h @@ -285,6 +285,18 @@ int bluetooth_mesh_network_load(const char *token, bluetooth_mesh_network_t *network); /** + * Create a Remote Unprovisioned Node + */ +int bluetooth_mesh_network_join(bluetooth_mesh_node_t *node, + uint16_t total_models, + bluetooth_mesh_model_t **models); + +/** + * Cancel the ongoing request + */ +int bluetooth_mesh_cancel_join(bluetooth_mesh_node_info_t *node); + +/** * Scan for Unprovisioned Devices */ int bluetooth_mesh_network_scan(bluetooth_mesh_network_t *network, diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index 95794dc..36c8308 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -472,6 +472,8 @@ typedef enum { BT_MESH_NETWORK_DESTROY, BT_MESH_NETWORK_LOAD, BT_MESH_NETWORK_UNLOAD, + BT_MESH_NETWORK_JOIN, + BT_MESH_CANCEL_JOIN, BT_MESH_NETWORK_SCAN, BT_MESH_NETWORK_CANCEL_SCAN, BT_MESH_NETWORK_SET_CAPABILITIES, @@ -750,6 +752,7 @@ typedef struct { #define BT_MESH_MODEL_SUB_CONF "MeshModelSubConfiguration" #define BT_MESH_MODEL_VIR_SUB_CONF "MeshModelVirSubConfiguration" #define BT_MESH_MODEL_PUB_STATUS "MeshModelPublicationStatus" +#define BT_MESH_JOIN_COMPLETED "MeshJoinCompleted" #define BT_FEATURE_COMMON "http://tizen.org/feature/network.bluetooth" #define BT_FEATURE_OPP "http://tizen.org/feature/network.bluetooth.opp" -- 2.7.4