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_dbus_path(gconstpointer data, gconstpointer user_data)
423 const meshcfg_app *app = (meshcfg_app*) data;
424 char *path = (char *) user_data;
426 INFO("Mesh: NULL dbus path");
429 char **strings = g_strsplit(path, "/elem", 2);
430 ret = g_strcmp0(strings[0], app->path);
435 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
437 const meshcfg_el *elem = data;
438 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
442 return (elem->index == elem_index ? 0 : -1);
445 static void __send_network_destroy_event(void *param, uint8_t status)
447 struct hal_ev_mesh_network_destroyed ev;
448 meshcfg_app *app = (meshcfg_app*)param;
450 memset(&ev, 0, sizeof(ev));
451 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
452 memcpy(ev.token, app->token.u8, 8);
456 mesh_event_cb(HAL_EV_MESH_NETWORK_DESTROYED,
457 (void*)&ev, sizeof(ev));
460 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
462 const char *interface = l_dbus_proxy_get_interface(proxy);
463 const char *path = l_dbus_proxy_get_path(proxy);
465 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
467 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
468 struct hal_ev_mesh_network_proxy_added ev;
469 INFO("Mesh: Network Proxy added");
471 /* Save Global proxy */
474 INFO("Mesh: Net Proxy [%p]", net_proxy);
476 memset(&ev, 0, sizeof(ev));
477 ev.status = BT_STATUS_SUCCESS;
481 mesh_event_cb(HAL_EV_MESH_NETWORK_PROXY_ADDED,
482 (void*)&ev, sizeof(ev));
487 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
490 INFO("Mesh: Mgmt Proxy added");
491 INFO("Mesh: Number of mesh app present in list [%d]",
492 g_slist_length(mesh_apps));
493 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
496 app->mgmt_proxy = proxy;
498 ERR("Mesh: app not found for Mgmt proxy");
503 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
504 INFO("Mesh: Node Proxy added");
507 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
512 ERR("Mesh: app not found for Node proxy");
518 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
520 const char *interface = l_dbus_proxy_get_interface(proxy);
521 const char *path = l_dbus_proxy_get_path(proxy);
523 INFO("Proxy removed: %s (%s)\n", interface, path);
525 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
526 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
527 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
529 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
533 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
534 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
537 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
540 /* Send event to app about removal of a mesh local node */
541 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
542 __bt_hal_mesh_destroy_app_object(app);
544 ERR("Mesh: app not found for Mgmt proxy");
547 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
548 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
551 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
554 /* Send event to app about removal of a mesh local node */
555 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
556 __bt_hal_mesh_destroy_app_object(app);
558 ERR("Mesh: app not found for Mgmt proxy");
564 static void __mesh_property_changed(struct l_dbus_proxy *proxy, const char *name,
565 struct l_dbus_message *msg, void *user_data)
567 const char *interface = l_dbus_proxy_get_interface(proxy);
568 const char *path = l_dbus_proxy_get_path(proxy);
570 meshcfg_app *app = NULL;
572 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
576 ERR("Mesh: app not found for Mgmt proxy");
579 INFO("Property changed: %s %s %s\n", name, path, interface);
584 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
586 if (!strcmp(name, "IvIndex")) {
589 if (!l_dbus_message_get_arguments(msg, "u", &ivi))
592 INFO("New IV Index: %u\n", ivi);
595 /*TODO: save iv index */
601 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
604 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
608 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
609 bool queued, void *user_data)
611 if (success == false)
612 ERR("Mesh: Fail to acquire dbus name\n");
614 if (!l_dbus_object_manager_enable(dbus_obj, "/"))
615 ERR("Mesh: Failed to register the ObjectManager\n");
618 static void __mesh_ready_callback(void *user_data)
620 INFO("Mesh: Connected to D-Bus\n");
622 if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
623 __mesh_acquire_name_callback, NULL))
624 ERR("Mesh: Failed to own well-known name\n");
627 bool _bt_hal_mesh_stack_init(void)
629 INFO("Mesh: Connect with meshd");
630 /* Connect with meshd */
631 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
635 INFO("Mesh: Got dbus [%p]", dbus);
637 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
640 client = l_dbus_client_new(dbus,
641 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
645 if (!l_dbus_client_set_connect_handler(client,
646 __mesh_client_connected, NULL, NULL))
649 if (!l_dbus_client_set_disconnect_handler(client,
650 __mesh_client_disconnected, NULL,
653 if (!l_dbus_client_set_proxy_handlers(client,
654 __mesh_proxy_added, __mesh_proxy_removed,
655 __mesh_property_changed, NULL, NULL))
657 if (!l_dbus_client_set_ready_handler(client,
658 __mesh_dbus_client_ready, NULL, NULL))
661 INFO("Mesh: Stack Init watchers registered with meshd");
665 void _bt_hal_mesh_stack_deinit(void)
667 INFO("Mesh: Stack Deinit");
670 l_dbus_client_destroy(client);
675 l_dbus_destroy(dbus);
682 INFO("Mesh: Number of meshapps present in memory [%d]",
683 g_slist_length(mesh_apps));
686 /* To send stack event to hal-mesh handler */
687 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
692 /* To send stack event to hal-mesh handler */
693 void _bt_hal_mesh_unregister_dbus_handler_cb()
695 mesh_event_cb = NULL;
698 static bool __mesh_get_companyid(struct l_dbus *dbus,
699 struct l_dbus_message *message,
700 struct l_dbus_message_builder *builder,
703 meshcfg_app *app = (meshcfg_app*) user_data;
707 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
712 static bool __mesh_get_productid(struct l_dbus *dbus,
713 struct l_dbus_message *message,
714 struct l_dbus_message_builder *builder,
717 meshcfg_app *app = (meshcfg_app*) user_data;
720 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
725 static bool __mesh_get_versionid(struct l_dbus *dbus,
726 struct l_dbus_message *message,
727 struct l_dbus_message_builder *builder,
730 meshcfg_app *app = (meshcfg_app*) user_data;
733 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
738 static bool __mesh_get_crpl(struct l_dbus *dbus,
739 struct l_dbus_message *message,
740 struct l_dbus_message_builder *builder,
743 meshcfg_app *app = (meshcfg_app*) user_data;
746 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
751 static void __send_network_attach_event(void *param, uint8_t status)
753 struct hal_ev_mesh_network_attached ev;
754 meshcfg_app *app = (meshcfg_app*)param;
756 memset(&ev, 0, sizeof(ev));
757 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
758 memcpy(ev.token, app->token.u8, 8);
759 ev.is_prov = app->is_prov;
763 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
764 (void*)&ev, sizeof(ev));
767 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
768 struct l_dbus_message *msg, void *user_data)
770 struct l_dbus_message_iter iter_cfg;
772 meshcfg_app *app = (meshcfg_app*) user_data;
775 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
776 app->path, app->agent_path);
778 if (l_dbus_message_is_error(msg)) {
780 l_dbus_message_get_error(msg, &name, NULL);
781 ERR("Mesh: Failed to attach node: %s", name);
786 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
790 INFO("Mesh: Attached with path %s\n", app->path);
791 __send_network_attach_event(app, BT_STATUS_SUCCESS);
793 if (l_dbus_proxy_get_property(app->proxy, "IvIndex", "u", &ivi) &&
796 /* TODO: Save IV index */
801 __send_network_attach_event(app, BT_STATUS_FAIL);
802 /* Destroy mesh app object */
803 __bt_hal_mesh_destroy_app_object(app);
806 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
809 meshcfg_app *app = (meshcfg_app*) user_data;
811 l_dbus_message_set_arguments(msg, "ot", app->path,
812 l_get_be64(app->token.u8));
816 static void __bt_hal_mesh_attach_node(void *user_data)
818 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
819 __bt_hal_mesh_attach_node_setup,
820 __bt_hal_mesh_attach_node_reply,
823 ERR("Mesh: Node attach failed!!");
824 /* Node could not be attached */
825 __send_network_attach_event(user_data, BT_STATUS_FAIL);
826 /* Destroy mesh app object */
827 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
831 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
832 struct l_dbus_message *message,
838 meshcfg_app *app = (meshcfg_app*) user_data;
839 INFO("Mesh: Join Complete");
842 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
844 /* Send Network creation fail event */
845 __send_network_attach_event(app, BT_STATUS_FAIL);
847 /* Destroy mesh app object */
848 __bt_hal_mesh_destroy_app_object(app);
850 return l_dbus_message_new_error(message, dbus_err_args, NULL);
854 app->token.u64 = l_get_be64(&tmp);
855 str = l_util_hexstring(&app->token.u8[0], 8);
856 INFO("Mesh: Created new node with token %s\n", str);
859 /* Authenticate the node */
860 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
861 return l_dbus_message_new_method_return(message);
864 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
865 const char *key, const char *signature,
871 l_dbus_message_builder_enter_dict(builder, "sv");
872 l_dbus_message_builder_append_basic(builder, 's', key);
873 l_dbus_message_builder_enter_variant(builder, signature);
874 l_dbus_message_builder_append_basic(builder, signature[0], data);
875 l_dbus_message_builder_leave_variant(builder);
876 l_dbus_message_builder_leave_dict(builder);
879 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
882 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
883 meshcfg_model *model_info = (meshcfg_model*) data;
884 bool pub_enable = true;
885 bool sub_enable = true;
887 l_dbus_message_builder_enter_struct(builder, "qa{sv}");
888 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
889 l_dbus_message_builder_enter_array(builder, "{sv}");
890 append_dict_entry_basic(builder, "Subscribe", "b", &sub_enable);
891 append_dict_entry_basic(builder, "Publish", "b", &pub_enable);
892 l_dbus_message_builder_leave_array(builder);
893 l_dbus_message_builder_leave_struct(builder);
896 static bool __mesh_model_getter(struct l_dbus *dbus,
897 struct l_dbus_message *message,
898 struct l_dbus_message_builder *builder,
901 meshcfg_el *element = (meshcfg_el*) user_data;
903 l_dbus_message_builder_enter_array(builder, "(qa{sv})");
904 g_slist_foreach(element->models,
905 __bt_hal_mesh_foreach_model_getter, builder);
907 l_dbus_message_builder_leave_array(builder);
912 /*TODO: Vendor Model handling is currently not Handled */
913 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
914 struct l_dbus_message *message,
915 struct l_dbus_message_builder *builder,
918 l_dbus_message_builder_enter_array(builder, "(qqa{sv})");
919 l_dbus_message_builder_leave_array(builder);
924 static bool __mesh_element_index_getter(struct l_dbus *dbus,
925 struct l_dbus_message *message,
926 struct l_dbus_message_builder *builder,
929 meshcfg_el *element = (meshcfg_el*) user_data;
930 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
936 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
937 struct l_dbus_message *msg, void *user_data)
939 struct l_dbus_message_iter iter;
944 const char *dbus_path;
947 dbus_path = l_dbus_message_get_path(msg);
948 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
949 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
950 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
952 INFO("Mesh: app path [%s]", dbus_path);
954 memset(buf, 0, sizeof(buf));
955 size = (uint16_t) sizeof(*ev);
956 memcpy(ev->net_uuid, net_uuid, 16);
959 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
961 ERR("Mesh: Cannot parse received message");
962 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
965 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
966 ERR("Mesh: Cannot parse received message: data");
967 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
970 INFO("Mesh: Received dev key message (len %u):", n);
971 ev->source_addr = src;
972 ev->is_remote_devkey = rmt;
973 ev->netkey_idx = idx;
975 memcpy(ev->data, data, n);
978 INFO("Mesh: Src [0x%2.2x]", src);
979 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
980 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
981 /* Send DevKeyMessage Received event */
983 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
984 return l_dbus_message_new_method_return(msg);
987 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
988 struct l_dbus_message *msg, void *user_data)
990 struct l_dbus_message_iter iter;
991 uint16_t src, idx, dst;
994 const char *dbus_path;
996 bool is_provisioner = true;
998 dbus_path = l_dbus_message_get_path(msg);
999 GSList *l = g_slist_find_custom(mesh_apps, dbus_path, __compare_dbus_path);
1001 meshcfg_app *app = NULL;
1003 INFO("Mesh: is Provisioner [%d]", app->is_prov);
1004 is_provisioner = app->is_prov;
1006 ERR("Mesh: app is NULL");
1008 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, is_provisioner, MESH_ELEMENT_IFACE);
1009 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
1010 struct hal_ev_mesh_message_event *ev = (void *)buf;
1012 INFO("Mesh: app path [%s]", dbus_path);
1014 memset(buf, 0, sizeof(buf));
1015 size = (uint16_t) sizeof(*ev);
1016 memcpy(ev->net_uuid, net_uuid, 16);
1018 ev->is_prov = is_provisioner;
1020 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
1022 ERR("Mesh: Cannot parse received message");
1023 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1026 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
1027 ERR("Mesh: Cannot parse received message: data");
1028 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1031 INFO("Mesh: Received mesh message (len %u):", n);
1032 ev->source_addr = src;
1033 ev->dest_addr = dst;
1036 memcpy(ev->data, data, n);
1039 INFO("Mesh: Src [0x%2.2x]", src);
1040 INFO("Mesh: Dst [0x%2.2x]", dst);
1041 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
1042 /* Send Message Received event */
1043 if (mesh_event_cb) {
1044 INFO("Mesh: Send message event");
1045 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
1047 return l_dbus_message_new_method_return(msg);
1050 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
1052 INFO("Mesh: Setup element interface properties & methods");
1054 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
1056 l_dbus_interface_property(iface, "VendorModels", 0, "a(qqa{sv})",
1057 __mesh_vendor_model_getter, NULL);
1058 l_dbus_interface_property(iface, "Models", 0, "a(qa{sv})", __mesh_model_getter,
1062 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
1063 __mesh_device_message_received, "", "qbqay", "source",
1064 "remote", "net_index", "data");
1065 l_dbus_interface_method(iface, "MessageReceived", 0,
1066 __mesh_message_received, "", "qqvay", "source",
1067 "key_index", "destination", "data");
1068 /* TODO: Other methods */
1071 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
1072 struct l_dbus_message *msg,
1075 struct l_dbus_message_iter iter, opts;
1076 meshcfg_app *app = (meshcfg_app*) user_data;
1081 const char *sig = "naya{sv}";
1083 /* Find network uuid from dbus path */
1084 struct hal_ev_mesh_scan_result ev;
1086 if (!app->scan_timer_id) {
1087 /* Scan is not running */
1088 INFO("Got scan result, but scan is already stopped");
1089 return l_dbus_message_new_method_return(msg);
1091 memset(&ev, 0, sizeof(ev));
1092 memcpy(ev.net_uuid, app->uuid, 16);
1094 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
1095 ERR("Mesh: Cannot parse scan results");
1096 ev.status = BT_STATUS_FAIL;
1098 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1099 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1102 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
1104 ERR("Mesh: Cannot parse scan result: data");
1105 ev.status = BT_STATUS_FAIL;
1107 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
1108 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1111 INFO("Mesh: Scan result:\n");
1112 INFO("Mesh: Scan rssi = [%d]\n", rssi);
1113 str = l_util_hexstring_upper(prov_data, 16);
1114 INFO("Mesh: Scan UUID = [%s]\n", str);
1118 str = l_util_hexstring_upper(prov_data + 16, 2);
1119 INFO("Mesh: Scan OOB = [%s]\n", str);
1124 str = l_util_hexstring_upper(prov_data + 18, 4);
1125 INFO("Mesh: Scan URI hash = [%s]\n", str);
1129 /* 16 octet Dev UUID */
1130 memcpy(ev.dev_uuid, prov_data, 16);
1132 /* 2 octet Dev OOB Info */
1133 memcpy(ev.oob_info, prov_data + 16, 2);
1135 /* 4 octet URI Hash */
1136 memcpy(ev.uri_hash, prov_data + 18, 4);
1140 ev.status = BT_STATUS_SUCCESS;
1142 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1143 (void*)&ev, sizeof(ev));
1145 return l_dbus_message_new_method_return(msg);
1148 static struct l_dbus_message *__mesh_request_provisioner_call(
1149 struct l_dbus *dbus,
1150 struct l_dbus_message *msg,
1154 struct hal_ev_mesh_provision_finished ev;
1155 struct hal_ev_mesh_provision_data_request req;
1157 meshcfg_app *app = user_data;
1159 INFO("Mesh: provisioning data requested app path [%s]",
1161 uuid_string = l_util_hexstring(app->uuid, 16);
1162 INFO("Mesh: Network UUID [%s]", uuid_string);
1164 memset(&ev, 0, sizeof(ev));
1165 memset(&req, 0, sizeof(req));
1166 memcpy(ev.net_uuid, app->uuid, 16);
1167 memcpy(req.net_uuid, app->uuid, 16);
1168 l_free(uuid_string);
1170 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1171 ERR("Mesh: Cannot parse request for prov data");
1173 ev.status = BT_STATUS_FAIL;
1174 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1176 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1177 (void*)&ev, sizeof(ev));
1178 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1184 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1185 (void*)&req, sizeof(req));
1187 l_dbus_message_ref(msg);
1191 static struct l_dbus_message *__mesh_node_add_completed(
1192 struct l_dbus *dbus,
1193 struct l_dbus_message *msg,
1196 struct l_dbus_message_iter iter;
1201 struct hal_ev_mesh_provision_finished ev;
1202 const char *dbus_path;
1204 dbus_path = l_dbus_message_get_path(msg);
1205 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1206 true, MESH_PROV_IFACE);
1208 INFO("Mesh: app path [%s]", dbus_path);
1210 memset(&ev, 0, sizeof(ev));
1211 memcpy(ev.net_uuid, net_uuid, 16);
1215 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1216 ERR("Mesh: Cannot parse add node complete message");
1218 ev.status = BT_STATUS_FAIL;
1219 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1221 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1222 (void*)&ev, sizeof(ev));
1223 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1226 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1228 ERR("Mesh: Cannot parse add node complete message: uuid");
1230 ev.status = BT_STATUS_FAIL;
1231 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1233 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1234 (void*)&ev, sizeof(ev));
1235 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1239 ev.status = BT_STATUS_SUCCESS;
1240 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1241 memcpy(ev.dev_uuid, uuid, 16);
1242 ev.unicast = unicast;
1246 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1247 (void*)&ev, sizeof(ev));
1249 return l_dbus_message_new_method_return(msg);
1252 static struct l_dbus_message *__mesh_node_add_failed(
1253 struct l_dbus *dbus,
1254 struct l_dbus_message *msg,
1257 struct l_dbus_message_iter iter;
1261 struct hal_ev_mesh_provision_finished ev;
1262 const char *dbus_path;
1265 dbus_path = l_dbus_message_get_path(msg);
1266 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1267 true, MESH_PROV_IFACE);
1269 memset(&ev, 0, sizeof(ev));
1270 memcpy(ev.net_uuid, net_uuid, 16);
1273 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1274 ERR("Mesh: Cannot parse add node failed message");
1276 ev.status = BT_STATUS_FAIL;
1277 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1279 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1280 (void*)&ev, sizeof(ev));
1281 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1284 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1286 ERR("Mesh:Cannot parse add node failed message: uuid");
1287 ev.status = BT_STATUS_FAIL;
1288 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1290 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1291 (void*)&ev, sizeof(ev));
1292 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1295 INFO("Mesh: Provisioning failed:\n");
1296 str = l_util_hexstring_upper(uuid, 16);
1297 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1299 ev.status = BT_STATUS_FAIL;
1300 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1301 memcpy(ev.dev_uuid, uuid, 16);
1306 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1307 (void*)&ev, sizeof(ev));
1309 return l_dbus_message_new_method_return(msg);
1312 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1314 INFO("Mesh: Setup provisioner interface properties & methods");
1315 l_dbus_interface_method(interface, "ScanResult", 0,
1316 __mesh_scan_result_received, "",
1317 "naya{sv}", "rssi", "data", "options");
1319 l_dbus_interface_method(interface, "RequestProvData", 0,
1320 __mesh_request_provisioner_call,
1321 "qq", "y", "net_index", "unicast", "count");
1323 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1324 __mesh_node_add_completed, "", "ayqy",
1325 "uuid", "unicast", "count");
1327 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1328 __mesh_node_add_failed,
1329 "", "ays", "uuid", "reason");
1332 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1334 INFO("Mesh: Setup application interface properties & methods");
1336 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1337 __mesh_get_companyid,
1339 l_dbus_interface_property(iface, "VersionID", 0, "q",
1340 __mesh_get_versionid,
1342 l_dbus_interface_property(iface, "ProductID", 0, "q",
1343 __mesh_get_productid,
1345 l_dbus_interface_property(iface, "CRPL", 0, "q",
1346 __mesh_get_crpl, NULL);
1347 l_dbus_interface_method(iface, "JoinComplete", 0,
1348 __mesh_node_join_complete,
1354 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1355 struct l_dbus_message_builder *builder)
1357 if (app->in_oob & 0x08)
1358 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1359 if (app->in_oob & 0x04)
1360 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1361 if (app->in_oob & 0x02)
1362 l_dbus_message_builder_append_basic(builder, 's', "twist");
1363 if (app->in_oob & 0x01)
1364 l_dbus_message_builder_append_basic(builder, 's', "push");
1367 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1368 struct l_dbus_message_builder *builder)
1370 if (app->out_oob & 0x10)
1371 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1372 if (app->out_oob & 0x08)
1373 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1374 if (app->out_oob & 0x04)
1375 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1376 if (app->out_oob & 0x02)
1377 l_dbus_message_builder_append_basic(builder, 's', "beep");
1378 if (app->out_oob & 0x01)
1379 l_dbus_message_builder_append_basic(builder, 's', "blink");
1382 static bool __mesh_agent_capability_getter(
1383 struct l_dbus *dbus, struct l_dbus_message *message,
1384 struct l_dbus_message_builder *builder,
1389 INFO("Mesh: app path [%s]", app->path);
1390 INFO("Mesh: Agent path [%s]", app->agent_path);
1392 if (!l_dbus_message_builder_enter_array(builder, "s"))
1395 __mesh_fill_out_capabilities(app, builder);
1396 __mesh_fill_in_capabilities(app, builder);
1398 if (app->static_oob)
1399 l_dbus_message_builder_append_basic(builder,
1403 l_dbus_message_builder_leave_array(builder);
1404 INFO("Mesh: __agent_capability_getter: Success");
1408 static struct l_dbus_message *__mesh_agent_display_string_request(
1409 struct l_dbus *dbus,
1410 struct l_dbus_message *msg,
1413 struct hal_ev_mesh_authentication_request ev;
1416 const char *dbus_path;
1419 INFO("Mesh: app path [%s]", app->path);
1420 INFO("Mesh: Agent path [%s]", app->agent_path);
1422 dbus_path = l_dbus_message_get_path(msg);
1423 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1424 true, MESH_AGENT_IFACE);
1426 INFO("Mesh: app path [%s]", dbus_path);
1428 memset(&ev, 0, sizeof(ev));
1429 memcpy(ev.net_uuid, net_uuid, 16);
1432 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1433 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1434 struct hal_ev_mesh_provision_finished ev;
1435 memset(&ev, 0, sizeof(ev));
1436 memcpy(ev.net_uuid, net_uuid, 16);
1437 ev.status = BT_STATUS_FAIL;
1438 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1440 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1441 (void*)&ev, sizeof(ev));
1445 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1448 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1449 ev.auth_type = __mesh_get_authentication_type(str);
1450 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1451 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1452 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1455 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1456 (void*)&ev, sizeof(ev));
1459 return l_dbus_message_new_method_return(msg);
1462 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1463 struct l_dbus *dbus,
1464 struct l_dbus_message *msg,
1468 struct hal_ev_mesh_authentication_request ev;
1472 const char *dbus_path;
1475 INFO("Mesh: app path [%s]", app->path);
1476 INFO("Mesh: Agent path [%s]", app->agent_path);
1478 dbus_path = l_dbus_message_get_path(msg);
1479 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1480 true, MESH_AGENT_IFACE);
1482 INFO("Mesh: app path [%s]", dbus_path);
1484 memset(&ev, 0, sizeof(ev));
1485 memcpy(ev.net_uuid, net_uuid, 16);
1488 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1489 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1490 struct hal_ev_mesh_provision_finished ev;
1491 memset(&ev, 0, sizeof(ev));
1492 memcpy(ev.net_uuid, net_uuid, 16);
1493 ev.status = BT_STATUS_FAIL;
1494 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1495 if (mesh_event_cb) {
1496 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1497 (void*)&ev, sizeof(ev));
1500 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1503 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1504 auth_value = l_strdup_printf("%u", n);
1505 ev.auth_type = __mesh_get_authentication_type(str);
1506 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD) {
1509 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1511 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1514 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1515 (void*)&ev, sizeof(ev));
1520 return l_dbus_message_new_method_return(msg);
1523 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1524 struct l_dbus *dbus,
1525 struct l_dbus_message *msg,
1528 struct hal_ev_mesh_authentication_request ev;
1531 const char *dbus_path;
1535 dbus_path = l_dbus_message_get_path(msg);
1536 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1537 true, MESH_AGENT_IFACE);
1539 INFO("Mesh: app path [%s]", dbus_path);
1541 l = g_slist_find_custom(mesh_apps, net_uuid,
1542 __mesh_compare_network_uuid);
1549 memset(&ev, 0, sizeof(ev));
1550 memcpy(ev.net_uuid, net_uuid, 16);
1553 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1554 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1556 struct hal_ev_mesh_provision_finished ev;
1557 memset(&ev, 0, sizeof(ev));
1558 memcpy(ev.net_uuid, app->uuid, 16);
1559 ev.status = BT_STATUS_FAIL;
1560 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1561 if (mesh_event_cb) {
1562 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1563 (void*)&ev, sizeof(ev));
1565 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1568 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1570 ev.auth_type = __mesh_get_authentication_type(str);
1571 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1572 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1574 l_dbus_message_ref(msg);
1576 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1577 (void*)&ev, sizeof(ev));
1582 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1583 struct l_dbus *dbus,
1584 struct l_dbus_message *msg,
1587 struct hal_ev_mesh_authentication_request ev;
1590 const char *dbus_path;
1592 meshcfg_app *app = NULL;
1594 dbus_path = l_dbus_message_get_path(msg);
1595 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1598 INFO("Mesh: app path [%s]", dbus_path);
1600 l = g_slist_find_custom(mesh_apps, net_uuid,
1601 __mesh_compare_network_uuid);
1606 ERR("Mesh: app not found");
1609 memset(&ev, 0, sizeof(ev));
1610 memcpy(ev.net_uuid, net_uuid, 16);
1613 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1614 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1616 struct hal_ev_mesh_provision_finished ev;
1617 memset(&ev, 0, sizeof(ev));
1620 memcpy(ev.net_uuid, app->uuid, 16);
1622 ev.status = BT_STATUS_FAIL;
1623 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1625 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1626 (void*)&ev, sizeof(ev));
1627 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1630 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1632 ev.auth_type = __mesh_get_authentication_type(str);
1633 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1634 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1636 l_dbus_message_ref(msg);
1638 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1639 (void*)&ev, sizeof(ev));
1644 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1646 INFO("Mesh: Setup Agent interface properties & methods");
1647 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1648 __mesh_agent_capability_getter,
1650 /* TODO: Other properties */
1651 l_dbus_interface_method(interface, "DisplayString", 0,
1652 __mesh_agent_display_string_request,
1654 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1655 __mesh_agent_display_numeric_request,
1656 "", "su", "type", "number");
1657 l_dbus_interface_method(interface, "PromptNumeric", 0,
1658 __mesh_agent_prompt_numeric_request,
1659 "u", "s", "number", "type");
1660 l_dbus_interface_method(interface, "PromptStatic", 0,
1661 __mesh_agent_prompt_static_request,
1662 "ay", "s", "data", "type");
1665 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1667 meshcfg_el *elem = (meshcfg_el*) data;
1668 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1669 elem->index, elem->path);
1670 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1671 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1672 ERR("Mesh: Failed to register object %s", elem->path);
1676 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1681 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1682 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1683 ERR("Mesh: Unable to register agent interface");
1687 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1688 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1689 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1690 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1694 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1695 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1696 ERR("Mesh: Failed to add interface %s",
1697 L_DBUS_INTERFACE_PROPERTIES);
1704 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1712 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1713 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1714 ERR("Mesh: Failed to register interface %s",
1715 BT_HAL_MESH_APPLICATION_INTERFACE);
1719 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1720 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1721 ERR("Mesh: Failed to register interface %s",
1722 BT_HAL_MESH_PROVISIONER_INTERFACE);
1726 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1727 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1728 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1730 ERR("Mesh: Failed to register object %s", ptr->path);
1734 if (!__bt_hal_mesh_register_agent(ptr))
1737 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1738 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1739 ERR("Mesh: Failed to register interface %s",
1740 BT_HAL_MESH_ELEMENT_INTERFACE);
1744 INFO("Mesh: Number of elements to be registsred [%d]",
1745 g_slist_length(ptr->elements));
1747 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1749 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1750 if (!l_dbus_object_add_interface(dbus, ptr->path,
1751 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1752 ERR("Mesh: Failed to add interface %s",
1753 L_DBUS_INTERFACE_OBJECT_MANAGER);
1756 INFO("Mesh: Application Register completed");
1761 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1765 meshcfg_model *model_info = (meshcfg_model*) data;
1766 meshcfg_app *app = (meshcfg_app*) user_data;
1768 l = g_slist_find_custom(app->elements,
1769 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1773 elem = g_malloc0(sizeof(meshcfg_el));
1774 elem->index = model_info->elem_index;
1775 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1776 app->elements = g_slist_append(app->elements, elem);
1777 INFO("Mesh: Created element index [%d] path [%s]",
1778 elem->index, elem->path);
1780 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1781 model_info->model, elem->index);
1782 /* Add Model in the element */
1783 elem->models = g_slist_append(elem->models, model_info);
1784 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1785 elem->index, g_slist_length(elem->models));
1788 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1789 GSList *models, bool is_prov)
1792 meshcfg_app *app = NULL;
1793 char *uuid_str = NULL;
1795 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1796 INFO("Mesh: Network UUID [%s]", uuid_str);
1798 app = g_malloc0(sizeof(meshcfg_app));
1799 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1801 app->cid = node->vendor_info.companyid;
1802 app->pid = node->vendor_info.vendorid;
1803 app->vid = node->vendor_info.versionid;
1804 app->crpl = node->vendor_info.crpl;
1805 INFO("Mesh: is_prov [%d]", is_prov);
1808 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1809 app->agent_path = g_strdup_printf("%s/agent", app->path);
1812 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1813 app->agent_path = g_strdup_printf("%s/agent", app->path);
1815 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1818 app->is_prov = is_prov;
1819 app->token.u64 = node->token.u64;
1820 INFO("Mesh: Token [%llu]", (unsigned long long int)app->token.u64);
1821 INFO("Mesh: app created");
1825 static void __bt_hal_mesh_leave_net_reply(
1826 struct l_dbus_proxy *proxy,
1827 struct l_dbus_message *msg, void *user_data)
1830 app = (meshcfg_app*) user_data;
1832 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1833 if (l_dbus_message_is_error(msg)) {
1836 l_dbus_message_get_error(msg, &name, NULL);
1837 ERR("Mesh: Failed to leave network: %s", name);
1839 /* Send Network Destroy fail event */
1840 __send_network_destroy_event(app, BT_STATUS_FAIL);
1842 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1846 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1849 meshcfg_app *app = (meshcfg_app*) user_data;
1851 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1852 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1855 static void __bt_hal_mesh_release_net_reply(
1856 struct l_dbus_proxy *proxy,
1857 struct l_dbus_message *msg, void *user_data)
1860 app = (meshcfg_app*) user_data;
1862 INFO("Mesh:Release Network Reply from Meshd: app path [%s]", app->path);
1863 if (l_dbus_message_is_error(msg)) {
1866 l_dbus_message_get_error(msg, &name, NULL);
1867 ERR("Mesh: Failed to Release network: %s", name);
1870 INFO("Mesh: Release Network: Success, cleanup app after proxy removed");
1874 static void __bt_hal_mesh_release_net_setup(struct l_dbus_message *msg,
1877 meshcfg_app *app = (meshcfg_app*) user_data;
1879 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1880 INFO("Mesh: Release Network Setup app path [%s]", app->path);
1883 static void __bt_hal_mesh_create_net_reply(
1884 struct l_dbus_proxy *proxy,
1885 struct l_dbus_message *msg, void *user_data)
1888 app = (meshcfg_app*) user_data;
1890 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1891 if (l_dbus_message_is_error(msg)) {
1894 l_dbus_message_get_error(msg, &name, NULL);
1895 ERR("Mesh: Failed to create network: %s", name);
1897 /* Send Network creation fail event */
1898 __send_network_attach_event(app, BT_STATUS_FAIL);
1900 /* Destroy mesh app object */
1901 __bt_hal_mesh_destroy_app_object(app);
1906 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1910 struct l_dbus_message_builder *builder;
1911 app = (meshcfg_app*) user_data;
1913 builder = l_dbus_message_builder_new(msg);
1915 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1916 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1917 __mesh_append_byte_array(builder, app->uuid, 16);
1918 l_dbus_message_builder_finalize(builder);
1919 l_dbus_message_builder_destroy(builder);
1922 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1924 struct hal_ev_mesh_scan_state_changed ev;
1926 memset(&ev, 0, sizeof(ev));
1927 memcpy(ev.net_uuid, app->uuid, 16);
1929 ev.status = BT_STATUS_SUCCESS;
1931 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1933 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1934 (void*)&ev, sizeof(ev));
1937 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1939 meshcfg_app *app = (meshcfg_app*) user_data;
1940 __mesh_trigger_scan_finished_event(app);
1944 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1948 l = g_slist_find_custom(mesh_apps, net_uuid,
1949 __mesh_compare_network_uuid);
1954 if (app->scan_timer_id > 0) {
1955 g_source_remove(app->scan_timer_id);
1956 app->scan_timer_id = 0;
1959 app->scan_timer_id = g_timeout_add_seconds(secs,
1960 __bt_mesh_scan_timer_cb, app);
1965 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1966 struct l_dbus_message *msg, void *user_data)
1968 struct hal_ev_mesh_scan_state_changed ev;
1969 const char *dbus_path;
1971 dbus_path = l_dbus_proxy_get_path(proxy);
1972 INFO("Mesh: DBUS path [%s]", dbus_path);
1973 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1975 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1976 INFO("Mesh: Scan duration [%u]", secs);
1978 memset(&ev, 0, sizeof(ev));
1979 memcpy(ev.net_uuid, net_uuid, 16);
1981 if (l_dbus_message_is_error(msg)) {
1983 l_dbus_message_get_error(msg, &name, NULL);
1984 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1985 ev.status = BT_STATUS_FAIL;
1987 INFO("Mesh: Unprovisioned scan started\n");
1988 ev.status = BT_STATUS_SUCCESS;
1989 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1992 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1994 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1995 (void*)&ev, sizeof(ev));
1999 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
2001 struct l_dbus_message_builder *builder;
2002 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
2003 INFO("Mesh: Scan duration [%u]", secs);
2005 builder = l_dbus_message_builder_new(msg);
2006 l_dbus_message_builder_enter_array(builder, "{sv}");
2007 append_dict_entry_basic(builder, "Seconds", "q", &secs);
2008 l_dbus_message_builder_leave_array(builder);
2009 l_dbus_message_builder_finalize(builder);
2010 l_dbus_message_builder_destroy(builder);
2014 bt_status_t _bt_hal_mesh_network_set_caps(
2015 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
2019 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2023 app->public_oob = caps->public_oob;
2024 app->static_oob = caps->static_oob;
2025 app->out_oob = caps->out_oob;
2026 app->in_oob = caps->in_oob;
2028 ERR("Mesh: app not found!!");
2029 return BT_STATUS_PARM_INVALID;
2032 return BT_STATUS_SUCCESS;
2035 static void __bt_hal_mesh_add_node_reply(
2036 struct l_dbus_proxy *proxy,
2037 struct l_dbus_message *msg,
2040 struct hal_ev_mesh_provision_status ev;
2041 const char *dbus_path;
2043 dbus_path = l_dbus_proxy_get_path(proxy);
2044 INFO("Mesh: DBUS path [%s]", dbus_path);
2045 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2047 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
2049 INFO("Mesh: app path [%s]", dbus_path);
2051 memset(&ev, 0, sizeof(ev));
2052 memcpy(ev.net_uuid, net_uuid, 16);
2053 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
2055 /* Free User data */
2056 g_free((void*)dev_uuid);
2059 if (l_dbus_message_is_error(msg)) {
2062 l_dbus_message_get_error(msg, &name, NULL);
2063 ERR("Mesh: Failed to start provisioning: %s", name);
2064 ev.status = BT_STATUS_FAIL;
2066 INFO("Mesh: Provisioning started\n");
2067 ev.status = BT_STATUS_SUCCESS;
2070 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
2071 (void*)&ev, sizeof(ev));
2072 INFO("Mesh: Provisioning status sent");
2075 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
2079 bt_uuid_t *dev = user_data;
2080 struct l_dbus_message_builder *builder;
2082 uuid = l_util_hexstring(dev->uu, 16);
2086 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
2088 builder = l_dbus_message_builder_new(msg);
2089 __mesh_append_byte_array(builder, dev->uu, 16);
2090 l_dbus_message_builder_enter_array(builder, "{sv}");
2091 l_dbus_message_builder_leave_array(builder);
2092 l_dbus_message_builder_finalize(builder);
2093 l_dbus_message_builder_destroy(builder);
2098 bt_status_t _bt_hal_mesh_provision_device(
2099 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
2104 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2107 dev = g_memdup2((gpointer)dev_uuid, 16);
2108 INFO("Mesh: Schedule Add Node request to meshd");
2109 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
2110 __bt_hal_mesh_add_node_setup,
2111 __bt_hal_mesh_add_node_reply,
2113 return BT_STATUS_FAIL;
2115 ERR("Mesh: app not found!!");
2116 return BT_STATUS_PARM_INVALID;
2119 return BT_STATUS_SUCCESS;
2122 static void __bt_hal_mesh_subnet_key_setup(
2123 struct l_dbus_message *msg, void *user_data)
2125 struct subnet_key_request *req = user_data;
2126 uint16_t idx = (uint16_t) req->idx;
2128 l_dbus_message_set_arguments(msg, "q", idx);
2131 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
2132 struct l_dbus_message *msg, void *user_data)
2134 struct hal_ev_mesh_netkey_execute_event ev;
2135 const char *dbus_path;
2137 struct subnet_key_request *req = user_data;
2138 const char *method = req->str;
2140 dbus_path = l_dbus_proxy_get_path(proxy);
2141 INFO("Mesh: DBUS path [%s]", dbus_path);
2142 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2144 memset(&ev, 0, sizeof(ev));
2145 memcpy(ev.net_uuid, net_uuid, 16);
2146 ev.key_idx = req->idx;
2150 if (l_dbus_message_is_error(msg)) {
2153 l_dbus_message_get_error(msg, &name, NULL);
2154 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
2155 ev.status = BT_STATUS_FAIL;
2158 ev.status = BT_STATUS_SUCCESS;
2160 if (!strcmp("CreateSubnet", method)) {
2161 INFO("Mesh: Reply for CreateSubnet");
2162 ev.key_event = HAL_MESH_KEY_ADD;
2163 } else if (!strcmp("DeleteSubnet", method)) {
2164 INFO("Mesh: Reply for DeleteSubnet");
2165 ev.key_event = HAL_MESH_KEY_DELETE;
2166 } else if (!strcmp("UpdateSubnet", method)) {
2167 INFO("Mesh: Reply for UpdateSubnet");
2168 ev.key_event = HAL_MESH_KEY_UPDATE;
2172 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2173 (void*)&ev, sizeof(ev));
2176 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2177 uint16_t index, const char *key_execute_method)
2179 struct subnet_key_request *req;
2181 req = l_new(struct subnet_key_request, 1);
2182 req->str = key_execute_method;
2185 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2186 __bt_hal_mesh_subnet_key_setup,
2187 __bt_hal_mesh_subnet_key_reply,
2194 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2197 struct app_key_request *req = user_data;
2198 uint16_t net_idx = (uint16_t) req->net_idx;
2199 uint16_t app_idx = (uint16_t) req->app_idx;
2201 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2202 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2204 l_dbus_message_set_arguments(msg, "q", app_idx);
2207 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2208 struct l_dbus_message *msg, void *user_data)
2210 struct hal_ev_mesh_appkey_execute_event ev;
2211 const char *dbus_path;
2213 struct app_key_request *req = user_data;
2214 const char *method = req->str;
2216 dbus_path = l_dbus_proxy_get_path(proxy);
2217 INFO("Mesh: DBUS path [%s]", dbus_path);
2218 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2220 memset(&ev, 0, sizeof(ev));
2221 memcpy(ev.net_uuid, net_uuid, 16);
2222 ev.net_idx = req->net_idx;
2223 ev.app_idx = req->app_idx;
2227 if (l_dbus_message_is_error(msg)) {
2230 l_dbus_message_get_error(msg, &name, NULL);
2231 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2232 ev.status = BT_STATUS_FAIL;
2234 ev.status = BT_STATUS_SUCCESS;
2236 if (!strcmp("CreateAppKey", method)) {
2237 INFO("Mesh: AppKey Create Reply");
2238 ev.key_event = HAL_MESH_KEY_ADD;
2239 } else if (!strcmp("DeleteAppKey", method)) {
2240 INFO("Mesh: AppKey Delete Reply");
2241 ev.key_event = HAL_MESH_KEY_DELETE;
2242 } else if (!strcmp("UpdateAppKey", method)) {
2243 INFO("Mesh: AppKey Update Reply");
2244 ev.key_event = HAL_MESH_KEY_UPDATE;
2248 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2251 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2252 uint16_t net_idx, uint16_t app_idx,
2253 const char *key_execute_method)
2255 struct app_key_request *req;
2257 req = l_new(struct app_key_request, 1);
2258 req->str = key_execute_method;
2259 req->net_idx = net_idx;
2260 req->app_idx = app_idx;
2262 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2263 __bt_hal_mesh_app_key_setup,
2264 __bt_hal_mesh_app_key_reply,
2271 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2272 bt_mesh_key_op_e op, uint16_t netkey_idx)
2277 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2281 if (op == BT_MESH_KEY_CREATE)
2282 status = __mesh_subnet_netkey_command_execute(app,
2283 netkey_idx, "CreateSubnet");
2284 else if (op == BT_MESH_KEY_DELETE)
2285 status = __mesh_subnet_netkey_command_execute(app,
2286 netkey_idx, "DeleteSubnet");
2287 else if (op == BT_MESH_KEY_UPDATE)
2288 status = __mesh_subnet_netkey_command_execute(app,
2289 netkey_idx, "UpdateSubnet");
2291 return BT_STATUS_FAIL;
2294 ERR("Mesh: app not found!!");
2295 return BT_STATUS_PARM_INVALID;
2298 return BT_STATUS_SUCCESS;
2301 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2302 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2307 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2311 if (op == BT_MESH_KEY_CREATE)
2312 status = __mesh_subnet_appkey_command_execute(app,
2313 netkey_idx, appkey_idx, "CreateAppKey");
2314 else if (op == BT_MESH_KEY_DELETE)
2315 status = __mesh_subnet_appkey_command_execute(app,
2316 netkey_idx, appkey_idx, "DeleteAppKey");
2317 else if (op == BT_MESH_KEY_UPDATE) {
2318 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2319 netkey_idx, appkey_idx);
2320 status = __mesh_subnet_appkey_command_execute(app,
2321 netkey_idx, appkey_idx, "UpdateAppKey");
2324 return BT_STATUS_FAIL;
2327 ERR("Mesh: app not found!!");
2328 return BT_STATUS_PARM_INVALID;
2331 return BT_STATUS_SUCCESS;
2334 bt_status_t _bt_hal_mesh_send_provision_data(
2335 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2339 struct l_dbus_message *msg;
2340 struct l_dbus_message *reply;
2342 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2347 reply = l_dbus_message_new_method_return(msg);
2348 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2349 l_dbus_send(dbus, reply);
2351 ERR("Mesh: app not found!!");
2352 return BT_STATUS_PARM_INVALID;
2354 return BT_STATUS_SUCCESS;
2357 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2361 l = g_slist_find_custom(mesh_apps,
2362 net_uuid->uu, __mesh_compare_network_uuid);
2365 if (!__bt_mesh_proxy_check(app)) {
2366 ERR("Mesh: Proxy check failed!!");
2367 return BT_STATUS_FAIL;
2369 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2370 "UnprovisionedScanCancel",
2371 NULL, NULL, NULL, NULL))
2372 return BT_STATUS_FAIL;
2374 ERR("Mesh: app not found!!");
2375 return BT_STATUS_PARM_INVALID;
2378 /* Stop Scan timer */
2379 if (app->scan_timer_id > 0) {
2380 g_source_remove(app->scan_timer_id);
2381 app->scan_timer_id = 0;
2384 /* Trigger Scan finished event */
2385 __mesh_trigger_scan_finished_event(app);
2387 return BT_STATUS_SUCCESS;
2390 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2391 const char *auth_value)
2394 struct l_dbus_message *reply = NULL;
2395 struct l_dbus_message_builder *builder;
2397 bt_status_t ret = BT_STATUS_SUCCESS;
2401 if (!__bt_mesh_proxy_check(0)) {
2402 ERR("Mesh: Proxy check failed!!");
2403 return BT_STATUS_FAIL;
2405 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2406 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2407 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2408 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2409 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2410 INFO("Mesh: Authentication reply: Numeric Type");
2411 val_u32 = atoi(auth_value);
2412 reply = l_dbus_message_new_method_return(agent_msg);
2413 l_dbus_message_set_arguments(reply, "u", val_u32);
2415 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2416 l_dbus_send(dbus, reply);
2417 ret = BT_STATUS_SUCCESS;
2418 /* For Alpha-Numeric */
2419 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2420 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2421 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2422 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2423 alpha = l_util_from_hexstring(auth_value, &sz);
2424 reply = l_dbus_message_new_method_return(agent_msg);
2425 builder = l_dbus_message_builder_new(reply);
2426 __mesh_append_byte_array(builder, alpha, 16);
2427 l_dbus_message_builder_finalize(builder);
2428 l_dbus_message_builder_destroy(builder);
2431 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2432 l_dbus_send(dbus, reply);
2433 ret = BT_STATUS_SUCCESS;
2438 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2439 bt_hal_mesh_scan_param_t *param)
2443 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2446 if (!__bt_mesh_proxy_check(app)) {
2447 ERR("Mesh: Proxy check failed!!");
2448 return BT_STATUS_FAIL;
2450 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2451 __mesh_scan_setup, __mesh_scan_reply,
2452 L_UINT_TO_PTR(param->scan_time), NULL))
2453 return BT_STATUS_FAIL;
2455 ERR("Mesh: app not found!!");
2456 return BT_STATUS_PARM_INVALID;
2458 return BT_STATUS_SUCCESS;
2461 static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
2464 struct mesh_remote_node_info *node_info = \
2465 (struct mesh_remote_node_info*) user_data;
2467 l_dbus_message_set_arguments(msg, "qy",
2468 node_info->unicast, node_info->num_elements);
2469 INFO("Mesh: Delete Remote Node Setup params passed");
2472 static void __bt_hal_mesh_delete_node_reply(
2473 struct l_dbus_proxy *proxy,
2474 struct l_dbus_message *msg, void *user_data)
2476 INFO("Mesh: Delete Remote Node Reply from DBUS");
2479 bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
2480 uint16_t unicast, uint16_t num_elements)
2484 struct mesh_remote_node_info *node_info;
2485 INFO("Mesh: Delete Remote Node");
2486 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2489 if (!__bt_mesh_proxy_check(app)) {
2490 ERR("Mesh: Proxy check failed!!");
2491 return BT_STATUS_FAIL;
2493 INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
2494 unicast, num_elements);
2496 /* Delete Remote Node Request */
2497 node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
2498 node_info->unicast = unicast;
2499 node_info->num_elements = num_elements;
2501 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
2502 __bt_hal_mesh_delete_node_setup,
2503 __bt_hal_mesh_delete_node_reply, node_info,
2505 ERR("Mesh: Delete Remote Node Request failed!!");
2507 return BT_STATUS_FAIL;
2510 ERR("Mesh: App not found!!");
2511 return BT_STATUS_PARM_INVALID;
2513 INFO("Mesh: Delete Remote Node Call issued successfully!!");
2514 return BT_STATUS_SUCCESS;
2517 bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid)
2521 INFO("Mesh: Release Network");
2522 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2525 if (!__bt_mesh_proxy_check(app)) {
2526 ERR("Mesh: Proxy check failed!!");
2527 return BT_STATUS_FAIL;
2529 INFO("Mesh: Release Network");
2530 /* Create CFG Network */
2531 if (!l_dbus_proxy_method_call(net_proxy, "Release",
2532 __bt_hal_mesh_release_net_setup,
2533 __bt_hal_mesh_release_net_reply, app,
2535 ERR("Mesh: Network Release failed!!");
2536 return BT_STATUS_FAIL;
2539 ERR("Mesh: App not found!!");
2540 return BT_STATUS_PARM_INVALID;
2542 INFO("Mesh: Network Release Call issued successfully!!");
2543 return BT_STATUS_SUCCESS;
2546 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2550 INFO("Mesh: Destroy network");
2551 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2554 if (!__bt_mesh_proxy_check(app)) {
2555 ERR("Mesh: Proxy check failed!!");
2556 return BT_STATUS_FAIL;
2558 INFO("Mesh: Destroy Network");
2559 /* Create CFG Network */
2560 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2561 __bt_hal_mesh_leave_net_setup,
2562 __bt_hal_mesh_leave_net_reply, app,
2564 ERR("Mesh: Network Leave failed!!");
2565 return BT_STATUS_FAIL;
2568 ERR("Mesh: App not found!!");
2569 return BT_STATUS_PARM_INVALID;
2571 INFO("Mesh: Network Leave Call issued successfully!!");
2572 return BT_STATUS_SUCCESS;
2575 bt_status_t _bt_hal_mesh_create_network(
2576 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2580 INFO("Mesh: Create Network Request");
2582 if (!__bt_mesh_proxy_check(0)) {
2583 ERR("Mesh: Proxy check failed!!");
2584 return BT_STATUS_FAIL;
2587 INFO("Mesh: Node Element count [%d]", node->num_elements);
2588 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2589 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2590 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2591 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2592 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2593 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2594 INFO("Mesh: Token [%llu]", (unsigned long long int)node->token.u64);
2595 /* Create DBUS APP */
2596 app = __bt_hal_mesh_create_app(node, models, is_prov);
2598 return BT_STATUS_FAIL;
2600 /* Register DBUS APP */
2601 if (!__bt_hal_mesh_register_application(app))
2604 if (app->token.u64 == 0) {
2605 INFO("Mesh: Create New Network");
2606 /* Create CFG Network */
2607 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2608 __bt_hal_mesh_create_net_setup,
2609 __bt_hal_mesh_create_net_reply, app,
2611 ERR("Mesh: Network Create failed!!");
2615 INFO("Mesh: Attach Node to Network: Token [%llu]", (unsigned long long int)app->token.u64);
2616 /* Attach to Network */
2617 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2618 __bt_hal_mesh_attach_node_setup,
2619 __bt_hal_mesh_attach_node_reply,
2622 ERR("Mesh: Node attach failed!!");
2627 INFO("Mesh: Node registration request scheudled");
2628 mesh_apps = g_slist_append(mesh_apps, app);
2629 INFO("Mesh: Total number of apps in list [%d]",
2630 g_slist_length(mesh_apps));
2631 return BT_STATUS_SUCCESS;
2633 ERR("Mesh: network can not be created!!");
2634 __bt_hal_mesh_destroy_app_object(app);
2635 return BT_STATUS_FAIL;
2638 bt_status_t _bt_hal_mesh_join_network(
2639 bt_hal_mesh_node_t *node, GSList *models)
2643 INFO("Mesh: Join Network Request");
2645 if (!__bt_mesh_proxy_check(0)) {
2646 ERR("Mesh: Proxy check failed!!");
2647 return BT_STATUS_FAIL;
2650 INFO("Mesh: Node Element count [%d]", node->num_elements);
2651 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2652 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2653 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2654 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2655 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2656 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2657 INFO("Mesh: Token [%llu]", (unsigned long long int)node->token.u64);
2658 /* Create DBUS APP */
2659 app = __bt_hal_mesh_create_app(node, models, false);
2661 return BT_STATUS_FAIL;
2662 /* Register DBUS APP */
2663 if (!__bt_hal_mesh_register_application(app))
2666 INFO("Mesh: Create New Network");
2667 INFO("Mesh: app is_prov [%d]", app->is_prov);
2668 if (!l_dbus_proxy_method_call(net_proxy, "Join",
2669 __bt_hal_mesh_create_net_setup,
2670 __bt_hal_mesh_create_net_reply, app,
2672 ERR("Mesh: Join Network failed!!");
2676 INFO("Mesh: Node registration request scheudled");
2677 INFO("Mesh: Total number of apps in list Before [%d]",
2678 g_slist_length(mesh_apps));
2679 mesh_apps = g_slist_append(mesh_apps, app);
2680 INFO("Mesh: Total number of apps in list [%d]",
2681 g_slist_length(mesh_apps));
2682 return BT_STATUS_SUCCESS;
2684 ERR("Mesh: network can not be joined!!");
2685 __bt_hal_mesh_destroy_app_object(app);
2686 return BT_STATUS_FAIL;
2689 bt_status_t _bt_hal_mesh_join_cancel(bt_uuid_t *node_uuid)
2693 INFO("Mesh: Call cancel join");
2694 l = g_slist_last(mesh_apps);
2697 if (!l_dbus_proxy_method_call(net_proxy, "Cancel",
2701 ERR("Mesh: Cancel Join failed!!");
2702 return BT_STATUS_FAIL;
2705 ERR("Mesh: App not found!!");
2706 return BT_STATUS_PARM_INVALID;
2708 INFO("Mesh: Cancel Join request Call issued successfully!!");
2709 __bt_hal_mesh_destroy_app_object(app);
2710 return BT_STATUS_SUCCESS;
2713 static void __bt_hal_mesh_config_send(
2714 struct l_dbus_message *msg, void *user_data)
2716 struct configuration_request *req = user_data;
2717 struct l_dbus_message_builder *builder;
2719 builder = l_dbus_message_builder_new(msg);
2721 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2722 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2723 if (req->is_dev_key)
2724 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2726 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2729 l_dbus_message_builder_enter_array(builder, "{sv}");
2730 l_dbus_message_builder_enter_dict(builder, "sv");
2731 l_dbus_message_builder_leave_dict(builder);
2732 l_dbus_message_builder_leave_array(builder);
2734 __mesh_append_byte_array(builder, req->data, req->len);
2735 l_dbus_message_builder_finalize(builder);
2736 l_dbus_message_builder_destroy(builder);
2739 static void __bt_hal_mesh_key_config_send(
2740 struct l_dbus_message *msg, void *user_data)
2742 struct key_config_request *req = user_data;
2743 struct l_dbus_message_builder *builder;
2745 builder = l_dbus_message_builder_new(msg);
2747 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2748 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2749 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2750 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2751 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2752 l_dbus_message_builder_finalize(builder);
2753 l_dbus_message_builder_destroy(builder);
2756 static void __bt_hal_mesh_model_execute_message(
2757 struct l_dbus_message *msg, void *user_data)
2759 struct configuration_request *req = user_data;
2760 struct l_dbus_message_builder *builder;
2762 builder = l_dbus_message_builder_new(msg);
2764 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2765 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2766 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2769 l_dbus_message_builder_enter_array(builder, "{sv}");
2770 l_dbus_message_builder_enter_dict(builder, "sv");
2771 l_dbus_message_builder_leave_dict(builder);
2772 l_dbus_message_builder_leave_array(builder);
2774 __mesh_append_byte_array(builder, req->data, req->len);
2775 l_dbus_message_builder_finalize(builder);
2776 l_dbus_message_builder_destroy(builder);
2779 bt_status_t _bt_hal_mesh_send_key_config_message(
2780 bt_uuid_t *network, uint16_t dest,
2781 bool is_netkey, bool is_update,
2782 uint16_t key_idx, uint16_t netkey_idx)
2786 struct key_config_request *req;
2789 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2790 /* Source is Config Client Local Node */
2791 int src_elem_idx = 0;
2792 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2795 if (!__bt_mesh_proxy_check(app)) {
2796 ERR("Mesh: Proxy check failed!!");
2797 return BT_STATUS_FAIL;
2799 l1 = g_slist_find_custom(app->elements,
2800 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2802 return BT_STATUS_FAIL;
2805 req = l_new(struct key_config_request, 1);
2806 req->ele_path = elem->path;
2808 req->key_req_idx = key_idx;
2809 req->idx = netkey_idx; /* Encryption Key index */
2810 req->update_req = is_update;
2812 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2813 __bt_hal_mesh_key_config_send, NULL,
2814 (void*)req, l_free))
2815 return BT_STATUS_FAIL;
2817 ERR("Mesh: app not found!!");
2818 return BT_STATUS_PARM_INVALID;
2821 return BT_STATUS_SUCCESS;
2824 bt_status_t _bt_hal_mesh_send_configuration_message(
2825 bt_uuid_t *network, uint16_t dest,
2826 bool is_dev_key, uint16_t netkey_idx,
2827 uint8_t *buf, int len)
2831 struct configuration_request *req;
2834 int src_elem_idx = 0;
2835 l = g_slist_find_custom(mesh_apps, network->uu,
2836 __mesh_compare_network_uuid);
2839 if (!__bt_mesh_proxy_check(app)) {
2840 ERR("Mesh: Proxy check failed!!");
2841 return BT_STATUS_FAIL;
2843 l1 = g_slist_find_custom(app->elements,
2844 GUINT_TO_POINTER(src_elem_idx),
2845 __compare_element_index);
2847 return BT_STATUS_FAIL;
2850 req = l_new(struct configuration_request, 1);
2851 req->ele_path = elem->path;
2853 req->idx = netkey_idx;
2857 req->is_dev_key = is_dev_key;
2859 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2860 __bt_hal_mesh_config_send, NULL,
2861 (void*)req, l_free))
2862 return BT_STATUS_FAIL;
2864 ERR("Mesh: app not found!!");
2865 return BT_STATUS_PARM_INVALID;
2868 return BT_STATUS_SUCCESS;
2871 bt_status_t _bt_hal_mesh_model_execute_message(
2872 bt_uuid_t *network, uint16_t dest,
2873 uint16_t appkey_idx, uint8_t *buf, int len)
2877 struct configuration_request *req;
2880 int src_elem_idx = 0;
2881 l = g_slist_find_custom(mesh_apps, network->uu,
2882 __mesh_compare_network_uuid);
2885 if (!__bt_mesh_proxy_check(app)) {
2886 ERR("Mesh: Proxy check failed!!");
2887 return BT_STATUS_FAIL;
2889 l1 = g_slist_find_custom(app->elements,
2890 GUINT_TO_POINTER(src_elem_idx),
2891 __compare_element_index);
2893 return BT_STATUS_FAIL;
2896 req = l_new(struct configuration_request, 1);
2897 req->ele_path = elem->path;
2899 req->idx = appkey_idx;
2903 req->is_dev_key = false;
2905 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2906 __bt_hal_mesh_model_execute_message,
2907 NULL, (void*)req, l_free))
2908 return BT_STATUS_FAIL;
2910 ERR("Mesh: app not found!!");
2911 return BT_STATUS_PARM_INVALID;
2914 return BT_STATUS_SUCCESS;