Mesh: Implement Mesh Node Role API's 24/254324/5
authoranuj.bhumiya <anuj.bhumiya@samsung.com>
Fri, 26 Feb 2021 11:15:25 +0000 (16:45 +0530)
committeranuj.bhumiya <anuj.bhumiya@samsung.com>
Fri, 26 Mar 2021 10:58:41 +0000 (16:28 +0530)
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 <anuj.bhumiya@samsung.com>
19 files changed:
bt-api/bt-event-handler.c
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-mesh.h
bt-oal/oal-mesh.c
bt-service/services/bt-request-handler.c
bt-service/services/bt-service-event-sender.c
bt-service/services/include/bt-service-mesh-network.h
bt-service/services/mesh/bt-service-mesh-config-client.c
bt-service/services/mesh/bt-service-mesh-main.c
bt-service/services/mesh/bt-service-mesh-model.c
bt-service/services/mesh/bt-service-mesh-network.c
include/bluetooth-api.h
include/bluetooth-mesh-api.h
include/bt-internal-types.h

index de5e298..1c4f329 100644 (file)
@@ -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, &param);
+               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 <<");
 }
index a1e2920..2d64020 100644 (file)
@@ -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)
index 0d1199f..56884ae 100644 (file)
@@ -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;
index 1c42379..14b60f2 100644 (file)
@@ -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)
 {
index b22bf40..1a9185b 100644 (file)
@@ -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,
index ad5711d..e969538 100644 (file)
@@ -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,
index 090045e..087c1b0 100644 (file)
@@ -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);
index c84a277..a5d426f 100644 (file)
@@ -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
index 3c88100..e980233 100644 (file)
@@ -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;
index ad3562b..232ada1 100644 (file)
@@ -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:
index 63961f1..6b136c5 100644 (file)
@@ -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;
index 9344f71..e7a7d61 100644 (file)
@@ -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);
index 9b57173..6780b86 100644 (file)
@@ -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:
index bf44116..9c3b2c8 100644 (file)
@@ -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(
index 1e4ce05..0e5d370 100644 (file)
@@ -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, &param,
-               sizeof(bluetooth_mesh_model_msg_t));
+       if (!event->is_prov) {
+               BT_DBG("Node role supported is ON");
+               __bt_mesh_send_model_msg_event(result, &param);
+       } else {
+               __bt_mesh_handle_pending_msg_request_info(result,
+                       BT_MESH_MODEL_EXECUTE_MSG, &param,
+                       sizeof(bluetooth_mesh_model_msg_t));
+       }
 
 }
 
index ba5c7c7..d6097ac 100644 (file)
@@ -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)
index aa5ae3b..a4c74bb 100644 (file)
@@ -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;
 
  /**
index 464b668..0dd41a1 100644 (file)
@@ -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,
index 95794dc..36c8308 100644 (file)
@@ -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"