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);
364 static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
366 ERR("MESH: D-Bus client connected\n");
369 INFO("Mesh: MeshD connected: dbus [%p]", dbus);
372 static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
374 ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
375 /* TODO: Send event to app about meshd termination & then remove all mesh apps */
376 INFO("Mesh: Total number of networks present [%d]",
377 g_slist_length(mesh_apps));
380 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
383 /* Set DBUS to NULL */
385 INFO("Mesh: dbus [%p]", dbus);
387 INFO("Mesh: net proxy [%p]", net_proxy);
391 INFO("Mesh: All apps cleaned up after meshd exited");
394 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
398 const meshcfg_app *app = (meshcfg_app*) data;
399 char *path = (char *) user_data;
400 INFO("Mesh: proxy path compare: path [%s]", path);
401 INFO("Mesh: App Path path [%s]", app->path);
405 app_uuid_path = l_util_hexstring(app->uuid, 16);
406 INFO("Mesh:App UUID string [%s]", app_uuid_path);
407 char **strings = g_strsplit(path, "node", 2);
409 INFO("Mesh:String 0 [%s]", strings[0]);
410 INFO("Mesh:String 1 [%s]", strings[1]);
411 ret = g_strcmp0(strings[1], app_uuid_path);
414 l_free(app_uuid_path);
418 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
420 const meshcfg_el *elem = data;
421 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
425 return (elem->index == elem_index ? 0 : -1);
428 static void __send_network_destroy_event(void *param, uint8_t status)
430 struct hal_ev_mesh_network_destroyed ev;
431 meshcfg_app *app = (meshcfg_app*)param;
433 memset(&ev, 0, sizeof(ev));
434 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
435 memcpy(ev.token, app->token.u8, 8);
439 mesh_event_cb(HAL_EV_MESH_NETWORK_DESTROYED,
440 (void*)&ev, sizeof(ev));
443 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
445 const char *interface = l_dbus_proxy_get_interface(proxy);
446 const char *path = l_dbus_proxy_get_path(proxy);
448 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
450 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
451 INFO("Mesh: Network Proxy added");
452 /* Save Global proxy */
455 INFO("Mesh: Net Proxy [%p]", net_proxy);
459 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
462 INFO("Mesh: Mgmt Proxy added");
463 INFO("Mesh: Number of mesh app present in list [%d]",
464 g_slist_length(mesh_apps));
465 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
468 app->mgmt_proxy = proxy;
470 ERR("Mesh: app not found for Mgmt proxy");
475 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
476 INFO("Mesh: Node Proxy added");
479 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
484 ERR("Mesh: app not found for Node proxy");
490 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
492 const char *interface = l_dbus_proxy_get_interface(proxy);
493 const char *path = l_dbus_proxy_get_path(proxy);
495 INFO("Proxy removed: %s (%s)\n", interface, path);
497 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
498 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
499 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
501 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
505 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
506 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
509 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
512 /* Send event to app about removal of a mesh local node */
513 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
514 __bt_hal_mesh_destroy_app_object(app);
516 ERR("Mesh: app not found for Mgmt proxy");
519 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
520 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
523 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
526 /* Send event to app about removal of a mesh local node */
527 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
528 __bt_hal_mesh_destroy_app_object(app);
530 ERR("Mesh: app not found for Mgmt proxy");
536 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
539 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
543 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
544 bool queued, void *user_data)
546 if (success == false)
547 ERR("Mesh: Fail to acquire dbus name\n");
549 if (!l_dbus_object_manager_enable(dbus_obj, "/"))
550 ERR("Mesh: Failed to register the ObjectManager\n");
553 static void __mesh_ready_callback(void *user_data)
555 INFO("Mesh: Connected to D-Bus\n");
557 if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
558 __mesh_acquire_name_callback, NULL))
559 ERR("Mesh: Failed to own well-known name\n");
562 bool _bt_hal_mesh_stack_init(void)
564 INFO("Mesh: Connect with meshd");
565 /* Connect with meshd */
566 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
570 INFO("Mesh: Got dbus [%p]", dbus);
572 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
575 client = l_dbus_client_new(dbus,
576 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
580 if (!l_dbus_client_set_connect_handler(client,
581 __mesh_client_connected, NULL, NULL))
584 if (!l_dbus_client_set_disconnect_handler(client,
585 __mesh_client_disconnected, NULL,
588 if (!l_dbus_client_set_proxy_handlers(client,
589 __mesh_proxy_added, __mesh_proxy_removed,
592 if (!l_dbus_client_set_ready_handler(client,
593 __mesh_dbus_client_ready, NULL, NULL))
596 INFO("Mesh: Stack Init watchers registered with meshd");
600 void _bt_hal_mesh_stack_deinit(void)
602 INFO("Mesh: Stack Deinit");
605 l_dbus_client_destroy(client);
610 l_dbus_destroy(dbus);
615 /* To send stack event to hal-mesh handler */
616 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
621 /* To send stack event to hal-mesh handler */
622 void _bt_hal_mesh_unregister_dbus_handler_cb()
624 mesh_event_cb = NULL;
627 static bool __mesh_get_companyid(struct l_dbus *dbus,
628 struct l_dbus_message *message,
629 struct l_dbus_message_builder *builder,
632 meshcfg_app *app = (meshcfg_app*) user_data;
636 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
641 static bool __mesh_get_productid(struct l_dbus *dbus,
642 struct l_dbus_message *message,
643 struct l_dbus_message_builder *builder,
646 meshcfg_app *app = (meshcfg_app*) user_data;
649 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
654 static bool __mesh_get_versionid(struct l_dbus *dbus,
655 struct l_dbus_message *message,
656 struct l_dbus_message_builder *builder,
659 meshcfg_app *app = (meshcfg_app*) user_data;
662 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
667 static bool __mesh_get_crpl(struct l_dbus *dbus,
668 struct l_dbus_message *message,
669 struct l_dbus_message_builder *builder,
672 meshcfg_app *app = (meshcfg_app*) user_data;
675 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
680 static void __send_network_attach_event(void *param, uint8_t status)
682 struct hal_ev_mesh_network_attached ev;
683 meshcfg_app *app = (meshcfg_app*)param;
685 memset(&ev, 0, sizeof(ev));
686 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
687 memcpy(ev.token, app->token.u8, 8);
691 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
692 (void*)&ev, sizeof(ev));
695 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
696 struct l_dbus_message *msg, void *user_data)
698 struct l_dbus_message_iter iter_cfg;
700 meshcfg_app *app = (meshcfg_app*) user_data;
701 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
702 app->path, app->agent_path);
704 if (l_dbus_message_is_error(msg)) {
706 l_dbus_message_get_error(msg, &name, NULL);
707 ERR("Mesh: Failed to attach node: %s", name);
712 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
716 INFO("Mesh: Attached with path %s\n", app->path);
717 __send_network_attach_event(app, BT_STATUS_SUCCESS);
720 __send_network_attach_event(app, BT_STATUS_FAIL);
721 /* Destroy mesh app object */
722 __bt_hal_mesh_destroy_app_object(app);
725 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
728 meshcfg_app *app = (meshcfg_app*) user_data;
730 l_dbus_message_set_arguments(msg, "ot", app->path,
731 l_get_be64(app->token.u8));
735 static void __bt_hal_mesh_attach_node(void *user_data)
737 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
738 __bt_hal_mesh_attach_node_setup,
739 __bt_hal_mesh_attach_node_reply,
742 ERR("Mesh: Node attach failed!!");
743 /* Node could not be attached */
744 __send_network_attach_event(user_data, BT_STATUS_FAIL);
745 /* Destroy mesh app object */
746 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
750 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
751 struct l_dbus_message *message,
757 meshcfg_app *app = (meshcfg_app*) user_data;
758 INFO("Mesh: Join Complete");
761 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
763 /* Send Network creation fail event */
764 __send_network_attach_event(app, BT_STATUS_FAIL);
766 /* Destroy mesh app object */
767 __bt_hal_mesh_destroy_app_object(app);
769 return l_dbus_message_new_error(message, dbus_err_args, NULL);
773 app->token.u64 = l_get_be64(&tmp);
774 str = l_util_hexstring(&app->token.u8[0], 8);
775 INFO("Mesh: Created new node with token %s\n", str);
778 /* Authenticate the node */
779 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
780 return l_dbus_message_new_method_return(message);
783 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
786 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
787 meshcfg_model *model_info = (meshcfg_model*) data;
789 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
792 static bool __mesh_model_getter(struct l_dbus *dbus,
793 struct l_dbus_message *message,
794 struct l_dbus_message_builder *builder,
797 meshcfg_el *element = (meshcfg_el*) user_data;
799 l_dbus_message_builder_enter_array(builder, "q");
800 g_slist_foreach(element->models,
801 __bt_hal_mesh_foreach_model_getter, builder);
803 l_dbus_message_builder_leave_array(builder);
808 /*TODO: Vendor Model handling is currently not Handled */
809 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
810 struct l_dbus_message *message,
811 struct l_dbus_message_builder *builder,
814 l_dbus_message_builder_enter_array(builder, "(qq)");
815 l_dbus_message_builder_leave_array(builder);
820 static bool __mesh_element_index_getter(struct l_dbus *dbus,
821 struct l_dbus_message *message,
822 struct l_dbus_message_builder *builder,
825 meshcfg_el *element = (meshcfg_el*) user_data;
826 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
832 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
833 struct l_dbus_message *msg, void *user_data)
835 struct l_dbus_message_iter iter;
840 const char *dbus_path;
843 dbus_path = l_dbus_message_get_path(msg);
844 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
845 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
846 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
848 INFO("Mesh: app path [%s]", dbus_path);
850 memset(buf, 0, sizeof(buf));
851 size = (uint16_t) sizeof(*ev);
852 memcpy(ev->net_uuid, net_uuid, 16);
855 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
857 ERR("Mesh: Cannot parse received message");
858 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
861 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
862 ERR("Mesh: Cannot parse received message: data");
863 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
866 INFO("Mesh: Received dev key message (len %u):", n);
867 ev->source_addr = src;
868 ev->is_remote_devkey = rmt;
869 ev->netkey_idx = idx;
871 memcpy(ev->data, data, n);
874 INFO("Mesh: Src [0x%2.2x]", src);
875 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
876 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
877 /* Send DevKeyMessage Received event */
879 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
880 return l_dbus_message_new_method_return(msg);
883 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
884 struct l_dbus_message *msg, void *user_data)
886 struct l_dbus_message_iter iter;
887 uint16_t src, idx, dst;
890 const char *dbus_path;
893 dbus_path = l_dbus_message_get_path(msg);
894 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
895 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
896 struct hal_ev_mesh_message_event *ev = (void *)buf;
898 INFO("Mesh: app path [%s]", dbus_path);
900 memset(buf, 0, sizeof(buf));
901 size = (uint16_t) sizeof(*ev);
902 memcpy(ev->net_uuid, net_uuid, 16);
905 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
907 ERR("Mesh: Cannot parse received message");
908 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
911 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
912 ERR("Mesh: Cannot parse received message: data");
913 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
916 INFO("Mesh: Received mesh message (len %u):", n);
917 ev->source_addr = src;
921 memcpy(ev->data, data, n);
924 INFO("Mesh: Src [0x%2.2x]", src);
925 INFO("Mesh: Dst [0x%2.2x]", dst);
926 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
927 /* Send Message Received event */
929 INFO("Mesh: Send message event");
930 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
932 return l_dbus_message_new_method_return(msg);
935 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
937 INFO("Mesh: Setup element interface properties & methods");
939 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
941 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
942 __mesh_vendor_model_getter, NULL);
943 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
946 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
947 __mesh_device_message_received, "", "qbqay", "source",
948 "remote", "net_index", "data");
949 l_dbus_interface_method(iface, "MessageReceived", 0,
950 __mesh_message_received, "", "qqvay", "source",
951 "key_index", "destination", "data");
952 /* TODO: Other methods */
955 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
956 struct l_dbus_message *msg,
959 struct l_dbus_message_iter iter, opts;
960 meshcfg_app *app = (meshcfg_app*) user_data;
965 const char *sig = "naya{sv}";
967 /* Find network uuid from dbus path */
968 struct hal_ev_mesh_scan_result ev;
970 if (!app->scan_timer_id) {
971 /* Scan is not running */
972 INFO("Got scan result, but scan is already stopped");
973 return l_dbus_message_new_method_return(msg);
975 memset(&ev, 0, sizeof(ev));
976 memcpy(ev.net_uuid, app->uuid, 16);
978 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
979 ERR("Mesh: Cannot parse scan results");
980 ev.status = BT_STATUS_FAIL;
982 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
983 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
986 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
988 ERR("Mesh: Cannot parse scan result: data");
989 ev.status = BT_STATUS_FAIL;
991 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
992 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
995 INFO("Mesh: Scan result:\n");
996 INFO("Mesh: Scan rssi = [%d]\n", rssi);
997 str = l_util_hexstring_upper(prov_data, 16);
998 INFO("Mesh: Scan UUID = [%s]\n", str);
1002 str = l_util_hexstring_upper(prov_data + 16, 2);
1003 INFO("Mesh: Scan OOB = [%s]\n", str);
1008 str = l_util_hexstring_upper(prov_data + 18, 4);
1009 INFO("Mesh: Scan URI hash = [%s]\n", str);
1013 /* 16 octet Dev UUID */
1014 memcpy(ev.dev_uuid, prov_data, 16);
1016 /* 2 octet Dev OOB Info */
1017 memcpy(ev.oob_info, prov_data + 16, 2);
1019 /* 4 octet URI Hash */
1020 memcpy(ev.uri_hash, prov_data + 18, 4);
1024 ev.status = BT_STATUS_SUCCESS;
1026 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1027 (void*)&ev, sizeof(ev));
1029 return l_dbus_message_new_method_return(msg);
1032 static struct l_dbus_message *__mesh_request_provisioner_call(
1033 struct l_dbus *dbus,
1034 struct l_dbus_message *msg,
1038 struct hal_ev_mesh_provision_finished ev;
1039 struct hal_ev_mesh_provision_data_request req;
1041 meshcfg_app *app = user_data;
1043 INFO("Mesh: provisioning data requested app path [%s]",
1045 uuid_string = l_util_hexstring(app->uuid, 16);
1046 INFO("Mesh: Network UUID [%s]", uuid_string);
1048 memset(&ev, 0, sizeof(ev));
1049 memset(&req, 0, sizeof(req));
1050 memcpy(ev.net_uuid, app->uuid, 16);
1051 memcpy(req.net_uuid, app->uuid, 16);
1052 l_free(uuid_string);
1054 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1055 ERR("Mesh: Cannot parse request for prov data");
1057 ev.status = BT_STATUS_FAIL;
1058 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1060 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1061 (void*)&ev, sizeof(ev));
1062 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1068 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1069 (void*)&req, sizeof(req));
1071 l_dbus_message_ref(msg);
1075 static struct l_dbus_message *__mesh_node_add_completed(
1076 struct l_dbus *dbus,
1077 struct l_dbus_message *msg,
1080 struct l_dbus_message_iter iter;
1085 struct hal_ev_mesh_provision_finished ev;
1086 const char *dbus_path;
1088 dbus_path = l_dbus_message_get_path(msg);
1089 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1090 true, MESH_PROV_IFACE);
1092 INFO("Mesh: app path [%s]", dbus_path);
1094 memset(&ev, 0, sizeof(ev));
1095 memcpy(ev.net_uuid, net_uuid, 16);
1099 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1100 ERR("Mesh: Cannot parse add node complete message");
1102 ev.status = BT_STATUS_FAIL;
1103 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1105 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1106 (void*)&ev, sizeof(ev));
1107 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1110 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1112 ERR("Mesh: Cannot parse add node complete message: uuid");
1114 ev.status = BT_STATUS_FAIL;
1115 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1117 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1118 (void*)&ev, sizeof(ev));
1119 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1123 ev.status = BT_STATUS_SUCCESS;
1124 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1125 memcpy(ev.dev_uuid, uuid, 16);
1126 ev.unicast = unicast;
1130 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1131 (void*)&ev, sizeof(ev));
1133 return l_dbus_message_new_method_return(msg);
1136 static struct l_dbus_message *__mesh_node_add_failed(
1137 struct l_dbus *dbus,
1138 struct l_dbus_message *msg,
1141 struct l_dbus_message_iter iter;
1145 struct hal_ev_mesh_provision_finished ev;
1146 const char *dbus_path;
1149 dbus_path = l_dbus_message_get_path(msg);
1150 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1151 true, MESH_PROV_IFACE);
1153 memset(&ev, 0, sizeof(ev));
1154 memcpy(ev.net_uuid, net_uuid, 16);
1157 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1158 ERR("Mesh: Cannot parse add node failed message");
1160 ev.status = BT_STATUS_FAIL;
1161 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1163 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1164 (void*)&ev, sizeof(ev));
1165 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1168 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1170 ERR("Mesh:Cannot parse add node failed message: uuid");
1171 ev.status = BT_STATUS_FAIL;
1172 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1174 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1175 (void*)&ev, sizeof(ev));
1176 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1179 INFO("Mesh: Provisioning failed:\n");
1180 str = l_util_hexstring_upper(uuid, 16);
1181 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1184 ev.status = BT_STATUS_FAIL;
1185 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1186 memcpy(ev.dev_uuid, uuid, 16);
1189 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1190 (void*)&ev, sizeof(ev));
1192 return l_dbus_message_new_method_return(msg);
1195 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1197 INFO("Mesh: Setup provisioner interface properties & methods");
1198 l_dbus_interface_method(interface, "ScanResult", 0,
1199 __mesh_scan_result_received, "",
1200 "naya{sv}", "rssi", "data", "options");
1202 l_dbus_interface_method(interface, "RequestProvData", 0,
1203 __mesh_request_provisioner_call,
1204 "qq", "y", "net_index", "unicast", "count");
1206 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1207 __mesh_node_add_completed, "", "ayqy",
1208 "uuid", "unicast", "count");
1210 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1211 __mesh_node_add_failed,
1212 "", "ays", "uuid", "reason");
1215 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1217 INFO("Mesh: Setup application interface properties & methods");
1219 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1220 __mesh_get_companyid,
1222 l_dbus_interface_property(iface, "VersionID", 0, "q",
1223 __mesh_get_versionid,
1225 l_dbus_interface_property(iface, "ProductID", 0, "q",
1226 __mesh_get_productid,
1228 l_dbus_interface_property(iface, "CRPL", 0, "q",
1229 __mesh_get_crpl, NULL);
1230 l_dbus_interface_method(iface, "JoinComplete", 0,
1231 __mesh_node_join_complete,
1237 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1238 struct l_dbus_message_builder *builder)
1240 if (app->in_oob & 0x08)
1241 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1242 if (app->in_oob & 0x04)
1243 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1244 if (app->in_oob & 0x02)
1245 l_dbus_message_builder_append_basic(builder, 's', "twist");
1246 if (app->in_oob & 0x01)
1247 l_dbus_message_builder_append_basic(builder, 's', "push");
1250 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1251 struct l_dbus_message_builder *builder)
1253 if (app->out_oob & 0x10)
1254 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1255 if (app->out_oob & 0x08)
1256 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1257 if (app->out_oob & 0x04)
1258 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1259 if (app->out_oob & 0x02)
1260 l_dbus_message_builder_append_basic(builder, 's', "beep");
1261 if (app->out_oob & 0x01)
1262 l_dbus_message_builder_append_basic(builder, 's', "blink");
1265 static bool __mesh_agent_capability_getter(
1266 struct l_dbus *dbus, struct l_dbus_message *message,
1267 struct l_dbus_message_builder *builder,
1272 INFO("Mesh: app path [%s]", app->path);
1273 INFO("Mesh: Agent path [%s]", app->agent_path);
1275 if (!l_dbus_message_builder_enter_array(builder, "s"))
1278 __mesh_fill_out_capabilities(app, builder);
1279 __mesh_fill_in_capabilities(app, builder);
1281 if (app->static_oob)
1282 l_dbus_message_builder_append_basic(builder,
1286 l_dbus_message_builder_leave_array(builder);
1287 INFO("Mesh: __agent_capability_getter: Success");
1291 static struct l_dbus_message *__mesh_agent_display_string_request(
1292 struct l_dbus *dbus,
1293 struct l_dbus_message *msg,
1296 struct hal_ev_mesh_authentication_request ev;
1299 const char *dbus_path;
1302 INFO("Mesh: app path [%s]", app->path);
1303 INFO("Mesh: Agent path [%s]", app->agent_path);
1305 dbus_path = l_dbus_message_get_path(msg);
1306 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1307 true, MESH_AGENT_IFACE);
1309 INFO("Mesh: app path [%s]", dbus_path);
1311 memset(&ev, 0, sizeof(ev));
1312 memcpy(ev.net_uuid, net_uuid, 16);
1315 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1316 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1317 struct hal_ev_mesh_provision_finished ev;
1318 memset(&ev, 0, sizeof(ev));
1319 memcpy(ev.net_uuid, net_uuid, 16);
1320 ev.status = BT_STATUS_FAIL;
1321 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1323 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1324 (void*)&ev, sizeof(ev));
1328 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1331 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1332 ev.auth_type = __mesh_get_authentication_type(str);
1333 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1334 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1335 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1338 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1339 (void*)&ev, sizeof(ev));
1342 return l_dbus_message_new_method_return(msg);
1345 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1346 struct l_dbus *dbus,
1347 struct l_dbus_message *msg,
1351 struct hal_ev_mesh_authentication_request ev;
1355 const char *dbus_path;
1358 INFO("Mesh: app path [%s]", app->path);
1359 INFO("Mesh: Agent path [%s]", app->agent_path);
1361 dbus_path = l_dbus_message_get_path(msg);
1362 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1363 true, MESH_AGENT_IFACE);
1365 INFO("Mesh: app path [%s]", dbus_path);
1367 memset(&ev, 0, sizeof(ev));
1368 memcpy(ev.net_uuid, net_uuid, 16);
1371 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1372 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1373 struct hal_ev_mesh_provision_finished ev;
1374 memset(&ev, 0, sizeof(ev));
1375 memcpy(ev.net_uuid, net_uuid, 16);
1376 ev.status = BT_STATUS_FAIL;
1377 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1378 if (mesh_event_cb) {
1379 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1380 (void*)&ev, sizeof(ev));
1383 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1386 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1387 auth_value = l_strdup_printf("%u", n);
1388 ev.auth_type = __mesh_get_authentication_type(str);
1389 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1390 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1391 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1394 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1395 (void*)&ev, sizeof(ev));
1399 return l_dbus_message_new_method_return(msg);
1402 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1403 struct l_dbus *dbus,
1404 struct l_dbus_message *msg,
1407 struct hal_ev_mesh_authentication_request ev;
1410 const char *dbus_path;
1414 dbus_path = l_dbus_message_get_path(msg);
1415 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1416 true, MESH_AGENT_IFACE);
1418 INFO("Mesh: app path [%s]", dbus_path);
1420 l = g_slist_find_custom(mesh_apps, net_uuid,
1421 __mesh_compare_network_uuid);
1428 memset(&ev, 0, sizeof(ev));
1429 memcpy(ev.net_uuid, net_uuid, 16);
1432 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1433 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1435 struct hal_ev_mesh_provision_finished ev;
1436 memset(&ev, 0, sizeof(ev));
1437 memcpy(ev.net_uuid, app->uuid, 16);
1438 ev.status = BT_STATUS_FAIL;
1439 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1440 if (mesh_event_cb) {
1441 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1442 (void*)&ev, sizeof(ev));
1444 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1447 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1449 ev.auth_type = __mesh_get_authentication_type(str);
1450 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1451 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1453 l_dbus_message_ref(msg);
1455 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1456 (void*)&ev, sizeof(ev));
1461 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1462 struct l_dbus *dbus,
1463 struct l_dbus_message *msg,
1466 struct hal_ev_mesh_authentication_request ev;
1469 const char *dbus_path;
1471 meshcfg_app *app = NULL;
1473 dbus_path = l_dbus_message_get_path(msg);
1474 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1477 INFO("Mesh: app path [%s]", dbus_path);
1479 l = g_slist_find_custom(mesh_apps, net_uuid,
1480 __mesh_compare_network_uuid);
1485 ERR("Mesh: app not found");
1489 memset(&ev, 0, sizeof(ev));
1490 memcpy(ev.net_uuid, net_uuid, 16);
1493 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1494 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1496 struct hal_ev_mesh_provision_finished ev;
1497 memset(&ev, 0, sizeof(ev));
1500 memcpy(ev.net_uuid, app->uuid, 16);
1502 ev.status = BT_STATUS_FAIL;
1503 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1505 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1506 (void*)&ev, sizeof(ev));
1507 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1510 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1512 ev.auth_type = __mesh_get_authentication_type(str);
1513 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1514 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1516 l_dbus_message_ref(msg);
1518 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1519 (void*)&ev, sizeof(ev));
1524 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1526 INFO("Mesh: Setup Agent interface properties & methods");
1527 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1528 __mesh_agent_capability_getter,
1530 /* TODO: Other properties */
1531 l_dbus_interface_method(interface, "DisplayString", 0,
1532 __mesh_agent_display_string_request,
1534 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1535 __mesh_agent_display_numeric_request,
1536 "", "su", "type", "number");
1537 l_dbus_interface_method(interface, "PromptNumeric", 0,
1538 __mesh_agent_prompt_numeric_request,
1539 "u", "s", "number", "type");
1540 l_dbus_interface_method(interface, "PromptStatic", 0,
1541 __mesh_agent_prompt_static_request,
1542 "ay", "s", "data", "type");
1545 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1547 meshcfg_el *elem = (meshcfg_el*) data;
1548 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1549 elem->index, elem->path);
1550 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1551 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1552 ERR("Mesh: Failed to register object %s", elem->path);
1556 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1561 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1562 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1563 ERR("Mesh: Unable to register agent interface");
1567 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1568 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1569 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1570 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1574 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1575 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1576 ERR("Mesh: Failed to add interface %s",
1577 L_DBUS_INTERFACE_PROPERTIES);
1584 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1592 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1593 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1594 ERR("Mesh: Failed to register interface %s",
1595 BT_HAL_MESH_APPLICATION_INTERFACE);
1599 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1600 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1601 ERR("Mesh: Failed to register interface %s",
1602 BT_HAL_MESH_PROVISIONER_INTERFACE);
1606 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1607 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1608 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1610 ERR("Mesh: Failed to register object %s", ptr->path);
1614 if (!__bt_hal_mesh_register_agent(ptr))
1617 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1618 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1619 ERR("Mesh: Failed to register interface %s",
1620 BT_HAL_MESH_ELEMENT_INTERFACE);
1624 INFO("Mesh: Number of elements to be registsred [%d]",
1625 g_slist_length(ptr->elements));
1627 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1629 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1630 if (!l_dbus_object_add_interface(dbus, ptr->path,
1631 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1632 ERR("Mesh: Failed to add interface %s",
1633 L_DBUS_INTERFACE_OBJECT_MANAGER);
1636 INFO("Mesh: Application Register completed");
1641 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1645 meshcfg_model *model_info = (meshcfg_model*) data;
1646 meshcfg_app *app = (meshcfg_app*) user_data;
1648 l = g_slist_find_custom(app->elements,
1649 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1653 elem = g_malloc0(sizeof(meshcfg_el));
1654 elem->index = model_info->elem_index;
1655 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1656 app->elements = g_slist_append(app->elements, elem);
1657 INFO("Mesh: Created element index [%d] path [%s]",
1658 elem->index, elem->path);
1660 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1661 model_info->model, elem->index);
1662 /* Add Model in the element */
1663 elem->models = g_slist_append(elem->models, model_info);
1664 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1665 elem->index, g_slist_length(elem->models));
1668 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1669 GSList *models, bool is_prov)
1672 meshcfg_app *app = NULL;
1673 char *uuid_str = NULL;
1675 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1677 app = g_malloc0(sizeof(meshcfg_app));
1678 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1680 app->cid = node->vendor_info.companyid;
1681 app->pid = node->vendor_info.vendorid;
1682 app->vid = node->vendor_info.versionid;
1683 app->crpl = node->vendor_info.crpl;
1686 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1687 app->agent_path = g_strdup_printf("%s/agent", app->path);
1690 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1691 app->agent_path = g_strdup_printf("%s/agent", app->path);
1693 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1696 app->is_prov = is_prov;
1697 INFO("Mesh: app created");
1701 static void __bt_hal_mesh_leave_net_reply(
1702 struct l_dbus_proxy *proxy,
1703 struct l_dbus_message *msg, void *user_data)
1706 app = (meshcfg_app*) user_data;
1708 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1709 if (l_dbus_message_is_error(msg)) {
1712 l_dbus_message_get_error(msg, &name, NULL);
1713 ERR("Mesh: Failed to leave network: %s", name);
1715 /* Send Network Destroy fail event */
1716 __send_network_destroy_event(app, BT_STATUS_FAIL);
1718 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1722 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1725 meshcfg_app *app = (meshcfg_app*) user_data;
1727 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1728 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1731 static void __bt_hal_mesh_create_net_reply(
1732 struct l_dbus_proxy *proxy,
1733 struct l_dbus_message *msg, void *user_data)
1736 app = (meshcfg_app*) user_data;
1738 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1739 if (l_dbus_message_is_error(msg)) {
1742 l_dbus_message_get_error(msg, &name, NULL);
1743 ERR("Mesh: Failed to create network: %s", name);
1745 /* Send Network creation fail event */
1746 __send_network_attach_event(app, BT_STATUS_FAIL);
1748 /* Destroy mesh app object */
1749 __bt_hal_mesh_destroy_app_object(app);
1754 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1758 struct l_dbus_message_builder *builder;
1759 app = (meshcfg_app*) user_data;
1761 builder = l_dbus_message_builder_new(msg);
1763 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1764 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1765 __mesh_append_byte_array(builder, app->uuid, 16);
1766 l_dbus_message_builder_finalize(builder);
1767 l_dbus_message_builder_destroy(builder);
1770 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1772 struct hal_ev_mesh_scan_state_changed ev;
1774 memset(&ev, 0, sizeof(ev));
1775 memcpy(ev.net_uuid, app->uuid, 16);
1777 ev.status = BT_STATUS_SUCCESS;
1779 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1781 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1782 (void*)&ev, sizeof(ev));
1785 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1787 meshcfg_app *app = (meshcfg_app*) user_data;
1788 __mesh_trigger_scan_finished_event(app);
1792 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1796 l = g_slist_find_custom(mesh_apps, net_uuid,
1797 __mesh_compare_network_uuid);
1802 if (app->scan_timer_id > 0) {
1803 g_source_remove(app->scan_timer_id);
1804 app->scan_timer_id = 0;
1807 app->scan_timer_id = g_timeout_add_seconds(secs,
1808 __bt_mesh_scan_timer_cb, app);
1813 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1814 struct l_dbus_message *msg, void *user_data)
1816 struct hal_ev_mesh_scan_state_changed ev;
1817 const char *dbus_path;
1819 dbus_path = l_dbus_proxy_get_path(proxy);
1820 INFO("Mesh: DBUS path [%s]", dbus_path);
1821 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1823 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1824 INFO("Mesh: Scan duration [%u]", secs);
1826 memset(&ev, 0, sizeof(ev));
1827 memcpy(ev.net_uuid, net_uuid, 16);
1829 if (l_dbus_message_is_error(msg)) {
1831 l_dbus_message_get_error(msg, &name, NULL);
1832 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1833 ev.status = BT_STATUS_FAIL;
1835 INFO("Mesh: Unprovisioned scan started\n");
1836 ev.status = BT_STATUS_SUCCESS;
1837 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1840 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1842 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1843 (void*)&ev, sizeof(ev));
1847 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1848 const char *key, const char *signature,
1854 l_dbus_message_builder_enter_dict(builder, "sv");
1855 l_dbus_message_builder_append_basic(builder, 's', key);
1856 l_dbus_message_builder_enter_variant(builder, signature);
1857 l_dbus_message_builder_append_basic(builder, signature[0], data);
1858 l_dbus_message_builder_leave_variant(builder);
1859 l_dbus_message_builder_leave_dict(builder);
1862 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1864 struct l_dbus_message_builder *builder;
1865 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1866 INFO("Mesh: Scan duration [%u]", secs);
1868 builder = l_dbus_message_builder_new(msg);
1869 l_dbus_message_builder_enter_array(builder, "{sv}");
1870 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1871 l_dbus_message_builder_leave_array(builder);
1872 l_dbus_message_builder_finalize(builder);
1873 l_dbus_message_builder_destroy(builder);
1877 bt_status_t _bt_hal_mesh_network_set_caps(
1878 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1882 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1886 app->public_oob = caps->public_oob;
1887 app->static_oob = caps->static_oob;
1888 app->out_oob = caps->out_oob;
1889 app->in_oob = caps->in_oob;
1891 ERR("Mesh: app not found!!");
1892 return BT_STATUS_PARM_INVALID;
1895 return BT_STATUS_SUCCESS;
1898 static void __bt_hal_mesh_add_node_reply(
1899 struct l_dbus_proxy *proxy,
1900 struct l_dbus_message *msg,
1903 struct hal_ev_mesh_provision_status ev;
1904 const char *dbus_path;
1906 dbus_path = l_dbus_proxy_get_path(proxy);
1907 INFO("Mesh: DBUS path [%s]", dbus_path);
1908 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1910 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1912 INFO("Mesh: app path [%s]", dbus_path);
1914 memset(&ev, 0, sizeof(ev));
1915 memcpy(ev.net_uuid, net_uuid, 16);
1916 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1918 /* Free User data */
1919 g_free((void*)dev_uuid);
1922 if (l_dbus_message_is_error(msg)) {
1925 l_dbus_message_get_error(msg, &name, NULL);
1926 ERR("Mesh: Failed to start provisioning: %s", name);
1927 ev.status = BT_STATUS_FAIL;
1929 INFO("Mesh: Provisioning started\n");
1930 ev.status = BT_STATUS_SUCCESS;
1933 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1934 (void*)&ev, sizeof(ev));
1935 INFO("Mesh: Provisioning status sent");
1938 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1942 bt_uuid_t *dev = user_data;
1943 struct l_dbus_message_builder *builder;
1944 uuid = l_util_hexstring(dev->uu, 16);
1945 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1947 builder = l_dbus_message_builder_new(msg);
1948 __mesh_append_byte_array(builder, dev->uu, 16);
1949 l_dbus_message_builder_enter_array(builder, "{sv}");
1950 l_dbus_message_builder_leave_array(builder);
1951 l_dbus_message_builder_finalize(builder);
1952 l_dbus_message_builder_destroy(builder);
1955 bt_status_t _bt_hal_mesh_provision_device(
1956 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1961 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1964 dev = g_memdup((gpointer)dev_uuid, 16);
1965 INFO("Mesh: Schedule Add Node request to meshd");
1966 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1967 __bt_hal_mesh_add_node_setup,
1968 __bt_hal_mesh_add_node_reply,
1970 return BT_STATUS_FAIL;
1972 ERR("Mesh: app not found!!");
1973 return BT_STATUS_PARM_INVALID;
1976 return BT_STATUS_SUCCESS;
1979 static void __bt_hal_mesh_subnet_key_setup(
1980 struct l_dbus_message *msg, void *user_data)
1982 struct subnet_key_request *req = user_data;
1983 uint16_t idx = (uint16_t) req->idx;
1985 l_dbus_message_set_arguments(msg, "q", idx);
1988 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1989 struct l_dbus_message *msg, void *user_data)
1991 struct hal_ev_mesh_netkey_execute_event ev;
1992 const char *dbus_path;
1994 struct subnet_key_request *req = user_data;
1995 const char *method = req->str;
1997 dbus_path = l_dbus_proxy_get_path(proxy);
1998 INFO("Mesh: DBUS path [%s]", dbus_path);
1999 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2001 memset(&ev, 0, sizeof(ev));
2002 memcpy(ev.net_uuid, net_uuid, 16);
2003 ev.key_idx = req->idx;
2007 if (l_dbus_message_is_error(msg)) {
2010 l_dbus_message_get_error(msg, &name, NULL);
2011 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
2012 ev.status = BT_STATUS_FAIL;
2015 ev.status = BT_STATUS_SUCCESS;
2017 if (!strcmp("CreateSubnet", method)) {
2018 INFO("Mesh: Reply for CreateSubnet");
2019 ev.key_event = HAL_MESH_KEY_ADD;
2020 } else if (!strcmp("DeleteSubnet", method)) {
2021 INFO("Mesh: Reply for DeleteSubnet");
2022 ev.key_event = HAL_MESH_KEY_DELETE;
2023 } else if (!strcmp("UpdateSubnet", method)) {
2024 INFO("Mesh: Reply for UpdateSubnet");
2025 ev.key_event = HAL_MESH_KEY_UPDATE;
2029 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2030 (void*)&ev, sizeof(ev));
2033 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2034 uint16_t index, const char *key_execute_method)
2036 struct subnet_key_request *req;
2038 req = l_new(struct subnet_key_request, 1);
2039 req->str = key_execute_method;
2042 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2043 __bt_hal_mesh_subnet_key_setup,
2044 __bt_hal_mesh_subnet_key_reply,
2051 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2054 struct app_key_request *req = user_data;
2055 uint16_t net_idx = (uint16_t) req->net_idx;
2056 uint16_t app_idx = (uint16_t) req->app_idx;
2058 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2059 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2061 l_dbus_message_set_arguments(msg, "q", app_idx);
2064 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2065 struct l_dbus_message *msg, void *user_data)
2067 struct hal_ev_mesh_appkey_execute_event ev;
2068 const char *dbus_path;
2070 struct app_key_request *req = user_data;
2071 const char *method = req->str;
2073 dbus_path = l_dbus_proxy_get_path(proxy);
2074 INFO("Mesh: DBUS path [%s]", dbus_path);
2075 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2077 memset(&ev, 0, sizeof(ev));
2078 memcpy(ev.net_uuid, net_uuid, 16);
2079 ev.net_idx = req->net_idx;
2080 ev.app_idx = req->app_idx;
2084 if (l_dbus_message_is_error(msg)) {
2087 l_dbus_message_get_error(msg, &name, NULL);
2088 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2089 ev.status = BT_STATUS_FAIL;
2091 ev.status = BT_STATUS_SUCCESS;
2093 if (!strcmp("CreateAppKey", method)) {
2094 INFO("Mesh: AppKey Create Reply");
2095 ev.key_event = HAL_MESH_KEY_ADD;
2096 } else if (!strcmp("DeleteAppKey", method)) {
2097 INFO("Mesh: AppKey Delete Reply");
2098 ev.key_event = HAL_MESH_KEY_DELETE;
2099 } else if (!strcmp("UpdateAppKey", method)) {
2100 INFO("Mesh: AppKey Update Reply");
2101 ev.key_event = HAL_MESH_KEY_UPDATE;
2105 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2108 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2109 uint16_t net_idx, uint16_t app_idx,
2110 const char *key_execute_method)
2112 struct app_key_request *req;
2114 req = l_new(struct app_key_request, 1);
2115 req->str = key_execute_method;
2116 req->net_idx = net_idx;
2117 req->app_idx = app_idx;
2119 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2120 __bt_hal_mesh_app_key_setup,
2121 __bt_hal_mesh_app_key_reply,
2128 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2129 bt_mesh_key_op_e op, uint16_t netkey_idx)
2134 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2138 if (op == BT_MESH_KEY_CREATE)
2139 status = __mesh_subnet_netkey_command_execute(app,
2140 netkey_idx, "CreateSubnet");
2141 else if (op == BT_MESH_KEY_DELETE)
2142 status = __mesh_subnet_netkey_command_execute(app,
2143 netkey_idx, "DeleteSubnet");
2144 else if (op == BT_MESH_KEY_UPDATE)
2145 status = __mesh_subnet_netkey_command_execute(app,
2146 netkey_idx, "UpdateSubnet");
2148 return BT_STATUS_FAIL;
2151 ERR("Mesh: app not found!!");
2152 return BT_STATUS_PARM_INVALID;
2155 return BT_STATUS_SUCCESS;
2158 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2159 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2164 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2168 if (op == BT_MESH_KEY_CREATE)
2169 status = __mesh_subnet_appkey_command_execute(app,
2170 netkey_idx, appkey_idx, "CreateAppKey");
2171 else if (op == BT_MESH_KEY_DELETE)
2172 status = __mesh_subnet_appkey_command_execute(app,
2173 netkey_idx, appkey_idx, "DeleteAppKey");
2174 else if (op == BT_MESH_KEY_UPDATE) {
2175 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2176 netkey_idx, appkey_idx);
2177 status = __mesh_subnet_appkey_command_execute(app,
2178 netkey_idx, appkey_idx, "UpdateAppKey");
2181 return BT_STATUS_FAIL;
2184 ERR("Mesh: app not found!!");
2185 return BT_STATUS_PARM_INVALID;
2188 return BT_STATUS_SUCCESS;
2191 bt_status_t _bt_hal_mesh_send_provision_data(
2192 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2196 struct l_dbus_message *msg;
2197 struct l_dbus_message *reply;
2199 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2204 reply = l_dbus_message_new_method_return(msg);
2205 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2206 l_dbus_send(dbus, reply);
2208 ERR("Mesh: app not found!!");
2209 return BT_STATUS_PARM_INVALID;
2211 return BT_STATUS_SUCCESS;
2214 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2218 l = g_slist_find_custom(mesh_apps,
2219 net_uuid->uu, __mesh_compare_network_uuid);
2222 if (!__bt_mesh_proxy_check(app)) {
2223 ERR("Mesh: Proxy check failed!!");
2224 return BT_STATUS_FAIL;
2226 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2227 "UnprovisionedScanCancel",
2228 NULL, NULL, NULL, NULL))
2229 return BT_STATUS_FAIL;
2231 ERR("Mesh: app not found!!");
2232 return BT_STATUS_PARM_INVALID;
2235 /* Stop Scan timer */
2236 if (app->scan_timer_id > 0) {
2237 g_source_remove(app->scan_timer_id);
2238 app->scan_timer_id = 0;
2241 /* Trigger Scan finished event */
2242 __mesh_trigger_scan_finished_event(app);
2244 return BT_STATUS_SUCCESS;
2247 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2248 const char *auth_value)
2251 struct l_dbus_message *reply = NULL;
2252 struct l_dbus_message_builder *builder;
2254 bt_status_t ret = BT_STATUS_SUCCESS;
2258 if (!__bt_mesh_proxy_check(0)) {
2259 ERR("Mesh: Proxy check failed!!");
2260 return BT_STATUS_FAIL;
2262 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2263 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2264 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2265 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2266 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2267 INFO("Mesh: Authentication reply: Numeric Type");
2268 val_u32 = atoi(auth_value);
2269 reply = l_dbus_message_new_method_return(agent_msg);
2270 l_dbus_message_set_arguments(reply, "u", val_u32);
2272 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2273 l_dbus_send(dbus, reply);
2274 ret = BT_STATUS_SUCCESS;
2275 /* For Alpha-Numeric */
2276 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2277 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2278 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2279 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2280 alpha = l_util_from_hexstring(auth_value, &sz);
2281 reply = l_dbus_message_new_method_return(agent_msg);
2282 builder = l_dbus_message_builder_new(reply);
2283 __mesh_append_byte_array(builder, alpha, 16);
2284 l_dbus_message_builder_finalize(builder);
2285 l_dbus_message_builder_destroy(builder);
2288 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2289 l_dbus_send(dbus, reply);
2290 ret = BT_STATUS_SUCCESS;
2295 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2296 bt_hal_mesh_scan_param_t *param)
2300 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2303 if (!__bt_mesh_proxy_check(app)) {
2304 ERR("Mesh: Proxy check failed!!");
2305 return BT_STATUS_FAIL;
2307 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2308 __mesh_scan_setup, __mesh_scan_reply,
2309 L_UINT_TO_PTR(param->scan_time), NULL))
2310 return BT_STATUS_FAIL;
2312 ERR("Mesh: app not found!!");
2313 return BT_STATUS_PARM_INVALID;
2315 return BT_STATUS_SUCCESS;
2318 static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
2321 struct mesh_remote_node_info *node_info = \
2322 (struct mesh_remote_node_info*) user_data;
2324 l_dbus_message_set_arguments(msg, "qy",
2325 node_info->unicast, node_info->num_elements);
2326 INFO("Mesh: Delete Remote Node Setup params passed");
2329 static void __bt_hal_mesh_delete_node_reply(
2330 struct l_dbus_proxy *proxy,
2331 struct l_dbus_message *msg, void *user_data)
2333 INFO("Mesh: Delete Remote Node Reply from DBUS");
2336 bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
2337 uint16_t unicast, uint16_t num_elements)
2341 struct mesh_remote_node_info *node_info;
2342 INFO("Mesh: Delete Remote Node");
2343 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2346 if (!__bt_mesh_proxy_check(app)) {
2347 ERR("Mesh: Proxy check failed!!");
2348 return BT_STATUS_FAIL;
2350 INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
2351 unicast, num_elements);
2353 /* Delete Remote Node Request */
2354 node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
2355 node_info->unicast = unicast;
2356 node_info->num_elements = num_elements;
2358 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
2359 __bt_hal_mesh_delete_node_setup,
2360 __bt_hal_mesh_delete_node_reply, node_info,
2362 ERR("Mesh: Delete Remote Node Request failed!!");
2364 return BT_STATUS_FAIL;
2367 ERR("Mesh: App not found!!");
2368 return BT_STATUS_PARM_INVALID;
2370 INFO("Mesh: Delete Remote Node Call issued successfully!!");
2371 return BT_STATUS_SUCCESS;
2374 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2378 INFO("Mesh: Destroy network");
2379 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2382 if (!__bt_mesh_proxy_check(app)) {
2383 ERR("Mesh: Proxy check failed!!");
2384 return BT_STATUS_FAIL;
2386 INFO("Mesh: Create New Network");
2387 /* Create CFG Network */
2388 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2389 __bt_hal_mesh_leave_net_setup,
2390 __bt_hal_mesh_leave_net_reply, app,
2392 ERR("Mesh: Network Leave failed!!");
2393 return BT_STATUS_FAIL;
2396 ERR("Mesh: App not found!!");
2397 return BT_STATUS_PARM_INVALID;
2399 INFO("Mesh: Network Leave Call issued successfully!!");
2400 return BT_STATUS_SUCCESS;
2403 bt_status_t _bt_hal_mesh_create_network(
2404 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2408 INFO("Mesh: Create Network Request");
2410 if (!__bt_mesh_proxy_check(0)) {
2411 ERR("Mesh: Proxy check failed!!");
2412 return BT_STATUS_FAIL;
2415 INFO("Mesh: Node Element count [%d]", node->num_elements);
2416 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2417 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2418 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2419 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2420 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2421 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2422 /* Create DBUS APP */
2423 app = __bt_hal_mesh_create_app(node, models, is_prov);
2425 return BT_STATUS_FAIL;
2427 /* Register DBUS APP */
2428 if (!__bt_hal_mesh_register_application(app))
2431 if (app->token.u64 == 0) {
2432 INFO("Mesh: Create New Network");
2433 /* Create CFG Network */
2434 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2435 __bt_hal_mesh_create_net_setup,
2436 __bt_hal_mesh_create_net_reply, app,
2438 ERR("Mesh: Network Create failed!!");
2442 INFO("Mesh: Attach Node to Network");
2443 /* Attach to Network */
2444 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2445 __bt_hal_mesh_attach_node_setup,
2446 __bt_hal_mesh_attach_node_reply,
2449 ERR("Mesh: Node attach failed!!");
2454 INFO("Mesh: Node registration request scheudled");
2455 mesh_apps = g_slist_append(mesh_apps, app);
2456 INFO("Mesh: Total number of apps in list [%d]",
2457 g_slist_length(mesh_apps));
2458 return BT_STATUS_SUCCESS;
2460 ERR("Mesh: network can not be created!!");
2461 __bt_hal_mesh_destroy_app_object(app);
2462 return BT_STATUS_FAIL;
2465 static void __bt_hal_mesh_config_send(
2466 struct l_dbus_message *msg, void *user_data)
2468 struct configuration_request *req = user_data;
2469 struct l_dbus_message_builder *builder;
2471 builder = l_dbus_message_builder_new(msg);
2473 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2474 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2475 if (req->is_dev_key)
2476 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2478 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2479 __mesh_append_byte_array(builder, req->data, req->len);
2480 l_dbus_message_builder_finalize(builder);
2481 l_dbus_message_builder_destroy(builder);
2484 static void __bt_hal_mesh_key_config_send(
2485 struct l_dbus_message *msg, void *user_data)
2487 struct key_config_request *req = user_data;
2488 struct l_dbus_message_builder *builder;
2490 builder = l_dbus_message_builder_new(msg);
2492 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2493 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2494 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2495 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2496 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2497 l_dbus_message_builder_finalize(builder);
2498 l_dbus_message_builder_destroy(builder);
2501 static void __bt_hal_mesh_model_execute_message(
2502 struct l_dbus_message *msg, void *user_data)
2504 struct configuration_request *req = user_data;
2505 struct l_dbus_message_builder *builder;
2507 builder = l_dbus_message_builder_new(msg);
2509 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2510 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2511 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2512 __mesh_append_byte_array(builder, req->data, req->len);
2513 l_dbus_message_builder_finalize(builder);
2514 l_dbus_message_builder_destroy(builder);
2517 bt_status_t _bt_hal_mesh_send_key_config_message(
2518 bt_uuid_t *network, uint16_t dest,
2519 bool is_netkey, bool is_update,
2520 uint16_t key_idx, uint16_t netkey_idx)
2524 struct key_config_request *req;
2527 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2528 /* Source is Config Client Local Node */
2529 int src_elem_idx = 0;
2530 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2533 if (!__bt_mesh_proxy_check(app)) {
2534 ERR("Mesh: Proxy check failed!!");
2535 return BT_STATUS_FAIL;
2537 l1 = g_slist_find_custom(app->elements,
2538 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2540 return BT_STATUS_FAIL;
2543 req = l_new(struct key_config_request, 1);
2544 req->ele_path = elem->path;
2546 req->key_req_idx = key_idx;
2547 req->idx = netkey_idx; /* Encryption Key index */
2548 req->update_req = is_update;
2550 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2551 __bt_hal_mesh_key_config_send, NULL,
2552 (void*)req, l_free))
2553 return BT_STATUS_FAIL;
2555 ERR("Mesh: app not found!!");
2556 return BT_STATUS_PARM_INVALID;
2559 return BT_STATUS_SUCCESS;
2562 bt_status_t _bt_hal_mesh_send_configuration_message(
2563 bt_uuid_t *network, uint16_t dest,
2564 bool is_dev_key, uint16_t netkey_idx,
2565 uint8_t *buf, int len)
2569 struct configuration_request *req;
2572 int src_elem_idx = 0;
2573 l = g_slist_find_custom(mesh_apps, network->uu,
2574 __mesh_compare_network_uuid);
2577 if (!__bt_mesh_proxy_check(app)) {
2578 ERR("Mesh: Proxy check failed!!");
2579 return BT_STATUS_FAIL;
2581 l1 = g_slist_find_custom(app->elements,
2582 GUINT_TO_POINTER(src_elem_idx),
2583 __compare_element_index);
2585 return BT_STATUS_FAIL;
2588 req = l_new(struct configuration_request, 1);
2589 req->ele_path = elem->path;
2591 req->idx = netkey_idx;
2595 req->is_dev_key = is_dev_key;
2597 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2598 __bt_hal_mesh_config_send, NULL,
2599 (void*)req, l_free))
2600 return BT_STATUS_FAIL;
2602 ERR("Mesh: app not found!!");
2603 return BT_STATUS_PARM_INVALID;
2606 return BT_STATUS_SUCCESS;
2609 bt_status_t _bt_hal_mesh_model_execute_message(
2610 bt_uuid_t *network, uint16_t dest,
2611 uint16_t appkey_idx, uint8_t *buf, int len)
2615 struct configuration_request *req;
2618 int src_elem_idx = 0;
2619 l = g_slist_find_custom(mesh_apps, network->uu,
2620 __mesh_compare_network_uuid);
2623 if (!__bt_mesh_proxy_check(app)) {
2624 ERR("Mesh: Proxy check failed!!");
2625 return BT_STATUS_FAIL;
2627 l1 = g_slist_find_custom(app->elements,
2628 GUINT_TO_POINTER(src_elem_idx),
2629 __compare_element_index);
2631 return BT_STATUS_FAIL;
2634 req = l_new(struct configuration_request, 1);
2635 req->ele_path = elem->path;
2637 req->idx = appkey_idx;
2641 req->is_dev_key = false;
2643 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2644 __bt_hal_mesh_model_execute_message,
2645 NULL, (void*)req, l_free))
2646 return BT_STATUS_FAIL;
2648 ERR("Mesh: app not found!!");
2649 return BT_STATUS_PARM_INVALID;
2652 return BT_STATUS_SUCCESS;