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;
66 static uint32_t iv_index;
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_property_changed(struct l_dbus_proxy *proxy, const char *name,
550 struct l_dbus_message *msg, void *user_data)
552 const char *interface = l_dbus_proxy_get_interface(proxy);
553 const char *path = l_dbus_proxy_get_path(proxy);
555 meshcfg_app *app = NULL;
557 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
561 ERR("Mesh: app not found for Mgmt proxy");
564 INFO("Property changed: %s %s %s\n", name, path, interface);
569 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
571 if (!strcmp(name, "IvIndex")) {
574 if (!l_dbus_message_get_arguments(msg, "u", &ivi))
577 INFO("New IV Index: %u\n", ivi);
580 /*TODO: save iv index */
586 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
589 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
593 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
594 bool queued, void *user_data)
596 if (success == false)
597 ERR("Mesh: Fail to acquire dbus name\n");
599 if (!l_dbus_object_manager_enable(dbus_obj, "/"))
600 ERR("Mesh: Failed to register the ObjectManager\n");
603 static void __mesh_ready_callback(void *user_data)
605 INFO("Mesh: Connected to D-Bus\n");
607 if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
608 __mesh_acquire_name_callback, NULL))
609 ERR("Mesh: Failed to own well-known name\n");
612 bool _bt_hal_mesh_stack_init(void)
614 INFO("Mesh: Connect with meshd");
615 /* Connect with meshd */
616 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
620 INFO("Mesh: Got dbus [%p]", dbus);
622 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
625 client = l_dbus_client_new(dbus,
626 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
630 if (!l_dbus_client_set_connect_handler(client,
631 __mesh_client_connected, NULL, NULL))
634 if (!l_dbus_client_set_disconnect_handler(client,
635 __mesh_client_disconnected, NULL,
638 if (!l_dbus_client_set_proxy_handlers(client,
639 __mesh_proxy_added, __mesh_proxy_removed,
640 __mesh_property_changed, NULL, NULL))
642 if (!l_dbus_client_set_ready_handler(client,
643 __mesh_dbus_client_ready, NULL, NULL))
646 INFO("Mesh: Stack Init watchers registered with meshd");
650 void _bt_hal_mesh_stack_deinit(void)
652 INFO("Mesh: Stack Deinit");
655 l_dbus_client_destroy(client);
660 l_dbus_destroy(dbus);
667 INFO("Mesh: Number of meshapps present in memory [%d]",
668 g_slist_length(mesh_apps));
671 /* To send stack event to hal-mesh handler */
672 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
677 /* To send stack event to hal-mesh handler */
678 void _bt_hal_mesh_unregister_dbus_handler_cb()
680 mesh_event_cb = NULL;
683 static bool __mesh_get_companyid(struct l_dbus *dbus,
684 struct l_dbus_message *message,
685 struct l_dbus_message_builder *builder,
688 meshcfg_app *app = (meshcfg_app*) user_data;
692 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
697 static bool __mesh_get_productid(struct l_dbus *dbus,
698 struct l_dbus_message *message,
699 struct l_dbus_message_builder *builder,
702 meshcfg_app *app = (meshcfg_app*) user_data;
705 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
710 static bool __mesh_get_versionid(struct l_dbus *dbus,
711 struct l_dbus_message *message,
712 struct l_dbus_message_builder *builder,
715 meshcfg_app *app = (meshcfg_app*) user_data;
718 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
723 static bool __mesh_get_crpl(struct l_dbus *dbus,
724 struct l_dbus_message *message,
725 struct l_dbus_message_builder *builder,
728 meshcfg_app *app = (meshcfg_app*) user_data;
731 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
736 static void __send_network_attach_event(void *param, uint8_t status)
738 struct hal_ev_mesh_network_attached ev;
739 meshcfg_app *app = (meshcfg_app*)param;
741 memset(&ev, 0, sizeof(ev));
742 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
743 memcpy(ev.token, app->token.u8, 8);
747 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
748 (void*)&ev, sizeof(ev));
751 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
752 struct l_dbus_message *msg, void *user_data)
754 struct l_dbus_message_iter iter_cfg;
756 meshcfg_app *app = (meshcfg_app*) user_data;
759 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
760 app->path, app->agent_path);
762 if (l_dbus_message_is_error(msg)) {
764 l_dbus_message_get_error(msg, &name, NULL);
765 ERR("Mesh: Failed to attach node: %s", name);
770 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
774 INFO("Mesh: Attached with path %s\n", app->path);
775 __send_network_attach_event(app, BT_STATUS_SUCCESS);
777 if (l_dbus_proxy_get_property(app->proxy, "IvIndex", "u", &ivi) &&
780 /* TODO: Save IV index */
785 __send_network_attach_event(app, BT_STATUS_FAIL);
786 /* Destroy mesh app object */
787 __bt_hal_mesh_destroy_app_object(app);
790 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
793 meshcfg_app *app = (meshcfg_app*) user_data;
795 l_dbus_message_set_arguments(msg, "ot", app->path,
796 l_get_be64(app->token.u8));
800 static void __bt_hal_mesh_attach_node(void *user_data)
802 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
803 __bt_hal_mesh_attach_node_setup,
804 __bt_hal_mesh_attach_node_reply,
807 ERR("Mesh: Node attach failed!!");
808 /* Node could not be attached */
809 __send_network_attach_event(user_data, BT_STATUS_FAIL);
810 /* Destroy mesh app object */
811 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
815 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
816 struct l_dbus_message *message,
822 meshcfg_app *app = (meshcfg_app*) user_data;
823 INFO("Mesh: Join Complete");
826 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
828 /* Send Network creation fail event */
829 __send_network_attach_event(app, BT_STATUS_FAIL);
831 /* Destroy mesh app object */
832 __bt_hal_mesh_destroy_app_object(app);
834 return l_dbus_message_new_error(message, dbus_err_args, NULL);
838 app->token.u64 = l_get_be64(&tmp);
839 str = l_util_hexstring(&app->token.u8[0], 8);
840 INFO("Mesh: Created new node with token %s\n", str);
843 /* Authenticate the node */
844 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
845 return l_dbus_message_new_method_return(message);
848 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
849 const char *key, const char *signature,
855 l_dbus_message_builder_enter_dict(builder, "sv");
856 l_dbus_message_builder_append_basic(builder, 's', key);
857 l_dbus_message_builder_enter_variant(builder, signature);
858 l_dbus_message_builder_append_basic(builder, signature[0], data);
859 l_dbus_message_builder_leave_variant(builder);
860 l_dbus_message_builder_leave_dict(builder);
863 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
866 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
867 meshcfg_model *model_info = (meshcfg_model*) data;
868 bool pub_enable = false;
869 bool sub_enable = false;
871 l_dbus_message_builder_enter_struct(builder, "qa{sv}");
872 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
873 l_dbus_message_builder_enter_array(builder, "{sv}");
874 append_dict_entry_basic(builder, "Subscribe", "b", &sub_enable);
875 append_dict_entry_basic(builder, "Publish", "b", &pub_enable);
876 l_dbus_message_builder_leave_array(builder);
877 l_dbus_message_builder_leave_struct(builder);
880 static bool __mesh_model_getter(struct l_dbus *dbus,
881 struct l_dbus_message *message,
882 struct l_dbus_message_builder *builder,
885 meshcfg_el *element = (meshcfg_el*) user_data;
887 l_dbus_message_builder_enter_array(builder, "(qa{sv})");
888 g_slist_foreach(element->models,
889 __bt_hal_mesh_foreach_model_getter, builder);
891 l_dbus_message_builder_leave_array(builder);
896 /*TODO: Vendor Model handling is currently not Handled */
897 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
898 struct l_dbus_message *message,
899 struct l_dbus_message_builder *builder,
902 l_dbus_message_builder_enter_array(builder, "(qqa{sv})");
903 l_dbus_message_builder_leave_array(builder);
908 static bool __mesh_element_index_getter(struct l_dbus *dbus,
909 struct l_dbus_message *message,
910 struct l_dbus_message_builder *builder,
913 meshcfg_el *element = (meshcfg_el*) user_data;
914 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
920 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
921 struct l_dbus_message *msg, void *user_data)
923 struct l_dbus_message_iter iter;
928 const char *dbus_path;
931 dbus_path = l_dbus_message_get_path(msg);
932 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
933 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
934 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
936 INFO("Mesh: app path [%s]", dbus_path);
938 memset(buf, 0, sizeof(buf));
939 size = (uint16_t) sizeof(*ev);
940 memcpy(ev->net_uuid, net_uuid, 16);
943 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
945 ERR("Mesh: Cannot parse received message");
946 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
949 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
950 ERR("Mesh: Cannot parse received message: data");
951 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
954 INFO("Mesh: Received dev key message (len %u):", n);
955 ev->source_addr = src;
956 ev->is_remote_devkey = rmt;
957 ev->netkey_idx = idx;
959 memcpy(ev->data, data, n);
962 INFO("Mesh: Src [0x%2.2x]", src);
963 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
964 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
965 /* Send DevKeyMessage Received event */
967 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
968 return l_dbus_message_new_method_return(msg);
971 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
972 struct l_dbus_message *msg, void *user_data)
974 struct l_dbus_message_iter iter;
975 uint16_t src, idx, dst;
978 const char *dbus_path;
981 dbus_path = l_dbus_message_get_path(msg);
982 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
983 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
984 struct hal_ev_mesh_message_event *ev = (void *)buf;
986 INFO("Mesh: app path [%s]", dbus_path);
988 memset(buf, 0, sizeof(buf));
989 size = (uint16_t) sizeof(*ev);
990 memcpy(ev->net_uuid, net_uuid, 16);
993 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
995 ERR("Mesh: Cannot parse received message");
996 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
999 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
1000 ERR("Mesh: Cannot parse received message: data");
1001 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1004 INFO("Mesh: Received mesh message (len %u):", n);
1005 ev->source_addr = src;
1006 ev->dest_addr = dst;
1009 memcpy(ev->data, data, n);
1012 INFO("Mesh: Src [0x%2.2x]", src);
1013 INFO("Mesh: Dst [0x%2.2x]", dst);
1014 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
1015 /* Send Message Received event */
1016 if (mesh_event_cb) {
1017 INFO("Mesh: Send message event");
1018 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
1020 return l_dbus_message_new_method_return(msg);
1023 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
1025 INFO("Mesh: Setup element interface properties & methods");
1027 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
1029 l_dbus_interface_property(iface, "VendorModels", 0, "a(qqa{sv})",
1030 __mesh_vendor_model_getter, NULL);
1031 l_dbus_interface_property(iface, "Models", 0, "a(qa{sv})", __mesh_model_getter,
1035 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
1036 __mesh_device_message_received, "", "qbqay", "source",
1037 "remote", "net_index", "data");
1038 l_dbus_interface_method(iface, "MessageReceived", 0,
1039 __mesh_message_received, "", "qqvay", "source",
1040 "key_index", "destination", "data");
1041 /* TODO: Other methods */
1044 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
1045 struct l_dbus_message *msg,
1048 struct l_dbus_message_iter iter, opts;
1049 meshcfg_app *app = (meshcfg_app*) user_data;
1054 const char *sig = "naya{sv}";
1056 /* Find network uuid from dbus path */
1057 struct hal_ev_mesh_scan_result ev;
1059 if (!app->scan_timer_id) {
1060 /* Scan is not running */
1061 INFO("Got scan result, but scan is already stopped");
1062 return l_dbus_message_new_method_return(msg);
1064 memset(&ev, 0, sizeof(ev));
1065 memcpy(ev.net_uuid, app->uuid, 16);
1067 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
1068 ERR("Mesh: Cannot parse scan results");
1069 ev.status = BT_STATUS_FAIL;
1071 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1072 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1075 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
1077 ERR("Mesh: Cannot parse scan result: data");
1078 ev.status = BT_STATUS_FAIL;
1080 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1081 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1084 INFO("Mesh: Scan result:\n");
1085 INFO("Mesh: Scan rssi = [%d]\n", rssi);
1086 str = l_util_hexstring_upper(prov_data, 16);
1087 INFO("Mesh: Scan UUID = [%s]\n", str);
1091 str = l_util_hexstring_upper(prov_data + 16, 2);
1092 INFO("Mesh: Scan OOB = [%s]\n", str);
1097 str = l_util_hexstring_upper(prov_data + 18, 4);
1098 INFO("Mesh: Scan URI hash = [%s]\n", str);
1102 /* 16 octet Dev UUID */
1103 memcpy(ev.dev_uuid, prov_data, 16);
1105 /* 2 octet Dev OOB Info */
1106 memcpy(ev.oob_info, prov_data + 16, 2);
1108 /* 4 octet URI Hash */
1109 memcpy(ev.uri_hash, prov_data + 18, 4);
1113 ev.status = BT_STATUS_SUCCESS;
1115 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1116 (void*)&ev, sizeof(ev));
1118 return l_dbus_message_new_method_return(msg);
1121 static struct l_dbus_message *__mesh_request_provisioner_call(
1122 struct l_dbus *dbus,
1123 struct l_dbus_message *msg,
1127 struct hal_ev_mesh_provision_finished ev;
1128 struct hal_ev_mesh_provision_data_request req;
1130 meshcfg_app *app = user_data;
1132 INFO("Mesh: provisioning data requested app path [%s]",
1134 uuid_string = l_util_hexstring(app->uuid, 16);
1135 INFO("Mesh: Network UUID [%s]", uuid_string);
1137 memset(&ev, 0, sizeof(ev));
1138 memset(&req, 0, sizeof(req));
1139 memcpy(ev.net_uuid, app->uuid, 16);
1140 memcpy(req.net_uuid, app->uuid, 16);
1141 l_free(uuid_string);
1143 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1144 ERR("Mesh: Cannot parse request for prov data");
1146 ev.status = BT_STATUS_FAIL;
1147 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1149 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1150 (void*)&ev, sizeof(ev));
1151 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1157 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1158 (void*)&req, sizeof(req));
1160 l_dbus_message_ref(msg);
1164 static struct l_dbus_message *__mesh_node_add_completed(
1165 struct l_dbus *dbus,
1166 struct l_dbus_message *msg,
1169 struct l_dbus_message_iter iter;
1174 struct hal_ev_mesh_provision_finished ev;
1175 const char *dbus_path;
1177 dbus_path = l_dbus_message_get_path(msg);
1178 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1179 true, MESH_PROV_IFACE);
1181 INFO("Mesh: app path [%s]", dbus_path);
1183 memset(&ev, 0, sizeof(ev));
1184 memcpy(ev.net_uuid, net_uuid, 16);
1188 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1189 ERR("Mesh: Cannot parse add node complete message");
1191 ev.status = BT_STATUS_FAIL;
1192 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1194 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1195 (void*)&ev, sizeof(ev));
1196 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1199 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1201 ERR("Mesh: Cannot parse add node complete message: uuid");
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);
1212 ev.status = BT_STATUS_SUCCESS;
1213 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1214 memcpy(ev.dev_uuid, uuid, 16);
1215 ev.unicast = unicast;
1219 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1220 (void*)&ev, sizeof(ev));
1222 return l_dbus_message_new_method_return(msg);
1225 static struct l_dbus_message *__mesh_node_add_failed(
1226 struct l_dbus *dbus,
1227 struct l_dbus_message *msg,
1230 struct l_dbus_message_iter iter;
1234 struct hal_ev_mesh_provision_finished ev;
1235 const char *dbus_path;
1238 dbus_path = l_dbus_message_get_path(msg);
1239 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1240 true, MESH_PROV_IFACE);
1242 memset(&ev, 0, sizeof(ev));
1243 memcpy(ev.net_uuid, net_uuid, 16);
1246 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1247 ERR("Mesh: Cannot parse add node failed message");
1249 ev.status = BT_STATUS_FAIL;
1250 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1252 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1253 (void*)&ev, sizeof(ev));
1254 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1257 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1259 ERR("Mesh:Cannot parse add node failed message: uuid");
1260 ev.status = BT_STATUS_FAIL;
1261 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1263 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1264 (void*)&ev, sizeof(ev));
1265 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1268 INFO("Mesh: Provisioning failed:\n");
1269 str = l_util_hexstring_upper(uuid, 16);
1270 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1272 ev.status = BT_STATUS_FAIL;
1273 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1274 memcpy(ev.dev_uuid, uuid, 16);
1279 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1280 (void*)&ev, sizeof(ev));
1282 return l_dbus_message_new_method_return(msg);
1285 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1287 INFO("Mesh: Setup provisioner interface properties & methods");
1288 l_dbus_interface_method(interface, "ScanResult", 0,
1289 __mesh_scan_result_received, "",
1290 "naya{sv}", "rssi", "data", "options");
1292 l_dbus_interface_method(interface, "RequestProvData", 0,
1293 __mesh_request_provisioner_call,
1294 "qq", "y", "net_index", "unicast", "count");
1296 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1297 __mesh_node_add_completed, "", "ayqy",
1298 "uuid", "unicast", "count");
1300 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1301 __mesh_node_add_failed,
1302 "", "ays", "uuid", "reason");
1305 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1307 INFO("Mesh: Setup application interface properties & methods");
1309 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1310 __mesh_get_companyid,
1312 l_dbus_interface_property(iface, "VersionID", 0, "q",
1313 __mesh_get_versionid,
1315 l_dbus_interface_property(iface, "ProductID", 0, "q",
1316 __mesh_get_productid,
1318 l_dbus_interface_property(iface, "CRPL", 0, "q",
1319 __mesh_get_crpl, NULL);
1320 l_dbus_interface_method(iface, "JoinComplete", 0,
1321 __mesh_node_join_complete,
1327 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1328 struct l_dbus_message_builder *builder)
1330 if (app->in_oob & 0x08)
1331 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1332 if (app->in_oob & 0x04)
1333 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1334 if (app->in_oob & 0x02)
1335 l_dbus_message_builder_append_basic(builder, 's', "twist");
1336 if (app->in_oob & 0x01)
1337 l_dbus_message_builder_append_basic(builder, 's', "push");
1340 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1341 struct l_dbus_message_builder *builder)
1343 if (app->out_oob & 0x10)
1344 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1345 if (app->out_oob & 0x08)
1346 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1347 if (app->out_oob & 0x04)
1348 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1349 if (app->out_oob & 0x02)
1350 l_dbus_message_builder_append_basic(builder, 's', "beep");
1351 if (app->out_oob & 0x01)
1352 l_dbus_message_builder_append_basic(builder, 's', "blink");
1355 static bool __mesh_agent_capability_getter(
1356 struct l_dbus *dbus, struct l_dbus_message *message,
1357 struct l_dbus_message_builder *builder,
1362 INFO("Mesh: app path [%s]", app->path);
1363 INFO("Mesh: Agent path [%s]", app->agent_path);
1365 if (!l_dbus_message_builder_enter_array(builder, "s"))
1368 __mesh_fill_out_capabilities(app, builder);
1369 __mesh_fill_in_capabilities(app, builder);
1371 if (app->static_oob)
1372 l_dbus_message_builder_append_basic(builder,
1376 l_dbus_message_builder_leave_array(builder);
1377 INFO("Mesh: __agent_capability_getter: Success");
1381 static struct l_dbus_message *__mesh_agent_display_string_request(
1382 struct l_dbus *dbus,
1383 struct l_dbus_message *msg,
1386 struct hal_ev_mesh_authentication_request ev;
1389 const char *dbus_path;
1392 INFO("Mesh: app path [%s]", app->path);
1393 INFO("Mesh: Agent path [%s]", app->agent_path);
1395 dbus_path = l_dbus_message_get_path(msg);
1396 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1397 true, MESH_AGENT_IFACE);
1399 INFO("Mesh: app path [%s]", dbus_path);
1401 memset(&ev, 0, sizeof(ev));
1402 memcpy(ev.net_uuid, net_uuid, 16);
1405 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1406 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1407 struct hal_ev_mesh_provision_finished ev;
1408 memset(&ev, 0, sizeof(ev));
1409 memcpy(ev.net_uuid, net_uuid, 16);
1410 ev.status = BT_STATUS_FAIL;
1411 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1413 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1414 (void*)&ev, sizeof(ev));
1418 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1421 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1422 ev.auth_type = __mesh_get_authentication_type(str);
1423 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1424 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1425 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1428 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1429 (void*)&ev, sizeof(ev));
1432 return l_dbus_message_new_method_return(msg);
1435 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1436 struct l_dbus *dbus,
1437 struct l_dbus_message *msg,
1441 struct hal_ev_mesh_authentication_request ev;
1445 const char *dbus_path;
1448 INFO("Mesh: app path [%s]", app->path);
1449 INFO("Mesh: Agent path [%s]", app->agent_path);
1451 dbus_path = l_dbus_message_get_path(msg);
1452 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1453 true, MESH_AGENT_IFACE);
1455 INFO("Mesh: app path [%s]", dbus_path);
1457 memset(&ev, 0, sizeof(ev));
1458 memcpy(ev.net_uuid, net_uuid, 16);
1461 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1462 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1463 struct hal_ev_mesh_provision_finished ev;
1464 memset(&ev, 0, sizeof(ev));
1465 memcpy(ev.net_uuid, net_uuid, 16);
1466 ev.status = BT_STATUS_FAIL;
1467 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1468 if (mesh_event_cb) {
1469 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1470 (void*)&ev, sizeof(ev));
1473 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1476 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1477 auth_value = l_strdup_printf("%u", n);
1478 ev.auth_type = __mesh_get_authentication_type(str);
1479 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1480 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1481 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1484 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1485 (void*)&ev, sizeof(ev));
1489 return l_dbus_message_new_method_return(msg);
1492 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1493 struct l_dbus *dbus,
1494 struct l_dbus_message *msg,
1497 struct hal_ev_mesh_authentication_request ev;
1500 const char *dbus_path;
1504 dbus_path = l_dbus_message_get_path(msg);
1505 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1506 true, MESH_AGENT_IFACE);
1508 INFO("Mesh: app path [%s]", dbus_path);
1510 l = g_slist_find_custom(mesh_apps, net_uuid,
1511 __mesh_compare_network_uuid);
1518 memset(&ev, 0, sizeof(ev));
1519 memcpy(ev.net_uuid, net_uuid, 16);
1522 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1523 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1525 struct hal_ev_mesh_provision_finished ev;
1526 memset(&ev, 0, sizeof(ev));
1527 memcpy(ev.net_uuid, app->uuid, 16);
1528 ev.status = BT_STATUS_FAIL;
1529 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1530 if (mesh_event_cb) {
1531 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1532 (void*)&ev, sizeof(ev));
1534 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1537 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1539 ev.auth_type = __mesh_get_authentication_type(str);
1540 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1541 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1543 l_dbus_message_ref(msg);
1545 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1546 (void*)&ev, sizeof(ev));
1551 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1552 struct l_dbus *dbus,
1553 struct l_dbus_message *msg,
1556 struct hal_ev_mesh_authentication_request ev;
1559 const char *dbus_path;
1561 meshcfg_app *app = NULL;
1563 dbus_path = l_dbus_message_get_path(msg);
1564 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1567 INFO("Mesh: app path [%s]", dbus_path);
1569 l = g_slist_find_custom(mesh_apps, net_uuid,
1570 __mesh_compare_network_uuid);
1575 ERR("Mesh: app not found");
1578 memset(&ev, 0, sizeof(ev));
1579 memcpy(ev.net_uuid, net_uuid, 16);
1582 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1583 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1585 struct hal_ev_mesh_provision_finished ev;
1586 memset(&ev, 0, sizeof(ev));
1589 memcpy(ev.net_uuid, app->uuid, 16);
1591 ev.status = BT_STATUS_FAIL;
1592 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1594 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1595 (void*)&ev, sizeof(ev));
1596 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1599 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1601 ev.auth_type = __mesh_get_authentication_type(str);
1602 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1603 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1605 l_dbus_message_ref(msg);
1607 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1608 (void*)&ev, sizeof(ev));
1613 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1615 INFO("Mesh: Setup Agent interface properties & methods");
1616 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1617 __mesh_agent_capability_getter,
1619 /* TODO: Other properties */
1620 l_dbus_interface_method(interface, "DisplayString", 0,
1621 __mesh_agent_display_string_request,
1623 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1624 __mesh_agent_display_numeric_request,
1625 "", "su", "type", "number");
1626 l_dbus_interface_method(interface, "PromptNumeric", 0,
1627 __mesh_agent_prompt_numeric_request,
1628 "u", "s", "number", "type");
1629 l_dbus_interface_method(interface, "PromptStatic", 0,
1630 __mesh_agent_prompt_static_request,
1631 "ay", "s", "data", "type");
1634 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1636 meshcfg_el *elem = (meshcfg_el*) data;
1637 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1638 elem->index, elem->path);
1639 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1640 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1641 ERR("Mesh: Failed to register object %s", elem->path);
1645 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1650 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1651 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1652 ERR("Mesh: Unable to register agent interface");
1656 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1657 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1658 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1659 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1663 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1664 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1665 ERR("Mesh: Failed to add interface %s",
1666 L_DBUS_INTERFACE_PROPERTIES);
1673 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1681 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1682 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1683 ERR("Mesh: Failed to register interface %s",
1684 BT_HAL_MESH_APPLICATION_INTERFACE);
1688 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1689 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1690 ERR("Mesh: Failed to register interface %s",
1691 BT_HAL_MESH_PROVISIONER_INTERFACE);
1695 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1696 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1697 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1699 ERR("Mesh: Failed to register object %s", ptr->path);
1703 if (!__bt_hal_mesh_register_agent(ptr))
1706 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1707 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1708 ERR("Mesh: Failed to register interface %s",
1709 BT_HAL_MESH_ELEMENT_INTERFACE);
1713 INFO("Mesh: Number of elements to be registsred [%d]",
1714 g_slist_length(ptr->elements));
1716 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1718 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1719 if (!l_dbus_object_add_interface(dbus, ptr->path,
1720 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1721 ERR("Mesh: Failed to add interface %s",
1722 L_DBUS_INTERFACE_OBJECT_MANAGER);
1725 INFO("Mesh: Application Register completed");
1730 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1734 meshcfg_model *model_info = (meshcfg_model*) data;
1735 meshcfg_app *app = (meshcfg_app*) user_data;
1737 l = g_slist_find_custom(app->elements,
1738 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1742 elem = g_malloc0(sizeof(meshcfg_el));
1743 elem->index = model_info->elem_index;
1744 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1745 app->elements = g_slist_append(app->elements, elem);
1746 INFO("Mesh: Created element index [%d] path [%s]",
1747 elem->index, elem->path);
1749 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1750 model_info->model, elem->index);
1751 /* Add Model in the element */
1752 elem->models = g_slist_append(elem->models, model_info);
1753 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1754 elem->index, g_slist_length(elem->models));
1757 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1758 GSList *models, bool is_prov)
1761 meshcfg_app *app = NULL;
1762 char *uuid_str = NULL;
1764 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1765 INFO("Mesh: Network UUID [%s]", uuid_str);
1767 app = g_malloc0(sizeof(meshcfg_app));
1768 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1770 app->cid = node->vendor_info.companyid;
1771 app->pid = node->vendor_info.vendorid;
1772 app->vid = node->vendor_info.versionid;
1773 app->crpl = node->vendor_info.crpl;
1776 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1777 app->agent_path = g_strdup_printf("%s/agent", app->path);
1780 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1781 app->agent_path = g_strdup_printf("%s/agent", app->path);
1783 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1786 app->is_prov = is_prov;
1787 app->token.u64 = node->token.u64;
1788 INFO("Mesh: Token [%llu]", (unsigned long long int)app->token.u64);
1789 INFO("Mesh: app created");
1793 static void __bt_hal_mesh_leave_net_reply(
1794 struct l_dbus_proxy *proxy,
1795 struct l_dbus_message *msg, void *user_data)
1798 app = (meshcfg_app*) user_data;
1800 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1801 if (l_dbus_message_is_error(msg)) {
1804 l_dbus_message_get_error(msg, &name, NULL);
1805 ERR("Mesh: Failed to leave network: %s", name);
1807 /* Send Network Destroy fail event */
1808 __send_network_destroy_event(app, BT_STATUS_FAIL);
1810 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1814 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1817 meshcfg_app *app = (meshcfg_app*) user_data;
1819 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1820 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1823 static void __bt_hal_mesh_release_net_reply(
1824 struct l_dbus_proxy *proxy,
1825 struct l_dbus_message *msg, void *user_data)
1828 app = (meshcfg_app*) user_data;
1830 INFO("Mesh:Release Network Reply from Meshd: app path [%s]", app->path);
1831 if (l_dbus_message_is_error(msg)) {
1834 l_dbus_message_get_error(msg, &name, NULL);
1835 ERR("Mesh: Failed to Release network: %s", name);
1838 INFO("Mesh: Release Network: Success, cleanup app after proxy removed");
1842 static void __bt_hal_mesh_release_net_setup(struct l_dbus_message *msg,
1845 meshcfg_app *app = (meshcfg_app*) user_data;
1847 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1848 INFO("Mesh: Release Network Setup app path [%s]", app->path);
1851 static void __bt_hal_mesh_create_net_reply(
1852 struct l_dbus_proxy *proxy,
1853 struct l_dbus_message *msg, void *user_data)
1856 app = (meshcfg_app*) user_data;
1858 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1859 if (l_dbus_message_is_error(msg)) {
1862 l_dbus_message_get_error(msg, &name, NULL);
1863 ERR("Mesh: Failed to create network: %s", name);
1865 /* Send Network creation fail event */
1866 __send_network_attach_event(app, BT_STATUS_FAIL);
1868 /* Destroy mesh app object */
1869 __bt_hal_mesh_destroy_app_object(app);
1874 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1878 struct l_dbus_message_builder *builder;
1879 app = (meshcfg_app*) user_data;
1881 builder = l_dbus_message_builder_new(msg);
1883 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1884 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1885 __mesh_append_byte_array(builder, app->uuid, 16);
1886 l_dbus_message_builder_finalize(builder);
1887 l_dbus_message_builder_destroy(builder);
1890 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1892 struct hal_ev_mesh_scan_state_changed ev;
1894 memset(&ev, 0, sizeof(ev));
1895 memcpy(ev.net_uuid, app->uuid, 16);
1897 ev.status = BT_STATUS_SUCCESS;
1899 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1901 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1902 (void*)&ev, sizeof(ev));
1905 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1907 meshcfg_app *app = (meshcfg_app*) user_data;
1908 __mesh_trigger_scan_finished_event(app);
1912 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1916 l = g_slist_find_custom(mesh_apps, net_uuid,
1917 __mesh_compare_network_uuid);
1922 if (app->scan_timer_id > 0) {
1923 g_source_remove(app->scan_timer_id);
1924 app->scan_timer_id = 0;
1927 app->scan_timer_id = g_timeout_add_seconds(secs,
1928 __bt_mesh_scan_timer_cb, app);
1933 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1934 struct l_dbus_message *msg, void *user_data)
1936 struct hal_ev_mesh_scan_state_changed ev;
1937 const char *dbus_path;
1939 dbus_path = l_dbus_proxy_get_path(proxy);
1940 INFO("Mesh: DBUS path [%s]", dbus_path);
1941 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1943 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1944 INFO("Mesh: Scan duration [%u]", secs);
1946 memset(&ev, 0, sizeof(ev));
1947 memcpy(ev.net_uuid, net_uuid, 16);
1949 if (l_dbus_message_is_error(msg)) {
1951 l_dbus_message_get_error(msg, &name, NULL);
1952 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1953 ev.status = BT_STATUS_FAIL;
1955 INFO("Mesh: Unprovisioned scan started\n");
1956 ev.status = BT_STATUS_SUCCESS;
1957 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1960 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1962 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1963 (void*)&ev, sizeof(ev));
1967 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1969 struct l_dbus_message_builder *builder;
1970 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1971 INFO("Mesh: Scan duration [%u]", secs);
1973 builder = l_dbus_message_builder_new(msg);
1974 l_dbus_message_builder_enter_array(builder, "{sv}");
1975 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1976 l_dbus_message_builder_leave_array(builder);
1977 l_dbus_message_builder_finalize(builder);
1978 l_dbus_message_builder_destroy(builder);
1982 bt_status_t _bt_hal_mesh_network_set_caps(
1983 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1987 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1991 app->public_oob = caps->public_oob;
1992 app->static_oob = caps->static_oob;
1993 app->out_oob = caps->out_oob;
1994 app->in_oob = caps->in_oob;
1996 ERR("Mesh: app not found!!");
1997 return BT_STATUS_PARM_INVALID;
2000 return BT_STATUS_SUCCESS;
2003 static void __bt_hal_mesh_add_node_reply(
2004 struct l_dbus_proxy *proxy,
2005 struct l_dbus_message *msg,
2008 struct hal_ev_mesh_provision_status ev;
2009 const char *dbus_path;
2011 dbus_path = l_dbus_proxy_get_path(proxy);
2012 INFO("Mesh: DBUS path [%s]", dbus_path);
2013 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2015 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
2017 INFO("Mesh: app path [%s]", dbus_path);
2019 memset(&ev, 0, sizeof(ev));
2020 memcpy(ev.net_uuid, net_uuid, 16);
2021 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
2023 /* Free User data */
2024 g_free((void*)dev_uuid);
2027 if (l_dbus_message_is_error(msg)) {
2030 l_dbus_message_get_error(msg, &name, NULL);
2031 ERR("Mesh: Failed to start provisioning: %s", name);
2032 ev.status = BT_STATUS_FAIL;
2034 INFO("Mesh: Provisioning started\n");
2035 ev.status = BT_STATUS_SUCCESS;
2038 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
2039 (void*)&ev, sizeof(ev));
2040 INFO("Mesh: Provisioning status sent");
2043 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
2047 bt_uuid_t *dev = user_data;
2048 struct l_dbus_message_builder *builder;
2050 uuid = l_util_hexstring(dev->uu, 16);
2054 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
2056 builder = l_dbus_message_builder_new(msg);
2057 __mesh_append_byte_array(builder, dev->uu, 16);
2058 l_dbus_message_builder_enter_array(builder, "{sv}");
2059 l_dbus_message_builder_leave_array(builder);
2060 l_dbus_message_builder_finalize(builder);
2061 l_dbus_message_builder_destroy(builder);
2066 bt_status_t _bt_hal_mesh_provision_device(
2067 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
2072 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2075 dev = g_memdup((gpointer)dev_uuid, 16);
2076 INFO("Mesh: Schedule Add Node request to meshd");
2077 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
2078 __bt_hal_mesh_add_node_setup,
2079 __bt_hal_mesh_add_node_reply,
2081 return BT_STATUS_FAIL;
2083 ERR("Mesh: app not found!!");
2084 return BT_STATUS_PARM_INVALID;
2087 return BT_STATUS_SUCCESS;
2090 static void __bt_hal_mesh_subnet_key_setup(
2091 struct l_dbus_message *msg, void *user_data)
2093 struct subnet_key_request *req = user_data;
2094 uint16_t idx = (uint16_t) req->idx;
2096 l_dbus_message_set_arguments(msg, "q", idx);
2099 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
2100 struct l_dbus_message *msg, void *user_data)
2102 struct hal_ev_mesh_netkey_execute_event ev;
2103 const char *dbus_path;
2105 struct subnet_key_request *req = user_data;
2106 const char *method = req->str;
2108 dbus_path = l_dbus_proxy_get_path(proxy);
2109 INFO("Mesh: DBUS path [%s]", dbus_path);
2110 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2112 memset(&ev, 0, sizeof(ev));
2113 memcpy(ev.net_uuid, net_uuid, 16);
2114 ev.key_idx = req->idx;
2118 if (l_dbus_message_is_error(msg)) {
2121 l_dbus_message_get_error(msg, &name, NULL);
2122 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
2123 ev.status = BT_STATUS_FAIL;
2126 ev.status = BT_STATUS_SUCCESS;
2128 if (!strcmp("CreateSubnet", method)) {
2129 INFO("Mesh: Reply for CreateSubnet");
2130 ev.key_event = HAL_MESH_KEY_ADD;
2131 } else if (!strcmp("DeleteSubnet", method)) {
2132 INFO("Mesh: Reply for DeleteSubnet");
2133 ev.key_event = HAL_MESH_KEY_DELETE;
2134 } else if (!strcmp("UpdateSubnet", method)) {
2135 INFO("Mesh: Reply for UpdateSubnet");
2136 ev.key_event = HAL_MESH_KEY_UPDATE;
2140 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2141 (void*)&ev, sizeof(ev));
2144 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2145 uint16_t index, const char *key_execute_method)
2147 struct subnet_key_request *req;
2149 req = l_new(struct subnet_key_request, 1);
2150 req->str = key_execute_method;
2153 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2154 __bt_hal_mesh_subnet_key_setup,
2155 __bt_hal_mesh_subnet_key_reply,
2162 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2165 struct app_key_request *req = user_data;
2166 uint16_t net_idx = (uint16_t) req->net_idx;
2167 uint16_t app_idx = (uint16_t) req->app_idx;
2169 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2170 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2172 l_dbus_message_set_arguments(msg, "q", app_idx);
2175 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2176 struct l_dbus_message *msg, void *user_data)
2178 struct hal_ev_mesh_appkey_execute_event ev;
2179 const char *dbus_path;
2181 struct app_key_request *req = user_data;
2182 const char *method = req->str;
2184 dbus_path = l_dbus_proxy_get_path(proxy);
2185 INFO("Mesh: DBUS path [%s]", dbus_path);
2186 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2188 memset(&ev, 0, sizeof(ev));
2189 memcpy(ev.net_uuid, net_uuid, 16);
2190 ev.net_idx = req->net_idx;
2191 ev.app_idx = req->app_idx;
2195 if (l_dbus_message_is_error(msg)) {
2198 l_dbus_message_get_error(msg, &name, NULL);
2199 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2200 ev.status = BT_STATUS_FAIL;
2202 ev.status = BT_STATUS_SUCCESS;
2204 if (!strcmp("CreateAppKey", method)) {
2205 INFO("Mesh: AppKey Create Reply");
2206 ev.key_event = HAL_MESH_KEY_ADD;
2207 } else if (!strcmp("DeleteAppKey", method)) {
2208 INFO("Mesh: AppKey Delete Reply");
2209 ev.key_event = HAL_MESH_KEY_DELETE;
2210 } else if (!strcmp("UpdateAppKey", method)) {
2211 INFO("Mesh: AppKey Update Reply");
2212 ev.key_event = HAL_MESH_KEY_UPDATE;
2216 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2219 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2220 uint16_t net_idx, uint16_t app_idx,
2221 const char *key_execute_method)
2223 struct app_key_request *req;
2225 req = l_new(struct app_key_request, 1);
2226 req->str = key_execute_method;
2227 req->net_idx = net_idx;
2228 req->app_idx = app_idx;
2230 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2231 __bt_hal_mesh_app_key_setup,
2232 __bt_hal_mesh_app_key_reply,
2239 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2240 bt_mesh_key_op_e op, uint16_t netkey_idx)
2245 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2249 if (op == BT_MESH_KEY_CREATE)
2250 status = __mesh_subnet_netkey_command_execute(app,
2251 netkey_idx, "CreateSubnet");
2252 else if (op == BT_MESH_KEY_DELETE)
2253 status = __mesh_subnet_netkey_command_execute(app,
2254 netkey_idx, "DeleteSubnet");
2255 else if (op == BT_MESH_KEY_UPDATE)
2256 status = __mesh_subnet_netkey_command_execute(app,
2257 netkey_idx, "UpdateSubnet");
2259 return BT_STATUS_FAIL;
2262 ERR("Mesh: app not found!!");
2263 return BT_STATUS_PARM_INVALID;
2266 return BT_STATUS_SUCCESS;
2269 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2270 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2275 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2279 if (op == BT_MESH_KEY_CREATE)
2280 status = __mesh_subnet_appkey_command_execute(app,
2281 netkey_idx, appkey_idx, "CreateAppKey");
2282 else if (op == BT_MESH_KEY_DELETE)
2283 status = __mesh_subnet_appkey_command_execute(app,
2284 netkey_idx, appkey_idx, "DeleteAppKey");
2285 else if (op == BT_MESH_KEY_UPDATE) {
2286 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2287 netkey_idx, appkey_idx);
2288 status = __mesh_subnet_appkey_command_execute(app,
2289 netkey_idx, appkey_idx, "UpdateAppKey");
2292 return BT_STATUS_FAIL;
2295 ERR("Mesh: app not found!!");
2296 return BT_STATUS_PARM_INVALID;
2299 return BT_STATUS_SUCCESS;
2302 bt_status_t _bt_hal_mesh_send_provision_data(
2303 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2307 struct l_dbus_message *msg;
2308 struct l_dbus_message *reply;
2310 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2315 reply = l_dbus_message_new_method_return(msg);
2316 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2317 l_dbus_send(dbus, reply);
2319 ERR("Mesh: app not found!!");
2320 return BT_STATUS_PARM_INVALID;
2322 return BT_STATUS_SUCCESS;
2325 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2329 l = g_slist_find_custom(mesh_apps,
2330 net_uuid->uu, __mesh_compare_network_uuid);
2333 if (!__bt_mesh_proxy_check(app)) {
2334 ERR("Mesh: Proxy check failed!!");
2335 return BT_STATUS_FAIL;
2337 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2338 "UnprovisionedScanCancel",
2339 NULL, NULL, NULL, NULL))
2340 return BT_STATUS_FAIL;
2342 ERR("Mesh: app not found!!");
2343 return BT_STATUS_PARM_INVALID;
2346 /* Stop Scan timer */
2347 if (app->scan_timer_id > 0) {
2348 g_source_remove(app->scan_timer_id);
2349 app->scan_timer_id = 0;
2352 /* Trigger Scan finished event */
2353 __mesh_trigger_scan_finished_event(app);
2355 return BT_STATUS_SUCCESS;
2358 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2359 const char *auth_value)
2362 struct l_dbus_message *reply = NULL;
2363 struct l_dbus_message_builder *builder;
2365 bt_status_t ret = BT_STATUS_SUCCESS;
2369 if (!__bt_mesh_proxy_check(0)) {
2370 ERR("Mesh: Proxy check failed!!");
2371 return BT_STATUS_FAIL;
2373 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2374 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2375 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2376 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2377 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2378 INFO("Mesh: Authentication reply: Numeric Type");
2379 val_u32 = atoi(auth_value);
2380 reply = l_dbus_message_new_method_return(agent_msg);
2381 l_dbus_message_set_arguments(reply, "u", val_u32);
2383 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2384 l_dbus_send(dbus, reply);
2385 ret = BT_STATUS_SUCCESS;
2386 /* For Alpha-Numeric */
2387 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2388 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2389 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2390 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2391 alpha = l_util_from_hexstring(auth_value, &sz);
2392 reply = l_dbus_message_new_method_return(agent_msg);
2393 builder = l_dbus_message_builder_new(reply);
2394 __mesh_append_byte_array(builder, alpha, 16);
2395 l_dbus_message_builder_finalize(builder);
2396 l_dbus_message_builder_destroy(builder);
2399 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2400 l_dbus_send(dbus, reply);
2401 ret = BT_STATUS_SUCCESS;
2406 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2407 bt_hal_mesh_scan_param_t *param)
2411 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2414 if (!__bt_mesh_proxy_check(app)) {
2415 ERR("Mesh: Proxy check failed!!");
2416 return BT_STATUS_FAIL;
2418 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2419 __mesh_scan_setup, __mesh_scan_reply,
2420 L_UINT_TO_PTR(param->scan_time), NULL))
2421 return BT_STATUS_FAIL;
2423 ERR("Mesh: app not found!!");
2424 return BT_STATUS_PARM_INVALID;
2426 return BT_STATUS_SUCCESS;
2429 static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
2432 struct mesh_remote_node_info *node_info = \
2433 (struct mesh_remote_node_info*) user_data;
2435 l_dbus_message_set_arguments(msg, "qy",
2436 node_info->unicast, node_info->num_elements);
2437 INFO("Mesh: Delete Remote Node Setup params passed");
2440 static void __bt_hal_mesh_delete_node_reply(
2441 struct l_dbus_proxy *proxy,
2442 struct l_dbus_message *msg, void *user_data)
2444 INFO("Mesh: Delete Remote Node Reply from DBUS");
2447 bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
2448 uint16_t unicast, uint16_t num_elements)
2452 struct mesh_remote_node_info *node_info;
2453 INFO("Mesh: Delete Remote Node");
2454 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2457 if (!__bt_mesh_proxy_check(app)) {
2458 ERR("Mesh: Proxy check failed!!");
2459 return BT_STATUS_FAIL;
2461 INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
2462 unicast, num_elements);
2464 /* Delete Remote Node Request */
2465 node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
2466 node_info->unicast = unicast;
2467 node_info->num_elements = num_elements;
2469 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
2470 __bt_hal_mesh_delete_node_setup,
2471 __bt_hal_mesh_delete_node_reply, node_info,
2473 ERR("Mesh: Delete Remote Node Request failed!!");
2475 return BT_STATUS_FAIL;
2478 ERR("Mesh: App not found!!");
2479 return BT_STATUS_PARM_INVALID;
2481 INFO("Mesh: Delete Remote Node Call issued successfully!!");
2482 return BT_STATUS_SUCCESS;
2485 bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid)
2489 INFO("Mesh: Release Network");
2490 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2493 if (!__bt_mesh_proxy_check(app)) {
2494 ERR("Mesh: Proxy check failed!!");
2495 return BT_STATUS_FAIL;
2497 INFO("Mesh: Release Network");
2498 /* Create CFG Network */
2499 if (!l_dbus_proxy_method_call(net_proxy, "Release",
2500 __bt_hal_mesh_release_net_setup,
2501 __bt_hal_mesh_release_net_reply, app,
2503 ERR("Mesh: Network Release failed!!");
2504 return BT_STATUS_FAIL;
2507 ERR("Mesh: App not found!!");
2508 return BT_STATUS_PARM_INVALID;
2510 INFO("Mesh: Network Release Call issued successfully!!");
2511 return BT_STATUS_SUCCESS;
2514 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2518 INFO("Mesh: Destroy network");
2519 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2522 if (!__bt_mesh_proxy_check(app)) {
2523 ERR("Mesh: Proxy check failed!!");
2524 return BT_STATUS_FAIL;
2526 INFO("Mesh: Destroy Network");
2527 /* Create CFG Network */
2528 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2529 __bt_hal_mesh_leave_net_setup,
2530 __bt_hal_mesh_leave_net_reply, app,
2532 ERR("Mesh: Network Leave failed!!");
2533 return BT_STATUS_FAIL;
2536 ERR("Mesh: App not found!!");
2537 return BT_STATUS_PARM_INVALID;
2539 INFO("Mesh: Network Leave Call issued successfully!!");
2540 return BT_STATUS_SUCCESS;
2543 bt_status_t _bt_hal_mesh_create_network(
2544 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2548 INFO("Mesh: Create Network Request");
2550 if (!__bt_mesh_proxy_check(0)) {
2551 ERR("Mesh: Proxy check failed!!");
2552 return BT_STATUS_FAIL;
2555 INFO("Mesh: Node Element count [%d]", node->num_elements);
2556 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2557 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2558 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2559 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2560 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2561 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2562 INFO("Mesh: Token [%llu]", (unsigned long long int)node->token.u64);
2563 /* Create DBUS APP */
2564 app = __bt_hal_mesh_create_app(node, models, is_prov);
2566 return BT_STATUS_FAIL;
2568 /* Register DBUS APP */
2569 if (!__bt_hal_mesh_register_application(app))
2572 if (app->token.u64 == 0) {
2573 INFO("Mesh: Create New Network");
2574 /* Create CFG Network */
2575 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2576 __bt_hal_mesh_create_net_setup,
2577 __bt_hal_mesh_create_net_reply, app,
2579 ERR("Mesh: Network Create failed!!");
2583 INFO("Mesh: Attach Node to Network: Token [%llu]", (unsigned long long int)app->token.u64);
2584 /* Attach to Network */
2585 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2586 __bt_hal_mesh_attach_node_setup,
2587 __bt_hal_mesh_attach_node_reply,
2590 ERR("Mesh: Node attach failed!!");
2595 INFO("Mesh: Node registration request scheudled");
2596 mesh_apps = g_slist_append(mesh_apps, app);
2597 INFO("Mesh: Total number of apps in list [%d]",
2598 g_slist_length(mesh_apps));
2599 return BT_STATUS_SUCCESS;
2601 ERR("Mesh: network can not be created!!");
2602 __bt_hal_mesh_destroy_app_object(app);
2603 return BT_STATUS_FAIL;
2606 static void __bt_hal_mesh_config_send(
2607 struct l_dbus_message *msg, void *user_data)
2609 struct configuration_request *req = user_data;
2610 struct l_dbus_message_builder *builder;
2612 builder = l_dbus_message_builder_new(msg);
2614 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2615 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2616 if (req->is_dev_key)
2617 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2619 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2622 l_dbus_message_builder_enter_array(builder, "{sv}");
2623 l_dbus_message_builder_enter_dict(builder, "sv");
2624 l_dbus_message_builder_leave_dict(builder);
2625 l_dbus_message_builder_leave_array(builder);
2627 __mesh_append_byte_array(builder, req->data, req->len);
2628 l_dbus_message_builder_finalize(builder);
2629 l_dbus_message_builder_destroy(builder);
2632 static void __bt_hal_mesh_key_config_send(
2633 struct l_dbus_message *msg, void *user_data)
2635 struct key_config_request *req = user_data;
2636 struct l_dbus_message_builder *builder;
2638 builder = l_dbus_message_builder_new(msg);
2640 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2641 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2642 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2643 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2644 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2645 l_dbus_message_builder_finalize(builder);
2646 l_dbus_message_builder_destroy(builder);
2649 static void __bt_hal_mesh_model_execute_message(
2650 struct l_dbus_message *msg, void *user_data)
2652 struct configuration_request *req = user_data;
2653 struct l_dbus_message_builder *builder;
2655 builder = l_dbus_message_builder_new(msg);
2657 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2658 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2659 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2662 l_dbus_message_builder_enter_array(builder, "{sv}");
2663 l_dbus_message_builder_enter_dict(builder, "sv");
2664 l_dbus_message_builder_leave_dict(builder);
2665 l_dbus_message_builder_leave_array(builder);
2667 __mesh_append_byte_array(builder, req->data, req->len);
2668 l_dbus_message_builder_finalize(builder);
2669 l_dbus_message_builder_destroy(builder);
2672 bt_status_t _bt_hal_mesh_send_key_config_message(
2673 bt_uuid_t *network, uint16_t dest,
2674 bool is_netkey, bool is_update,
2675 uint16_t key_idx, uint16_t netkey_idx)
2679 struct key_config_request *req;
2682 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2683 /* Source is Config Client Local Node */
2684 int src_elem_idx = 0;
2685 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2688 if (!__bt_mesh_proxy_check(app)) {
2689 ERR("Mesh: Proxy check failed!!");
2690 return BT_STATUS_FAIL;
2692 l1 = g_slist_find_custom(app->elements,
2693 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2695 return BT_STATUS_FAIL;
2698 req = l_new(struct key_config_request, 1);
2699 req->ele_path = elem->path;
2701 req->key_req_idx = key_idx;
2702 req->idx = netkey_idx; /* Encryption Key index */
2703 req->update_req = is_update;
2705 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2706 __bt_hal_mesh_key_config_send, NULL,
2707 (void*)req, l_free))
2708 return BT_STATUS_FAIL;
2710 ERR("Mesh: app not found!!");
2711 return BT_STATUS_PARM_INVALID;
2714 return BT_STATUS_SUCCESS;
2717 bt_status_t _bt_hal_mesh_send_configuration_message(
2718 bt_uuid_t *network, uint16_t dest,
2719 bool is_dev_key, uint16_t netkey_idx,
2720 uint8_t *buf, int len)
2724 struct configuration_request *req;
2727 int src_elem_idx = 0;
2728 l = g_slist_find_custom(mesh_apps, network->uu,
2729 __mesh_compare_network_uuid);
2732 if (!__bt_mesh_proxy_check(app)) {
2733 ERR("Mesh: Proxy check failed!!");
2734 return BT_STATUS_FAIL;
2736 l1 = g_slist_find_custom(app->elements,
2737 GUINT_TO_POINTER(src_elem_idx),
2738 __compare_element_index);
2740 return BT_STATUS_FAIL;
2743 req = l_new(struct configuration_request, 1);
2744 req->ele_path = elem->path;
2746 req->idx = netkey_idx;
2750 req->is_dev_key = is_dev_key;
2752 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2753 __bt_hal_mesh_config_send, NULL,
2754 (void*)req, l_free))
2755 return BT_STATUS_FAIL;
2757 ERR("Mesh: app not found!!");
2758 return BT_STATUS_PARM_INVALID;
2761 return BT_STATUS_SUCCESS;
2764 bt_status_t _bt_hal_mesh_model_execute_message(
2765 bt_uuid_t *network, uint16_t dest,
2766 uint16_t appkey_idx, uint8_t *buf, int len)
2770 struct configuration_request *req;
2773 int src_elem_idx = 0;
2774 l = g_slist_find_custom(mesh_apps, network->uu,
2775 __mesh_compare_network_uuid);
2778 if (!__bt_mesh_proxy_check(app)) {
2779 ERR("Mesh: Proxy check failed!!");
2780 return BT_STATUS_FAIL;
2782 l1 = g_slist_find_custom(app->elements,
2783 GUINT_TO_POINTER(src_elem_idx),
2784 __compare_element_index);
2786 return BT_STATUS_FAIL;
2789 req = l_new(struct configuration_request, 1);
2790 req->ele_path = elem->path;
2792 req->idx = appkey_idx;
2796 req->is_dev_key = false;
2798 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2799 __bt_hal_mesh_model_execute_message,
2800 NULL, (void*)req, l_free))
2801 return BT_STATUS_FAIL;
2803 ERR("Mesh: app not found!!");
2804 return BT_STATUS_PARM_INVALID;
2807 return BT_STATUS_SUCCESS;