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 append_dict_entry_basic(struct l_dbus_message_builder *builder,
803 const char *key, const char *signature,
809 l_dbus_message_builder_enter_dict(builder, "sv");
810 l_dbus_message_builder_append_basic(builder, 's', key);
811 l_dbus_message_builder_enter_variant(builder, signature);
812 l_dbus_message_builder_append_basic(builder, signature[0], data);
813 l_dbus_message_builder_leave_variant(builder);
814 l_dbus_message_builder_leave_dict(builder);
817 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
820 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
821 meshcfg_model *model_info = (meshcfg_model*) data;
822 bool pub_enable = false;
823 bool sub_enable = false;
825 l_dbus_message_builder_enter_struct(builder, "qa{sv}");
826 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
827 l_dbus_message_builder_enter_array(builder, "{sv}");
828 append_dict_entry_basic(builder, "Subscribe", "b", &sub_enable);
829 append_dict_entry_basic(builder, "Publish", "b", &pub_enable);
830 l_dbus_message_builder_leave_array(builder);
831 l_dbus_message_builder_leave_struct(builder);
834 static bool __mesh_model_getter(struct l_dbus *dbus,
835 struct l_dbus_message *message,
836 struct l_dbus_message_builder *builder,
839 meshcfg_el *element = (meshcfg_el*) user_data;
841 l_dbus_message_builder_enter_array(builder, "(qa{sv})");
842 g_slist_foreach(element->models,
843 __bt_hal_mesh_foreach_model_getter, builder);
845 l_dbus_message_builder_leave_array(builder);
850 /*TODO: Vendor Model handling is currently not Handled */
851 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
852 struct l_dbus_message *message,
853 struct l_dbus_message_builder *builder,
856 l_dbus_message_builder_enter_array(builder, "(qqa{sv})");
857 l_dbus_message_builder_leave_array(builder);
862 static bool __mesh_element_index_getter(struct l_dbus *dbus,
863 struct l_dbus_message *message,
864 struct l_dbus_message_builder *builder,
867 meshcfg_el *element = (meshcfg_el*) user_data;
868 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
874 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
875 struct l_dbus_message *msg, void *user_data)
877 struct l_dbus_message_iter iter;
882 const char *dbus_path;
885 dbus_path = l_dbus_message_get_path(msg);
886 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
887 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
888 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
890 INFO("Mesh: app path [%s]", dbus_path);
892 memset(buf, 0, sizeof(buf));
893 size = (uint16_t) sizeof(*ev);
894 memcpy(ev->net_uuid, net_uuid, 16);
897 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
899 ERR("Mesh: Cannot parse received message");
900 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
903 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
904 ERR("Mesh: Cannot parse received message: data");
905 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
908 INFO("Mesh: Received dev key message (len %u):", n);
909 ev->source_addr = src;
910 ev->is_remote_devkey = rmt;
911 ev->netkey_idx = idx;
913 memcpy(ev->data, data, n);
916 INFO("Mesh: Src [0x%2.2x]", src);
917 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
918 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
919 /* Send DevKeyMessage Received event */
921 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
922 return l_dbus_message_new_method_return(msg);
925 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
926 struct l_dbus_message *msg, void *user_data)
928 struct l_dbus_message_iter iter;
929 uint16_t src, idx, dst;
932 const char *dbus_path;
935 dbus_path = l_dbus_message_get_path(msg);
936 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
937 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
938 struct hal_ev_mesh_message_event *ev = (void *)buf;
940 INFO("Mesh: app path [%s]", dbus_path);
942 memset(buf, 0, sizeof(buf));
943 size = (uint16_t) sizeof(*ev);
944 memcpy(ev->net_uuid, net_uuid, 16);
947 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
949 ERR("Mesh: Cannot parse received message");
950 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
953 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
954 ERR("Mesh: Cannot parse received message: data");
955 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
958 INFO("Mesh: Received mesh message (len %u):", n);
959 ev->source_addr = src;
963 memcpy(ev->data, data, n);
966 INFO("Mesh: Src [0x%2.2x]", src);
967 INFO("Mesh: Dst [0x%2.2x]", dst);
968 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
969 /* Send Message Received event */
971 INFO("Mesh: Send message event");
972 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
974 return l_dbus_message_new_method_return(msg);
977 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
979 INFO("Mesh: Setup element interface properties & methods");
981 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
983 l_dbus_interface_property(iface, "VendorModels", 0, "a(qqa{sv})",
984 __mesh_vendor_model_getter, NULL);
985 l_dbus_interface_property(iface, "Models", 0, "a(qa{sv})", __mesh_model_getter,
989 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
990 __mesh_device_message_received, "", "qbqay", "source",
991 "remote", "net_index", "data");
992 l_dbus_interface_method(iface, "MessageReceived", 0,
993 __mesh_message_received, "", "qqvay", "source",
994 "key_index", "destination", "data");
995 /* TODO: Other methods */
998 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
999 struct l_dbus_message *msg,
1002 struct l_dbus_message_iter iter, opts;
1003 meshcfg_app *app = (meshcfg_app*) user_data;
1008 const char *sig = "naya{sv}";
1010 /* Find network uuid from dbus path */
1011 struct hal_ev_mesh_scan_result ev;
1013 if (!app->scan_timer_id) {
1014 /* Scan is not running */
1015 INFO("Got scan result, but scan is already stopped");
1016 return l_dbus_message_new_method_return(msg);
1018 memset(&ev, 0, sizeof(ev));
1019 memcpy(ev.net_uuid, app->uuid, 16);
1021 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
1022 ERR("Mesh: Cannot parse scan results");
1023 ev.status = BT_STATUS_FAIL;
1025 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1026 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1029 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
1031 ERR("Mesh: Cannot parse scan result: data");
1032 ev.status = BT_STATUS_FAIL;
1034 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1035 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1038 INFO("Mesh: Scan result:\n");
1039 INFO("Mesh: Scan rssi = [%d]\n", rssi);
1040 str = l_util_hexstring_upper(prov_data, 16);
1041 INFO("Mesh: Scan UUID = [%s]\n", str);
1045 str = l_util_hexstring_upper(prov_data + 16, 2);
1046 INFO("Mesh: Scan OOB = [%s]\n", str);
1051 str = l_util_hexstring_upper(prov_data + 18, 4);
1052 INFO("Mesh: Scan URI hash = [%s]\n", str);
1056 /* 16 octet Dev UUID */
1057 memcpy(ev.dev_uuid, prov_data, 16);
1059 /* 2 octet Dev OOB Info */
1060 memcpy(ev.oob_info, prov_data + 16, 2);
1062 /* 4 octet URI Hash */
1063 memcpy(ev.uri_hash, prov_data + 18, 4);
1067 ev.status = BT_STATUS_SUCCESS;
1069 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1070 (void*)&ev, sizeof(ev));
1072 return l_dbus_message_new_method_return(msg);
1075 static struct l_dbus_message *__mesh_request_provisioner_call(
1076 struct l_dbus *dbus,
1077 struct l_dbus_message *msg,
1081 struct hal_ev_mesh_provision_finished ev;
1082 struct hal_ev_mesh_provision_data_request req;
1084 meshcfg_app *app = user_data;
1086 INFO("Mesh: provisioning data requested app path [%s]",
1088 uuid_string = l_util_hexstring(app->uuid, 16);
1089 INFO("Mesh: Network UUID [%s]", uuid_string);
1091 memset(&ev, 0, sizeof(ev));
1092 memset(&req, 0, sizeof(req));
1093 memcpy(ev.net_uuid, app->uuid, 16);
1094 memcpy(req.net_uuid, app->uuid, 16);
1095 l_free(uuid_string);
1097 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1098 ERR("Mesh: Cannot parse request for prov data");
1100 ev.status = BT_STATUS_FAIL;
1101 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1103 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1104 (void*)&ev, sizeof(ev));
1105 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1111 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1112 (void*)&req, sizeof(req));
1114 l_dbus_message_ref(msg);
1118 static struct l_dbus_message *__mesh_node_add_completed(
1119 struct l_dbus *dbus,
1120 struct l_dbus_message *msg,
1123 struct l_dbus_message_iter iter;
1128 struct hal_ev_mesh_provision_finished ev;
1129 const char *dbus_path;
1131 dbus_path = l_dbus_message_get_path(msg);
1132 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1133 true, MESH_PROV_IFACE);
1135 INFO("Mesh: app path [%s]", dbus_path);
1137 memset(&ev, 0, sizeof(ev));
1138 memcpy(ev.net_uuid, net_uuid, 16);
1142 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1143 ERR("Mesh: Cannot parse add node complete message");
1145 ev.status = BT_STATUS_FAIL;
1146 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1148 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1149 (void*)&ev, sizeof(ev));
1150 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1153 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1155 ERR("Mesh: Cannot parse add node complete message: uuid");
1157 ev.status = BT_STATUS_FAIL;
1158 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1160 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1161 (void*)&ev, sizeof(ev));
1162 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1166 ev.status = BT_STATUS_SUCCESS;
1167 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1168 memcpy(ev.dev_uuid, uuid, 16);
1169 ev.unicast = unicast;
1173 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1174 (void*)&ev, sizeof(ev));
1176 return l_dbus_message_new_method_return(msg);
1179 static struct l_dbus_message *__mesh_node_add_failed(
1180 struct l_dbus *dbus,
1181 struct l_dbus_message *msg,
1184 struct l_dbus_message_iter iter;
1188 struct hal_ev_mesh_provision_finished ev;
1189 const char *dbus_path;
1192 dbus_path = l_dbus_message_get_path(msg);
1193 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1194 true, MESH_PROV_IFACE);
1196 memset(&ev, 0, sizeof(ev));
1197 memcpy(ev.net_uuid, net_uuid, 16);
1200 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1201 ERR("Mesh: Cannot parse add node failed message");
1203 ev.status = BT_STATUS_FAIL;
1204 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1206 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1207 (void*)&ev, sizeof(ev));
1208 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1211 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1213 ERR("Mesh:Cannot parse add node failed message: uuid");
1214 ev.status = BT_STATUS_FAIL;
1215 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1217 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1218 (void*)&ev, sizeof(ev));
1219 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1222 INFO("Mesh: Provisioning failed:\n");
1223 str = l_util_hexstring_upper(uuid, 16);
1224 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1226 ev.status = BT_STATUS_FAIL;
1227 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1228 memcpy(ev.dev_uuid, uuid, 16);
1233 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1234 (void*)&ev, sizeof(ev));
1236 return l_dbus_message_new_method_return(msg);
1239 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1241 INFO("Mesh: Setup provisioner interface properties & methods");
1242 l_dbus_interface_method(interface, "ScanResult", 0,
1243 __mesh_scan_result_received, "",
1244 "naya{sv}", "rssi", "data", "options");
1246 l_dbus_interface_method(interface, "RequestProvData", 0,
1247 __mesh_request_provisioner_call,
1248 "qq", "y", "net_index", "unicast", "count");
1250 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1251 __mesh_node_add_completed, "", "ayqy",
1252 "uuid", "unicast", "count");
1254 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1255 __mesh_node_add_failed,
1256 "", "ays", "uuid", "reason");
1259 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1261 INFO("Mesh: Setup application interface properties & methods");
1263 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1264 __mesh_get_companyid,
1266 l_dbus_interface_property(iface, "VersionID", 0, "q",
1267 __mesh_get_versionid,
1269 l_dbus_interface_property(iface, "ProductID", 0, "q",
1270 __mesh_get_productid,
1272 l_dbus_interface_property(iface, "CRPL", 0, "q",
1273 __mesh_get_crpl, NULL);
1274 l_dbus_interface_method(iface, "JoinComplete", 0,
1275 __mesh_node_join_complete,
1281 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1282 struct l_dbus_message_builder *builder)
1284 if (app->in_oob & 0x08)
1285 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1286 if (app->in_oob & 0x04)
1287 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1288 if (app->in_oob & 0x02)
1289 l_dbus_message_builder_append_basic(builder, 's', "twist");
1290 if (app->in_oob & 0x01)
1291 l_dbus_message_builder_append_basic(builder, 's', "push");
1294 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1295 struct l_dbus_message_builder *builder)
1297 if (app->out_oob & 0x10)
1298 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1299 if (app->out_oob & 0x08)
1300 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1301 if (app->out_oob & 0x04)
1302 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1303 if (app->out_oob & 0x02)
1304 l_dbus_message_builder_append_basic(builder, 's', "beep");
1305 if (app->out_oob & 0x01)
1306 l_dbus_message_builder_append_basic(builder, 's', "blink");
1309 static bool __mesh_agent_capability_getter(
1310 struct l_dbus *dbus, struct l_dbus_message *message,
1311 struct l_dbus_message_builder *builder,
1316 INFO("Mesh: app path [%s]", app->path);
1317 INFO("Mesh: Agent path [%s]", app->agent_path);
1319 if (!l_dbus_message_builder_enter_array(builder, "s"))
1322 __mesh_fill_out_capabilities(app, builder);
1323 __mesh_fill_in_capabilities(app, builder);
1325 if (app->static_oob)
1326 l_dbus_message_builder_append_basic(builder,
1330 l_dbus_message_builder_leave_array(builder);
1331 INFO("Mesh: __agent_capability_getter: Success");
1335 static struct l_dbus_message *__mesh_agent_display_string_request(
1336 struct l_dbus *dbus,
1337 struct l_dbus_message *msg,
1340 struct hal_ev_mesh_authentication_request ev;
1343 const char *dbus_path;
1346 INFO("Mesh: app path [%s]", app->path);
1347 INFO("Mesh: Agent path [%s]", app->agent_path);
1349 dbus_path = l_dbus_message_get_path(msg);
1350 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1351 true, MESH_AGENT_IFACE);
1353 INFO("Mesh: app path [%s]", dbus_path);
1355 memset(&ev, 0, sizeof(ev));
1356 memcpy(ev.net_uuid, net_uuid, 16);
1359 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1360 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1361 struct hal_ev_mesh_provision_finished ev;
1362 memset(&ev, 0, sizeof(ev));
1363 memcpy(ev.net_uuid, net_uuid, 16);
1364 ev.status = BT_STATUS_FAIL;
1365 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1367 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1368 (void*)&ev, sizeof(ev));
1372 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1375 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1376 ev.auth_type = __mesh_get_authentication_type(str);
1377 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1378 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1379 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1382 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1383 (void*)&ev, sizeof(ev));
1386 return l_dbus_message_new_method_return(msg);
1389 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1390 struct l_dbus *dbus,
1391 struct l_dbus_message *msg,
1395 struct hal_ev_mesh_authentication_request ev;
1399 const char *dbus_path;
1402 INFO("Mesh: app path [%s]", app->path);
1403 INFO("Mesh: Agent path [%s]", app->agent_path);
1405 dbus_path = l_dbus_message_get_path(msg);
1406 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1407 true, MESH_AGENT_IFACE);
1409 INFO("Mesh: app path [%s]", dbus_path);
1411 memset(&ev, 0, sizeof(ev));
1412 memcpy(ev.net_uuid, net_uuid, 16);
1415 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1416 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1417 struct hal_ev_mesh_provision_finished ev;
1418 memset(&ev, 0, sizeof(ev));
1419 memcpy(ev.net_uuid, net_uuid, 16);
1420 ev.status = BT_STATUS_FAIL;
1421 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1422 if (mesh_event_cb) {
1423 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1424 (void*)&ev, sizeof(ev));
1427 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1430 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1431 auth_value = l_strdup_printf("%u", n);
1432 ev.auth_type = __mesh_get_authentication_type(str);
1433 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1434 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1435 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1438 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1439 (void*)&ev, sizeof(ev));
1443 return l_dbus_message_new_method_return(msg);
1446 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1447 struct l_dbus *dbus,
1448 struct l_dbus_message *msg,
1451 struct hal_ev_mesh_authentication_request ev;
1454 const char *dbus_path;
1458 dbus_path = l_dbus_message_get_path(msg);
1459 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1460 true, MESH_AGENT_IFACE);
1462 INFO("Mesh: app path [%s]", dbus_path);
1464 l = g_slist_find_custom(mesh_apps, net_uuid,
1465 __mesh_compare_network_uuid);
1472 memset(&ev, 0, sizeof(ev));
1473 memcpy(ev.net_uuid, net_uuid, 16);
1476 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1477 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1479 struct hal_ev_mesh_provision_finished ev;
1480 memset(&ev, 0, sizeof(ev));
1481 memcpy(ev.net_uuid, app->uuid, 16);
1482 ev.status = BT_STATUS_FAIL;
1483 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1484 if (mesh_event_cb) {
1485 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1486 (void*)&ev, sizeof(ev));
1488 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1491 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1493 ev.auth_type = __mesh_get_authentication_type(str);
1494 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1495 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1497 l_dbus_message_ref(msg);
1499 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1500 (void*)&ev, sizeof(ev));
1505 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1506 struct l_dbus *dbus,
1507 struct l_dbus_message *msg,
1510 struct hal_ev_mesh_authentication_request ev;
1513 const char *dbus_path;
1515 meshcfg_app *app = NULL;
1517 dbus_path = l_dbus_message_get_path(msg);
1518 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1521 INFO("Mesh: app path [%s]", dbus_path);
1523 l = g_slist_find_custom(mesh_apps, net_uuid,
1524 __mesh_compare_network_uuid);
1529 ERR("Mesh: app not found");
1532 memset(&ev, 0, sizeof(ev));
1533 memcpy(ev.net_uuid, net_uuid, 16);
1536 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1537 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1539 struct hal_ev_mesh_provision_finished ev;
1540 memset(&ev, 0, sizeof(ev));
1543 memcpy(ev.net_uuid, app->uuid, 16);
1545 ev.status = BT_STATUS_FAIL;
1546 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1548 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1549 (void*)&ev, sizeof(ev));
1550 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1553 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1555 ev.auth_type = __mesh_get_authentication_type(str);
1556 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1557 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1559 l_dbus_message_ref(msg);
1561 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1562 (void*)&ev, sizeof(ev));
1567 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1569 INFO("Mesh: Setup Agent interface properties & methods");
1570 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1571 __mesh_agent_capability_getter,
1573 /* TODO: Other properties */
1574 l_dbus_interface_method(interface, "DisplayString", 0,
1575 __mesh_agent_display_string_request,
1577 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1578 __mesh_agent_display_numeric_request,
1579 "", "su", "type", "number");
1580 l_dbus_interface_method(interface, "PromptNumeric", 0,
1581 __mesh_agent_prompt_numeric_request,
1582 "u", "s", "number", "type");
1583 l_dbus_interface_method(interface, "PromptStatic", 0,
1584 __mesh_agent_prompt_static_request,
1585 "ay", "s", "data", "type");
1588 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1590 meshcfg_el *elem = (meshcfg_el*) data;
1591 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1592 elem->index, elem->path);
1593 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1594 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1595 ERR("Mesh: Failed to register object %s", elem->path);
1599 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1604 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1605 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1606 ERR("Mesh: Unable to register agent interface");
1610 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1611 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1612 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1613 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1617 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1618 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1619 ERR("Mesh: Failed to add interface %s",
1620 L_DBUS_INTERFACE_PROPERTIES);
1627 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1635 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1636 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1637 ERR("Mesh: Failed to register interface %s",
1638 BT_HAL_MESH_APPLICATION_INTERFACE);
1642 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1643 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1644 ERR("Mesh: Failed to register interface %s",
1645 BT_HAL_MESH_PROVISIONER_INTERFACE);
1649 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1650 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1651 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1653 ERR("Mesh: Failed to register object %s", ptr->path);
1657 if (!__bt_hal_mesh_register_agent(ptr))
1660 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1661 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1662 ERR("Mesh: Failed to register interface %s",
1663 BT_HAL_MESH_ELEMENT_INTERFACE);
1667 INFO("Mesh: Number of elements to be registsred [%d]",
1668 g_slist_length(ptr->elements));
1670 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1672 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1673 if (!l_dbus_object_add_interface(dbus, ptr->path,
1674 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1675 ERR("Mesh: Failed to add interface %s",
1676 L_DBUS_INTERFACE_OBJECT_MANAGER);
1679 INFO("Mesh: Application Register completed");
1684 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1688 meshcfg_model *model_info = (meshcfg_model*) data;
1689 meshcfg_app *app = (meshcfg_app*) user_data;
1691 l = g_slist_find_custom(app->elements,
1692 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1696 elem = g_malloc0(sizeof(meshcfg_el));
1697 elem->index = model_info->elem_index;
1698 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1699 app->elements = g_slist_append(app->elements, elem);
1700 INFO("Mesh: Created element index [%d] path [%s]",
1701 elem->index, elem->path);
1703 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1704 model_info->model, elem->index);
1705 /* Add Model in the element */
1706 elem->models = g_slist_append(elem->models, model_info);
1707 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1708 elem->index, g_slist_length(elem->models));
1711 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1712 GSList *models, bool is_prov)
1715 meshcfg_app *app = NULL;
1716 char *uuid_str = NULL;
1718 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1719 INFO("Mesh: Network UUID [%s]", uuid_str);
1721 app = g_malloc0(sizeof(meshcfg_app));
1722 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1724 app->cid = node->vendor_info.companyid;
1725 app->pid = node->vendor_info.vendorid;
1726 app->vid = node->vendor_info.versionid;
1727 app->crpl = node->vendor_info.crpl;
1730 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1731 app->agent_path = g_strdup_printf("%s/agent", app->path);
1734 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1735 app->agent_path = g_strdup_printf("%s/agent", app->path);
1737 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1740 app->is_prov = is_prov;
1741 app->token.u64 = node->token.u64;
1742 INFO("Mesh: Token [%llu]", (unsigned long long int)app->token.u64);
1743 INFO("Mesh: app created");
1747 static void __bt_hal_mesh_leave_net_reply(
1748 struct l_dbus_proxy *proxy,
1749 struct l_dbus_message *msg, void *user_data)
1752 app = (meshcfg_app*) user_data;
1754 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1755 if (l_dbus_message_is_error(msg)) {
1758 l_dbus_message_get_error(msg, &name, NULL);
1759 ERR("Mesh: Failed to leave network: %s", name);
1761 /* Send Network Destroy fail event */
1762 __send_network_destroy_event(app, BT_STATUS_FAIL);
1764 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1768 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1771 meshcfg_app *app = (meshcfg_app*) user_data;
1773 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1774 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1777 static void __bt_hal_mesh_release_net_reply(
1778 struct l_dbus_proxy *proxy,
1779 struct l_dbus_message *msg, void *user_data)
1782 app = (meshcfg_app*) user_data;
1784 INFO("Mesh:Release Network Reply from Meshd: app path [%s]", app->path);
1785 if (l_dbus_message_is_error(msg)) {
1788 l_dbus_message_get_error(msg, &name, NULL);
1789 ERR("Mesh: Failed to Release network: %s", name);
1792 INFO("Mesh: Release Network: Success, cleanup app after proxy removed");
1796 static void __bt_hal_mesh_release_net_setup(struct l_dbus_message *msg,
1799 meshcfg_app *app = (meshcfg_app*) user_data;
1801 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1802 INFO("Mesh: Release Network Setup app path [%s]", app->path);
1805 static void __bt_hal_mesh_create_net_reply(
1806 struct l_dbus_proxy *proxy,
1807 struct l_dbus_message *msg, void *user_data)
1810 app = (meshcfg_app*) user_data;
1812 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1813 if (l_dbus_message_is_error(msg)) {
1816 l_dbus_message_get_error(msg, &name, NULL);
1817 ERR("Mesh: Failed to create network: %s", name);
1819 /* Send Network creation fail event */
1820 __send_network_attach_event(app, BT_STATUS_FAIL);
1822 /* Destroy mesh app object */
1823 __bt_hal_mesh_destroy_app_object(app);
1828 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1832 struct l_dbus_message_builder *builder;
1833 app = (meshcfg_app*) user_data;
1835 builder = l_dbus_message_builder_new(msg);
1837 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1838 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1839 __mesh_append_byte_array(builder, app->uuid, 16);
1840 l_dbus_message_builder_finalize(builder);
1841 l_dbus_message_builder_destroy(builder);
1844 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1846 struct hal_ev_mesh_scan_state_changed ev;
1848 memset(&ev, 0, sizeof(ev));
1849 memcpy(ev.net_uuid, app->uuid, 16);
1851 ev.status = BT_STATUS_SUCCESS;
1853 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1855 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1856 (void*)&ev, sizeof(ev));
1859 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1861 meshcfg_app *app = (meshcfg_app*) user_data;
1862 __mesh_trigger_scan_finished_event(app);
1866 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1870 l = g_slist_find_custom(mesh_apps, net_uuid,
1871 __mesh_compare_network_uuid);
1876 if (app->scan_timer_id > 0) {
1877 g_source_remove(app->scan_timer_id);
1878 app->scan_timer_id = 0;
1881 app->scan_timer_id = g_timeout_add_seconds(secs,
1882 __bt_mesh_scan_timer_cb, app);
1887 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1888 struct l_dbus_message *msg, void *user_data)
1890 struct hal_ev_mesh_scan_state_changed ev;
1891 const char *dbus_path;
1893 dbus_path = l_dbus_proxy_get_path(proxy);
1894 INFO("Mesh: DBUS path [%s]", dbus_path);
1895 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1897 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1898 INFO("Mesh: Scan duration [%u]", secs);
1900 memset(&ev, 0, sizeof(ev));
1901 memcpy(ev.net_uuid, net_uuid, 16);
1903 if (l_dbus_message_is_error(msg)) {
1905 l_dbus_message_get_error(msg, &name, NULL);
1906 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1907 ev.status = BT_STATUS_FAIL;
1909 INFO("Mesh: Unprovisioned scan started\n");
1910 ev.status = BT_STATUS_SUCCESS;
1911 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1914 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1916 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1917 (void*)&ev, sizeof(ev));
1921 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1923 struct l_dbus_message_builder *builder;
1924 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1925 INFO("Mesh: Scan duration [%u]", secs);
1927 builder = l_dbus_message_builder_new(msg);
1928 l_dbus_message_builder_enter_array(builder, "{sv}");
1929 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1930 l_dbus_message_builder_leave_array(builder);
1931 l_dbus_message_builder_finalize(builder);
1932 l_dbus_message_builder_destroy(builder);
1936 bt_status_t _bt_hal_mesh_network_set_caps(
1937 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1941 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1945 app->public_oob = caps->public_oob;
1946 app->static_oob = caps->static_oob;
1947 app->out_oob = caps->out_oob;
1948 app->in_oob = caps->in_oob;
1950 ERR("Mesh: app not found!!");
1951 return BT_STATUS_PARM_INVALID;
1954 return BT_STATUS_SUCCESS;
1957 static void __bt_hal_mesh_add_node_reply(
1958 struct l_dbus_proxy *proxy,
1959 struct l_dbus_message *msg,
1962 struct hal_ev_mesh_provision_status ev;
1963 const char *dbus_path;
1965 dbus_path = l_dbus_proxy_get_path(proxy);
1966 INFO("Mesh: DBUS path [%s]", dbus_path);
1967 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1969 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1971 INFO("Mesh: app path [%s]", dbus_path);
1973 memset(&ev, 0, sizeof(ev));
1974 memcpy(ev.net_uuid, net_uuid, 16);
1975 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1977 /* Free User data */
1978 g_free((void*)dev_uuid);
1981 if (l_dbus_message_is_error(msg)) {
1984 l_dbus_message_get_error(msg, &name, NULL);
1985 ERR("Mesh: Failed to start provisioning: %s", name);
1986 ev.status = BT_STATUS_FAIL;
1988 INFO("Mesh: Provisioning started\n");
1989 ev.status = BT_STATUS_SUCCESS;
1992 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1993 (void*)&ev, sizeof(ev));
1994 INFO("Mesh: Provisioning status sent");
1997 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
2001 bt_uuid_t *dev = user_data;
2002 struct l_dbus_message_builder *builder;
2004 uuid = l_util_hexstring(dev->uu, 16);
2008 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
2010 builder = l_dbus_message_builder_new(msg);
2011 __mesh_append_byte_array(builder, dev->uu, 16);
2012 l_dbus_message_builder_enter_array(builder, "{sv}");
2013 l_dbus_message_builder_leave_array(builder);
2014 l_dbus_message_builder_finalize(builder);
2015 l_dbus_message_builder_destroy(builder);
2020 bt_status_t _bt_hal_mesh_provision_device(
2021 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
2026 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2029 dev = g_memdup((gpointer)dev_uuid, 16);
2030 INFO("Mesh: Schedule Add Node request to meshd");
2031 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
2032 __bt_hal_mesh_add_node_setup,
2033 __bt_hal_mesh_add_node_reply,
2035 return BT_STATUS_FAIL;
2037 ERR("Mesh: app not found!!");
2038 return BT_STATUS_PARM_INVALID;
2041 return BT_STATUS_SUCCESS;
2044 static void __bt_hal_mesh_subnet_key_setup(
2045 struct l_dbus_message *msg, void *user_data)
2047 struct subnet_key_request *req = user_data;
2048 uint16_t idx = (uint16_t) req->idx;
2050 l_dbus_message_set_arguments(msg, "q", idx);
2053 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
2054 struct l_dbus_message *msg, void *user_data)
2056 struct hal_ev_mesh_netkey_execute_event ev;
2057 const char *dbus_path;
2059 struct subnet_key_request *req = user_data;
2060 const char *method = req->str;
2062 dbus_path = l_dbus_proxy_get_path(proxy);
2063 INFO("Mesh: DBUS path [%s]", dbus_path);
2064 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2066 memset(&ev, 0, sizeof(ev));
2067 memcpy(ev.net_uuid, net_uuid, 16);
2068 ev.key_idx = req->idx;
2072 if (l_dbus_message_is_error(msg)) {
2075 l_dbus_message_get_error(msg, &name, NULL);
2076 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
2077 ev.status = BT_STATUS_FAIL;
2080 ev.status = BT_STATUS_SUCCESS;
2082 if (!strcmp("CreateSubnet", method)) {
2083 INFO("Mesh: Reply for CreateSubnet");
2084 ev.key_event = HAL_MESH_KEY_ADD;
2085 } else if (!strcmp("DeleteSubnet", method)) {
2086 INFO("Mesh: Reply for DeleteSubnet");
2087 ev.key_event = HAL_MESH_KEY_DELETE;
2088 } else if (!strcmp("UpdateSubnet", method)) {
2089 INFO("Mesh: Reply for UpdateSubnet");
2090 ev.key_event = HAL_MESH_KEY_UPDATE;
2094 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2095 (void*)&ev, sizeof(ev));
2098 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2099 uint16_t index, const char *key_execute_method)
2101 struct subnet_key_request *req;
2103 req = l_new(struct subnet_key_request, 1);
2104 req->str = key_execute_method;
2107 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2108 __bt_hal_mesh_subnet_key_setup,
2109 __bt_hal_mesh_subnet_key_reply,
2116 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2119 struct app_key_request *req = user_data;
2120 uint16_t net_idx = (uint16_t) req->net_idx;
2121 uint16_t app_idx = (uint16_t) req->app_idx;
2123 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2124 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2126 l_dbus_message_set_arguments(msg, "q", app_idx);
2129 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2130 struct l_dbus_message *msg, void *user_data)
2132 struct hal_ev_mesh_appkey_execute_event ev;
2133 const char *dbus_path;
2135 struct app_key_request *req = user_data;
2136 const char *method = req->str;
2138 dbus_path = l_dbus_proxy_get_path(proxy);
2139 INFO("Mesh: DBUS path [%s]", dbus_path);
2140 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2142 memset(&ev, 0, sizeof(ev));
2143 memcpy(ev.net_uuid, net_uuid, 16);
2144 ev.net_idx = req->net_idx;
2145 ev.app_idx = req->app_idx;
2149 if (l_dbus_message_is_error(msg)) {
2152 l_dbus_message_get_error(msg, &name, NULL);
2153 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2154 ev.status = BT_STATUS_FAIL;
2156 ev.status = BT_STATUS_SUCCESS;
2158 if (!strcmp("CreateAppKey", method)) {
2159 INFO("Mesh: AppKey Create Reply");
2160 ev.key_event = HAL_MESH_KEY_ADD;
2161 } else if (!strcmp("DeleteAppKey", method)) {
2162 INFO("Mesh: AppKey Delete Reply");
2163 ev.key_event = HAL_MESH_KEY_DELETE;
2164 } else if (!strcmp("UpdateAppKey", method)) {
2165 INFO("Mesh: AppKey Update Reply");
2166 ev.key_event = HAL_MESH_KEY_UPDATE;
2170 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2173 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2174 uint16_t net_idx, uint16_t app_idx,
2175 const char *key_execute_method)
2177 struct app_key_request *req;
2179 req = l_new(struct app_key_request, 1);
2180 req->str = key_execute_method;
2181 req->net_idx = net_idx;
2182 req->app_idx = app_idx;
2184 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2185 __bt_hal_mesh_app_key_setup,
2186 __bt_hal_mesh_app_key_reply,
2193 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2194 bt_mesh_key_op_e op, uint16_t netkey_idx)
2199 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2203 if (op == BT_MESH_KEY_CREATE)
2204 status = __mesh_subnet_netkey_command_execute(app,
2205 netkey_idx, "CreateSubnet");
2206 else if (op == BT_MESH_KEY_DELETE)
2207 status = __mesh_subnet_netkey_command_execute(app,
2208 netkey_idx, "DeleteSubnet");
2209 else if (op == BT_MESH_KEY_UPDATE)
2210 status = __mesh_subnet_netkey_command_execute(app,
2211 netkey_idx, "UpdateSubnet");
2213 return BT_STATUS_FAIL;
2216 ERR("Mesh: app not found!!");
2217 return BT_STATUS_PARM_INVALID;
2220 return BT_STATUS_SUCCESS;
2223 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2224 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2229 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2233 if (op == BT_MESH_KEY_CREATE)
2234 status = __mesh_subnet_appkey_command_execute(app,
2235 netkey_idx, appkey_idx, "CreateAppKey");
2236 else if (op == BT_MESH_KEY_DELETE)
2237 status = __mesh_subnet_appkey_command_execute(app,
2238 netkey_idx, appkey_idx, "DeleteAppKey");
2239 else if (op == BT_MESH_KEY_UPDATE) {
2240 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2241 netkey_idx, appkey_idx);
2242 status = __mesh_subnet_appkey_command_execute(app,
2243 netkey_idx, appkey_idx, "UpdateAppKey");
2246 return BT_STATUS_FAIL;
2249 ERR("Mesh: app not found!!");
2250 return BT_STATUS_PARM_INVALID;
2253 return BT_STATUS_SUCCESS;
2256 bt_status_t _bt_hal_mesh_send_provision_data(
2257 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2261 struct l_dbus_message *msg;
2262 struct l_dbus_message *reply;
2264 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2269 reply = l_dbus_message_new_method_return(msg);
2270 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2271 l_dbus_send(dbus, reply);
2273 ERR("Mesh: app not found!!");
2274 return BT_STATUS_PARM_INVALID;
2276 return BT_STATUS_SUCCESS;
2279 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2283 l = g_slist_find_custom(mesh_apps,
2284 net_uuid->uu, __mesh_compare_network_uuid);
2287 if (!__bt_mesh_proxy_check(app)) {
2288 ERR("Mesh: Proxy check failed!!");
2289 return BT_STATUS_FAIL;
2291 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2292 "UnprovisionedScanCancel",
2293 NULL, NULL, NULL, NULL))
2294 return BT_STATUS_FAIL;
2296 ERR("Mesh: app not found!!");
2297 return BT_STATUS_PARM_INVALID;
2300 /* Stop Scan timer */
2301 if (app->scan_timer_id > 0) {
2302 g_source_remove(app->scan_timer_id);
2303 app->scan_timer_id = 0;
2306 /* Trigger Scan finished event */
2307 __mesh_trigger_scan_finished_event(app);
2309 return BT_STATUS_SUCCESS;
2312 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2313 const char *auth_value)
2316 struct l_dbus_message *reply = NULL;
2317 struct l_dbus_message_builder *builder;
2319 bt_status_t ret = BT_STATUS_SUCCESS;
2323 if (!__bt_mesh_proxy_check(0)) {
2324 ERR("Mesh: Proxy check failed!!");
2325 return BT_STATUS_FAIL;
2327 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2328 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2329 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2330 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2331 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2332 INFO("Mesh: Authentication reply: Numeric Type");
2333 val_u32 = atoi(auth_value);
2334 reply = l_dbus_message_new_method_return(agent_msg);
2335 l_dbus_message_set_arguments(reply, "u", val_u32);
2337 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2338 l_dbus_send(dbus, reply);
2339 ret = BT_STATUS_SUCCESS;
2340 /* For Alpha-Numeric */
2341 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2342 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2343 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2344 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2345 alpha = l_util_from_hexstring(auth_value, &sz);
2346 reply = l_dbus_message_new_method_return(agent_msg);
2347 builder = l_dbus_message_builder_new(reply);
2348 __mesh_append_byte_array(builder, alpha, 16);
2349 l_dbus_message_builder_finalize(builder);
2350 l_dbus_message_builder_destroy(builder);
2353 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2354 l_dbus_send(dbus, reply);
2355 ret = BT_STATUS_SUCCESS;
2360 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2361 bt_hal_mesh_scan_param_t *param)
2365 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2368 if (!__bt_mesh_proxy_check(app)) {
2369 ERR("Mesh: Proxy check failed!!");
2370 return BT_STATUS_FAIL;
2372 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2373 __mesh_scan_setup, __mesh_scan_reply,
2374 L_UINT_TO_PTR(param->scan_time), NULL))
2375 return BT_STATUS_FAIL;
2377 ERR("Mesh: app not found!!");
2378 return BT_STATUS_PARM_INVALID;
2380 return BT_STATUS_SUCCESS;
2383 static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
2386 struct mesh_remote_node_info *node_info = \
2387 (struct mesh_remote_node_info*) user_data;
2389 l_dbus_message_set_arguments(msg, "qy",
2390 node_info->unicast, node_info->num_elements);
2391 INFO("Mesh: Delete Remote Node Setup params passed");
2394 static void __bt_hal_mesh_delete_node_reply(
2395 struct l_dbus_proxy *proxy,
2396 struct l_dbus_message *msg, void *user_data)
2398 INFO("Mesh: Delete Remote Node Reply from DBUS");
2401 bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
2402 uint16_t unicast, uint16_t num_elements)
2406 struct mesh_remote_node_info *node_info;
2407 INFO("Mesh: Delete Remote Node");
2408 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2411 if (!__bt_mesh_proxy_check(app)) {
2412 ERR("Mesh: Proxy check failed!!");
2413 return BT_STATUS_FAIL;
2415 INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
2416 unicast, num_elements);
2418 /* Delete Remote Node Request */
2419 node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
2420 node_info->unicast = unicast;
2421 node_info->num_elements = num_elements;
2423 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
2424 __bt_hal_mesh_delete_node_setup,
2425 __bt_hal_mesh_delete_node_reply, node_info,
2427 ERR("Mesh: Delete Remote Node Request failed!!");
2429 return BT_STATUS_FAIL;
2432 ERR("Mesh: App not found!!");
2433 return BT_STATUS_PARM_INVALID;
2435 INFO("Mesh: Delete Remote Node Call issued successfully!!");
2436 return BT_STATUS_SUCCESS;
2439 bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid)
2443 INFO("Mesh: Release Network");
2444 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2447 if (!__bt_mesh_proxy_check(app)) {
2448 ERR("Mesh: Proxy check failed!!");
2449 return BT_STATUS_FAIL;
2451 INFO("Mesh: Release Network");
2452 /* Create CFG Network */
2453 if (!l_dbus_proxy_method_call(net_proxy, "Release",
2454 __bt_hal_mesh_release_net_setup,
2455 __bt_hal_mesh_release_net_reply, app,
2457 ERR("Mesh: Network Release failed!!");
2458 return BT_STATUS_FAIL;
2461 ERR("Mesh: App not found!!");
2462 return BT_STATUS_PARM_INVALID;
2464 INFO("Mesh: Network Release Call issued successfully!!");
2465 return BT_STATUS_SUCCESS;
2468 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2472 INFO("Mesh: Destroy network");
2473 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2476 if (!__bt_mesh_proxy_check(app)) {
2477 ERR("Mesh: Proxy check failed!!");
2478 return BT_STATUS_FAIL;
2480 INFO("Mesh: Destroy Network");
2481 /* Create CFG Network */
2482 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2483 __bt_hal_mesh_leave_net_setup,
2484 __bt_hal_mesh_leave_net_reply, app,
2486 ERR("Mesh: Network Leave failed!!");
2487 return BT_STATUS_FAIL;
2490 ERR("Mesh: App not found!!");
2491 return BT_STATUS_PARM_INVALID;
2493 INFO("Mesh: Network Leave Call issued successfully!!");
2494 return BT_STATUS_SUCCESS;
2497 bt_status_t _bt_hal_mesh_create_network(
2498 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2502 INFO("Mesh: Create Network Request");
2504 if (!__bt_mesh_proxy_check(0)) {
2505 ERR("Mesh: Proxy check failed!!");
2506 return BT_STATUS_FAIL;
2509 INFO("Mesh: Node Element count [%d]", node->num_elements);
2510 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2511 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2512 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2513 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2514 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2515 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2516 INFO("Mesh: Token [%llu]", (unsigned long long int)node->token.u64);
2517 /* Create DBUS APP */
2518 app = __bt_hal_mesh_create_app(node, models, is_prov);
2520 return BT_STATUS_FAIL;
2522 /* Register DBUS APP */
2523 if (!__bt_hal_mesh_register_application(app))
2526 if (app->token.u64 == 0) {
2527 INFO("Mesh: Create New Network");
2528 /* Create CFG Network */
2529 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2530 __bt_hal_mesh_create_net_setup,
2531 __bt_hal_mesh_create_net_reply, app,
2533 ERR("Mesh: Network Create failed!!");
2537 INFO("Mesh: Attach Node to Network: Token [%llu]", (unsigned long long int)app->token.u64);
2538 /* Attach to Network */
2539 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2540 __bt_hal_mesh_attach_node_setup,
2541 __bt_hal_mesh_attach_node_reply,
2544 ERR("Mesh: Node attach failed!!");
2549 INFO("Mesh: Node registration request scheudled");
2550 mesh_apps = g_slist_append(mesh_apps, app);
2551 INFO("Mesh: Total number of apps in list [%d]",
2552 g_slist_length(mesh_apps));
2553 return BT_STATUS_SUCCESS;
2555 ERR("Mesh: network can not be created!!");
2556 __bt_hal_mesh_destroy_app_object(app);
2557 return BT_STATUS_FAIL;
2560 static void __bt_hal_mesh_config_send(
2561 struct l_dbus_message *msg, void *user_data)
2563 struct configuration_request *req = user_data;
2564 struct l_dbus_message_builder *builder;
2566 builder = l_dbus_message_builder_new(msg);
2568 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2569 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2570 if (req->is_dev_key)
2571 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2573 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2574 __mesh_append_byte_array(builder, req->data, req->len);
2575 l_dbus_message_builder_finalize(builder);
2576 l_dbus_message_builder_destroy(builder);
2579 static void __bt_hal_mesh_key_config_send(
2580 struct l_dbus_message *msg, void *user_data)
2582 struct key_config_request *req = user_data;
2583 struct l_dbus_message_builder *builder;
2585 builder = l_dbus_message_builder_new(msg);
2587 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2588 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2589 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2590 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2591 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2592 l_dbus_message_builder_finalize(builder);
2593 l_dbus_message_builder_destroy(builder);
2596 static void __bt_hal_mesh_model_execute_message(
2597 struct l_dbus_message *msg, void *user_data)
2599 struct configuration_request *req = user_data;
2600 struct l_dbus_message_builder *builder;
2602 builder = l_dbus_message_builder_new(msg);
2604 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2605 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2606 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2607 __mesh_append_byte_array(builder, req->data, req->len);
2608 l_dbus_message_builder_finalize(builder);
2609 l_dbus_message_builder_destroy(builder);
2612 bt_status_t _bt_hal_mesh_send_key_config_message(
2613 bt_uuid_t *network, uint16_t dest,
2614 bool is_netkey, bool is_update,
2615 uint16_t key_idx, uint16_t netkey_idx)
2619 struct key_config_request *req;
2622 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2623 /* Source is Config Client Local Node */
2624 int src_elem_idx = 0;
2625 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2628 if (!__bt_mesh_proxy_check(app)) {
2629 ERR("Mesh: Proxy check failed!!");
2630 return BT_STATUS_FAIL;
2632 l1 = g_slist_find_custom(app->elements,
2633 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2635 return BT_STATUS_FAIL;
2638 req = l_new(struct key_config_request, 1);
2639 req->ele_path = elem->path;
2641 req->key_req_idx = key_idx;
2642 req->idx = netkey_idx; /* Encryption Key index */
2643 req->update_req = is_update;
2645 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2646 __bt_hal_mesh_key_config_send, NULL,
2647 (void*)req, l_free))
2648 return BT_STATUS_FAIL;
2650 ERR("Mesh: app not found!!");
2651 return BT_STATUS_PARM_INVALID;
2654 return BT_STATUS_SUCCESS;
2657 bt_status_t _bt_hal_mesh_send_configuration_message(
2658 bt_uuid_t *network, uint16_t dest,
2659 bool is_dev_key, uint16_t netkey_idx,
2660 uint8_t *buf, int len)
2664 struct configuration_request *req;
2667 int src_elem_idx = 0;
2668 l = g_slist_find_custom(mesh_apps, network->uu,
2669 __mesh_compare_network_uuid);
2672 if (!__bt_mesh_proxy_check(app)) {
2673 ERR("Mesh: Proxy check failed!!");
2674 return BT_STATUS_FAIL;
2676 l1 = g_slist_find_custom(app->elements,
2677 GUINT_TO_POINTER(src_elem_idx),
2678 __compare_element_index);
2680 return BT_STATUS_FAIL;
2683 req = l_new(struct configuration_request, 1);
2684 req->ele_path = elem->path;
2686 req->idx = netkey_idx;
2690 req->is_dev_key = is_dev_key;
2692 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2693 __bt_hal_mesh_config_send, NULL,
2694 (void*)req, l_free))
2695 return BT_STATUS_FAIL;
2697 ERR("Mesh: app not found!!");
2698 return BT_STATUS_PARM_INVALID;
2701 return BT_STATUS_SUCCESS;
2704 bt_status_t _bt_hal_mesh_model_execute_message(
2705 bt_uuid_t *network, uint16_t dest,
2706 uint16_t appkey_idx, uint8_t *buf, int len)
2710 struct configuration_request *req;
2713 int src_elem_idx = 0;
2714 l = g_slist_find_custom(mesh_apps, network->uu,
2715 __mesh_compare_network_uuid);
2718 if (!__bt_mesh_proxy_check(app)) {
2719 ERR("Mesh: Proxy check failed!!");
2720 return BT_STATUS_FAIL;
2722 l1 = g_slist_find_custom(app->elements,
2723 GUINT_TO_POINTER(src_elem_idx),
2724 __compare_element_index);
2726 return BT_STATUS_FAIL;
2729 req = l_new(struct configuration_request, 1);
2730 req->ele_path = elem->path;
2732 req->idx = appkey_idx;
2736 req->is_dev_key = false;
2738 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2739 __bt_hal_mesh_model_execute_message,
2740 NULL, (void*)req, l_free))
2741 return BT_STATUS_FAIL;
2743 ERR("Mesh: app not found!!");
2744 return BT_STATUS_PARM_INVALID;
2747 return BT_STATUS_SUCCESS;