static struct l_dbus_message *agent_msg;
static handle_stack_msg mesh_event_cb = NULL;
-
+static uint32_t iv_index;
struct subnet_key_request {
uint16_t idx;
g_slist_length(app->elements));
g_slist_free_full(app->elements, __mesh_hal_free_elements);
}
+
+ if (app->scan_timer_id > 0) {
+ INFO("Mesh: Remove timer if already running");
+ g_source_remove(app->scan_timer_id);
+ app->scan_timer_id = 0;
+ }
g_free(app);
}
char **strings = g_strsplit(path, "node", 2);
ret = g_strcmp0(strings[1], app_uuid_path);
- g_free(strings[0]);
- g_free(strings[1]);
+
+ g_strfreev(strings);
l_free(app_uuid_path);
+
+ 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);
+ g_strfreev(strings);
return ret;
}
}
}
+static void __mesh_property_changed(struct l_dbus_proxy *proxy, const char *name,
+ struct l_dbus_message *msg, void *user_data)
+{
+ const char *interface = l_dbus_proxy_get_interface(proxy);
+ const char *path = l_dbus_proxy_get_path(proxy);
+ GSList *l;
+ meshcfg_app *app = NULL;
+
+ l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
+ if (l) {
+ app = l->data;
+ } else {
+ ERR("Mesh: app not found for Mgmt proxy");
+ }
+
+ INFO("Property changed: %s %s %s\n", name, path, interface);
+
+ if (!app)
+ return;
+
+ if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
+
+ if (!strcmp(name, "IvIndex")) {
+ uint32_t ivi;
+
+ if (!l_dbus_message_get_arguments(msg, "u", &ivi))
+ return;
+
+ INFO("New IV Index: %u\n", ivi);
+
+ iv_index = ivi;
+ /*TODO: save iv index */
+ }
+ }
+}
+
+
static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
void *user_data)
{
return false;
if (!l_dbus_client_set_proxy_handlers(client,
__mesh_proxy_added, __mesh_proxy_removed,
- NULL, NULL, NULL))
+ __mesh_property_changed, NULL, NULL))
return false;
if (!l_dbus_client_set_ready_handler(client,
__mesh_dbus_client_ready, NULL, NULL))
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)
struct l_dbus_message_iter iter_cfg;
char *path;
meshcfg_app *app = (meshcfg_app*) user_data;
+ uint32_t ivi;
+
INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
app->path, app->agent_path);
INFO("Mesh: Attached with path %s\n", app->path);
__send_network_attach_event(app, BT_STATUS_SUCCESS);
+
+ if (l_dbus_proxy_get_property(app->proxy, "IvIndex", "u", &ivi) &&
+ ivi != iv_index) {
+ iv_index = ivi;
+ /* TODO: Save IV index */
+ }
+
return;
failed:
__send_network_attach_event(app, BT_STATUS_FAIL);
return l_dbus_message_new_method_return(message);
}
+static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
+ const char *key, const char *signature,
+ const void *data)
+{
+ if (!builder)
+ return;
+
+ l_dbus_message_builder_enter_dict(builder, "sv");
+ l_dbus_message_builder_append_basic(builder, 's', key);
+ l_dbus_message_builder_enter_variant(builder, signature);
+ l_dbus_message_builder_append_basic(builder, signature[0], data);
+ l_dbus_message_builder_leave_variant(builder);
+ l_dbus_message_builder_leave_dict(builder);
+}
+
static void __bt_hal_mesh_foreach_model_getter(gpointer data,
gpointer user_data)
{
struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
meshcfg_model *model_info = (meshcfg_model*) data;
+ 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);
+ l_dbus_message_builder_enter_array(builder, "{sv}");
+ append_dict_entry_basic(builder, "Subscribe", "b", &sub_enable);
+ append_dict_entry_basic(builder, "Publish", "b", &pub_enable);
+ l_dbus_message_builder_leave_array(builder);
+ l_dbus_message_builder_leave_struct(builder);
}
static bool __mesh_model_getter(struct l_dbus *dbus,
{
meshcfg_el *element = (meshcfg_el*) user_data;
- l_dbus_message_builder_enter_array(builder, "q");
+ l_dbus_message_builder_enter_array(builder, "(qa{sv})");
g_slist_foreach(element->models,
__bt_hal_mesh_foreach_model_getter, builder);
struct l_dbus_message_builder *builder,
void *user_data)
{
- l_dbus_message_builder_enter_array(builder, "(qq)");
+ l_dbus_message_builder_enter_array(builder, "(qqa{sv})");
l_dbus_message_builder_leave_array(builder);
return true;
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;
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)) {
/* Properties */
l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
NULL);
- l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
+ l_dbus_interface_property(iface, "VendorModels", 0, "a(qqa{sv})",
__mesh_vendor_model_getter, NULL);
- l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
+ l_dbus_interface_property(iface, "Models", 0, "a(qa{sv})", __mesh_model_getter,
+ NULL);
/* Methods */
l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
INFO("Mesh: Provisioning failed:\n");
str = l_util_hexstring_upper(uuid, 16);
INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
- l_free(str);
ev.status = BT_STATUS_FAIL;
ev.reason = __bt_mesh_util_get_prov_error_code(str);
memcpy(ev.dev_uuid, uuid, 16);
+ l_free(str);
+
if (mesh_event_cb)
mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
(void*)&ev, sizeof(ev));
l = g_slist_find_custom(mesh_apps, net_uuid,
__mesh_compare_network_uuid);
- if (l) {
+ if (l)
app = l->data;
- } else {
+ else
ERR("Mesh: app not found");
- }
memset(&ev, 0, sizeof(ev));
__bt_hal_mesh_setup_app_iface, NULL, false)) {
ERR("Mesh: Failed to register interface %s",
BT_HAL_MESH_APPLICATION_INTERFACE);
- //return false;
+ return false;
}
if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
__bt_hal_mesh_setup_prov_iface, NULL, false)) {
ERR("Mesh: Failed to register interface %s",
BT_HAL_MESH_PROVISIONER_INTERFACE);
- //return false;
+ return false;
}
if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
__bt_hal_mesh_setup_ele_iface, NULL, false)) {
ERR("Mesh: Failed to register interface %s",
BT_HAL_MESH_ELEMENT_INTERFACE);
- //return false;
+ return false;
}
INFO("Mesh: Number of elements to be registsred [%d]",
char *uuid_str = NULL;
uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
+ INFO("Mesh: Network UUID [%s]", uuid_str);
app = g_malloc0(sizeof(meshcfg_app));
memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
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);
g_free(uuid_str);
app->is_prov = is_prov;
+ app->token.u64 = node->token.u64;
+ INFO("Mesh: Token [%llu]", (unsigned long long int)app->token.u64);
INFO("Mesh: app created");
return app;
}
l_free(net_uuid);
}
-static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
- const char *key, const char *signature,
- const void *data)
-{
- if (!builder)
- return;
-
- l_dbus_message_builder_enter_dict(builder, "sv");
- l_dbus_message_builder_append_basic(builder, 's', key);
- l_dbus_message_builder_enter_variant(builder, signature);
- l_dbus_message_builder_append_basic(builder, signature[0], data);
- l_dbus_message_builder_leave_variant(builder);
- l_dbus_message_builder_leave_dict(builder);
-}
-
static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
{
struct l_dbus_message_builder *builder;
static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
void *user_data)
{
- char *uuid;
+ char *uuid = NULL;
bt_uuid_t *dev = user_data;
struct l_dbus_message_builder *builder;
+
uuid = l_util_hexstring(dev->uu, 16);
+ if (uuid == NULL)
+ return;
+
INFO("Mesh: Add Node Setup UUID [%s]", uuid);
builder = l_dbus_message_builder_new(msg);
l_dbus_message_builder_leave_array(builder);
l_dbus_message_builder_finalize(builder);
l_dbus_message_builder_destroy(builder);
+
+ l_free(uuid);
}
bt_status_t _bt_hal_mesh_provision_device(
ERR("Mesh: Proxy check failed!!");
return BT_STATUS_FAIL;
}
- INFO("Mesh: Create New Network");
+ INFO("Mesh: Destroy Network");
/* Create CFG Network */
if (!l_dbus_proxy_method_call(net_proxy, "Leave",
__bt_hal_mesh_leave_net_setup,
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, is_prov);
if (!app)
goto failed;
}
} else {
- INFO("Mesh: Attach Node to Network");
+ INFO("Mesh: Attach Node to Network: Token [%llu]", (unsigned long long int)app->token.u64);
/* Attach to Network */
if (!l_dbus_proxy_method_call(net_proxy, "Attach",
__bt_hal_mesh_attach_node_setup,
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)
{
l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
+
+ /* Options */
+ l_dbus_message_builder_enter_array(builder, "{sv}");
+ l_dbus_message_builder_enter_dict(builder, "sv");
+ l_dbus_message_builder_leave_dict(builder);
+ l_dbus_message_builder_leave_array(builder);
+
__mesh_append_byte_array(builder, req->data, req->len);
l_dbus_message_builder_finalize(builder);
l_dbus_message_builder_destroy(builder);
l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
+
+ /* Options */
+ l_dbus_message_builder_enter_array(builder, "{sv}");
+ l_dbus_message_builder_enter_dict(builder, "sv");
+ l_dbus_message_builder_leave_dict(builder);
+ l_dbus_message_builder_leave_array(builder);
+
__mesh_append_byte_array(builder, req->data, req->len);
l_dbus_message_builder_finalize(builder);
l_dbus_message_builder_destroy(builder);