4 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
6 * @author: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
33 #include "bt-hal-mesh-dbus-handler.h"
34 #include "bt-hal-dbus-common-utils.h"
35 #include "bt-hal-internal.h"
37 #include <hardware/bt_mesh.h>
39 #define BT_HAL_MESH_DBUS_NAME "org.projectx.bt.mesh"
41 #define BT_HAL_UUID_LEN 16
42 #define BT_HAL_BLUEZ_MESH_NAME "org.bluez.mesh"
44 #define BT_HAL_MESH_NETWORK_INTERFACE "org.bluez.mesh.Network1"
45 #define BT_HAL_MESH_NODE_INTERFACE "org.bluez.mesh.Node1"
46 #define BT_HAL_MESH_MANAGEMENT_INTERFACE "org.bluez.mesh.Management1"
47 #define BT_HAL_MESH_ELEMENT_INTERFACE "org.bluez.mesh.Element1"
48 #define BT_HAL_MESH_APPLICATION_INTERFACE "org.bluez.mesh.Application1"
49 #define BT_HAL_MESH_PROVISION_AGENT_INTERFACE "org.bluez.mesh.ProvisionAgent1"
50 #define BT_HAL_MESH_PROVISIONER_INTERFACE "org.bluez.mesh.Provisioner1"
51 #define BT_HAL_MESH_ERROR_INTERFACE "org.bluez.mesh.Error"
53 #define BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE 2048
54 #define BT_HAL_MESH_MAX_MSG_BUF_SIZE 2048
56 static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs";
57 static const char *dbus_err_fail = "org.freedesktop.DBus.Error.Failed";
59 static struct l_dbus *dbus = NULL;
60 static struct l_dbus_client *client = NULL;
62 static struct l_dbus_proxy *net_proxy = NULL;
63 static struct l_dbus_message *agent_msg;
65 static handle_stack_msg mesh_event_cb = NULL;
68 struct subnet_key_request {
73 struct app_key_request {
79 struct configuration_request {
89 struct key_config_request {
97 struct mesh_provision_auth_action {
99 bt_hal_mesh_auth_variant_e auth_type;
102 struct mesh_remote_node_info {
104 uint8_t num_elements;
107 static struct mesh_provision_auth_action auth_table[] = {
108 { "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
109 { "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
110 { "vibrate", BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT},
111 { "in-numeric", BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT},
112 { "in-alpha", BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT},
113 { "twist", BT_HAL_MESH_AUTH_TWIST_COUNT_DISPLAY},
114 { "push", BT_HAL_MESH_AUTH_PUSH_COUNT_DISPLAY},
115 { "out-numeric", BT_HAL_MESH_AUTH_NUMERIC_DISPLAY},
116 { "out-alpha", BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY},
117 { "static-oob", BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT},
118 { "unknown", BT_HAL_MESH_UNKNOWN_AUTH_METHOD},
122 static uint8_t __bt_mesh_util_get_prov_error_code(char *prov_err_str)
126 if (!g_strcmp0(prov_err_str, "success"))
127 ret = BT_HAL_MESH_PROV_ERR_SUCCESS;
128 else if (!g_strcmp0(prov_err_str, "bad-pduread"))
129 ret = BT_HAL_MESH_PROV_ERR_INVALID_PDU;
130 else if (!g_strcmp0(prov_err_str, "confirmation-failed"))
131 ret = BT_HAL_MESH_PROV_ERR_CONFIRM_FAILED;
132 else if (!g_strcmp0(prov_err_str, "out-of-resources"))
133 ret = BT_HAL_MESH_PROV_ERR_INSUF_RESOURCE;
134 else if (!g_strcmp0(prov_err_str, "decryption-error"))
135 ret = BT_HAL_MESH_PROV_ERR_DECRYPT_FAILED;
136 else if (!g_strcmp0(prov_err_str, "cannot-assign-addresses"))
137 ret = BT_HAL_MESH_PROV_ERR_CANT_ASSIGN_ADDR;
138 else if (!g_strcmp0(prov_err_str, "timeout"))
139 ret = BT_HAL_MESH_PROV_ERR_TIMEOUT;
140 else if (!g_strcmp0(prov_err_str, "unexpected-error"))
141 ret = BT_HAL_MESH_PROV_ERR_UNEXPECTED_ERR;
146 static bt_hal_mesh_auth_variant_e __mesh_get_authentication_type(char *str)
148 int len = strlen(str);
149 int sz = L_ARRAY_SIZE(auth_table);
152 for (i = 0; i < sz; ++i)
153 if (len == strlen(auth_table[i].action) &&
154 !strcmp(str, auth_table[i].action))
157 return auth_table[i].auth_type;
159 ERR("Mesh : Not A Proper Authentication Type!");
160 return BT_HAL_MESH_UNKNOWN_AUTH_METHOD;
164 enum mesh_dbus_interface_e {
171 typedef enum mesh_dbus_interface_e mesh_dbus_interface_e;
173 struct meshcfg_model {
178 typedef struct meshcfg_model meshcfg_model;
186 typedef struct meshcfg_el meshcfg_el;
189 /* Remember Proxies & dbus paths */
192 struct l_dbus_proxy *proxy;
193 struct l_dbus_proxy *mgmt_proxy;
195 /* Local node Info */
212 struct l_dbus_message *msg;
216 typedef struct meshcfg_app meshcfg_app;
218 /* Will contain critical data related to local Mesh Network */
219 static GSList *mesh_apps = NULL;
222 struct meshcfg_node {
224 struct l_dbus_proxy *proxy;
225 struct l_dbus_proxy *mgmt_proxy;
232 typedef struct meshcfg_node meshcfg_node;
234 static void __mesh_append_byte_array(struct l_dbus_message_builder *builder,
235 unsigned char *data, unsigned int len)
239 l_dbus_message_builder_enter_array(builder, "y");
241 for (i = 0; i < len; i++)
242 l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
244 l_dbus_message_builder_leave_array(builder);
247 static gint __mesh_compare_network_uuid(gconstpointer data, gconstpointer user_data)
249 const meshcfg_app *app = (meshcfg_app*) data;
251 memcpy(uuid, (uint8_t*) user_data, 16);
253 return memcmp(uuid, app->uuid, sizeof(bt_uuid_t));
256 static unsigned char* __mesh_get_net_uuid_from_dbus_proxy_path(
257 const char *dbus_path)
262 memcpy(uuid, (void*)&dbus_path[20], sizeof(uuid));
264 INFO("Mesh: Net UUID string [%s]", uuid);
265 return l_util_from_hexstring(uuid, &sz);
268 static unsigned char* __mesh_get_net_uuid_from_path(
269 const char *dbus_path, bool is_prov,
270 mesh_dbus_interface_e iface)
277 case MESH_PROV_IFACE: {
278 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
280 return l_util_from_hexstring(uuid, &sz);
282 case MESH_AGENT_IFACE: {
283 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[23], 32);
285 return l_util_from_hexstring(uuid, &sz);
287 case MESH_ELEMENT_IFACE: {
288 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
290 return l_util_from_hexstring(uuid, &sz);
297 static void __mesh_hal_free_elements(gpointer data)
299 meshcfg_el *element = (meshcfg_el*) data;
302 g_free(element->path);
304 g_slist_free_full(element->models, g_free);
306 element->models = NULL;
310 static bool __bt_mesh_proxy_check(meshcfg_app *app)
312 /* Check meshd stack Vis up or not */
314 ERR("Mesh: DBUS is not UP!, possibly stack not Up!");
317 /* Check Network Proxy is added or not */
319 ERR("Mesh: Network proxy is not attached yet!");
324 /* Check App management proxyis added or not */
325 if (!app->mgmt_proxy) {
326 ERR("Mesh: Network proxy is not attached yet!");
329 /* Check App Node Proxy is added or not */
331 ERR("Mesh: Node proxy is not attached yet!");
338 static void __bt_hal_mesh_destroy_app_object(gpointer data)
341 meshcfg_app *app = (meshcfg_app*) data;
345 mesh_apps = g_slist_remove(mesh_apps, app);
348 INFO("Mesh: App path [%s] ", app->path);
351 if (app->agent_path) {
352 INFO("Mesh: Agent Path [%s]", app->agent_path);
353 g_free(app->agent_path);
357 INFO("Mesh: Total elements present in app [%d]",
358 g_slist_length(app->elements));
359 g_slist_free_full(app->elements, __mesh_hal_free_elements);
362 if (app->scan_timer_id > 0) {
363 INFO("Mesh: Remove timer if already running");
364 g_source_remove(app->scan_timer_id);
365 app->scan_timer_id = 0;
370 static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
372 ERR("MESH: D-Bus client connected\n");
375 INFO("Mesh: MeshD connected: dbus [%p]", dbus);
378 static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
380 ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
381 /* TODO: Send event to app about meshd termination & then remove all mesh apps */
382 INFO("Mesh: Total number of networks present [%d]",
383 g_slist_length(mesh_apps));
386 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
389 /* Set DBUS to NULL */
391 INFO("Mesh: dbus [%p]", dbus);
393 INFO("Mesh: net proxy [%p]", net_proxy);
397 INFO("Mesh: All apps cleaned up after meshd exited");
400 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
404 const meshcfg_app *app = (meshcfg_app*) data;
405 char *path = (char *) user_data;
409 app_uuid_path = l_util_hexstring(app->uuid, 16);
410 char **strings = g_strsplit(path, "node", 2);
412 ret = g_strcmp0(strings[1], app_uuid_path);
415 l_free(app_uuid_path);
419 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
421 const meshcfg_el *elem = data;
422 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
426 return (elem->index == elem_index ? 0 : -1);
429 static void __send_network_destroy_event(void *param, uint8_t status)
431 struct hal_ev_mesh_network_destroyed ev;
432 meshcfg_app *app = (meshcfg_app*)param;
434 memset(&ev, 0, sizeof(ev));
435 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
436 memcpy(ev.token, app->token.u8, 8);
440 mesh_event_cb(HAL_EV_MESH_NETWORK_DESTROYED,
441 (void*)&ev, sizeof(ev));
444 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
446 const char *interface = l_dbus_proxy_get_interface(proxy);
447 const char *path = l_dbus_proxy_get_path(proxy);
449 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
451 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
452 struct hal_ev_mesh_network_proxy_added ev;
453 INFO("Mesh: Network Proxy added");
455 /* Save Global proxy */
458 INFO("Mesh: Net Proxy [%p]", net_proxy);
460 memset(&ev, 0, sizeof(ev));
461 ev.status = BT_STATUS_SUCCESS;
465 mesh_event_cb(HAL_EV_MESH_NETWORK_PROXY_ADDED,
466 (void*)&ev, sizeof(ev));
471 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
474 INFO("Mesh: Mgmt Proxy added");
475 INFO("Mesh: Number of mesh app present in list [%d]",
476 g_slist_length(mesh_apps));
477 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
480 app->mgmt_proxy = proxy;
482 ERR("Mesh: app not found for Mgmt proxy");
487 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
488 INFO("Mesh: Node Proxy added");
491 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
496 ERR("Mesh: app not found for Node proxy");
502 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
504 const char *interface = l_dbus_proxy_get_interface(proxy);
505 const char *path = l_dbus_proxy_get_path(proxy);
507 INFO("Proxy removed: %s (%s)\n", interface, path);
509 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
510 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
511 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
513 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
517 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
518 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
521 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
524 /* Send event to app about removal of a mesh local node */
525 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
526 __bt_hal_mesh_destroy_app_object(app);
528 ERR("Mesh: app not found for Mgmt proxy");
531 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
532 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
535 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
538 /* Send event to app about removal of a mesh local node */
539 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
540 __bt_hal_mesh_destroy_app_object(app);
542 ERR("Mesh: app not found for Mgmt proxy");
548 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
551 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
555 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
556 bool queued, void *user_data)
558 if (success == false)
559 ERR("Mesh: Fail to acquire dbus name\n");
561 if (!l_dbus_object_manager_enable(dbus_obj, "/"))
562 ERR("Mesh: Failed to register the ObjectManager\n");
565 static void __mesh_ready_callback(void *user_data)
567 INFO("Mesh: Connected to D-Bus\n");
569 if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
570 __mesh_acquire_name_callback, NULL))
571 ERR("Mesh: Failed to own well-known name\n");
574 bool _bt_hal_mesh_stack_init(void)
576 INFO("Mesh: Connect with meshd");
577 /* Connect with meshd */
578 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
582 INFO("Mesh: Got dbus [%p]", dbus);
584 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
587 client = l_dbus_client_new(dbus,
588 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
592 if (!l_dbus_client_set_connect_handler(client,
593 __mesh_client_connected, NULL, NULL))
596 if (!l_dbus_client_set_disconnect_handler(client,
597 __mesh_client_disconnected, NULL,
600 if (!l_dbus_client_set_proxy_handlers(client,
601 __mesh_proxy_added, __mesh_proxy_removed,
604 if (!l_dbus_client_set_ready_handler(client,
605 __mesh_dbus_client_ready, NULL, NULL))
608 INFO("Mesh: Stack Init watchers registered with meshd");
612 void _bt_hal_mesh_stack_deinit(void)
614 INFO("Mesh: Stack Deinit");
617 l_dbus_client_destroy(client);
622 l_dbus_destroy(dbus);
629 INFO("Mesh: Number of meshapps present in memory [%d]",
630 g_slist_length(mesh_apps));
633 /* To send stack event to hal-mesh handler */
634 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
639 /* To send stack event to hal-mesh handler */
640 void _bt_hal_mesh_unregister_dbus_handler_cb()
642 mesh_event_cb = NULL;
645 static bool __mesh_get_companyid(struct l_dbus *dbus,
646 struct l_dbus_message *message,
647 struct l_dbus_message_builder *builder,
650 meshcfg_app *app = (meshcfg_app*) user_data;
654 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
659 static bool __mesh_get_productid(struct l_dbus *dbus,
660 struct l_dbus_message *message,
661 struct l_dbus_message_builder *builder,
664 meshcfg_app *app = (meshcfg_app*) user_data;
667 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
672 static bool __mesh_get_versionid(struct l_dbus *dbus,
673 struct l_dbus_message *message,
674 struct l_dbus_message_builder *builder,
677 meshcfg_app *app = (meshcfg_app*) user_data;
680 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
685 static bool __mesh_get_crpl(struct l_dbus *dbus,
686 struct l_dbus_message *message,
687 struct l_dbus_message_builder *builder,
690 meshcfg_app *app = (meshcfg_app*) user_data;
693 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
698 static void __send_network_attach_event(void *param, uint8_t status)
700 struct hal_ev_mesh_network_attached ev;
701 meshcfg_app *app = (meshcfg_app*)param;
703 memset(&ev, 0, sizeof(ev));
704 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
705 memcpy(ev.token, app->token.u8, 8);
709 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
710 (void*)&ev, sizeof(ev));
713 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
714 struct l_dbus_message *msg, void *user_data)
716 struct l_dbus_message_iter iter_cfg;
718 meshcfg_app *app = (meshcfg_app*) user_data;
719 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
720 app->path, app->agent_path);
722 if (l_dbus_message_is_error(msg)) {
724 l_dbus_message_get_error(msg, &name, NULL);
725 ERR("Mesh: Failed to attach node: %s", name);
730 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
734 INFO("Mesh: Attached with path %s\n", app->path);
735 __send_network_attach_event(app, BT_STATUS_SUCCESS);
738 __send_network_attach_event(app, BT_STATUS_FAIL);
739 /* Destroy mesh app object */
740 __bt_hal_mesh_destroy_app_object(app);
743 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
746 meshcfg_app *app = (meshcfg_app*) user_data;
748 l_dbus_message_set_arguments(msg, "ot", app->path,
749 l_get_be64(app->token.u8));
753 static void __bt_hal_mesh_attach_node(void *user_data)
755 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
756 __bt_hal_mesh_attach_node_setup,
757 __bt_hal_mesh_attach_node_reply,
760 ERR("Mesh: Node attach failed!!");
761 /* Node could not be attached */
762 __send_network_attach_event(user_data, BT_STATUS_FAIL);
763 /* Destroy mesh app object */
764 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
768 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
769 struct l_dbus_message *message,
775 meshcfg_app *app = (meshcfg_app*) user_data;
776 INFO("Mesh: Join Complete");
779 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
781 /* Send Network creation fail event */
782 __send_network_attach_event(app, BT_STATUS_FAIL);
784 /* Destroy mesh app object */
785 __bt_hal_mesh_destroy_app_object(app);
787 return l_dbus_message_new_error(message, dbus_err_args, NULL);
791 app->token.u64 = l_get_be64(&tmp);
792 str = l_util_hexstring(&app->token.u8[0], 8);
793 INFO("Mesh: Created new node with token %s\n", str);
796 /* Authenticate the node */
797 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
798 return l_dbus_message_new_method_return(message);
801 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
804 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
805 meshcfg_model *model_info = (meshcfg_model*) data;
807 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
810 static bool __mesh_model_getter(struct l_dbus *dbus,
811 struct l_dbus_message *message,
812 struct l_dbus_message_builder *builder,
815 meshcfg_el *element = (meshcfg_el*) user_data;
817 l_dbus_message_builder_enter_array(builder, "q");
818 g_slist_foreach(element->models,
819 __bt_hal_mesh_foreach_model_getter, builder);
821 l_dbus_message_builder_leave_array(builder);
826 /*TODO: Vendor Model handling is currently not Handled */
827 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
828 struct l_dbus_message *message,
829 struct l_dbus_message_builder *builder,
832 l_dbus_message_builder_enter_array(builder, "(qq)");
833 l_dbus_message_builder_leave_array(builder);
838 static bool __mesh_element_index_getter(struct l_dbus *dbus,
839 struct l_dbus_message *message,
840 struct l_dbus_message_builder *builder,
843 meshcfg_el *element = (meshcfg_el*) user_data;
844 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
850 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
851 struct l_dbus_message *msg, void *user_data)
853 struct l_dbus_message_iter iter;
858 const char *dbus_path;
861 dbus_path = l_dbus_message_get_path(msg);
862 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
863 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
864 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
866 INFO("Mesh: app path [%s]", dbus_path);
868 memset(buf, 0, sizeof(buf));
869 size = (uint16_t) sizeof(*ev);
870 memcpy(ev->net_uuid, net_uuid, 16);
873 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
875 ERR("Mesh: Cannot parse received message");
876 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
879 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
880 ERR("Mesh: Cannot parse received message: data");
881 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
884 INFO("Mesh: Received dev key message (len %u):", n);
885 ev->source_addr = src;
886 ev->is_remote_devkey = rmt;
887 ev->netkey_idx = idx;
889 memcpy(ev->data, data, n);
892 INFO("Mesh: Src [0x%2.2x]", src);
893 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
894 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
895 /* Send DevKeyMessage Received event */
897 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
898 return l_dbus_message_new_method_return(msg);
901 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
902 struct l_dbus_message *msg, void *user_data)
904 struct l_dbus_message_iter iter;
905 uint16_t src, idx, dst;
908 const char *dbus_path;
911 dbus_path = l_dbus_message_get_path(msg);
912 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
913 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
914 struct hal_ev_mesh_message_event *ev = (void *)buf;
916 INFO("Mesh: app path [%s]", dbus_path);
918 memset(buf, 0, sizeof(buf));
919 size = (uint16_t) sizeof(*ev);
920 memcpy(ev->net_uuid, net_uuid, 16);
923 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
925 ERR("Mesh: Cannot parse received message");
926 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
929 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
930 ERR("Mesh: Cannot parse received message: data");
931 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
934 INFO("Mesh: Received mesh message (len %u):", n);
935 ev->source_addr = src;
939 memcpy(ev->data, data, n);
942 INFO("Mesh: Src [0x%2.2x]", src);
943 INFO("Mesh: Dst [0x%2.2x]", dst);
944 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
945 /* Send Message Received event */
947 INFO("Mesh: Send message event");
948 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
950 return l_dbus_message_new_method_return(msg);
953 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
955 INFO("Mesh: Setup element interface properties & methods");
957 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
959 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
960 __mesh_vendor_model_getter, NULL);
961 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
964 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
965 __mesh_device_message_received, "", "qbqay", "source",
966 "remote", "net_index", "data");
967 l_dbus_interface_method(iface, "MessageReceived", 0,
968 __mesh_message_received, "", "qqvay", "source",
969 "key_index", "destination", "data");
970 /* TODO: Other methods */
973 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
974 struct l_dbus_message *msg,
977 struct l_dbus_message_iter iter, opts;
978 meshcfg_app *app = (meshcfg_app*) user_data;
983 const char *sig = "naya{sv}";
985 /* Find network uuid from dbus path */
986 struct hal_ev_mesh_scan_result ev;
988 if (!app->scan_timer_id) {
989 /* Scan is not running */
990 INFO("Got scan result, but scan is already stopped");
991 return l_dbus_message_new_method_return(msg);
993 memset(&ev, 0, sizeof(ev));
994 memcpy(ev.net_uuid, app->uuid, 16);
996 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
997 ERR("Mesh: Cannot parse scan results");
998 ev.status = BT_STATUS_FAIL;
1000 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1001 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1004 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
1006 ERR("Mesh: Cannot parse scan result: data");
1007 ev.status = BT_STATUS_FAIL;
1009 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1010 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1013 INFO("Mesh: Scan result:\n");
1014 INFO("Mesh: Scan rssi = [%d]\n", rssi);
1015 str = l_util_hexstring_upper(prov_data, 16);
1016 INFO("Mesh: Scan UUID = [%s]\n", str);
1020 str = l_util_hexstring_upper(prov_data + 16, 2);
1021 INFO("Mesh: Scan OOB = [%s]\n", str);
1026 str = l_util_hexstring_upper(prov_data + 18, 4);
1027 INFO("Mesh: Scan URI hash = [%s]\n", str);
1031 /* 16 octet Dev UUID */
1032 memcpy(ev.dev_uuid, prov_data, 16);
1034 /* 2 octet Dev OOB Info */
1035 memcpy(ev.oob_info, prov_data + 16, 2);
1037 /* 4 octet URI Hash */
1038 memcpy(ev.uri_hash, prov_data + 18, 4);
1042 ev.status = BT_STATUS_SUCCESS;
1044 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1045 (void*)&ev, sizeof(ev));
1047 return l_dbus_message_new_method_return(msg);
1050 static struct l_dbus_message *__mesh_request_provisioner_call(
1051 struct l_dbus *dbus,
1052 struct l_dbus_message *msg,
1056 struct hal_ev_mesh_provision_finished ev;
1057 struct hal_ev_mesh_provision_data_request req;
1059 meshcfg_app *app = user_data;
1061 INFO("Mesh: provisioning data requested app path [%s]",
1063 uuid_string = l_util_hexstring(app->uuid, 16);
1064 INFO("Mesh: Network UUID [%s]", uuid_string);
1066 memset(&ev, 0, sizeof(ev));
1067 memset(&req, 0, sizeof(req));
1068 memcpy(ev.net_uuid, app->uuid, 16);
1069 memcpy(req.net_uuid, app->uuid, 16);
1070 l_free(uuid_string);
1072 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1073 ERR("Mesh: Cannot parse request for prov data");
1075 ev.status = BT_STATUS_FAIL;
1076 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1078 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1079 (void*)&ev, sizeof(ev));
1080 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1086 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1087 (void*)&req, sizeof(req));
1089 l_dbus_message_ref(msg);
1093 static struct l_dbus_message *__mesh_node_add_completed(
1094 struct l_dbus *dbus,
1095 struct l_dbus_message *msg,
1098 struct l_dbus_message_iter iter;
1103 struct hal_ev_mesh_provision_finished ev;
1104 const char *dbus_path;
1106 dbus_path = l_dbus_message_get_path(msg);
1107 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1108 true, MESH_PROV_IFACE);
1110 INFO("Mesh: app path [%s]", dbus_path);
1112 memset(&ev, 0, sizeof(ev));
1113 memcpy(ev.net_uuid, net_uuid, 16);
1117 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1118 ERR("Mesh: Cannot parse add node complete message");
1120 ev.status = BT_STATUS_FAIL;
1121 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1123 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1124 (void*)&ev, sizeof(ev));
1125 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1128 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1130 ERR("Mesh: Cannot parse add node complete message: uuid");
1132 ev.status = BT_STATUS_FAIL;
1133 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1135 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1136 (void*)&ev, sizeof(ev));
1137 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1141 ev.status = BT_STATUS_SUCCESS;
1142 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1143 memcpy(ev.dev_uuid, uuid, 16);
1144 ev.unicast = unicast;
1148 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1149 (void*)&ev, sizeof(ev));
1151 return l_dbus_message_new_method_return(msg);
1154 static struct l_dbus_message *__mesh_node_add_failed(
1155 struct l_dbus *dbus,
1156 struct l_dbus_message *msg,
1159 struct l_dbus_message_iter iter;
1163 struct hal_ev_mesh_provision_finished ev;
1164 const char *dbus_path;
1167 dbus_path = l_dbus_message_get_path(msg);
1168 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1169 true, MESH_PROV_IFACE);
1171 memset(&ev, 0, sizeof(ev));
1172 memcpy(ev.net_uuid, net_uuid, 16);
1175 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1176 ERR("Mesh: Cannot parse add node failed message");
1178 ev.status = BT_STATUS_FAIL;
1179 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1181 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1182 (void*)&ev, sizeof(ev));
1183 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1186 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1188 ERR("Mesh:Cannot parse add node failed message: uuid");
1189 ev.status = BT_STATUS_FAIL;
1190 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1192 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1193 (void*)&ev, sizeof(ev));
1194 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1197 INFO("Mesh: Provisioning failed:\n");
1198 str = l_util_hexstring_upper(uuid, 16);
1199 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1202 ev.status = BT_STATUS_FAIL;
1203 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1204 memcpy(ev.dev_uuid, uuid, 16);
1207 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1208 (void*)&ev, sizeof(ev));
1210 return l_dbus_message_new_method_return(msg);
1213 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1215 INFO("Mesh: Setup provisioner interface properties & methods");
1216 l_dbus_interface_method(interface, "ScanResult", 0,
1217 __mesh_scan_result_received, "",
1218 "naya{sv}", "rssi", "data", "options");
1220 l_dbus_interface_method(interface, "RequestProvData", 0,
1221 __mesh_request_provisioner_call,
1222 "qq", "y", "net_index", "unicast", "count");
1224 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1225 __mesh_node_add_completed, "", "ayqy",
1226 "uuid", "unicast", "count");
1228 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1229 __mesh_node_add_failed,
1230 "", "ays", "uuid", "reason");
1233 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1235 INFO("Mesh: Setup application interface properties & methods");
1237 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1238 __mesh_get_companyid,
1240 l_dbus_interface_property(iface, "VersionID", 0, "q",
1241 __mesh_get_versionid,
1243 l_dbus_interface_property(iface, "ProductID", 0, "q",
1244 __mesh_get_productid,
1246 l_dbus_interface_property(iface, "CRPL", 0, "q",
1247 __mesh_get_crpl, NULL);
1248 l_dbus_interface_method(iface, "JoinComplete", 0,
1249 __mesh_node_join_complete,
1255 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1256 struct l_dbus_message_builder *builder)
1258 if (app->in_oob & 0x08)
1259 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1260 if (app->in_oob & 0x04)
1261 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1262 if (app->in_oob & 0x02)
1263 l_dbus_message_builder_append_basic(builder, 's', "twist");
1264 if (app->in_oob & 0x01)
1265 l_dbus_message_builder_append_basic(builder, 's', "push");
1268 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1269 struct l_dbus_message_builder *builder)
1271 if (app->out_oob & 0x10)
1272 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1273 if (app->out_oob & 0x08)
1274 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1275 if (app->out_oob & 0x04)
1276 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1277 if (app->out_oob & 0x02)
1278 l_dbus_message_builder_append_basic(builder, 's', "beep");
1279 if (app->out_oob & 0x01)
1280 l_dbus_message_builder_append_basic(builder, 's', "blink");
1283 static bool __mesh_agent_capability_getter(
1284 struct l_dbus *dbus, struct l_dbus_message *message,
1285 struct l_dbus_message_builder *builder,
1290 INFO("Mesh: app path [%s]", app->path);
1291 INFO("Mesh: Agent path [%s]", app->agent_path);
1293 if (!l_dbus_message_builder_enter_array(builder, "s"))
1296 __mesh_fill_out_capabilities(app, builder);
1297 __mesh_fill_in_capabilities(app, builder);
1299 if (app->static_oob)
1300 l_dbus_message_builder_append_basic(builder,
1304 l_dbus_message_builder_leave_array(builder);
1305 INFO("Mesh: __agent_capability_getter: Success");
1309 static struct l_dbus_message *__mesh_agent_display_string_request(
1310 struct l_dbus *dbus,
1311 struct l_dbus_message *msg,
1314 struct hal_ev_mesh_authentication_request ev;
1317 const char *dbus_path;
1320 INFO("Mesh: app path [%s]", app->path);
1321 INFO("Mesh: Agent path [%s]", app->agent_path);
1323 dbus_path = l_dbus_message_get_path(msg);
1324 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1325 true, MESH_AGENT_IFACE);
1327 INFO("Mesh: app path [%s]", dbus_path);
1329 memset(&ev, 0, sizeof(ev));
1330 memcpy(ev.net_uuid, net_uuid, 16);
1333 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1334 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1335 struct hal_ev_mesh_provision_finished ev;
1336 memset(&ev, 0, sizeof(ev));
1337 memcpy(ev.net_uuid, net_uuid, 16);
1338 ev.status = BT_STATUS_FAIL;
1339 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1341 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1342 (void*)&ev, sizeof(ev));
1346 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1349 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1350 ev.auth_type = __mesh_get_authentication_type(str);
1351 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1352 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1353 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1356 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1357 (void*)&ev, sizeof(ev));
1360 return l_dbus_message_new_method_return(msg);
1363 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1364 struct l_dbus *dbus,
1365 struct l_dbus_message *msg,
1369 struct hal_ev_mesh_authentication_request ev;
1373 const char *dbus_path;
1376 INFO("Mesh: app path [%s]", app->path);
1377 INFO("Mesh: Agent path [%s]", app->agent_path);
1379 dbus_path = l_dbus_message_get_path(msg);
1380 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1381 true, MESH_AGENT_IFACE);
1383 INFO("Mesh: app path [%s]", dbus_path);
1385 memset(&ev, 0, sizeof(ev));
1386 memcpy(ev.net_uuid, net_uuid, 16);
1389 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1390 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1391 struct hal_ev_mesh_provision_finished ev;
1392 memset(&ev, 0, sizeof(ev));
1393 memcpy(ev.net_uuid, net_uuid, 16);
1394 ev.status = BT_STATUS_FAIL;
1395 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1396 if (mesh_event_cb) {
1397 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1398 (void*)&ev, sizeof(ev));
1401 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1404 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1405 auth_value = l_strdup_printf("%u", n);
1406 ev.auth_type = __mesh_get_authentication_type(str);
1407 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1408 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1409 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1412 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1413 (void*)&ev, sizeof(ev));
1417 return l_dbus_message_new_method_return(msg);
1420 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1421 struct l_dbus *dbus,
1422 struct l_dbus_message *msg,
1425 struct hal_ev_mesh_authentication_request ev;
1428 const char *dbus_path;
1432 dbus_path = l_dbus_message_get_path(msg);
1433 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1434 true, MESH_AGENT_IFACE);
1436 INFO("Mesh: app path [%s]", dbus_path);
1438 l = g_slist_find_custom(mesh_apps, net_uuid,
1439 __mesh_compare_network_uuid);
1446 memset(&ev, 0, sizeof(ev));
1447 memcpy(ev.net_uuid, net_uuid, 16);
1450 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1451 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1453 struct hal_ev_mesh_provision_finished ev;
1454 memset(&ev, 0, sizeof(ev));
1455 memcpy(ev.net_uuid, app->uuid, 16);
1456 ev.status = BT_STATUS_FAIL;
1457 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1458 if (mesh_event_cb) {
1459 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1460 (void*)&ev, sizeof(ev));
1462 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1465 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1467 ev.auth_type = __mesh_get_authentication_type(str);
1468 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1469 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1471 l_dbus_message_ref(msg);
1473 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1474 (void*)&ev, sizeof(ev));
1479 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1480 struct l_dbus *dbus,
1481 struct l_dbus_message *msg,
1484 struct hal_ev_mesh_authentication_request ev;
1487 const char *dbus_path;
1489 meshcfg_app *app = NULL;
1491 dbus_path = l_dbus_message_get_path(msg);
1492 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1495 INFO("Mesh: app path [%s]", dbus_path);
1497 l = g_slist_find_custom(mesh_apps, net_uuid,
1498 __mesh_compare_network_uuid);
1503 ERR("Mesh: app not found");
1507 memset(&ev, 0, sizeof(ev));
1508 memcpy(ev.net_uuid, net_uuid, 16);
1511 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1512 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1514 struct hal_ev_mesh_provision_finished ev;
1515 memset(&ev, 0, sizeof(ev));
1518 memcpy(ev.net_uuid, app->uuid, 16);
1520 ev.status = BT_STATUS_FAIL;
1521 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1523 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1524 (void*)&ev, sizeof(ev));
1525 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1528 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1530 ev.auth_type = __mesh_get_authentication_type(str);
1531 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1532 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1534 l_dbus_message_ref(msg);
1536 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1537 (void*)&ev, sizeof(ev));
1542 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1544 INFO("Mesh: Setup Agent interface properties & methods");
1545 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1546 __mesh_agent_capability_getter,
1548 /* TODO: Other properties */
1549 l_dbus_interface_method(interface, "DisplayString", 0,
1550 __mesh_agent_display_string_request,
1552 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1553 __mesh_agent_display_numeric_request,
1554 "", "su", "type", "number");
1555 l_dbus_interface_method(interface, "PromptNumeric", 0,
1556 __mesh_agent_prompt_numeric_request,
1557 "u", "s", "number", "type");
1558 l_dbus_interface_method(interface, "PromptStatic", 0,
1559 __mesh_agent_prompt_static_request,
1560 "ay", "s", "data", "type");
1563 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1565 meshcfg_el *elem = (meshcfg_el*) data;
1566 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1567 elem->index, elem->path);
1568 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1569 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1570 ERR("Mesh: Failed to register object %s", elem->path);
1574 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1579 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1580 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1581 ERR("Mesh: Unable to register agent interface");
1585 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1586 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1587 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1588 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1592 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1593 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1594 ERR("Mesh: Failed to add interface %s",
1595 L_DBUS_INTERFACE_PROPERTIES);
1602 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1610 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1611 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1612 ERR("Mesh: Failed to register interface %s",
1613 BT_HAL_MESH_APPLICATION_INTERFACE);
1617 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1618 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1619 ERR("Mesh: Failed to register interface %s",
1620 BT_HAL_MESH_PROVISIONER_INTERFACE);
1624 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1625 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1626 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1628 ERR("Mesh: Failed to register object %s", ptr->path);
1632 if (!__bt_hal_mesh_register_agent(ptr))
1635 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1636 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1637 ERR("Mesh: Failed to register interface %s",
1638 BT_HAL_MESH_ELEMENT_INTERFACE);
1642 INFO("Mesh: Number of elements to be registsred [%d]",
1643 g_slist_length(ptr->elements));
1645 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1647 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1648 if (!l_dbus_object_add_interface(dbus, ptr->path,
1649 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1650 ERR("Mesh: Failed to add interface %s",
1651 L_DBUS_INTERFACE_OBJECT_MANAGER);
1654 INFO("Mesh: Application Register completed");
1659 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1663 meshcfg_model *model_info = (meshcfg_model*) data;
1664 meshcfg_app *app = (meshcfg_app*) user_data;
1666 l = g_slist_find_custom(app->elements,
1667 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1671 elem = g_malloc0(sizeof(meshcfg_el));
1672 elem->index = model_info->elem_index;
1673 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1674 app->elements = g_slist_append(app->elements, elem);
1675 INFO("Mesh: Created element index [%d] path [%s]",
1676 elem->index, elem->path);
1678 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1679 model_info->model, elem->index);
1680 /* Add Model in the element */
1681 elem->models = g_slist_append(elem->models, model_info);
1682 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1683 elem->index, g_slist_length(elem->models));
1686 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1687 GSList *models, bool is_prov)
1690 meshcfg_app *app = NULL;
1691 char *uuid_str = NULL;
1693 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1694 INFO("Mesh: Network UUID [%s]", uuid_str);
1696 app = g_malloc0(sizeof(meshcfg_app));
1697 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1699 app->cid = node->vendor_info.companyid;
1700 app->pid = node->vendor_info.vendorid;
1701 app->vid = node->vendor_info.versionid;
1702 app->crpl = node->vendor_info.crpl;
1705 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1706 app->agent_path = g_strdup_printf("%s/agent", app->path);
1709 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1710 app->agent_path = g_strdup_printf("%s/agent", app->path);
1712 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1715 app->is_prov = is_prov;
1716 app->token.u64 = node->token.u64;
1717 INFO("Mesh: Token [%llu]", app->token.u64);
1718 INFO("Mesh: app created");
1722 static void __bt_hal_mesh_leave_net_reply(
1723 struct l_dbus_proxy *proxy,
1724 struct l_dbus_message *msg, void *user_data)
1727 app = (meshcfg_app*) user_data;
1729 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1730 if (l_dbus_message_is_error(msg)) {
1733 l_dbus_message_get_error(msg, &name, NULL);
1734 ERR("Mesh: Failed to leave network: %s", name);
1736 /* Send Network Destroy fail event */
1737 __send_network_destroy_event(app, BT_STATUS_FAIL);
1739 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1743 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1746 meshcfg_app *app = (meshcfg_app*) user_data;
1748 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1749 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1752 static void __bt_hal_mesh_release_net_reply(
1753 struct l_dbus_proxy *proxy,
1754 struct l_dbus_message *msg, void *user_data)
1757 app = (meshcfg_app*) user_data;
1759 INFO("Mesh:Release Network Reply from Meshd: app path [%s]", app->path);
1760 if (l_dbus_message_is_error(msg)) {
1763 l_dbus_message_get_error(msg, &name, NULL);
1764 ERR("Mesh: Failed to Release network: %s", name);
1767 INFO("Mesh: Release Network: Success, cleanup app after proxy removed");
1771 static void __bt_hal_mesh_release_net_setup(struct l_dbus_message *msg,
1774 meshcfg_app *app = (meshcfg_app*) user_data;
1776 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1777 INFO("Mesh: Release Network Setup app path [%s]", app->path);
1780 static void __bt_hal_mesh_create_net_reply(
1781 struct l_dbus_proxy *proxy,
1782 struct l_dbus_message *msg, void *user_data)
1785 app = (meshcfg_app*) user_data;
1787 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1788 if (l_dbus_message_is_error(msg)) {
1791 l_dbus_message_get_error(msg, &name, NULL);
1792 ERR("Mesh: Failed to create network: %s", name);
1794 /* Send Network creation fail event */
1795 __send_network_attach_event(app, BT_STATUS_FAIL);
1797 /* Destroy mesh app object */
1798 __bt_hal_mesh_destroy_app_object(app);
1803 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1807 struct l_dbus_message_builder *builder;
1808 app = (meshcfg_app*) user_data;
1810 builder = l_dbus_message_builder_new(msg);
1812 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1813 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1814 __mesh_append_byte_array(builder, app->uuid, 16);
1815 l_dbus_message_builder_finalize(builder);
1816 l_dbus_message_builder_destroy(builder);
1819 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1821 struct hal_ev_mesh_scan_state_changed ev;
1823 memset(&ev, 0, sizeof(ev));
1824 memcpy(ev.net_uuid, app->uuid, 16);
1826 ev.status = BT_STATUS_SUCCESS;
1828 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1830 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1831 (void*)&ev, sizeof(ev));
1834 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1836 meshcfg_app *app = (meshcfg_app*) user_data;
1837 __mesh_trigger_scan_finished_event(app);
1841 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1845 l = g_slist_find_custom(mesh_apps, net_uuid,
1846 __mesh_compare_network_uuid);
1851 if (app->scan_timer_id > 0) {
1852 g_source_remove(app->scan_timer_id);
1853 app->scan_timer_id = 0;
1856 app->scan_timer_id = g_timeout_add_seconds(secs,
1857 __bt_mesh_scan_timer_cb, app);
1862 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1863 struct l_dbus_message *msg, void *user_data)
1865 struct hal_ev_mesh_scan_state_changed ev;
1866 const char *dbus_path;
1868 dbus_path = l_dbus_proxy_get_path(proxy);
1869 INFO("Mesh: DBUS path [%s]", dbus_path);
1870 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1872 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1873 INFO("Mesh: Scan duration [%u]", secs);
1875 memset(&ev, 0, sizeof(ev));
1876 memcpy(ev.net_uuid, net_uuid, 16);
1878 if (l_dbus_message_is_error(msg)) {
1880 l_dbus_message_get_error(msg, &name, NULL);
1881 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1882 ev.status = BT_STATUS_FAIL;
1884 INFO("Mesh: Unprovisioned scan started\n");
1885 ev.status = BT_STATUS_SUCCESS;
1886 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1889 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1891 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1892 (void*)&ev, sizeof(ev));
1896 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1897 const char *key, const char *signature,
1903 l_dbus_message_builder_enter_dict(builder, "sv");
1904 l_dbus_message_builder_append_basic(builder, 's', key);
1905 l_dbus_message_builder_enter_variant(builder, signature);
1906 l_dbus_message_builder_append_basic(builder, signature[0], data);
1907 l_dbus_message_builder_leave_variant(builder);
1908 l_dbus_message_builder_leave_dict(builder);
1911 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1913 struct l_dbus_message_builder *builder;
1914 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1915 INFO("Mesh: Scan duration [%u]", secs);
1917 builder = l_dbus_message_builder_new(msg);
1918 l_dbus_message_builder_enter_array(builder, "{sv}");
1919 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1920 l_dbus_message_builder_leave_array(builder);
1921 l_dbus_message_builder_finalize(builder);
1922 l_dbus_message_builder_destroy(builder);
1926 bt_status_t _bt_hal_mesh_network_set_caps(
1927 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1931 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1935 app->public_oob = caps->public_oob;
1936 app->static_oob = caps->static_oob;
1937 app->out_oob = caps->out_oob;
1938 app->in_oob = caps->in_oob;
1940 ERR("Mesh: app not found!!");
1941 return BT_STATUS_PARM_INVALID;
1944 return BT_STATUS_SUCCESS;
1947 static void __bt_hal_mesh_add_node_reply(
1948 struct l_dbus_proxy *proxy,
1949 struct l_dbus_message *msg,
1952 struct hal_ev_mesh_provision_status ev;
1953 const char *dbus_path;
1955 dbus_path = l_dbus_proxy_get_path(proxy);
1956 INFO("Mesh: DBUS path [%s]", dbus_path);
1957 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1959 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1961 INFO("Mesh: app path [%s]", dbus_path);
1963 memset(&ev, 0, sizeof(ev));
1964 memcpy(ev.net_uuid, net_uuid, 16);
1965 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1967 /* Free User data */
1968 g_free((void*)dev_uuid);
1971 if (l_dbus_message_is_error(msg)) {
1974 l_dbus_message_get_error(msg, &name, NULL);
1975 ERR("Mesh: Failed to start provisioning: %s", name);
1976 ev.status = BT_STATUS_FAIL;
1978 INFO("Mesh: Provisioning started\n");
1979 ev.status = BT_STATUS_SUCCESS;
1982 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1983 (void*)&ev, sizeof(ev));
1984 INFO("Mesh: Provisioning status sent");
1987 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1991 bt_uuid_t *dev = user_data;
1992 struct l_dbus_message_builder *builder;
1993 uuid = l_util_hexstring(dev->uu, 16);
1994 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1996 builder = l_dbus_message_builder_new(msg);
1997 __mesh_append_byte_array(builder, dev->uu, 16);
1998 l_dbus_message_builder_enter_array(builder, "{sv}");
1999 l_dbus_message_builder_leave_array(builder);
2000 l_dbus_message_builder_finalize(builder);
2001 l_dbus_message_builder_destroy(builder);
2004 bt_status_t _bt_hal_mesh_provision_device(
2005 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
2010 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2013 dev = g_memdup((gpointer)dev_uuid, 16);
2014 INFO("Mesh: Schedule Add Node request to meshd");
2015 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
2016 __bt_hal_mesh_add_node_setup,
2017 __bt_hal_mesh_add_node_reply,
2019 return BT_STATUS_FAIL;
2021 ERR("Mesh: app not found!!");
2022 return BT_STATUS_PARM_INVALID;
2025 return BT_STATUS_SUCCESS;
2028 static void __bt_hal_mesh_subnet_key_setup(
2029 struct l_dbus_message *msg, void *user_data)
2031 struct subnet_key_request *req = user_data;
2032 uint16_t idx = (uint16_t) req->idx;
2034 l_dbus_message_set_arguments(msg, "q", idx);
2037 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
2038 struct l_dbus_message *msg, void *user_data)
2040 struct hal_ev_mesh_netkey_execute_event ev;
2041 const char *dbus_path;
2043 struct subnet_key_request *req = user_data;
2044 const char *method = req->str;
2046 dbus_path = l_dbus_proxy_get_path(proxy);
2047 INFO("Mesh: DBUS path [%s]", dbus_path);
2048 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2050 memset(&ev, 0, sizeof(ev));
2051 memcpy(ev.net_uuid, net_uuid, 16);
2052 ev.key_idx = req->idx;
2056 if (l_dbus_message_is_error(msg)) {
2059 l_dbus_message_get_error(msg, &name, NULL);
2060 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
2061 ev.status = BT_STATUS_FAIL;
2064 ev.status = BT_STATUS_SUCCESS;
2066 if (!strcmp("CreateSubnet", method)) {
2067 INFO("Mesh: Reply for CreateSubnet");
2068 ev.key_event = HAL_MESH_KEY_ADD;
2069 } else if (!strcmp("DeleteSubnet", method)) {
2070 INFO("Mesh: Reply for DeleteSubnet");
2071 ev.key_event = HAL_MESH_KEY_DELETE;
2072 } else if (!strcmp("UpdateSubnet", method)) {
2073 INFO("Mesh: Reply for UpdateSubnet");
2074 ev.key_event = HAL_MESH_KEY_UPDATE;
2078 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2079 (void*)&ev, sizeof(ev));
2082 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2083 uint16_t index, const char *key_execute_method)
2085 struct subnet_key_request *req;
2087 req = l_new(struct subnet_key_request, 1);
2088 req->str = key_execute_method;
2091 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2092 __bt_hal_mesh_subnet_key_setup,
2093 __bt_hal_mesh_subnet_key_reply,
2100 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2103 struct app_key_request *req = user_data;
2104 uint16_t net_idx = (uint16_t) req->net_idx;
2105 uint16_t app_idx = (uint16_t) req->app_idx;
2107 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2108 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2110 l_dbus_message_set_arguments(msg, "q", app_idx);
2113 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2114 struct l_dbus_message *msg, void *user_data)
2116 struct hal_ev_mesh_appkey_execute_event ev;
2117 const char *dbus_path;
2119 struct app_key_request *req = user_data;
2120 const char *method = req->str;
2122 dbus_path = l_dbus_proxy_get_path(proxy);
2123 INFO("Mesh: DBUS path [%s]", dbus_path);
2124 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2126 memset(&ev, 0, sizeof(ev));
2127 memcpy(ev.net_uuid, net_uuid, 16);
2128 ev.net_idx = req->net_idx;
2129 ev.app_idx = req->app_idx;
2133 if (l_dbus_message_is_error(msg)) {
2136 l_dbus_message_get_error(msg, &name, NULL);
2137 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2138 ev.status = BT_STATUS_FAIL;
2140 ev.status = BT_STATUS_SUCCESS;
2142 if (!strcmp("CreateAppKey", method)) {
2143 INFO("Mesh: AppKey Create Reply");
2144 ev.key_event = HAL_MESH_KEY_ADD;
2145 } else if (!strcmp("DeleteAppKey", method)) {
2146 INFO("Mesh: AppKey Delete Reply");
2147 ev.key_event = HAL_MESH_KEY_DELETE;
2148 } else if (!strcmp("UpdateAppKey", method)) {
2149 INFO("Mesh: AppKey Update Reply");
2150 ev.key_event = HAL_MESH_KEY_UPDATE;
2154 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2157 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2158 uint16_t net_idx, uint16_t app_idx,
2159 const char *key_execute_method)
2161 struct app_key_request *req;
2163 req = l_new(struct app_key_request, 1);
2164 req->str = key_execute_method;
2165 req->net_idx = net_idx;
2166 req->app_idx = app_idx;
2168 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2169 __bt_hal_mesh_app_key_setup,
2170 __bt_hal_mesh_app_key_reply,
2177 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2178 bt_mesh_key_op_e op, uint16_t netkey_idx)
2183 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2187 if (op == BT_MESH_KEY_CREATE)
2188 status = __mesh_subnet_netkey_command_execute(app,
2189 netkey_idx, "CreateSubnet");
2190 else if (op == BT_MESH_KEY_DELETE)
2191 status = __mesh_subnet_netkey_command_execute(app,
2192 netkey_idx, "DeleteSubnet");
2193 else if (op == BT_MESH_KEY_UPDATE)
2194 status = __mesh_subnet_netkey_command_execute(app,
2195 netkey_idx, "UpdateSubnet");
2197 return BT_STATUS_FAIL;
2200 ERR("Mesh: app not found!!");
2201 return BT_STATUS_PARM_INVALID;
2204 return BT_STATUS_SUCCESS;
2207 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2208 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2213 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2217 if (op == BT_MESH_KEY_CREATE)
2218 status = __mesh_subnet_appkey_command_execute(app,
2219 netkey_idx, appkey_idx, "CreateAppKey");
2220 else if (op == BT_MESH_KEY_DELETE)
2221 status = __mesh_subnet_appkey_command_execute(app,
2222 netkey_idx, appkey_idx, "DeleteAppKey");
2223 else if (op == BT_MESH_KEY_UPDATE) {
2224 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2225 netkey_idx, appkey_idx);
2226 status = __mesh_subnet_appkey_command_execute(app,
2227 netkey_idx, appkey_idx, "UpdateAppKey");
2230 return BT_STATUS_FAIL;
2233 ERR("Mesh: app not found!!");
2234 return BT_STATUS_PARM_INVALID;
2237 return BT_STATUS_SUCCESS;
2240 bt_status_t _bt_hal_mesh_send_provision_data(
2241 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2245 struct l_dbus_message *msg;
2246 struct l_dbus_message *reply;
2248 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2253 reply = l_dbus_message_new_method_return(msg);
2254 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2255 l_dbus_send(dbus, reply);
2257 ERR("Mesh: app not found!!");
2258 return BT_STATUS_PARM_INVALID;
2260 return BT_STATUS_SUCCESS;
2263 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2267 l = g_slist_find_custom(mesh_apps,
2268 net_uuid->uu, __mesh_compare_network_uuid);
2271 if (!__bt_mesh_proxy_check(app)) {
2272 ERR("Mesh: Proxy check failed!!");
2273 return BT_STATUS_FAIL;
2275 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2276 "UnprovisionedScanCancel",
2277 NULL, NULL, NULL, NULL))
2278 return BT_STATUS_FAIL;
2280 ERR("Mesh: app not found!!");
2281 return BT_STATUS_PARM_INVALID;
2284 /* Stop Scan timer */
2285 if (app->scan_timer_id > 0) {
2286 g_source_remove(app->scan_timer_id);
2287 app->scan_timer_id = 0;
2290 /* Trigger Scan finished event */
2291 __mesh_trigger_scan_finished_event(app);
2293 return BT_STATUS_SUCCESS;
2296 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2297 const char *auth_value)
2300 struct l_dbus_message *reply = NULL;
2301 struct l_dbus_message_builder *builder;
2303 bt_status_t ret = BT_STATUS_SUCCESS;
2307 if (!__bt_mesh_proxy_check(0)) {
2308 ERR("Mesh: Proxy check failed!!");
2309 return BT_STATUS_FAIL;
2311 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2312 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2313 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2314 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2315 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2316 INFO("Mesh: Authentication reply: Numeric Type");
2317 val_u32 = atoi(auth_value);
2318 reply = l_dbus_message_new_method_return(agent_msg);
2319 l_dbus_message_set_arguments(reply, "u", val_u32);
2321 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2322 l_dbus_send(dbus, reply);
2323 ret = BT_STATUS_SUCCESS;
2324 /* For Alpha-Numeric */
2325 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2326 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2327 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2328 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2329 alpha = l_util_from_hexstring(auth_value, &sz);
2330 reply = l_dbus_message_new_method_return(agent_msg);
2331 builder = l_dbus_message_builder_new(reply);
2332 __mesh_append_byte_array(builder, alpha, 16);
2333 l_dbus_message_builder_finalize(builder);
2334 l_dbus_message_builder_destroy(builder);
2337 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2338 l_dbus_send(dbus, reply);
2339 ret = BT_STATUS_SUCCESS;
2344 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2345 bt_hal_mesh_scan_param_t *param)
2349 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2352 if (!__bt_mesh_proxy_check(app)) {
2353 ERR("Mesh: Proxy check failed!!");
2354 return BT_STATUS_FAIL;
2356 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2357 __mesh_scan_setup, __mesh_scan_reply,
2358 L_UINT_TO_PTR(param->scan_time), NULL))
2359 return BT_STATUS_FAIL;
2361 ERR("Mesh: app not found!!");
2362 return BT_STATUS_PARM_INVALID;
2364 return BT_STATUS_SUCCESS;
2367 static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
2370 struct mesh_remote_node_info *node_info = \
2371 (struct mesh_remote_node_info*) user_data;
2373 l_dbus_message_set_arguments(msg, "qy",
2374 node_info->unicast, node_info->num_elements);
2375 INFO("Mesh: Delete Remote Node Setup params passed");
2378 static void __bt_hal_mesh_delete_node_reply(
2379 struct l_dbus_proxy *proxy,
2380 struct l_dbus_message *msg, void *user_data)
2382 INFO("Mesh: Delete Remote Node Reply from DBUS");
2385 bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
2386 uint16_t unicast, uint16_t num_elements)
2390 struct mesh_remote_node_info *node_info;
2391 INFO("Mesh: Delete Remote Node");
2392 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2395 if (!__bt_mesh_proxy_check(app)) {
2396 ERR("Mesh: Proxy check failed!!");
2397 return BT_STATUS_FAIL;
2399 INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
2400 unicast, num_elements);
2402 /* Delete Remote Node Request */
2403 node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
2404 node_info->unicast = unicast;
2405 node_info->num_elements = num_elements;
2407 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
2408 __bt_hal_mesh_delete_node_setup,
2409 __bt_hal_mesh_delete_node_reply, node_info,
2411 ERR("Mesh: Delete Remote Node Request failed!!");
2413 return BT_STATUS_FAIL;
2416 ERR("Mesh: App not found!!");
2417 return BT_STATUS_PARM_INVALID;
2419 INFO("Mesh: Delete Remote Node Call issued successfully!!");
2420 return BT_STATUS_SUCCESS;
2423 bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid)
2427 INFO("Mesh: Release Network");
2428 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2431 if (!__bt_mesh_proxy_check(app)) {
2432 ERR("Mesh: Proxy check failed!!");
2433 return BT_STATUS_FAIL;
2435 INFO("Mesh: Release Network");
2436 /* Create CFG Network */
2437 if (!l_dbus_proxy_method_call(net_proxy, "Release",
2438 __bt_hal_mesh_release_net_setup,
2439 __bt_hal_mesh_release_net_reply, app,
2441 ERR("Mesh: Network Release failed!!");
2442 return BT_STATUS_FAIL;
2445 ERR("Mesh: App not found!!");
2446 return BT_STATUS_PARM_INVALID;
2448 INFO("Mesh: Network Release Call issued successfully!!");
2449 return BT_STATUS_SUCCESS;
2452 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2456 INFO("Mesh: Destroy network");
2457 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2460 if (!__bt_mesh_proxy_check(app)) {
2461 ERR("Mesh: Proxy check failed!!");
2462 return BT_STATUS_FAIL;
2464 INFO("Mesh: Destroy Network");
2465 /* Create CFG Network */
2466 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2467 __bt_hal_mesh_leave_net_setup,
2468 __bt_hal_mesh_leave_net_reply, app,
2470 ERR("Mesh: Network Leave failed!!");
2471 return BT_STATUS_FAIL;
2474 ERR("Mesh: App not found!!");
2475 return BT_STATUS_PARM_INVALID;
2477 INFO("Mesh: Network Leave Call issued successfully!!");
2478 return BT_STATUS_SUCCESS;
2481 bt_status_t _bt_hal_mesh_create_network(
2482 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2486 INFO("Mesh: Create Network Request");
2488 if (!__bt_mesh_proxy_check(0)) {
2489 ERR("Mesh: Proxy check failed!!");
2490 return BT_STATUS_FAIL;
2493 INFO("Mesh: Node Element count [%d]", node->num_elements);
2494 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2495 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2496 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2497 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2498 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2499 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2500 INFO("Mesh: Token [%llu]", node->token.u64);
2501 /* Create DBUS APP */
2502 app = __bt_hal_mesh_create_app(node, models, is_prov);
2504 return BT_STATUS_FAIL;
2506 /* Register DBUS APP */
2507 if (!__bt_hal_mesh_register_application(app))
2510 if (app->token.u64 == 0) {
2511 INFO("Mesh: Create New Network");
2512 /* Create CFG Network */
2513 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2514 __bt_hal_mesh_create_net_setup,
2515 __bt_hal_mesh_create_net_reply, app,
2517 ERR("Mesh: Network Create failed!!");
2521 INFO("Mesh: Attach Node to Network: Token [%llu]", app->token.u64);
2522 /* Attach to Network */
2523 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2524 __bt_hal_mesh_attach_node_setup,
2525 __bt_hal_mesh_attach_node_reply,
2528 ERR("Mesh: Node attach failed!!");
2533 INFO("Mesh: Node registration request scheudled");
2534 mesh_apps = g_slist_append(mesh_apps, app);
2535 INFO("Mesh: Total number of apps in list [%d]",
2536 g_slist_length(mesh_apps));
2537 return BT_STATUS_SUCCESS;
2539 ERR("Mesh: network can not be created!!");
2540 __bt_hal_mesh_destroy_app_object(app);
2541 return BT_STATUS_FAIL;
2544 static void __bt_hal_mesh_config_send(
2545 struct l_dbus_message *msg, void *user_data)
2547 struct configuration_request *req = user_data;
2548 struct l_dbus_message_builder *builder;
2550 builder = l_dbus_message_builder_new(msg);
2552 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2553 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2554 if (req->is_dev_key)
2555 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2557 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2558 __mesh_append_byte_array(builder, req->data, req->len);
2559 l_dbus_message_builder_finalize(builder);
2560 l_dbus_message_builder_destroy(builder);
2563 static void __bt_hal_mesh_key_config_send(
2564 struct l_dbus_message *msg, void *user_data)
2566 struct key_config_request *req = user_data;
2567 struct l_dbus_message_builder *builder;
2569 builder = l_dbus_message_builder_new(msg);
2571 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2572 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2573 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2574 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2575 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2576 l_dbus_message_builder_finalize(builder);
2577 l_dbus_message_builder_destroy(builder);
2580 static void __bt_hal_mesh_model_execute_message(
2581 struct l_dbus_message *msg, void *user_data)
2583 struct configuration_request *req = user_data;
2584 struct l_dbus_message_builder *builder;
2586 builder = l_dbus_message_builder_new(msg);
2588 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2589 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2590 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2591 __mesh_append_byte_array(builder, req->data, req->len);
2592 l_dbus_message_builder_finalize(builder);
2593 l_dbus_message_builder_destroy(builder);
2596 bt_status_t _bt_hal_mesh_send_key_config_message(
2597 bt_uuid_t *network, uint16_t dest,
2598 bool is_netkey, bool is_update,
2599 uint16_t key_idx, uint16_t netkey_idx)
2603 struct key_config_request *req;
2606 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2607 /* Source is Config Client Local Node */
2608 int src_elem_idx = 0;
2609 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2612 if (!__bt_mesh_proxy_check(app)) {
2613 ERR("Mesh: Proxy check failed!!");
2614 return BT_STATUS_FAIL;
2616 l1 = g_slist_find_custom(app->elements,
2617 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2619 return BT_STATUS_FAIL;
2622 req = l_new(struct key_config_request, 1);
2623 req->ele_path = elem->path;
2625 req->key_req_idx = key_idx;
2626 req->idx = netkey_idx; /* Encryption Key index */
2627 req->update_req = is_update;
2629 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2630 __bt_hal_mesh_key_config_send, NULL,
2631 (void*)req, l_free))
2632 return BT_STATUS_FAIL;
2634 ERR("Mesh: app not found!!");
2635 return BT_STATUS_PARM_INVALID;
2638 return BT_STATUS_SUCCESS;
2641 bt_status_t _bt_hal_mesh_send_configuration_message(
2642 bt_uuid_t *network, uint16_t dest,
2643 bool is_dev_key, uint16_t netkey_idx,
2644 uint8_t *buf, int len)
2648 struct configuration_request *req;
2651 int src_elem_idx = 0;
2652 l = g_slist_find_custom(mesh_apps, network->uu,
2653 __mesh_compare_network_uuid);
2656 if (!__bt_mesh_proxy_check(app)) {
2657 ERR("Mesh: Proxy check failed!!");
2658 return BT_STATUS_FAIL;
2660 l1 = g_slist_find_custom(app->elements,
2661 GUINT_TO_POINTER(src_elem_idx),
2662 __compare_element_index);
2664 return BT_STATUS_FAIL;
2667 req = l_new(struct configuration_request, 1);
2668 req->ele_path = elem->path;
2670 req->idx = netkey_idx;
2674 req->is_dev_key = is_dev_key;
2676 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2677 __bt_hal_mesh_config_send, NULL,
2678 (void*)req, l_free))
2679 return BT_STATUS_FAIL;
2681 ERR("Mesh: app not found!!");
2682 return BT_STATUS_PARM_INVALID;
2685 return BT_STATUS_SUCCESS;
2688 bt_status_t _bt_hal_mesh_model_execute_message(
2689 bt_uuid_t *network, uint16_t dest,
2690 uint16_t appkey_idx, uint8_t *buf, int len)
2694 struct configuration_request *req;
2697 int src_elem_idx = 0;
2698 l = g_slist_find_custom(mesh_apps, network->uu,
2699 __mesh_compare_network_uuid);
2702 if (!__bt_mesh_proxy_check(app)) {
2703 ERR("Mesh: Proxy check failed!!");
2704 return BT_STATUS_FAIL;
2706 l1 = g_slist_find_custom(app->elements,
2707 GUINT_TO_POINTER(src_elem_idx),
2708 __compare_element_index);
2710 return BT_STATUS_FAIL;
2713 req = l_new(struct configuration_request, 1);
2714 req->ele_path = elem->path;
2716 req->idx = appkey_idx;
2720 req->is_dev_key = false;
2722 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2723 __bt_hal_mesh_model_execute_message,
2724 NULL, (void*)req, l_free))
2725 return BT_STATUS_FAIL;
2727 ERR("Mesh: app not found!!");
2728 return BT_STATUS_PARM_INVALID;
2731 return BT_STATUS_SUCCESS;