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);
420 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
422 const meshcfg_el *elem = data;
423 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
427 return (elem->index == elem_index ? 0 : -1);
430 static void __send_network_destroy_event(void *param, uint8_t status)
432 struct hal_ev_mesh_network_destroyed ev;
433 meshcfg_app *app = (meshcfg_app*)param;
435 memset(&ev, 0, sizeof(ev));
436 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
437 memcpy(ev.token, app->token.u8, 8);
441 mesh_event_cb(HAL_EV_MESH_NETWORK_DESTROYED,
442 (void*)&ev, sizeof(ev));
445 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
447 const char *interface = l_dbus_proxy_get_interface(proxy);
448 const char *path = l_dbus_proxy_get_path(proxy);
450 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
452 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
453 struct hal_ev_mesh_network_proxy_added ev;
454 INFO("Mesh: Network Proxy added");
456 /* Save Global proxy */
459 INFO("Mesh: Net Proxy [%p]", net_proxy);
461 memset(&ev, 0, sizeof(ev));
462 ev.status = BT_STATUS_SUCCESS;
466 mesh_event_cb(HAL_EV_MESH_NETWORK_PROXY_ADDED,
467 (void*)&ev, sizeof(ev));
472 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
475 INFO("Mesh: Mgmt Proxy added");
476 INFO("Mesh: Number of mesh app present in list [%d]",
477 g_slist_length(mesh_apps));
478 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
481 app->mgmt_proxy = proxy;
483 ERR("Mesh: app not found for Mgmt proxy");
488 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
489 INFO("Mesh: Node Proxy added");
492 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
497 ERR("Mesh: app not found for Node proxy");
503 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
505 const char *interface = l_dbus_proxy_get_interface(proxy);
506 const char *path = l_dbus_proxy_get_path(proxy);
508 INFO("Proxy removed: %s (%s)\n", interface, path);
510 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
511 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
512 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
514 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
518 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
519 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
522 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
525 /* Send event to app about removal of a mesh local node */
526 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
527 __bt_hal_mesh_destroy_app_object(app);
529 ERR("Mesh: app not found for Mgmt proxy");
532 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
533 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
536 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
539 /* Send event to app about removal of a mesh local node */
540 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
541 __bt_hal_mesh_destroy_app_object(app);
543 ERR("Mesh: app not found for Mgmt proxy");
549 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
552 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
556 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
557 bool queued, void *user_data)
559 if (success == false)
560 ERR("Mesh: Fail to acquire dbus name\n");
562 if (!l_dbus_object_manager_enable(dbus_obj, "/"))
563 ERR("Mesh: Failed to register the ObjectManager\n");
566 static void __mesh_ready_callback(void *user_data)
568 INFO("Mesh: Connected to D-Bus\n");
570 if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
571 __mesh_acquire_name_callback, NULL))
572 ERR("Mesh: Failed to own well-known name\n");
575 bool _bt_hal_mesh_stack_init(void)
577 INFO("Mesh: Connect with meshd");
578 /* Connect with meshd */
579 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
583 INFO("Mesh: Got dbus [%p]", dbus);
585 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
588 client = l_dbus_client_new(dbus,
589 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
593 if (!l_dbus_client_set_connect_handler(client,
594 __mesh_client_connected, NULL, NULL))
597 if (!l_dbus_client_set_disconnect_handler(client,
598 __mesh_client_disconnected, NULL,
601 if (!l_dbus_client_set_proxy_handlers(client,
602 __mesh_proxy_added, __mesh_proxy_removed,
605 if (!l_dbus_client_set_ready_handler(client,
606 __mesh_dbus_client_ready, NULL, NULL))
609 INFO("Mesh: Stack Init watchers registered with meshd");
613 void _bt_hal_mesh_stack_deinit(void)
615 INFO("Mesh: Stack Deinit");
618 l_dbus_client_destroy(client);
623 l_dbus_destroy(dbus);
630 INFO("Mesh: Number of meshapps present in memory [%d]",
631 g_slist_length(mesh_apps));
634 /* To send stack event to hal-mesh handler */
635 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
640 /* To send stack event to hal-mesh handler */
641 void _bt_hal_mesh_unregister_dbus_handler_cb()
643 mesh_event_cb = NULL;
646 static bool __mesh_get_companyid(struct l_dbus *dbus,
647 struct l_dbus_message *message,
648 struct l_dbus_message_builder *builder,
651 meshcfg_app *app = (meshcfg_app*) user_data;
655 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
660 static bool __mesh_get_productid(struct l_dbus *dbus,
661 struct l_dbus_message *message,
662 struct l_dbus_message_builder *builder,
665 meshcfg_app *app = (meshcfg_app*) user_data;
668 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
673 static bool __mesh_get_versionid(struct l_dbus *dbus,
674 struct l_dbus_message *message,
675 struct l_dbus_message_builder *builder,
678 meshcfg_app *app = (meshcfg_app*) user_data;
681 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
686 static bool __mesh_get_crpl(struct l_dbus *dbus,
687 struct l_dbus_message *message,
688 struct l_dbus_message_builder *builder,
691 meshcfg_app *app = (meshcfg_app*) user_data;
694 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
699 static void __send_network_attach_event(void *param, uint8_t status)
701 struct hal_ev_mesh_network_attached ev;
702 meshcfg_app *app = (meshcfg_app*)param;
704 memset(&ev, 0, sizeof(ev));
705 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
706 memcpy(ev.token, app->token.u8, 8);
710 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
711 (void*)&ev, sizeof(ev));
714 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
715 struct l_dbus_message *msg, void *user_data)
717 struct l_dbus_message_iter iter_cfg;
719 meshcfg_app *app = (meshcfg_app*) user_data;
720 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
721 app->path, app->agent_path);
723 if (l_dbus_message_is_error(msg)) {
725 l_dbus_message_get_error(msg, &name, NULL);
726 ERR("Mesh: Failed to attach node: %s", name);
731 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
735 INFO("Mesh: Attached with path %s\n", app->path);
736 __send_network_attach_event(app, BT_STATUS_SUCCESS);
739 __send_network_attach_event(app, BT_STATUS_FAIL);
740 /* Destroy mesh app object */
741 __bt_hal_mesh_destroy_app_object(app);
744 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
747 meshcfg_app *app = (meshcfg_app*) user_data;
749 l_dbus_message_set_arguments(msg, "ot", app->path,
750 l_get_be64(app->token.u8));
754 static void __bt_hal_mesh_attach_node(void *user_data)
756 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
757 __bt_hal_mesh_attach_node_setup,
758 __bt_hal_mesh_attach_node_reply,
761 ERR("Mesh: Node attach failed!!");
762 /* Node could not be attached */
763 __send_network_attach_event(user_data, BT_STATUS_FAIL);
764 /* Destroy mesh app object */
765 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
769 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
770 struct l_dbus_message *message,
776 meshcfg_app *app = (meshcfg_app*) user_data;
777 INFO("Mesh: Join Complete");
780 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
782 /* Send Network creation fail event */
783 __send_network_attach_event(app, BT_STATUS_FAIL);
785 /* Destroy mesh app object */
786 __bt_hal_mesh_destroy_app_object(app);
788 return l_dbus_message_new_error(message, dbus_err_args, NULL);
792 app->token.u64 = l_get_be64(&tmp);
793 str = l_util_hexstring(&app->token.u8[0], 8);
794 INFO("Mesh: Created new node with token %s\n", str);
797 /* Authenticate the node */
798 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
799 return l_dbus_message_new_method_return(message);
802 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
805 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
806 meshcfg_model *model_info = (meshcfg_model*) data;
808 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
811 static bool __mesh_model_getter(struct l_dbus *dbus,
812 struct l_dbus_message *message,
813 struct l_dbus_message_builder *builder,
816 meshcfg_el *element = (meshcfg_el*) user_data;
818 l_dbus_message_builder_enter_array(builder, "q");
819 g_slist_foreach(element->models,
820 __bt_hal_mesh_foreach_model_getter, builder);
822 l_dbus_message_builder_leave_array(builder);
827 /*TODO: Vendor Model handling is currently not Handled */
828 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
829 struct l_dbus_message *message,
830 struct l_dbus_message_builder *builder,
833 l_dbus_message_builder_enter_array(builder, "(qq)");
834 l_dbus_message_builder_leave_array(builder);
839 static bool __mesh_element_index_getter(struct l_dbus *dbus,
840 struct l_dbus_message *message,
841 struct l_dbus_message_builder *builder,
844 meshcfg_el *element = (meshcfg_el*) user_data;
845 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
851 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
852 struct l_dbus_message *msg, void *user_data)
854 struct l_dbus_message_iter iter;
859 const char *dbus_path;
862 dbus_path = l_dbus_message_get_path(msg);
863 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
864 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
865 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
867 INFO("Mesh: app path [%s]", dbus_path);
869 memset(buf, 0, sizeof(buf));
870 size = (uint16_t) sizeof(*ev);
871 memcpy(ev->net_uuid, net_uuid, 16);
874 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
876 ERR("Mesh: Cannot parse received message");
877 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
880 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
881 ERR("Mesh: Cannot parse received message: data");
882 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
885 INFO("Mesh: Received dev key message (len %u):", n);
886 ev->source_addr = src;
887 ev->is_remote_devkey = rmt;
888 ev->netkey_idx = idx;
890 memcpy(ev->data, data, n);
893 INFO("Mesh: Src [0x%2.2x]", src);
894 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
895 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
896 /* Send DevKeyMessage Received event */
898 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
899 return l_dbus_message_new_method_return(msg);
902 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
903 struct l_dbus_message *msg, void *user_data)
905 struct l_dbus_message_iter iter;
906 uint16_t src, idx, dst;
909 const char *dbus_path;
912 dbus_path = l_dbus_message_get_path(msg);
913 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
914 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
915 struct hal_ev_mesh_message_event *ev = (void *)buf;
917 INFO("Mesh: app path [%s]", dbus_path);
919 memset(buf, 0, sizeof(buf));
920 size = (uint16_t) sizeof(*ev);
921 memcpy(ev->net_uuid, net_uuid, 16);
924 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
926 ERR("Mesh: Cannot parse received message");
927 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
930 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
931 ERR("Mesh: Cannot parse received message: data");
932 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
935 INFO("Mesh: Received mesh message (len %u):", n);
936 ev->source_addr = src;
940 memcpy(ev->data, data, n);
943 INFO("Mesh: Src [0x%2.2x]", src);
944 INFO("Mesh: Dst [0x%2.2x]", dst);
945 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
946 /* Send Message Received event */
948 INFO("Mesh: Send message event");
949 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
951 return l_dbus_message_new_method_return(msg);
954 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
956 INFO("Mesh: Setup element interface properties & methods");
958 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
960 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
961 __mesh_vendor_model_getter, NULL);
962 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
965 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
966 __mesh_device_message_received, "", "qbqay", "source",
967 "remote", "net_index", "data");
968 l_dbus_interface_method(iface, "MessageReceived", 0,
969 __mesh_message_received, "", "qqvay", "source",
970 "key_index", "destination", "data");
971 /* TODO: Other methods */
974 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
975 struct l_dbus_message *msg,
978 struct l_dbus_message_iter iter, opts;
979 meshcfg_app *app = (meshcfg_app*) user_data;
984 const char *sig = "naya{sv}";
986 /* Find network uuid from dbus path */
987 struct hal_ev_mesh_scan_result ev;
989 if (!app->scan_timer_id) {
990 /* Scan is not running */
991 INFO("Got scan result, but scan is already stopped");
992 return l_dbus_message_new_method_return(msg);
994 memset(&ev, 0, sizeof(ev));
995 memcpy(ev.net_uuid, app->uuid, 16);
997 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
998 ERR("Mesh: Cannot parse scan results");
999 ev.status = BT_STATUS_FAIL;
1001 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1002 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1005 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
1007 ERR("Mesh: Cannot parse scan result: data");
1008 ev.status = BT_STATUS_FAIL;
1010 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1011 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1014 INFO("Mesh: Scan result:\n");
1015 INFO("Mesh: Scan rssi = [%d]\n", rssi);
1016 str = l_util_hexstring_upper(prov_data, 16);
1017 INFO("Mesh: Scan UUID = [%s]\n", str);
1021 str = l_util_hexstring_upper(prov_data + 16, 2);
1022 INFO("Mesh: Scan OOB = [%s]\n", str);
1027 str = l_util_hexstring_upper(prov_data + 18, 4);
1028 INFO("Mesh: Scan URI hash = [%s]\n", str);
1032 /* 16 octet Dev UUID */
1033 memcpy(ev.dev_uuid, prov_data, 16);
1035 /* 2 octet Dev OOB Info */
1036 memcpy(ev.oob_info, prov_data + 16, 2);
1038 /* 4 octet URI Hash */
1039 memcpy(ev.uri_hash, prov_data + 18, 4);
1043 ev.status = BT_STATUS_SUCCESS;
1045 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1046 (void*)&ev, sizeof(ev));
1048 return l_dbus_message_new_method_return(msg);
1051 static struct l_dbus_message *__mesh_request_provisioner_call(
1052 struct l_dbus *dbus,
1053 struct l_dbus_message *msg,
1057 struct hal_ev_mesh_provision_finished ev;
1058 struct hal_ev_mesh_provision_data_request req;
1060 meshcfg_app *app = user_data;
1062 INFO("Mesh: provisioning data requested app path [%s]",
1064 uuid_string = l_util_hexstring(app->uuid, 16);
1065 INFO("Mesh: Network UUID [%s]", uuid_string);
1067 memset(&ev, 0, sizeof(ev));
1068 memset(&req, 0, sizeof(req));
1069 memcpy(ev.net_uuid, app->uuid, 16);
1070 memcpy(req.net_uuid, app->uuid, 16);
1071 l_free(uuid_string);
1073 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1074 ERR("Mesh: Cannot parse request for prov data");
1076 ev.status = BT_STATUS_FAIL;
1077 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1079 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1080 (void*)&ev, sizeof(ev));
1081 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1087 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1088 (void*)&req, sizeof(req));
1090 l_dbus_message_ref(msg);
1094 static struct l_dbus_message *__mesh_node_add_completed(
1095 struct l_dbus *dbus,
1096 struct l_dbus_message *msg,
1099 struct l_dbus_message_iter iter;
1104 struct hal_ev_mesh_provision_finished ev;
1105 const char *dbus_path;
1107 dbus_path = l_dbus_message_get_path(msg);
1108 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1109 true, MESH_PROV_IFACE);
1111 INFO("Mesh: app path [%s]", dbus_path);
1113 memset(&ev, 0, sizeof(ev));
1114 memcpy(ev.net_uuid, net_uuid, 16);
1118 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1119 ERR("Mesh: Cannot parse add node complete message");
1121 ev.status = BT_STATUS_FAIL;
1122 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1124 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1125 (void*)&ev, sizeof(ev));
1126 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1129 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1131 ERR("Mesh: Cannot parse add node complete message: uuid");
1133 ev.status = BT_STATUS_FAIL;
1134 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1136 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1137 (void*)&ev, sizeof(ev));
1138 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1142 ev.status = BT_STATUS_SUCCESS;
1143 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1144 memcpy(ev.dev_uuid, uuid, 16);
1145 ev.unicast = unicast;
1149 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1150 (void*)&ev, sizeof(ev));
1152 return l_dbus_message_new_method_return(msg);
1155 static struct l_dbus_message *__mesh_node_add_failed(
1156 struct l_dbus *dbus,
1157 struct l_dbus_message *msg,
1160 struct l_dbus_message_iter iter;
1164 struct hal_ev_mesh_provision_finished ev;
1165 const char *dbus_path;
1168 dbus_path = l_dbus_message_get_path(msg);
1169 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1170 true, MESH_PROV_IFACE);
1172 memset(&ev, 0, sizeof(ev));
1173 memcpy(ev.net_uuid, net_uuid, 16);
1176 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1177 ERR("Mesh: Cannot parse add node failed message");
1179 ev.status = BT_STATUS_FAIL;
1180 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1182 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1183 (void*)&ev, sizeof(ev));
1184 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1187 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1189 ERR("Mesh:Cannot parse add node failed message: uuid");
1190 ev.status = BT_STATUS_FAIL;
1191 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1193 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1194 (void*)&ev, sizeof(ev));
1195 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1198 INFO("Mesh: Provisioning failed:\n");
1199 str = l_util_hexstring_upper(uuid, 16);
1200 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);
1209 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1210 (void*)&ev, sizeof(ev));
1212 return l_dbus_message_new_method_return(msg);
1215 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1217 INFO("Mesh: Setup provisioner interface properties & methods");
1218 l_dbus_interface_method(interface, "ScanResult", 0,
1219 __mesh_scan_result_received, "",
1220 "naya{sv}", "rssi", "data", "options");
1222 l_dbus_interface_method(interface, "RequestProvData", 0,
1223 __mesh_request_provisioner_call,
1224 "qq", "y", "net_index", "unicast", "count");
1226 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1227 __mesh_node_add_completed, "", "ayqy",
1228 "uuid", "unicast", "count");
1230 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1231 __mesh_node_add_failed,
1232 "", "ays", "uuid", "reason");
1235 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1237 INFO("Mesh: Setup application interface properties & methods");
1239 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1240 __mesh_get_companyid,
1242 l_dbus_interface_property(iface, "VersionID", 0, "q",
1243 __mesh_get_versionid,
1245 l_dbus_interface_property(iface, "ProductID", 0, "q",
1246 __mesh_get_productid,
1248 l_dbus_interface_property(iface, "CRPL", 0, "q",
1249 __mesh_get_crpl, NULL);
1250 l_dbus_interface_method(iface, "JoinComplete", 0,
1251 __mesh_node_join_complete,
1257 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1258 struct l_dbus_message_builder *builder)
1260 if (app->in_oob & 0x08)
1261 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1262 if (app->in_oob & 0x04)
1263 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1264 if (app->in_oob & 0x02)
1265 l_dbus_message_builder_append_basic(builder, 's', "twist");
1266 if (app->in_oob & 0x01)
1267 l_dbus_message_builder_append_basic(builder, 's', "push");
1270 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1271 struct l_dbus_message_builder *builder)
1273 if (app->out_oob & 0x10)
1274 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1275 if (app->out_oob & 0x08)
1276 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1277 if (app->out_oob & 0x04)
1278 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1279 if (app->out_oob & 0x02)
1280 l_dbus_message_builder_append_basic(builder, 's', "beep");
1281 if (app->out_oob & 0x01)
1282 l_dbus_message_builder_append_basic(builder, 's', "blink");
1285 static bool __mesh_agent_capability_getter(
1286 struct l_dbus *dbus, struct l_dbus_message *message,
1287 struct l_dbus_message_builder *builder,
1292 INFO("Mesh: app path [%s]", app->path);
1293 INFO("Mesh: Agent path [%s]", app->agent_path);
1295 if (!l_dbus_message_builder_enter_array(builder, "s"))
1298 __mesh_fill_out_capabilities(app, builder);
1299 __mesh_fill_in_capabilities(app, builder);
1301 if (app->static_oob)
1302 l_dbus_message_builder_append_basic(builder,
1306 l_dbus_message_builder_leave_array(builder);
1307 INFO("Mesh: __agent_capability_getter: Success");
1311 static struct l_dbus_message *__mesh_agent_display_string_request(
1312 struct l_dbus *dbus,
1313 struct l_dbus_message *msg,
1316 struct hal_ev_mesh_authentication_request ev;
1319 const char *dbus_path;
1322 INFO("Mesh: app path [%s]", app->path);
1323 INFO("Mesh: Agent path [%s]", app->agent_path);
1325 dbus_path = l_dbus_message_get_path(msg);
1326 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1327 true, MESH_AGENT_IFACE);
1329 INFO("Mesh: app path [%s]", dbus_path);
1331 memset(&ev, 0, sizeof(ev));
1332 memcpy(ev.net_uuid, net_uuid, 16);
1335 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1336 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1337 struct hal_ev_mesh_provision_finished ev;
1338 memset(&ev, 0, sizeof(ev));
1339 memcpy(ev.net_uuid, net_uuid, 16);
1340 ev.status = BT_STATUS_FAIL;
1341 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1343 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1344 (void*)&ev, sizeof(ev));
1348 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1351 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1352 ev.auth_type = __mesh_get_authentication_type(str);
1353 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1354 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1355 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1358 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1359 (void*)&ev, sizeof(ev));
1362 return l_dbus_message_new_method_return(msg);
1365 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1366 struct l_dbus *dbus,
1367 struct l_dbus_message *msg,
1371 struct hal_ev_mesh_authentication_request ev;
1375 const char *dbus_path;
1378 INFO("Mesh: app path [%s]", app->path);
1379 INFO("Mesh: Agent path [%s]", app->agent_path);
1381 dbus_path = l_dbus_message_get_path(msg);
1382 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1383 true, MESH_AGENT_IFACE);
1385 INFO("Mesh: app path [%s]", dbus_path);
1387 memset(&ev, 0, sizeof(ev));
1388 memcpy(ev.net_uuid, net_uuid, 16);
1391 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1392 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1393 struct hal_ev_mesh_provision_finished ev;
1394 memset(&ev, 0, sizeof(ev));
1395 memcpy(ev.net_uuid, net_uuid, 16);
1396 ev.status = BT_STATUS_FAIL;
1397 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1398 if (mesh_event_cb) {
1399 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1400 (void*)&ev, sizeof(ev));
1403 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1406 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1407 auth_value = l_strdup_printf("%u", n);
1408 ev.auth_type = __mesh_get_authentication_type(str);
1409 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1410 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1411 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1414 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1415 (void*)&ev, sizeof(ev));
1419 return l_dbus_message_new_method_return(msg);
1422 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1423 struct l_dbus *dbus,
1424 struct l_dbus_message *msg,
1427 struct hal_ev_mesh_authentication_request ev;
1430 const char *dbus_path;
1434 dbus_path = l_dbus_message_get_path(msg);
1435 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1436 true, MESH_AGENT_IFACE);
1438 INFO("Mesh: app path [%s]", dbus_path);
1440 l = g_slist_find_custom(mesh_apps, net_uuid,
1441 __mesh_compare_network_uuid);
1448 memset(&ev, 0, sizeof(ev));
1449 memcpy(ev.net_uuid, net_uuid, 16);
1452 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1453 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1455 struct hal_ev_mesh_provision_finished ev;
1456 memset(&ev, 0, sizeof(ev));
1457 memcpy(ev.net_uuid, app->uuid, 16);
1458 ev.status = BT_STATUS_FAIL;
1459 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1460 if (mesh_event_cb) {
1461 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1462 (void*)&ev, sizeof(ev));
1464 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1467 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1469 ev.auth_type = __mesh_get_authentication_type(str);
1470 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1471 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1473 l_dbus_message_ref(msg);
1475 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1476 (void*)&ev, sizeof(ev));
1481 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1482 struct l_dbus *dbus,
1483 struct l_dbus_message *msg,
1486 struct hal_ev_mesh_authentication_request ev;
1489 const char *dbus_path;
1491 meshcfg_app *app = NULL;
1493 dbus_path = l_dbus_message_get_path(msg);
1494 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1497 INFO("Mesh: app path [%s]", dbus_path);
1499 l = g_slist_find_custom(mesh_apps, net_uuid,
1500 __mesh_compare_network_uuid);
1505 ERR("Mesh: app not found");
1508 memset(&ev, 0, sizeof(ev));
1509 memcpy(ev.net_uuid, net_uuid, 16);
1512 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1513 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1515 struct hal_ev_mesh_provision_finished ev;
1516 memset(&ev, 0, sizeof(ev));
1519 memcpy(ev.net_uuid, app->uuid, 16);
1521 ev.status = BT_STATUS_FAIL;
1522 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1524 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1525 (void*)&ev, sizeof(ev));
1526 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1529 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1531 ev.auth_type = __mesh_get_authentication_type(str);
1532 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1533 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1535 l_dbus_message_ref(msg);
1537 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1538 (void*)&ev, sizeof(ev));
1543 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1545 INFO("Mesh: Setup Agent interface properties & methods");
1546 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1547 __mesh_agent_capability_getter,
1549 /* TODO: Other properties */
1550 l_dbus_interface_method(interface, "DisplayString", 0,
1551 __mesh_agent_display_string_request,
1553 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1554 __mesh_agent_display_numeric_request,
1555 "", "su", "type", "number");
1556 l_dbus_interface_method(interface, "PromptNumeric", 0,
1557 __mesh_agent_prompt_numeric_request,
1558 "u", "s", "number", "type");
1559 l_dbus_interface_method(interface, "PromptStatic", 0,
1560 __mesh_agent_prompt_static_request,
1561 "ay", "s", "data", "type");
1564 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1566 meshcfg_el *elem = (meshcfg_el*) data;
1567 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1568 elem->index, elem->path);
1569 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1570 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1571 ERR("Mesh: Failed to register object %s", elem->path);
1575 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1580 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1581 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1582 ERR("Mesh: Unable to register agent interface");
1586 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1587 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1588 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1589 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1593 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1594 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1595 ERR("Mesh: Failed to add interface %s",
1596 L_DBUS_INTERFACE_PROPERTIES);
1603 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1611 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1612 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1613 ERR("Mesh: Failed to register interface %s",
1614 BT_HAL_MESH_APPLICATION_INTERFACE);
1618 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1619 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1620 ERR("Mesh: Failed to register interface %s",
1621 BT_HAL_MESH_PROVISIONER_INTERFACE);
1625 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1626 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1627 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1629 ERR("Mesh: Failed to register object %s", ptr->path);
1633 if (!__bt_hal_mesh_register_agent(ptr))
1636 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1637 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1638 ERR("Mesh: Failed to register interface %s",
1639 BT_HAL_MESH_ELEMENT_INTERFACE);
1643 INFO("Mesh: Number of elements to be registsred [%d]",
1644 g_slist_length(ptr->elements));
1646 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1648 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1649 if (!l_dbus_object_add_interface(dbus, ptr->path,
1650 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1651 ERR("Mesh: Failed to add interface %s",
1652 L_DBUS_INTERFACE_OBJECT_MANAGER);
1655 INFO("Mesh: Application Register completed");
1660 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1664 meshcfg_model *model_info = (meshcfg_model*) data;
1665 meshcfg_app *app = (meshcfg_app*) user_data;
1667 l = g_slist_find_custom(app->elements,
1668 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1672 elem = g_malloc0(sizeof(meshcfg_el));
1673 elem->index = model_info->elem_index;
1674 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1675 app->elements = g_slist_append(app->elements, elem);
1676 INFO("Mesh: Created element index [%d] path [%s]",
1677 elem->index, elem->path);
1679 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1680 model_info->model, elem->index);
1681 /* Add Model in the element */
1682 elem->models = g_slist_append(elem->models, model_info);
1683 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1684 elem->index, g_slist_length(elem->models));
1687 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1688 GSList *models, bool is_prov)
1691 meshcfg_app *app = NULL;
1692 char *uuid_str = NULL;
1694 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1695 INFO("Mesh: Network UUID [%s]", uuid_str);
1697 app = g_malloc0(sizeof(meshcfg_app));
1698 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1700 app->cid = node->vendor_info.companyid;
1701 app->pid = node->vendor_info.vendorid;
1702 app->vid = node->vendor_info.versionid;
1703 app->crpl = node->vendor_info.crpl;
1706 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1707 app->agent_path = g_strdup_printf("%s/agent", app->path);
1710 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1711 app->agent_path = g_strdup_printf("%s/agent", app->path);
1713 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1716 app->is_prov = is_prov;
1717 app->token.u64 = node->token.u64;
1718 INFO("Mesh: Token [%llu]", (unsigned long long int)app->token.u64);
1719 INFO("Mesh: app created");
1723 static void __bt_hal_mesh_leave_net_reply(
1724 struct l_dbus_proxy *proxy,
1725 struct l_dbus_message *msg, void *user_data)
1728 app = (meshcfg_app*) user_data;
1730 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1731 if (l_dbus_message_is_error(msg)) {
1734 l_dbus_message_get_error(msg, &name, NULL);
1735 ERR("Mesh: Failed to leave network: %s", name);
1737 /* Send Network Destroy fail event */
1738 __send_network_destroy_event(app, BT_STATUS_FAIL);
1740 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1744 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1747 meshcfg_app *app = (meshcfg_app*) user_data;
1749 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1750 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1753 static void __bt_hal_mesh_release_net_reply(
1754 struct l_dbus_proxy *proxy,
1755 struct l_dbus_message *msg, void *user_data)
1758 app = (meshcfg_app*) user_data;
1760 INFO("Mesh:Release Network Reply from Meshd: app path [%s]", app->path);
1761 if (l_dbus_message_is_error(msg)) {
1764 l_dbus_message_get_error(msg, &name, NULL);
1765 ERR("Mesh: Failed to Release network: %s", name);
1768 INFO("Mesh: Release Network: Success, cleanup app after proxy removed");
1772 static void __bt_hal_mesh_release_net_setup(struct l_dbus_message *msg,
1775 meshcfg_app *app = (meshcfg_app*) user_data;
1777 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1778 INFO("Mesh: Release Network Setup app path [%s]", app->path);
1781 static void __bt_hal_mesh_create_net_reply(
1782 struct l_dbus_proxy *proxy,
1783 struct l_dbus_message *msg, void *user_data)
1786 app = (meshcfg_app*) user_data;
1788 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1789 if (l_dbus_message_is_error(msg)) {
1792 l_dbus_message_get_error(msg, &name, NULL);
1793 ERR("Mesh: Failed to create network: %s", name);
1795 /* Send Network creation fail event */
1796 __send_network_attach_event(app, BT_STATUS_FAIL);
1798 /* Destroy mesh app object */
1799 __bt_hal_mesh_destroy_app_object(app);
1804 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1808 struct l_dbus_message_builder *builder;
1809 app = (meshcfg_app*) user_data;
1811 builder = l_dbus_message_builder_new(msg);
1813 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1814 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1815 __mesh_append_byte_array(builder, app->uuid, 16);
1816 l_dbus_message_builder_finalize(builder);
1817 l_dbus_message_builder_destroy(builder);
1820 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1822 struct hal_ev_mesh_scan_state_changed ev;
1824 memset(&ev, 0, sizeof(ev));
1825 memcpy(ev.net_uuid, app->uuid, 16);
1827 ev.status = BT_STATUS_SUCCESS;
1829 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1831 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1832 (void*)&ev, sizeof(ev));
1835 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1837 meshcfg_app *app = (meshcfg_app*) user_data;
1838 __mesh_trigger_scan_finished_event(app);
1842 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1846 l = g_slist_find_custom(mesh_apps, net_uuid,
1847 __mesh_compare_network_uuid);
1852 if (app->scan_timer_id > 0) {
1853 g_source_remove(app->scan_timer_id);
1854 app->scan_timer_id = 0;
1857 app->scan_timer_id = g_timeout_add_seconds(secs,
1858 __bt_mesh_scan_timer_cb, app);
1863 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1864 struct l_dbus_message *msg, void *user_data)
1866 struct hal_ev_mesh_scan_state_changed ev;
1867 const char *dbus_path;
1869 dbus_path = l_dbus_proxy_get_path(proxy);
1870 INFO("Mesh: DBUS path [%s]", dbus_path);
1871 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1873 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1874 INFO("Mesh: Scan duration [%u]", secs);
1876 memset(&ev, 0, sizeof(ev));
1877 memcpy(ev.net_uuid, net_uuid, 16);
1879 if (l_dbus_message_is_error(msg)) {
1881 l_dbus_message_get_error(msg, &name, NULL);
1882 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1883 ev.status = BT_STATUS_FAIL;
1885 INFO("Mesh: Unprovisioned scan started\n");
1886 ev.status = BT_STATUS_SUCCESS;
1887 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1890 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1892 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1893 (void*)&ev, sizeof(ev));
1897 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1898 const char *key, const char *signature,
1904 l_dbus_message_builder_enter_dict(builder, "sv");
1905 l_dbus_message_builder_append_basic(builder, 's', key);
1906 l_dbus_message_builder_enter_variant(builder, signature);
1907 l_dbus_message_builder_append_basic(builder, signature[0], data);
1908 l_dbus_message_builder_leave_variant(builder);
1909 l_dbus_message_builder_leave_dict(builder);
1912 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1914 struct l_dbus_message_builder *builder;
1915 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1916 INFO("Mesh: Scan duration [%u]", secs);
1918 builder = l_dbus_message_builder_new(msg);
1919 l_dbus_message_builder_enter_array(builder, "{sv}");
1920 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1921 l_dbus_message_builder_leave_array(builder);
1922 l_dbus_message_builder_finalize(builder);
1923 l_dbus_message_builder_destroy(builder);
1927 bt_status_t _bt_hal_mesh_network_set_caps(
1928 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1932 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1936 app->public_oob = caps->public_oob;
1937 app->static_oob = caps->static_oob;
1938 app->out_oob = caps->out_oob;
1939 app->in_oob = caps->in_oob;
1941 ERR("Mesh: app not found!!");
1942 return BT_STATUS_PARM_INVALID;
1945 return BT_STATUS_SUCCESS;
1948 static void __bt_hal_mesh_add_node_reply(
1949 struct l_dbus_proxy *proxy,
1950 struct l_dbus_message *msg,
1953 struct hal_ev_mesh_provision_status ev;
1954 const char *dbus_path;
1956 dbus_path = l_dbus_proxy_get_path(proxy);
1957 INFO("Mesh: DBUS path [%s]", dbus_path);
1958 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1960 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1962 INFO("Mesh: app path [%s]", dbus_path);
1964 memset(&ev, 0, sizeof(ev));
1965 memcpy(ev.net_uuid, net_uuid, 16);
1966 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1968 /* Free User data */
1969 g_free((void*)dev_uuid);
1972 if (l_dbus_message_is_error(msg)) {
1975 l_dbus_message_get_error(msg, &name, NULL);
1976 ERR("Mesh: Failed to start provisioning: %s", name);
1977 ev.status = BT_STATUS_FAIL;
1979 INFO("Mesh: Provisioning started\n");
1980 ev.status = BT_STATUS_SUCCESS;
1983 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1984 (void*)&ev, sizeof(ev));
1985 INFO("Mesh: Provisioning status sent");
1988 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1992 bt_uuid_t *dev = user_data;
1993 struct l_dbus_message_builder *builder;
1995 uuid = l_util_hexstring(dev->uu, 16);
1999 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
2001 builder = l_dbus_message_builder_new(msg);
2002 __mesh_append_byte_array(builder, dev->uu, 16);
2003 l_dbus_message_builder_enter_array(builder, "{sv}");
2004 l_dbus_message_builder_leave_array(builder);
2005 l_dbus_message_builder_finalize(builder);
2006 l_dbus_message_builder_destroy(builder);
2011 bt_status_t _bt_hal_mesh_provision_device(
2012 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
2017 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2020 dev = g_memdup((gpointer)dev_uuid, 16);
2021 INFO("Mesh: Schedule Add Node request to meshd");
2022 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
2023 __bt_hal_mesh_add_node_setup,
2024 __bt_hal_mesh_add_node_reply,
2026 return BT_STATUS_FAIL;
2028 ERR("Mesh: app not found!!");
2029 return BT_STATUS_PARM_INVALID;
2032 return BT_STATUS_SUCCESS;
2035 static void __bt_hal_mesh_subnet_key_setup(
2036 struct l_dbus_message *msg, void *user_data)
2038 struct subnet_key_request *req = user_data;
2039 uint16_t idx = (uint16_t) req->idx;
2041 l_dbus_message_set_arguments(msg, "q", idx);
2044 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
2045 struct l_dbus_message *msg, void *user_data)
2047 struct hal_ev_mesh_netkey_execute_event ev;
2048 const char *dbus_path;
2050 struct subnet_key_request *req = user_data;
2051 const char *method = req->str;
2053 dbus_path = l_dbus_proxy_get_path(proxy);
2054 INFO("Mesh: DBUS path [%s]", dbus_path);
2055 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2057 memset(&ev, 0, sizeof(ev));
2058 memcpy(ev.net_uuid, net_uuid, 16);
2059 ev.key_idx = req->idx;
2063 if (l_dbus_message_is_error(msg)) {
2066 l_dbus_message_get_error(msg, &name, NULL);
2067 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
2068 ev.status = BT_STATUS_FAIL;
2071 ev.status = BT_STATUS_SUCCESS;
2073 if (!strcmp("CreateSubnet", method)) {
2074 INFO("Mesh: Reply for CreateSubnet");
2075 ev.key_event = HAL_MESH_KEY_ADD;
2076 } else if (!strcmp("DeleteSubnet", method)) {
2077 INFO("Mesh: Reply for DeleteSubnet");
2078 ev.key_event = HAL_MESH_KEY_DELETE;
2079 } else if (!strcmp("UpdateSubnet", method)) {
2080 INFO("Mesh: Reply for UpdateSubnet");
2081 ev.key_event = HAL_MESH_KEY_UPDATE;
2085 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2086 (void*)&ev, sizeof(ev));
2089 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2090 uint16_t index, const char *key_execute_method)
2092 struct subnet_key_request *req;
2094 req = l_new(struct subnet_key_request, 1);
2095 req->str = key_execute_method;
2098 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2099 __bt_hal_mesh_subnet_key_setup,
2100 __bt_hal_mesh_subnet_key_reply,
2107 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2110 struct app_key_request *req = user_data;
2111 uint16_t net_idx = (uint16_t) req->net_idx;
2112 uint16_t app_idx = (uint16_t) req->app_idx;
2114 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2115 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2117 l_dbus_message_set_arguments(msg, "q", app_idx);
2120 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2121 struct l_dbus_message *msg, void *user_data)
2123 struct hal_ev_mesh_appkey_execute_event ev;
2124 const char *dbus_path;
2126 struct app_key_request *req = user_data;
2127 const char *method = req->str;
2129 dbus_path = l_dbus_proxy_get_path(proxy);
2130 INFO("Mesh: DBUS path [%s]", dbus_path);
2131 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2133 memset(&ev, 0, sizeof(ev));
2134 memcpy(ev.net_uuid, net_uuid, 16);
2135 ev.net_idx = req->net_idx;
2136 ev.app_idx = req->app_idx;
2140 if (l_dbus_message_is_error(msg)) {
2143 l_dbus_message_get_error(msg, &name, NULL);
2144 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2145 ev.status = BT_STATUS_FAIL;
2147 ev.status = BT_STATUS_SUCCESS;
2149 if (!strcmp("CreateAppKey", method)) {
2150 INFO("Mesh: AppKey Create Reply");
2151 ev.key_event = HAL_MESH_KEY_ADD;
2152 } else if (!strcmp("DeleteAppKey", method)) {
2153 INFO("Mesh: AppKey Delete Reply");
2154 ev.key_event = HAL_MESH_KEY_DELETE;
2155 } else if (!strcmp("UpdateAppKey", method)) {
2156 INFO("Mesh: AppKey Update Reply");
2157 ev.key_event = HAL_MESH_KEY_UPDATE;
2161 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2164 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2165 uint16_t net_idx, uint16_t app_idx,
2166 const char *key_execute_method)
2168 struct app_key_request *req;
2170 req = l_new(struct app_key_request, 1);
2171 req->str = key_execute_method;
2172 req->net_idx = net_idx;
2173 req->app_idx = app_idx;
2175 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2176 __bt_hal_mesh_app_key_setup,
2177 __bt_hal_mesh_app_key_reply,
2184 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2185 bt_mesh_key_op_e op, uint16_t netkey_idx)
2190 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2194 if (op == BT_MESH_KEY_CREATE)
2195 status = __mesh_subnet_netkey_command_execute(app,
2196 netkey_idx, "CreateSubnet");
2197 else if (op == BT_MESH_KEY_DELETE)
2198 status = __mesh_subnet_netkey_command_execute(app,
2199 netkey_idx, "DeleteSubnet");
2200 else if (op == BT_MESH_KEY_UPDATE)
2201 status = __mesh_subnet_netkey_command_execute(app,
2202 netkey_idx, "UpdateSubnet");
2204 return BT_STATUS_FAIL;
2207 ERR("Mesh: app not found!!");
2208 return BT_STATUS_PARM_INVALID;
2211 return BT_STATUS_SUCCESS;
2214 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2215 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2220 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2224 if (op == BT_MESH_KEY_CREATE)
2225 status = __mesh_subnet_appkey_command_execute(app,
2226 netkey_idx, appkey_idx, "CreateAppKey");
2227 else if (op == BT_MESH_KEY_DELETE)
2228 status = __mesh_subnet_appkey_command_execute(app,
2229 netkey_idx, appkey_idx, "DeleteAppKey");
2230 else if (op == BT_MESH_KEY_UPDATE) {
2231 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2232 netkey_idx, appkey_idx);
2233 status = __mesh_subnet_appkey_command_execute(app,
2234 netkey_idx, appkey_idx, "UpdateAppKey");
2237 return BT_STATUS_FAIL;
2240 ERR("Mesh: app not found!!");
2241 return BT_STATUS_PARM_INVALID;
2244 return BT_STATUS_SUCCESS;
2247 bt_status_t _bt_hal_mesh_send_provision_data(
2248 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2252 struct l_dbus_message *msg;
2253 struct l_dbus_message *reply;
2255 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2260 reply = l_dbus_message_new_method_return(msg);
2261 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2262 l_dbus_send(dbus, reply);
2264 ERR("Mesh: app not found!!");
2265 return BT_STATUS_PARM_INVALID;
2267 return BT_STATUS_SUCCESS;
2270 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2274 l = g_slist_find_custom(mesh_apps,
2275 net_uuid->uu, __mesh_compare_network_uuid);
2278 if (!__bt_mesh_proxy_check(app)) {
2279 ERR("Mesh: Proxy check failed!!");
2280 return BT_STATUS_FAIL;
2282 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2283 "UnprovisionedScanCancel",
2284 NULL, NULL, NULL, NULL))
2285 return BT_STATUS_FAIL;
2287 ERR("Mesh: app not found!!");
2288 return BT_STATUS_PARM_INVALID;
2291 /* Stop Scan timer */
2292 if (app->scan_timer_id > 0) {
2293 g_source_remove(app->scan_timer_id);
2294 app->scan_timer_id = 0;
2297 /* Trigger Scan finished event */
2298 __mesh_trigger_scan_finished_event(app);
2300 return BT_STATUS_SUCCESS;
2303 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2304 const char *auth_value)
2307 struct l_dbus_message *reply = NULL;
2308 struct l_dbus_message_builder *builder;
2310 bt_status_t ret = BT_STATUS_SUCCESS;
2314 if (!__bt_mesh_proxy_check(0)) {
2315 ERR("Mesh: Proxy check failed!!");
2316 return BT_STATUS_FAIL;
2318 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2319 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2320 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2321 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2322 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2323 INFO("Mesh: Authentication reply: Numeric Type");
2324 val_u32 = atoi(auth_value);
2325 reply = l_dbus_message_new_method_return(agent_msg);
2326 l_dbus_message_set_arguments(reply, "u", val_u32);
2328 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2329 l_dbus_send(dbus, reply);
2330 ret = BT_STATUS_SUCCESS;
2331 /* For Alpha-Numeric */
2332 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2333 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2334 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2335 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2336 alpha = l_util_from_hexstring(auth_value, &sz);
2337 reply = l_dbus_message_new_method_return(agent_msg);
2338 builder = l_dbus_message_builder_new(reply);
2339 __mesh_append_byte_array(builder, alpha, 16);
2340 l_dbus_message_builder_finalize(builder);
2341 l_dbus_message_builder_destroy(builder);
2344 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2345 l_dbus_send(dbus, reply);
2346 ret = BT_STATUS_SUCCESS;
2351 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2352 bt_hal_mesh_scan_param_t *param)
2356 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2359 if (!__bt_mesh_proxy_check(app)) {
2360 ERR("Mesh: Proxy check failed!!");
2361 return BT_STATUS_FAIL;
2363 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2364 __mesh_scan_setup, __mesh_scan_reply,
2365 L_UINT_TO_PTR(param->scan_time), NULL))
2366 return BT_STATUS_FAIL;
2368 ERR("Mesh: app not found!!");
2369 return BT_STATUS_PARM_INVALID;
2371 return BT_STATUS_SUCCESS;
2374 static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
2377 struct mesh_remote_node_info *node_info = \
2378 (struct mesh_remote_node_info*) user_data;
2380 l_dbus_message_set_arguments(msg, "qy",
2381 node_info->unicast, node_info->num_elements);
2382 INFO("Mesh: Delete Remote Node Setup params passed");
2385 static void __bt_hal_mesh_delete_node_reply(
2386 struct l_dbus_proxy *proxy,
2387 struct l_dbus_message *msg, void *user_data)
2389 INFO("Mesh: Delete Remote Node Reply from DBUS");
2392 bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
2393 uint16_t unicast, uint16_t num_elements)
2397 struct mesh_remote_node_info *node_info;
2398 INFO("Mesh: Delete Remote Node");
2399 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2402 if (!__bt_mesh_proxy_check(app)) {
2403 ERR("Mesh: Proxy check failed!!");
2404 return BT_STATUS_FAIL;
2406 INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
2407 unicast, num_elements);
2409 /* Delete Remote Node Request */
2410 node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
2411 node_info->unicast = unicast;
2412 node_info->num_elements = num_elements;
2414 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
2415 __bt_hal_mesh_delete_node_setup,
2416 __bt_hal_mesh_delete_node_reply, node_info,
2418 ERR("Mesh: Delete Remote Node Request failed!!");
2420 return BT_STATUS_FAIL;
2423 ERR("Mesh: App not found!!");
2424 return BT_STATUS_PARM_INVALID;
2426 INFO("Mesh: Delete Remote Node Call issued successfully!!");
2427 return BT_STATUS_SUCCESS;
2430 bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid)
2434 INFO("Mesh: Release Network");
2435 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2438 if (!__bt_mesh_proxy_check(app)) {
2439 ERR("Mesh: Proxy check failed!!");
2440 return BT_STATUS_FAIL;
2442 INFO("Mesh: Release Network");
2443 /* Create CFG Network */
2444 if (!l_dbus_proxy_method_call(net_proxy, "Release",
2445 __bt_hal_mesh_release_net_setup,
2446 __bt_hal_mesh_release_net_reply, app,
2448 ERR("Mesh: Network Release failed!!");
2449 return BT_STATUS_FAIL;
2452 ERR("Mesh: App not found!!");
2453 return BT_STATUS_PARM_INVALID;
2455 INFO("Mesh: Network Release Call issued successfully!!");
2456 return BT_STATUS_SUCCESS;
2459 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2463 INFO("Mesh: Destroy network");
2464 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2467 if (!__bt_mesh_proxy_check(app)) {
2468 ERR("Mesh: Proxy check failed!!");
2469 return BT_STATUS_FAIL;
2471 INFO("Mesh: Destroy Network");
2472 /* Create CFG Network */
2473 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2474 __bt_hal_mesh_leave_net_setup,
2475 __bt_hal_mesh_leave_net_reply, app,
2477 ERR("Mesh: Network Leave failed!!");
2478 return BT_STATUS_FAIL;
2481 ERR("Mesh: App not found!!");
2482 return BT_STATUS_PARM_INVALID;
2484 INFO("Mesh: Network Leave Call issued successfully!!");
2485 return BT_STATUS_SUCCESS;
2488 bt_status_t _bt_hal_mesh_create_network(
2489 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2493 INFO("Mesh: Create Network Request");
2495 if (!__bt_mesh_proxy_check(0)) {
2496 ERR("Mesh: Proxy check failed!!");
2497 return BT_STATUS_FAIL;
2500 INFO("Mesh: Node Element count [%d]", node->num_elements);
2501 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2502 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2503 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2504 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2505 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2506 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2507 INFO("Mesh: Token [%llu]", (unsigned long long int)node->token.u64);
2508 /* Create DBUS APP */
2509 app = __bt_hal_mesh_create_app(node, models, is_prov);
2511 return BT_STATUS_FAIL;
2513 /* Register DBUS APP */
2514 if (!__bt_hal_mesh_register_application(app))
2517 if (app->token.u64 == 0) {
2518 INFO("Mesh: Create New Network");
2519 /* Create CFG Network */
2520 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2521 __bt_hal_mesh_create_net_setup,
2522 __bt_hal_mesh_create_net_reply, app,
2524 ERR("Mesh: Network Create failed!!");
2528 INFO("Mesh: Attach Node to Network: Token [%llu]", (unsigned long long int)app->token.u64);
2529 /* Attach to Network */
2530 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2531 __bt_hal_mesh_attach_node_setup,
2532 __bt_hal_mesh_attach_node_reply,
2535 ERR("Mesh: Node attach failed!!");
2540 INFO("Mesh: Node registration request scheudled");
2541 mesh_apps = g_slist_append(mesh_apps, app);
2542 INFO("Mesh: Total number of apps in list [%d]",
2543 g_slist_length(mesh_apps));
2544 return BT_STATUS_SUCCESS;
2546 ERR("Mesh: network can not be created!!");
2547 __bt_hal_mesh_destroy_app_object(app);
2548 return BT_STATUS_FAIL;
2551 static void __bt_hal_mesh_config_send(
2552 struct l_dbus_message *msg, void *user_data)
2554 struct configuration_request *req = user_data;
2555 struct l_dbus_message_builder *builder;
2557 builder = l_dbus_message_builder_new(msg);
2559 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2560 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2561 if (req->is_dev_key)
2562 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2564 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2565 __mesh_append_byte_array(builder, req->data, req->len);
2566 l_dbus_message_builder_finalize(builder);
2567 l_dbus_message_builder_destroy(builder);
2570 static void __bt_hal_mesh_key_config_send(
2571 struct l_dbus_message *msg, void *user_data)
2573 struct key_config_request *req = user_data;
2574 struct l_dbus_message_builder *builder;
2576 builder = l_dbus_message_builder_new(msg);
2578 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2579 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2580 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2581 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2582 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2583 l_dbus_message_builder_finalize(builder);
2584 l_dbus_message_builder_destroy(builder);
2587 static void __bt_hal_mesh_model_execute_message(
2588 struct l_dbus_message *msg, void *user_data)
2590 struct configuration_request *req = user_data;
2591 struct l_dbus_message_builder *builder;
2593 builder = l_dbus_message_builder_new(msg);
2595 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2596 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2597 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2598 __mesh_append_byte_array(builder, req->data, req->len);
2599 l_dbus_message_builder_finalize(builder);
2600 l_dbus_message_builder_destroy(builder);
2603 bt_status_t _bt_hal_mesh_send_key_config_message(
2604 bt_uuid_t *network, uint16_t dest,
2605 bool is_netkey, bool is_update,
2606 uint16_t key_idx, uint16_t netkey_idx)
2610 struct key_config_request *req;
2613 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2614 /* Source is Config Client Local Node */
2615 int src_elem_idx = 0;
2616 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2619 if (!__bt_mesh_proxy_check(app)) {
2620 ERR("Mesh: Proxy check failed!!");
2621 return BT_STATUS_FAIL;
2623 l1 = g_slist_find_custom(app->elements,
2624 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2626 return BT_STATUS_FAIL;
2629 req = l_new(struct key_config_request, 1);
2630 req->ele_path = elem->path;
2632 req->key_req_idx = key_idx;
2633 req->idx = netkey_idx; /* Encryption Key index */
2634 req->update_req = is_update;
2636 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2637 __bt_hal_mesh_key_config_send, NULL,
2638 (void*)req, l_free))
2639 return BT_STATUS_FAIL;
2641 ERR("Mesh: app not found!!");
2642 return BT_STATUS_PARM_INVALID;
2645 return BT_STATUS_SUCCESS;
2648 bt_status_t _bt_hal_mesh_send_configuration_message(
2649 bt_uuid_t *network, uint16_t dest,
2650 bool is_dev_key, uint16_t netkey_idx,
2651 uint8_t *buf, int len)
2655 struct configuration_request *req;
2658 int src_elem_idx = 0;
2659 l = g_slist_find_custom(mesh_apps, network->uu,
2660 __mesh_compare_network_uuid);
2663 if (!__bt_mesh_proxy_check(app)) {
2664 ERR("Mesh: Proxy check failed!!");
2665 return BT_STATUS_FAIL;
2667 l1 = g_slist_find_custom(app->elements,
2668 GUINT_TO_POINTER(src_elem_idx),
2669 __compare_element_index);
2671 return BT_STATUS_FAIL;
2674 req = l_new(struct configuration_request, 1);
2675 req->ele_path = elem->path;
2677 req->idx = netkey_idx;
2681 req->is_dev_key = is_dev_key;
2683 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2684 __bt_hal_mesh_config_send, NULL,
2685 (void*)req, l_free))
2686 return BT_STATUS_FAIL;
2688 ERR("Mesh: app not found!!");
2689 return BT_STATUS_PARM_INVALID;
2692 return BT_STATUS_SUCCESS;
2695 bt_status_t _bt_hal_mesh_model_execute_message(
2696 bt_uuid_t *network, uint16_t dest,
2697 uint16_t appkey_idx, uint8_t *buf, int len)
2701 struct configuration_request *req;
2704 int src_elem_idx = 0;
2705 l = g_slist_find_custom(mesh_apps, network->uu,
2706 __mesh_compare_network_uuid);
2709 if (!__bt_mesh_proxy_check(app)) {
2710 ERR("Mesh: Proxy check failed!!");
2711 return BT_STATUS_FAIL;
2713 l1 = g_slist_find_custom(app->elements,
2714 GUINT_TO_POINTER(src_elem_idx),
2715 __compare_element_index);
2717 return BT_STATUS_FAIL;
2720 req = l_new(struct configuration_request, 1);
2721 req->ele_path = elem->path;
2723 req->idx = appkey_idx;
2727 req->is_dev_key = false;
2729 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2730 __bt_hal_mesh_model_execute_message,
2731 NULL, (void*)req, l_free))
2732 return BT_STATUS_FAIL;
2734 ERR("Mesh: app not found!!");
2735 return BT_STATUS_PARM_INVALID;
2738 return BT_STATUS_SUCCESS;