#include <hardware/bt_mesh.h>
+#define BT_HAL_MESH_DBUS_NAME "org.projectx.bt.mesh"
+
#define BT_HAL_UUID_LEN 16
#define BT_HAL_BLUEZ_MESH_NAME "org.bluez.mesh"
#define BT_HAL_MESH_ERROR_INTERFACE "org.bluez.mesh.Error"
#define BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE 2048
+#define BT_HAL_MESH_MAX_MSG_BUF_SIZE 2048
static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs";
static const char *dbus_err_fail = "org.freedesktop.DBus.Error.Failed";
static struct l_dbus *dbus = NULL;
static struct l_dbus_client *client = NULL;
-static struct l_dbus_proxy *net_proxy;
+static struct l_dbus_proxy *net_proxy = NULL;
static struct l_dbus_message *agent_msg;
static handle_stack_msg mesh_event_cb = NULL;
bt_hal_mesh_auth_variant_e auth_type;
};
+struct mesh_remote_node_info {
+ uint16_t unicast;
+ uint8_t num_elements;
+};
+
static struct mesh_provision_auth_action auth_table[] = {
{ "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
{ "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
{ "out-numeric", BT_HAL_MESH_AUTH_NUMERIC_DISPLAY},
{ "out-alpha", BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY},
{ "static-oob", BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT},
+ { "unknown", BT_HAL_MESH_UNKNOWN_AUTH_METHOD},
};
if (len == strlen(auth_table[i].action) &&
!strcmp(str, auth_table[i].action))
break;
-
- return auth_table[i].auth_type;
+ if (i < sz) {
+ return auth_table[i].auth_type;
+ } else {
+ ERR("Mesh : Not A Proper Authentication Type!");
+ return BT_HAL_MESH_UNKNOWN_AUTH_METHOD;
+ }
}
enum mesh_dbus_interface_e {
typedef struct meshcfg_app meshcfg_app;
/* Will contain critical data related to local Mesh Network */
-GSList *mesh_apps;
+static GSList *mesh_apps = NULL;
struct meshcfg_node {
char uuid[33];
size_t sz;
- switch(iface) {
+ switch (iface) {
case MESH_APP_IFACE:
case MESH_PROV_IFACE: {
memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
return l_util_from_hexstring(uuid, &sz);
}
case MESH_AGENT_IFACE: {
- memcpy(uuid, is_prov ? (void*) &dbus_path[22] : (void*) &dbus_path[23], 32);
+ memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[23], 32);
uuid[32] = '\0';
return l_util_from_hexstring(uuid, &sz);
}
static void __mesh_hal_free_elements(gpointer data)
{
meshcfg_el *element = (meshcfg_el*) data;
+ if (!element)
+ return;
g_free(element->path);
if (element->models)
g_slist_free_full(element->models, g_free);
+
+ element->models = NULL;
g_free(element);
}
+static bool __bt_mesh_proxy_check(meshcfg_app *app)
+{
+ /* Check meshd stack Vis up or not */
+ if (!dbus) {
+ ERR("Mesh: DBUS is not UP!, possibly stack not Up!");
+ return false;
+ }
+ /* Check Network Proxy is added or not */
+ if (!net_proxy) {
+ ERR("Mesh: Network proxy is not attached yet!");
+ return false;
+ }
+
+ if (app) {
+ /* Check App management proxyis added or not */
+ if (!app->mgmt_proxy) {
+ ERR("Mesh: Network proxy is not attached yet!");
+ return false;
+ }
+ /* Check App Node Proxy is added or not */
+ if (!app->proxy) {
+ ERR("Mesh: Node proxy is not attached yet!");
+ return false;
+ }
+ }
+ return true;
+}
+
static void __bt_hal_mesh_destroy_app_object(gpointer data)
{
return;
mesh_apps = g_slist_remove(mesh_apps, app);
- g_free(app->path);
- g_free(app->agent_path);
- if (app->elements)
+ if (app->path) {
+ INFO("Mesh: App path [%s] ", app->path);
+ g_free(app->path);
+ }
+ if (app->agent_path) {
+ INFO("Mesh: Agent Path [%s]", app->agent_path);
+ g_free(app->agent_path);
+ }
+
+ if (app->elements) {
+ INFO("Mesh: Total elements present in app [%d]",
+ g_slist_length(app->elements));
g_slist_free_full(app->elements, __mesh_hal_free_elements);
+ }
g_free(app);
}
-static void __mesh_client_connected(struct l_dbus *dbus, void *user_data)
+static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
{
ERR("MESH: D-Bus client connected\n");
+ dbus = dbus_obj;
+ if (dbus)
+ INFO("Mesh: MeshD connected: dbus [%p]", dbus);
}
-static void __mesh_client_disconnected(struct l_dbus *dbus, void *user_data)
+static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
{
ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
/* TODO: Send event to app about meshd termination & then remove all mesh apps */
+ INFO("Mesh: Total number of networks present [%d]",
+ g_slist_length(mesh_apps));
+
if (mesh_apps) {
g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
mesh_apps = NULL;
}
+ /* Set DBUS to NULL */
+ if (dbus)
+ INFO("Mesh: dbus [%p]", dbus);
+ if (net_proxy)
+ INFO("Mesh: net proxy [%p]", net_proxy);
+
+ dbus = NULL;
+ net_proxy = NULL;
+ INFO("Mesh: All apps cleaned up after meshd exited");
}
static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
if (!elem)
return 1;
- return (elem->index == elem_index ? 0: -1);
+ return (elem->index == elem_index ? 0 : -1);
+}
+
+static void __send_network_destroy_event(void *param, uint8_t status)
+{
+ struct hal_ev_mesh_network_destroyed ev;
+ meshcfg_app *app = (meshcfg_app*)param;
+
+ memset(&ev, 0, sizeof(ev));
+ memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
+ memcpy(ev.token, app->token.u8, 8);
+
+ ev.status = status;
+ if (mesh_event_cb)
+ mesh_event_cb(HAL_EV_MESH_NETWORK_DESTROYED,
+ (void*)&ev, sizeof(ev));
}
static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
INFO("MESH: Proxy added: %s (%s)\n", interface, path);
if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
-
+ INFO("Mesh: Network Proxy added");
/* Save Global proxy */
net_proxy = proxy;
+ if (net_proxy)
+ INFO("Mesh: Net Proxy [%p]", net_proxy);
return;
}
if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
GSList *l;
meshcfg_app *app;
+ INFO("Mesh: Mgmt Proxy added");
INFO("Mesh: Number of mesh app present in list [%d]",
g_slist_length(mesh_apps));
l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
}
if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
-
+ INFO("Mesh: Node Proxy added");
GSList *l;
meshcfg_app *app;
l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
if (l) {
app = l->data;
- app->mgmt_proxy = proxy;
+ app->proxy = proxy;
} else {
ERR("Mesh: app not found for Node proxy");
}
l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
if (l) {
app = l->data;
- /*TODO: Send event to app about removal of a mesh local node */
+ /* Send event to app about removal of a mesh local node */
+ __send_network_destroy_event(app, BT_STATUS_SUCCESS);
__bt_hal_mesh_destroy_app_object(app);
} else {
ERR("Mesh: app not found for Mgmt proxy");
l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
if (l) {
app = l->data;
- /*TODO: Send event to app about removal of
- a mesh local node: first send event, then destroy mesh object */
+ /* Send event to app about removal of a mesh local node */
+ __send_network_destroy_event(app, BT_STATUS_SUCCESS);
__bt_hal_mesh_destroy_app_object(app);
} else {
ERR("Mesh: app not found for Mgmt proxy");
}
}
-static void __mesh_dbus_client_ready(struct l_dbus_client *client,
+static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
void *user_data)
{
INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
- /* TODO: Book keeping */
+ client = client_obj;
+}
+
+static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
+ bool queued, void *user_data)
+{
+ if (success == false)
+ ERR("Mesh: Fail to acquire dbus name\n");
+
+ if (!l_dbus_object_manager_enable(dbus_obj, "/"))
+ ERR("Mesh: Failed to register the ObjectManager\n");
}
static void __mesh_ready_callback(void *user_data)
{
INFO("Mesh: Connected to D-Bus\n");
- if (!l_dbus_object_manager_enable(dbus, "/"))
- ERR("Mesh: Failed to register the ObjectManager\n");
+
+ if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
+ __mesh_acquire_name_callback, NULL))
+ ERR("Mesh: Failed to own well-known name\n");
}
bool _bt_hal_mesh_stack_init(void)
if (!dbus)
return false;
+ INFO("Mesh: Got dbus [%p]", dbus);
+
if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
return false;
return true;
}
+void _bt_hal_mesh_stack_deinit(void)
+{
+ INFO("Mesh: Stack Deinit");
+
+ if (client) {
+ l_dbus_client_destroy(client);
+ client = NULL;
+ }
+
+ if (dbus) {
+ l_dbus_destroy(dbus);
+ dbus = NULL;
+ }
+}
+
/* To send stack event to hal-mesh handler */
void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
{
struct l_dbus_message *msg, void *user_data)
{
struct l_dbus_message_iter iter_cfg;
+ char *path;
meshcfg_app *app = (meshcfg_app*) user_data;
INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
app->path, app->agent_path);
}
if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
- &app->path, &iter_cfg))
+ &path, &iter_cfg))
goto failed;
INFO("Mesh: Attached with path %s\n", app->path);
INFO("Mesh: Created new node with token %s\n", str);
l_free(str);
- /* Athenticate the node */
+ /* Authenticate the node */
l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
return l_dbus_message_new_method_return(message);
}
ev->is_remote_devkey = rmt;
ev->netkey_idx = idx;
ev->data_len = n;
- memcpy(ev->data, buf, n);
+ memcpy(ev->data, data, n);
size += n;
+ INFO("Mesh: Src [0x%2.2x]", src);
+ INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
+ INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
/* Send DevKeyMessage Received event */
- if (mesh_event_cb) {
+ if (mesh_event_cb)
mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
+ return l_dbus_message_new_method_return(msg);
+}
+
+static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
+ struct l_dbus_message *msg, void *user_data)
+{
+ struct l_dbus_message_iter iter;
+ uint16_t src, idx, dst;
+ uint8_t *data;
+ uint32_t n;
+ const char *dbus_path;
+ uint16_t size;
+ 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);
+ uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
+ struct hal_ev_mesh_message_event *ev = (void *)buf;
+
+ INFO("Mesh: app path [%s]", dbus_path);
+
+ memset(buf, 0, sizeof(buf));
+ size = (uint16_t) sizeof(*ev);
+ memcpy(ev->net_uuid, net_uuid, 16);
+ g_free(net_uuid);
+
+ if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
+ &iter)) {
+ ERR("Mesh: Cannot parse received message");
+ return l_dbus_message_new_error(msg, dbus_err_args, NULL);
+ }
+
+ if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
+ ERR("Mesh: Cannot parse received message: data");
+ return l_dbus_message_new_error(msg, dbus_err_args, NULL);
+ }
+
+ INFO("Mesh: Received mesh message (len %u):", n);
+ ev->source_addr = src;
+ ev->dest_addr = dst;
+ ev->key_idx = idx;
+ ev->data_len = n;
+ memcpy(ev->data, data, n);
+ size += n;
+
+ INFO("Mesh: Src [0x%2.2x]", src);
+ INFO("Mesh: Dst [0x%2.2x]", dst);
+ INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
+ /* Send Message Received event */
+ if (mesh_event_cb) {
+ INFO("Mesh: Send message event");
+ mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
}
return l_dbus_message_new_method_return(msg);
}
l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
__mesh_device_message_received, "", "qbqay", "source",
"remote", "net_index", "data");
+ l_dbus_interface_method(iface, "MessageReceived", 0,
+ __mesh_message_received, "", "qqvay", "source",
+ "key_index", "destination", "data");
/* TODO: Other methods */
}
if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
ERR("Mesh: Cannot parse scan results");
ev.status = BT_STATUS_FAIL;
- if (mesh_event_cb) {
+ if (mesh_event_cb)
mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
- }
return l_dbus_message_new_error(msg, dbus_err_args, NULL);
}
n < 16) {
ERR("Mesh: Cannot parse scan result: data");
ev.status = BT_STATUS_FAIL;
- if (mesh_event_cb) {
+ if (mesh_event_cb)
mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
- }
return l_dbus_message_new_error(msg, dbus_err_args, NULL);
}
uint8_t cnt;
struct hal_ev_mesh_provision_finished ev;
struct hal_ev_mesh_provision_data_request req;
+ char *uuid_string;
meshcfg_app *app = user_data;
+ INFO("Mesh: provisioning data requested app path [%s]",
+ app->path);
+ uuid_string = l_util_hexstring(app->uuid, 16);
+ INFO("Mesh: Network UUID [%s]", uuid_string);
+
memset(&ev, 0, sizeof(ev));
memset(&req, 0, sizeof(req));
memcpy(ev.net_uuid, app->uuid, 16);
memcpy(req.net_uuid, app->uuid, 16);
+ l_free(uuid_string);
if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
ERR("Mesh: Cannot parse request for prov data");
req.count = cnt;
if (mesh_event_cb)
mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
- (void*)&ev, sizeof(ev));
+ (void*)&req, sizeof(req));
l_dbus_message_ref(msg);
return NULL;
}
static bool __mesh_agent_capability_getter(
- struct l_dbus *dbus,struct l_dbus_message *message,
+ struct l_dbus *dbus, struct l_dbus_message *message,
struct l_dbus_message_builder *builder,
void *user_data)
{
INFO("Mesh: app path [%s]", app->path);
INFO("Mesh: Agent path [%s]", app->agent_path);
- if (!l_dbus_message_builder_enter_array(builder, "s")) {
+ if (!l_dbus_message_builder_enter_array(builder, "s"))
return false;
- }
__mesh_fill_out_capabilities(app, builder);
__mesh_fill_in_capabilities(app, builder);
}
INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
- ev.auth_type = BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY;
+ ev.auth_type = __mesh_get_authentication_type(str);
+ if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
+ return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
if (mesh_event_cb)
}
INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
- auth_value = l_strdup_printf("%u",n);
+ auth_value = l_strdup_printf("%u", n);
ev.auth_type = __mesh_get_authentication_type(str);
+ if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
+ return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
if (mesh_event_cb)
l = g_slist_find_custom(mesh_apps, net_uuid,
__mesh_compare_network_uuid);
+ if (!l) {
+ g_free(net_uuid);
+ return NULL;
+ }
app = l->data;
memset(&ev, 0, sizeof(ev));
INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
ev.auth_type = __mesh_get_authentication_type(str);
+ if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
+ return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
agent_msg = msg;
l_dbus_message_ref(msg);
if (mesh_event_cb)
uint8_t *net_uuid;
const char *dbus_path;
GSList *l;
- meshcfg_app *app;
+ meshcfg_app *app = NULL;
dbus_path = l_dbus_message_get_path(msg);
net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
l = g_slist_find_custom(mesh_apps, net_uuid,
__mesh_compare_network_uuid);
- app = l->data;
+
+ if (l) {
+ app = l->data;
+ } else {
+ ERR("Mesh: app not found");
+ }
+
memset(&ev, 0, sizeof(ev));
memcpy(ev.net_uuid, net_uuid, 16);
struct hal_ev_mesh_provision_finished ev;
memset(&ev, 0, sizeof(ev));
- memcpy(ev.net_uuid, app->uuid, 16);
+
+ if (app)
+ memcpy(ev.net_uuid, app->uuid, 16);
+
ev.status = BT_STATUS_FAIL;
ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
if (mesh_event_cb)
INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
ev.auth_type = __mesh_get_authentication_type(str);
+ if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
+ return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
agent_msg = msg;
l_dbus_message_ref(msg);
if (mesh_event_cb)
if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
__bt_hal_mesh_setup_agent_iface, NULL, false)) {
ERR("Mesh: Unable to register agent interface");
- return false;
+ //return false;
}
INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
if (!ptr)
return false;
+ if (!dbus)
+ return false;
if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
__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]",
- g_slist_length(ptr->elements));
+ g_slist_length(ptr->elements));
g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
if (!l_dbus_object_add_interface(dbus, ptr->path,
L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
- ERR("Mesh: Failed to add interface %s",
- L_DBUS_INTERFACE_OBJECT_MANAGER);
- return false;
- }
+ ERR("Mesh: Failed to add interface %s",
+ L_DBUS_INTERFACE_OBJECT_MANAGER);
+ return false;
+ }
INFO("Mesh: Application Register completed");
return true;
} else {
elem = g_malloc0(sizeof(meshcfg_el));
elem->index = model_info->elem_index;
- elem->path = g_strdup_printf("%s/elem%u",app->path, elem->index);
+ elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
app->elements = g_slist_append(app->elements, elem);
INFO("Mesh: Created element index [%d] path [%s]",
elem->index, elem->path);
}
+ INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
+ model_info->model, elem->index);
/* Add Model in the element */
elem->models = g_slist_append(elem->models, model_info);
- INFO("Mesh: total models of the element with index [%d] is [%d]",
+ INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
elem->index, g_slist_length(elem->models));
}
if (is_prov) {
app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
- app->agent_path = g_strdup_printf("/tizen/mesh/cfg/agent/%s", uuid_str);
+ app->agent_path = g_strdup_printf("%s/agent", app->path);
} else {
app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
- app->agent_path = g_strdup_printf("/tizen/mesh/node/agent/%s", uuid_str);
+ app->agent_path = g_strdup_printf("%s/agent", app->path);
}
g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
return app;
}
+static void __bt_hal_mesh_leave_net_reply(
+ struct l_dbus_proxy *proxy,
+ struct l_dbus_message *msg, void *user_data)
+{
+ meshcfg_app *app;
+ app = (meshcfg_app*) user_data;
+
+ INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
+ if (l_dbus_message_is_error(msg)) {
+ const char *name;
+
+ l_dbus_message_get_error(msg, &name, NULL);
+ ERR("Mesh: Failed to leave network: %s", name);
+
+ /* Send Network Destroy fail event */
+ __send_network_destroy_event(app, BT_STATUS_FAIL);
+ } else {
+ INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
+ }
+}
+
+static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
+ void *user_data)
+{
+ meshcfg_app *app = (meshcfg_app*) user_data;
+
+ l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
+ INFO("Mesh: Leave Network Setup app path [%s]", app->path);
+}
+
static void __bt_hal_mesh_create_net_reply(
struct l_dbus_proxy *proxy,
struct l_dbus_message *msg, void *user_data)
meshcfg_app *app;
l = g_slist_find_custom(mesh_apps, net_uuid,
__mesh_compare_network_uuid);
+ if (!l)
+ return;
app = l->data;
if (app->scan_timer_id > 0) {
if (mesh_event_cb)
mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
(void*)&ev, sizeof(ev));
+ INFO("Mesh: Provisioning status sent");
}
static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
void *user_data)
{
+ char *uuid;
bt_uuid_t *dev = user_data;
struct l_dbus_message_builder *builder;
+ uuid = l_util_hexstring(dev->uu, 16);
+ INFO("Mesh: Add Node Setup UUID [%s]", uuid);
builder = l_dbus_message_builder_new(msg);
__mesh_append_byte_array(builder, dev->uu, 16);
l_dbus_message_builder_leave_array(builder);
l_dbus_message_builder_finalize(builder);
l_dbus_message_builder_destroy(builder);
-
- l_free(dev);
}
bt_status_t _bt_hal_mesh_provision_device(
if (l) {
app = l->data;
dev = g_memdup((gpointer)dev_uuid, 16);
-
+ INFO("Mesh: Schedule Add Node request to meshd");
if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
__bt_hal_mesh_add_node_setup,
__bt_hal_mesh_add_node_reply,
ev.status = BT_STATUS_SUCCESS;
if (!strcmp("CreateSubnet", method)) {
+ INFO("Mesh: Reply for CreateSubnet");
ev.key_event = HAL_MESH_KEY_ADD;
} else if (!strcmp("DeleteSubnet", method)) {
+ INFO("Mesh: Reply for DeleteSubnet");
ev.key_event = HAL_MESH_KEY_DELETE;
} else if (!strcmp("UpdateSubnet", method)) {
+ INFO("Mesh: Reply for UpdateSubnet");
ev.key_event = HAL_MESH_KEY_UPDATE;
}
uint16_t net_idx = (uint16_t) req->net_idx;
uint16_t app_idx = (uint16_t) req->app_idx;
- l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
+ if (g_strcmp0(req->str, "CreateAppKey") == 0)
+ l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
+ else
+ l_dbus_message_set_arguments(msg, "q", app_idx);
}
static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
l_dbus_message_get_error(msg, &name, NULL);
ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
ev.status = BT_STATUS_FAIL;
- }
-
- ev.status = BT_STATUS_SUCCESS;
+ } else
+ ev.status = BT_STATUS_SUCCESS;
if (!strcmp("CreateAppKey", method)) {
+ INFO("Mesh: AppKey Create Reply");
ev.key_event = HAL_MESH_KEY_ADD;
} else if (!strcmp("DeleteAppKey", method)) {
+ INFO("Mesh: AppKey Delete Reply");
ev.key_event = HAL_MESH_KEY_DELETE;
} else if (!strcmp("UpdateAppKey", method)) {
+ INFO("Mesh: AppKey Update Reply");
ev.key_event = HAL_MESH_KEY_UPDATE;
}
else if (op == BT_MESH_KEY_DELETE)
status = __mesh_subnet_appkey_command_execute(app,
netkey_idx, appkey_idx, "DeleteAppKey");
- else if (op == BT_MESH_KEY_UPDATE)
+ else if (op == BT_MESH_KEY_UPDATE) {
+ INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
+ netkey_idx, appkey_idx);
status = __mesh_subnet_appkey_command_execute(app,
netkey_idx, appkey_idx, "UpdateAppKey");
+ }
if (!status)
return BT_STATUS_FAIL;
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;
+ }
if (!l_dbus_proxy_method_call(app->mgmt_proxy,
"UnprovisionedScanCancel",
NULL, NULL, NULL, NULL))
uint32_t val_u32;
struct l_dbus_message *reply = NULL;
struct l_dbus_message_builder *builder;
- uint8_t alpha[16];
+ uint8_t *alpha;
+ bt_status_t ret = BT_STATUS_SUCCESS;
+ size_t sz = 0;
+ /* Proxy Check */
+ if (!__bt_mesh_proxy_check(0)) {
+ ERR("Mesh: Proxy check failed!!");
+ return BT_STATUS_FAIL;
+ }
+ INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
+ INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
/* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
- INFO("Mesh: Authentication reply: Numeric ype");
+ INFO("Mesh: Authentication reply: Numeric Type");
val_u32 = atoi(auth_value);
reply = l_dbus_message_new_method_return(agent_msg);
l_dbus_message_set_arguments(reply, "u", val_u32);
- /* For Alpha-Numeric */
- } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT) {
- INFO("Mesh: Authentication reply: Alpha-Numeric ype");
- memset(alpha, 0x00, 16);
- memcpy(alpha, auth_value, strlen(auth_value));
+ if (!reply)
+ reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
+ l_dbus_send(dbus, reply);
+ ret = BT_STATUS_SUCCESS;
+ /* For Alpha-Numeric */
+ } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
+ auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
+ auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
+ INFO("Mesh: Authentication reply: Alpha-Numeric Type");
+ alpha = l_util_from_hexstring(auth_value, &sz);
reply = l_dbus_message_new_method_return(agent_msg);
builder = l_dbus_message_builder_new(reply);
__mesh_append_byte_array(builder, alpha, 16);
l_dbus_message_builder_finalize(builder);
l_dbus_message_builder_destroy(builder);
+ l_free(alpha);
+ if (!reply)
+ reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
+ l_dbus_send(dbus, reply);
+ ret = BT_STATUS_SUCCESS;
}
- return BT_STATUS_SUCCESS;
+ return ret;
}
bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
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;
+ }
if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
__mesh_scan_setup, __mesh_scan_reply,
L_UINT_TO_PTR(param->scan_time), NULL))
return BT_STATUS_SUCCESS;
}
+static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
+ void *user_data)
+{
+ struct mesh_remote_node_info *node_info = \
+ (struct mesh_remote_node_info*) user_data;
+
+ l_dbus_message_set_arguments(msg, "qy",
+ node_info->unicast, node_info->num_elements);
+ INFO("Mesh: Delete Remote Node Setup params passed");
+}
+
+static void __bt_hal_mesh_delete_node_reply(
+ struct l_dbus_proxy *proxy,
+ struct l_dbus_message *msg, void *user_data)
+{
+ INFO("Mesh: Delete Remote Node Reply from DBUS");
+}
+
+bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
+ uint16_t unicast, uint16_t num_elements)
+{
+ GSList *l;
+ meshcfg_app *app;
+ struct mesh_remote_node_info *node_info;
+ INFO("Mesh: Delete Remote Node");
+ l = g_slist_find_custom(mesh_apps, network->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: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
+ unicast, num_elements);
+
+ /* Delete Remote Node Request */
+ node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
+ node_info->unicast = unicast;
+ node_info->num_elements = num_elements;
+
+ if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
+ __bt_hal_mesh_delete_node_setup,
+ __bt_hal_mesh_delete_node_reply, node_info,
+ l_free)) {
+ ERR("Mesh: Delete Remote Node Request failed!!");
+ g_free(node_info);
+ return BT_STATUS_FAIL;
+ }
+ } else {
+ ERR("Mesh: App not found!!");
+ return BT_STATUS_PARM_INVALID;
+ }
+ INFO("Mesh: Delete Remote Node Call issued successfully!!");
+ return BT_STATUS_SUCCESS;
+}
+
+bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
+{
+ GSList *l;
+ meshcfg_app *app;
+ INFO("Mesh: Destroy network");
+ l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
+ if (l) {
+ app = l->data;
+ if (!__bt_mesh_proxy_check(app)) {
+ ERR("Mesh: Proxy check failed!!");
+ return BT_STATUS_FAIL;
+ }
+ INFO("Mesh: Create New Network");
+ /* Create CFG Network */
+ if (!l_dbus_proxy_method_call(net_proxy, "Leave",
+ __bt_hal_mesh_leave_net_setup,
+ __bt_hal_mesh_leave_net_reply, app,
+ NULL)) {
+ ERR("Mesh: Network Leave failed!!");
+ return BT_STATUS_FAIL;
+ }
+ } else {
+ ERR("Mesh: App not found!!");
+ return BT_STATUS_PARM_INVALID;
+ }
+ INFO("Mesh: Network Leave Call issued successfully!!");
+ return BT_STATUS_SUCCESS;
+}
+
bt_status_t _bt_hal_mesh_create_network(
bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
{
meshcfg_app *app;
INFO("Mesh: Create 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));
/* Create DBUS APP */
app = __bt_hal_mesh_create_app(node, models, is_prov);
if (!app)
return BT_STATUS_FAIL;
/* Register DBUS APP */
- if (!__bt_hal_mesh_register_application(app)) {
+ if (!__bt_hal_mesh_register_application(app))
goto failed;
- }
if (app->token.u64 == 0) {
INFO("Mesh: Create New Network");
l_dbus_message_builder_destroy(builder);
}
+static void __bt_hal_mesh_model_execute_message(
+ struct l_dbus_message *msg, void *user_data)
+{
+ struct configuration_request *req = user_data;
+ struct l_dbus_message_builder *builder;
+
+ builder = l_dbus_message_builder_new(msg);
+
+ 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);
+ __mesh_append_byte_array(builder, req->data, req->len);
+ l_dbus_message_builder_finalize(builder);
+ l_dbus_message_builder_destroy(builder);
+}
+
bt_status_t _bt_hal_mesh_send_key_config_message(
bt_uuid_t *network, uint16_t dest,
bool is_netkey, bool is_update,
l = g_slist_find_custom(mesh_apps, network->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;
+ }
l1 = g_slist_find_custom(app->elements,
GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
+ if (!l1)
+ return BT_STATUS_FAIL;
elem = l1->data;
req = l_new(struct key_config_request, 1);
req->idx = netkey_idx; /* Encryption Key index */
req->update_req = is_update;
- if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_method,
+ if (!l_dbus_proxy_method_call(app->proxy, key_method,
__bt_hal_mesh_key_config_send, NULL,
(void*)req, l_free))
return BT_STATUS_FAIL;
__mesh_compare_network_uuid);
if (l) {
app = l->data;
+ if (!__bt_mesh_proxy_check(app)) {
+ ERR("Mesh: Proxy check failed!!");
+ return BT_STATUS_FAIL;
+ }
l1 = g_slist_find_custom(app->elements,
GUINT_TO_POINTER(src_elem_idx),
__compare_element_index);
+ if (!l1)
+ return BT_STATUS_FAIL;
elem = l1->data;
req = l_new(struct configuration_request, 1);
req->rmt = true;
req->is_dev_key = is_dev_key;
- if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DevKeySend",
+ if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
__bt_hal_mesh_config_send, NULL,
(void*)req, l_free))
return BT_STATUS_FAIL;
}
return BT_STATUS_SUCCESS;
}
+
+bt_status_t _bt_hal_mesh_model_execute_message(
+ bt_uuid_t *network, uint16_t dest,
+ uint16_t appkey_idx, uint8_t *buf, int len)
+{
+ GSList *l;
+ GSList *l1;
+ struct configuration_request *req;
+ meshcfg_app *app;
+ meshcfg_el *elem;
+ int src_elem_idx = 0;
+ l = g_slist_find_custom(mesh_apps, network->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;
+ }
+ l1 = g_slist_find_custom(app->elements,
+ GUINT_TO_POINTER(src_elem_idx),
+ __compare_element_index);
+ if (!l1)
+ return BT_STATUS_FAIL;
+ elem = l1->data;
+
+ req = l_new(struct configuration_request, 1);
+ req->ele_path = elem->path;
+ req->dst = dest;
+ req->idx = appkey_idx;
+ req->data = buf;
+ req->len = len;
+ req->rmt = false;
+ req->is_dev_key = false;
+
+ if (!l_dbus_proxy_method_call(app->proxy, "Send",
+ __bt_hal_mesh_model_execute_message,
+ NULL, (void*)req, l_free))
+ return BT_STATUS_FAIL;
+ } else {
+ ERR("Mesh: app not found!!");
+ return BT_STATUS_PARM_INVALID;
+
+ }
+ return BT_STATUS_SUCCESS;
+}