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_UUID_LEN 16
40 #define BT_HAL_BLUEZ_MESH_NAME "org.bluez.mesh"
42 #define BT_HAL_MESH_NETWORK_INTERFACE "org.bluez.mesh.Network1"
43 #define BT_HAL_MESH_NODE_INTERFACE "org.bluez.mesh.Node1"
44 #define BT_HAL_MESH_MANAGEMENT_INTERFACE "org.bluez.mesh.Management1"
45 #define BT_HAL_MESH_ELEMENT_INTERFACE "org.bluez.mesh.Element1"
46 #define BT_HAL_MESH_APPLICATION_INTERFACE "org.bluez.mesh.Application1"
47 #define BT_HAL_MESH_PROVISION_AGENT_INTERFACE "org.bluez.mesh.ProvisionAgent1"
48 #define BT_HAL_MESH_PROVISIONER_INTERFACE "org.bluez.mesh.Provisioner1"
49 #define BT_HAL_MESH_ERROR_INTERFACE "org.bluez.mesh.Error"
51 #define BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE 2048
53 static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs";
54 static const char *dbus_err_fail = "org.freedesktop.DBus.Error.Failed";
56 static struct l_dbus *dbus = NULL;
57 static struct l_dbus_client *client = NULL;
59 static struct l_dbus_proxy *net_proxy;
60 static struct l_dbus_message *agent_msg;
62 static handle_stack_msg mesh_event_cb = NULL;
65 struct subnet_key_request {
70 struct app_key_request {
76 struct configuration_request {
86 struct key_config_request {
94 struct mesh_provision_auth_action {
96 bt_hal_mesh_auth_variant_e auth_type;
99 static struct mesh_provision_auth_action auth_table[] = {
100 { "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
101 { "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
102 { "vibrate", BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT},
103 { "in-numeric", BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT},
104 { "in-alpha", BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT},
105 { "twist", BT_HAL_MESH_AUTH_TWIST_COUNT_DISPLAY},
106 { "push", BT_HAL_MESH_AUTH_PUSH_COUNT_DISPLAY},
107 { "out-numeric", BT_HAL_MESH_AUTH_NUMERIC_DISPLAY},
108 { "out-alpha", BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY},
109 { "static-oob", BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT},
113 static uint8_t __bt_mesh_util_get_prov_error_code(char *prov_err_str)
117 if (!g_strcmp0(prov_err_str, "success"))
118 ret = BT_HAL_MESH_PROV_ERR_SUCCESS;
119 else if (!g_strcmp0(prov_err_str, "bad-pduread"))
120 ret = BT_HAL_MESH_PROV_ERR_INVALID_PDU;
121 else if (!g_strcmp0(prov_err_str, "confirmation-failed"))
122 ret = BT_HAL_MESH_PROV_ERR_CONFIRM_FAILED;
123 else if (!g_strcmp0(prov_err_str, "out-of-resources"))
124 ret = BT_HAL_MESH_PROV_ERR_INSUF_RESOURCE;
125 else if (!g_strcmp0(prov_err_str, "decryption-error"))
126 ret = BT_HAL_MESH_PROV_ERR_DECRYPT_FAILED;
127 else if (!g_strcmp0(prov_err_str, "cannot-assign-addresses"))
128 ret = BT_HAL_MESH_PROV_ERR_CANT_ASSIGN_ADDR;
129 else if (!g_strcmp0(prov_err_str, "timeout"))
130 ret = BT_HAL_MESH_PROV_ERR_TIMEOUT;
131 else if (!g_strcmp0(prov_err_str, "unexpected-error"))
132 ret = BT_HAL_MESH_PROV_ERR_UNEXPECTED_ERR;
137 static bt_hal_mesh_auth_variant_e __mesh_get_authentication_type(char *str)
139 int len = strlen(str);
140 int sz = L_ARRAY_SIZE(auth_table);
143 for (i = 0; i < sz; ++i)
144 if (len == strlen(auth_table[i].action) &&
145 !strcmp(str, auth_table[i].action))
148 return auth_table[i].auth_type;
151 enum mesh_dbus_interface_e {
158 typedef enum mesh_dbus_interface_e mesh_dbus_interface_e;
160 struct meshcfg_model {
165 typedef struct meshcfg_model meshcfg_model;
173 typedef struct meshcfg_el meshcfg_el;
176 /* Remember Proxies & dbus paths */
179 struct l_dbus_proxy *proxy;
180 struct l_dbus_proxy *mgmt_proxy;
182 /* Local node Info */
199 struct l_dbus_message *msg;
203 typedef struct meshcfg_app meshcfg_app;
205 /* Will contain critical data related to local Mesh Network */
209 struct meshcfg_node {
211 struct l_dbus_proxy *proxy;
212 struct l_dbus_proxy *mgmt_proxy;
219 typedef struct meshcfg_node meshcfg_node;
221 static void __mesh_append_byte_array(struct l_dbus_message_builder *builder,
222 unsigned char *data, unsigned int len)
226 l_dbus_message_builder_enter_array(builder, "y");
228 for (i = 0; i < len; i++)
229 l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
231 l_dbus_message_builder_leave_array(builder);
234 static gint __mesh_compare_network_uuid(gconstpointer data, gconstpointer user_data)
236 const meshcfg_app *app = (meshcfg_app*) data;
238 memcpy(uuid, (uint8_t*) user_data, 16);
240 return memcmp(uuid, app->uuid, sizeof(bt_uuid_t));
243 static unsigned char* __mesh_get_net_uuid_from_dbus_proxy_path(
244 const char *dbus_path)
249 memcpy(uuid, (void*)&dbus_path[20], sizeof(uuid));
251 INFO("Mesh: Net UUID string [%s]", uuid);
252 return l_util_from_hexstring(uuid, &sz);
255 static unsigned char* __mesh_get_net_uuid_from_path(
256 const char *dbus_path, bool is_prov,
257 mesh_dbus_interface_e iface)
264 case MESH_PROV_IFACE: {
265 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
267 return l_util_from_hexstring(uuid, &sz);
269 case MESH_AGENT_IFACE: {
270 memcpy(uuid, is_prov ? (void*) &dbus_path[22] : (void*) &dbus_path[23], 32);
272 return l_util_from_hexstring(uuid, &sz);
274 case MESH_ELEMENT_IFACE: {
275 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
277 return l_util_from_hexstring(uuid, &sz);
284 static void __mesh_hal_free_elements(gpointer data)
286 meshcfg_el *element = (meshcfg_el*) data;
287 g_free(element->path);
289 g_slist_free_full(element->models, g_free);
293 static void __bt_hal_mesh_destroy_app_object(gpointer data)
296 meshcfg_app *app = (meshcfg_app*) data;
300 mesh_apps = g_slist_remove(mesh_apps, app);
302 g_free(app->agent_path);
305 g_slist_free_full(app->elements, __mesh_hal_free_elements);
309 static void __mesh_client_connected(struct l_dbus *dbus, void *user_data)
311 ERR("MESH: D-Bus client connected\n");
314 static void __mesh_client_disconnected(struct l_dbus *dbus, void *user_data)
316 ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
317 /* TODO: Send event to app about meshd termination & then remove all mesh apps */
319 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
324 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
328 const meshcfg_app *app = (meshcfg_app*) data;
329 char *path = (char *) user_data;
330 INFO("Mesh: proxy path compare: path [%s]", path);
331 INFO("Mesh: App Path path [%s]", app->path);
335 app_uuid_path = l_util_hexstring(app->uuid, 16);
336 INFO("Mesh:App UUID string [%s]", app_uuid_path);
337 char **strings = g_strsplit(path, "node", 2);
339 INFO("Mesh:String 0 [%s]", strings[0]);
340 INFO("Mesh:String 1 [%s]", strings[1]);
341 ret = g_strcmp0(strings[1], app_uuid_path);
344 l_free(app_uuid_path);
348 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
350 const meshcfg_el *elem = data;
351 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
355 return (elem->index == elem_index ? 0: -1);
358 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
360 const char *interface = l_dbus_proxy_get_interface(proxy);
361 const char *path = l_dbus_proxy_get_path(proxy);
363 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
365 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
367 /* Save Global proxy */
372 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
375 INFO("Mesh: Number of mesh app present in list [%d]",
376 g_slist_length(mesh_apps));
377 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
380 app->mgmt_proxy = proxy;
382 ERR("Mesh: app not found for Mgmt proxy");
387 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
391 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
394 app->mgmt_proxy = proxy;
396 ERR("Mesh: app not found for Node proxy");
402 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
404 const char *interface = l_dbus_proxy_get_interface(proxy);
405 const char *path = l_dbus_proxy_get_path(proxy);
407 INFO("Proxy removed: %s (%s)\n", interface, path);
409 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
410 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
411 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
413 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
417 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
418 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
421 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
424 /*TODO: Send event to app about removal of a mesh local node */
425 __bt_hal_mesh_destroy_app_object(app);
427 ERR("Mesh: app not found for Mgmt proxy");
430 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
431 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
434 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
437 /*TODO: Send event to app about removal of
438 a mesh local node: first send event, then destroy mesh object */
439 __bt_hal_mesh_destroy_app_object(app);
441 ERR("Mesh: app not found for Mgmt proxy");
447 static void __mesh_dbus_client_ready(struct l_dbus_client *client,
450 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
451 /* TODO: Book keeping */
454 static void __mesh_ready_callback(void *user_data)
456 INFO("Mesh: Connected to D-Bus\n");
457 if (!l_dbus_object_manager_enable(dbus, "/"))
458 ERR("Mesh: Failed to register the ObjectManager\n");
461 bool _bt_hal_mesh_stack_init(void)
463 INFO("Mesh: Connect with meshd");
464 /* Connect with meshd */
465 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
469 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
472 client = l_dbus_client_new(dbus,
473 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
477 if (!l_dbus_client_set_connect_handler(client,
478 __mesh_client_connected, NULL, NULL))
481 if (!l_dbus_client_set_disconnect_handler(client,
482 __mesh_client_disconnected, NULL,
485 if (!l_dbus_client_set_proxy_handlers(client,
486 __mesh_proxy_added, __mesh_proxy_removed,
489 if (!l_dbus_client_set_ready_handler(client,
490 __mesh_dbus_client_ready, NULL, NULL))
493 INFO("Mesh: Stack Init watchers registered with meshd");
497 /* To send stack event to hal-mesh handler */
498 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
503 /* To send stack event to hal-mesh handler */
504 void _bt_hal_mesh_unregister_dbus_handler_cb()
506 mesh_event_cb = NULL;
509 static bool __mesh_get_companyid(struct l_dbus *dbus,
510 struct l_dbus_message *message,
511 struct l_dbus_message_builder *builder,
514 meshcfg_app *app = (meshcfg_app*) user_data;
518 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
523 static bool __mesh_get_productid(struct l_dbus *dbus,
524 struct l_dbus_message *message,
525 struct l_dbus_message_builder *builder,
528 meshcfg_app *app = (meshcfg_app*) user_data;
531 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
536 static bool __mesh_get_versionid(struct l_dbus *dbus,
537 struct l_dbus_message *message,
538 struct l_dbus_message_builder *builder,
541 meshcfg_app *app = (meshcfg_app*) user_data;
544 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
549 static bool __mesh_get_crpl(struct l_dbus *dbus,
550 struct l_dbus_message *message,
551 struct l_dbus_message_builder *builder,
554 meshcfg_app *app = (meshcfg_app*) user_data;
557 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
562 static void __send_network_attach_event(void *param, uint8_t status)
564 struct hal_ev_mesh_network_attached ev;
565 meshcfg_app *app = (meshcfg_app*)param;
567 memset(&ev, 0, sizeof(ev));
568 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
569 memcpy(ev.token, app->token.u8, 8);
573 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
574 (void*)&ev, sizeof(ev));
577 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
578 struct l_dbus_message *msg, void *user_data)
580 struct l_dbus_message_iter iter_cfg;
581 meshcfg_app *app = (meshcfg_app*) user_data;
582 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
583 app->path, app->agent_path);
585 if (l_dbus_message_is_error(msg)) {
587 l_dbus_message_get_error(msg, &name, NULL);
588 ERR("Mesh: Failed to attach node: %s", name);
593 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
594 &app->path, &iter_cfg))
597 INFO("Mesh: Attached with path %s\n", app->path);
598 __send_network_attach_event(app, BT_STATUS_SUCCESS);
601 __send_network_attach_event(app, BT_STATUS_FAIL);
602 /* Destroy mesh app object */
603 __bt_hal_mesh_destroy_app_object(app);
606 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
609 meshcfg_app *app = (meshcfg_app*) user_data;
611 l_dbus_message_set_arguments(msg, "ot", app->path,
612 l_get_be64(app->token.u8));
616 static void __bt_hal_mesh_attach_node(void *user_data)
618 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
619 __bt_hal_mesh_attach_node_setup,
620 __bt_hal_mesh_attach_node_reply,
623 ERR("Mesh: Node attach failed!!");
624 /* Node could not be attached */
625 __send_network_attach_event(user_data, BT_STATUS_FAIL);
626 /* Destroy mesh app object */
627 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
631 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
632 struct l_dbus_message *message,
638 meshcfg_app *app = (meshcfg_app*) user_data;
639 INFO("Mesh: Join Complete");
642 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
644 /* Send Network creation fail event */
645 __send_network_attach_event(app, BT_STATUS_FAIL);
647 /* Destroy mesh app object */
648 __bt_hal_mesh_destroy_app_object(app);
650 return l_dbus_message_new_error(message, dbus_err_args, NULL);
654 app->token.u64 = l_get_be64(&tmp);
655 str = l_util_hexstring(&app->token.u8[0], 8);
656 INFO("Mesh: Created new node with token %s\n", str);
659 /* Athenticate the node */
660 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
661 return l_dbus_message_new_method_return(message);
664 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
667 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
668 meshcfg_model *model_info = (meshcfg_model*) data;
670 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
673 static bool __mesh_model_getter(struct l_dbus *dbus,
674 struct l_dbus_message *message,
675 struct l_dbus_message_builder *builder,
678 meshcfg_el *element = (meshcfg_el*) user_data;
680 l_dbus_message_builder_enter_array(builder, "q");
681 g_slist_foreach(element->models,
682 __bt_hal_mesh_foreach_model_getter, builder);
684 l_dbus_message_builder_leave_array(builder);
689 /*TODO: Vendor Model handling is currently not Handled */
690 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
691 struct l_dbus_message *message,
692 struct l_dbus_message_builder *builder,
695 l_dbus_message_builder_enter_array(builder, "(qq)");
696 l_dbus_message_builder_leave_array(builder);
701 static bool __mesh_element_index_getter(struct l_dbus *dbus,
702 struct l_dbus_message *message,
703 struct l_dbus_message_builder *builder,
706 meshcfg_el *element = (meshcfg_el*) user_data;
707 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
713 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
714 struct l_dbus_message *msg, void *user_data)
716 struct l_dbus_message_iter iter;
721 const char *dbus_path;
724 dbus_path = l_dbus_message_get_path(msg);
725 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
726 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
727 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
729 INFO("Mesh: app path [%s]", dbus_path);
731 memset(buf, 0, sizeof(buf));
732 size = (uint16_t) sizeof(*ev);
733 memcpy(ev->net_uuid, net_uuid, 16);
736 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
738 ERR("Mesh: Cannot parse received message");
739 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
742 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
743 ERR("Mesh: Cannot parse received message: data");
744 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
747 INFO("Mesh: Received dev key message (len %u):", n);
748 ev->source_addr = src;
749 ev->is_remote_devkey = rmt;
750 ev->netkey_idx = idx;
752 memcpy(ev->data, buf, n);
755 /* Send DevKeyMessage Received event */
757 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
759 return l_dbus_message_new_method_return(msg);
762 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
764 INFO("Mesh: Setup element interface properties & methods");
766 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
768 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
769 __mesh_vendor_model_getter, NULL);
770 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
773 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
774 __mesh_device_message_received, "", "qbqay", "source",
775 "remote", "net_index", "data");
776 /* TODO: Other methods */
779 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
780 struct l_dbus_message *msg,
783 struct l_dbus_message_iter iter, opts;
784 meshcfg_app *app = (meshcfg_app*) user_data;
789 const char *sig = "naya{sv}";
791 /* Find network uuid from dbus path */
792 struct hal_ev_mesh_scan_result ev;
794 if (!app->scan_timer_id) {
795 /* Scan is not running */
796 INFO("Got scan result, but scan is already stopped");
797 return l_dbus_message_new_method_return(msg);
799 memset(&ev, 0, sizeof(ev));
800 memcpy(ev.net_uuid, app->uuid, 16);
802 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
803 ERR("Mesh: Cannot parse scan results");
804 ev.status = BT_STATUS_FAIL;
806 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
808 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
811 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
813 ERR("Mesh: Cannot parse scan result: data");
814 ev.status = BT_STATUS_FAIL;
816 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
818 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
821 INFO("Mesh: Scan result:\n");
822 INFO("Mesh: Scan rssi = [%d]\n", rssi);
823 str = l_util_hexstring_upper(prov_data, 16);
824 INFO("Mesh: Scan UUID = [%s]\n", str);
828 str = l_util_hexstring_upper(prov_data + 16, 2);
829 INFO("Mesh: Scan OOB = [%s]\n", str);
834 str = l_util_hexstring_upper(prov_data + 18, 4);
835 INFO("Mesh: Scan URI hash = [%s]\n", str);
839 /* 16 octet Dev UUID */
840 memcpy(ev.dev_uuid, prov_data, 16);
842 /* 2 octet Dev OOB Info */
843 memcpy(ev.oob_info, prov_data + 16, 2);
845 /* 4 octet URI Hash */
846 memcpy(ev.uri_hash, prov_data + 18, 4);
850 ev.status = BT_STATUS_SUCCESS;
852 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
853 (void*)&ev, sizeof(ev));
855 return l_dbus_message_new_method_return(msg);
858 static struct l_dbus_message *__mesh_request_provisioner_call(
860 struct l_dbus_message *msg,
864 struct hal_ev_mesh_provision_finished ev;
865 struct hal_ev_mesh_provision_data_request req;
866 meshcfg_app *app = user_data;
868 memset(&ev, 0, sizeof(ev));
869 memset(&req, 0, sizeof(req));
870 memcpy(ev.net_uuid, app->uuid, 16);
871 memcpy(req.net_uuid, app->uuid, 16);
873 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
874 ERR("Mesh: Cannot parse request for prov data");
876 ev.status = BT_STATUS_FAIL;
877 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
879 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
880 (void*)&ev, sizeof(ev));
881 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
887 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
888 (void*)&ev, sizeof(ev));
890 l_dbus_message_ref(msg);
894 static struct l_dbus_message *__mesh_node_add_completed(
896 struct l_dbus_message *msg,
899 struct l_dbus_message_iter iter;
904 struct hal_ev_mesh_provision_finished ev;
905 const char *dbus_path;
907 dbus_path = l_dbus_message_get_path(msg);
908 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
909 true, MESH_PROV_IFACE);
911 INFO("Mesh: app path [%s]", dbus_path);
913 memset(&ev, 0, sizeof(ev));
914 memcpy(ev.net_uuid, net_uuid, 16);
918 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
919 ERR("Mesh: Cannot parse add node complete message");
921 ev.status = BT_STATUS_FAIL;
922 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
924 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
925 (void*)&ev, sizeof(ev));
926 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
929 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
931 ERR("Mesh: Cannot parse add node complete message: uuid");
933 ev.status = BT_STATUS_FAIL;
934 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
936 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
937 (void*)&ev, sizeof(ev));
938 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
942 ev.status = BT_STATUS_SUCCESS;
943 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
944 memcpy(ev.dev_uuid, uuid, 16);
945 ev.unicast = unicast;
949 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
950 (void*)&ev, sizeof(ev));
952 return l_dbus_message_new_method_return(msg);
955 static struct l_dbus_message *__mesh_node_add_failed(
957 struct l_dbus_message *msg,
960 struct l_dbus_message_iter iter;
964 struct hal_ev_mesh_provision_finished ev;
965 const char *dbus_path;
968 dbus_path = l_dbus_message_get_path(msg);
969 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
970 true, MESH_PROV_IFACE);
972 memset(&ev, 0, sizeof(ev));
973 memcpy(ev.net_uuid, net_uuid, 16);
976 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
977 ERR("Mesh: Cannot parse add node failed message");
979 ev.status = BT_STATUS_FAIL;
980 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
982 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
983 (void*)&ev, sizeof(ev));
984 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
987 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
989 ERR("Mesh:Cannot parse add node failed message: uuid");
990 ev.status = BT_STATUS_FAIL;
991 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
993 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
994 (void*)&ev, sizeof(ev));
995 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
998 INFO("Mesh: Provisioning failed:\n");
999 str = l_util_hexstring_upper(uuid, 16);
1000 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1003 ev.status = BT_STATUS_FAIL;
1004 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1005 memcpy(ev.dev_uuid, uuid, 16);
1008 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1009 (void*)&ev, sizeof(ev));
1011 return l_dbus_message_new_method_return(msg);
1014 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1016 INFO("Mesh: Setup provisioner interface properties & methods");
1017 l_dbus_interface_method(interface, "ScanResult", 0,
1018 __mesh_scan_result_received, "",
1019 "naya{sv}", "rssi", "data", "options");
1021 l_dbus_interface_method(interface, "RequestProvData", 0,
1022 __mesh_request_provisioner_call,
1023 "qq", "y", "net_index", "unicast", "count");
1025 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1026 __mesh_node_add_completed, "", "ayqy",
1027 "uuid", "unicast", "count");
1029 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1030 __mesh_node_add_failed,
1031 "", "ays", "uuid", "reason");
1034 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1036 INFO("Mesh: Setup application interface properties & methods");
1038 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1039 __mesh_get_companyid,
1041 l_dbus_interface_property(iface, "VersionID", 0, "q",
1042 __mesh_get_versionid,
1044 l_dbus_interface_property(iface, "ProductID", 0, "q",
1045 __mesh_get_productid,
1047 l_dbus_interface_property(iface, "CRPL", 0, "q",
1048 __mesh_get_crpl, NULL);
1049 l_dbus_interface_method(iface, "JoinComplete", 0,
1050 __mesh_node_join_complete,
1056 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1057 struct l_dbus_message_builder *builder)
1059 if (app->in_oob & 0x08)
1060 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1061 if (app->in_oob & 0x04)
1062 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1063 if (app->in_oob & 0x02)
1064 l_dbus_message_builder_append_basic(builder, 's', "twist");
1065 if (app->in_oob & 0x01)
1066 l_dbus_message_builder_append_basic(builder, 's', "push");
1069 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1070 struct l_dbus_message_builder *builder)
1072 if (app->out_oob & 0x10)
1073 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1074 if (app->out_oob & 0x08)
1075 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1076 if (app->out_oob & 0x04)
1077 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1078 if (app->out_oob & 0x02)
1079 l_dbus_message_builder_append_basic(builder, 's', "beep");
1080 if (app->out_oob & 0x01)
1081 l_dbus_message_builder_append_basic(builder, 's', "blink");
1084 static bool __mesh_agent_capability_getter(
1085 struct l_dbus *dbus,struct l_dbus_message *message,
1086 struct l_dbus_message_builder *builder,
1091 INFO("Mesh: app path [%s]", app->path);
1092 INFO("Mesh: Agent path [%s]", app->agent_path);
1094 if (!l_dbus_message_builder_enter_array(builder, "s")) {
1098 __mesh_fill_out_capabilities(app, builder);
1099 __mesh_fill_in_capabilities(app, builder);
1101 if (app->static_oob)
1102 l_dbus_message_builder_append_basic(builder,
1106 l_dbus_message_builder_leave_array(builder);
1107 INFO("Mesh: __agent_capability_getter: Success");
1111 static struct l_dbus_message *__mesh_agent_display_string_request(
1112 struct l_dbus *dbus,
1113 struct l_dbus_message *msg,
1116 struct hal_ev_mesh_authentication_request ev;
1119 const char *dbus_path;
1122 INFO("Mesh: app path [%s]", app->path);
1123 INFO("Mesh: Agent path [%s]", app->agent_path);
1125 dbus_path = l_dbus_message_get_path(msg);
1126 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1127 true, MESH_AGENT_IFACE);
1129 INFO("Mesh: app path [%s]", dbus_path);
1131 memset(&ev, 0, sizeof(ev));
1132 memcpy(ev.net_uuid, net_uuid, 16);
1135 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1136 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1137 struct hal_ev_mesh_provision_finished ev;
1138 memset(&ev, 0, sizeof(ev));
1139 memcpy(ev.net_uuid, net_uuid, 16);
1140 ev.status = BT_STATUS_FAIL;
1141 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1143 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1144 (void*)&ev, sizeof(ev));
1148 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1151 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1152 ev.auth_type = BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY;
1153 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1156 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1157 (void*)&ev, sizeof(ev));
1160 return l_dbus_message_new_method_return(msg);
1163 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1164 struct l_dbus *dbus,
1165 struct l_dbus_message *msg,
1169 struct hal_ev_mesh_authentication_request ev;
1173 const char *dbus_path;
1176 INFO("Mesh: app path [%s]", app->path);
1177 INFO("Mesh: Agent path [%s]", app->agent_path);
1179 dbus_path = l_dbus_message_get_path(msg);
1180 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1181 true, MESH_AGENT_IFACE);
1183 INFO("Mesh: app path [%s]", dbus_path);
1185 memset(&ev, 0, sizeof(ev));
1186 memcpy(ev.net_uuid, net_uuid, 16);
1189 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1190 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1191 struct hal_ev_mesh_provision_finished ev;
1192 memset(&ev, 0, sizeof(ev));
1193 memcpy(ev.net_uuid, net_uuid, 16);
1194 ev.status = BT_STATUS_FAIL;
1195 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1196 if (mesh_event_cb) {
1197 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1198 (void*)&ev, sizeof(ev));
1201 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1204 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1205 auth_value = l_strdup_printf("%u",n);
1206 ev.auth_type = __mesh_get_authentication_type(str);
1207 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1210 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1211 (void*)&ev, sizeof(ev));
1215 return l_dbus_message_new_method_return(msg);
1218 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1219 struct l_dbus *dbus,
1220 struct l_dbus_message *msg,
1223 struct hal_ev_mesh_authentication_request ev;
1226 const char *dbus_path;
1230 dbus_path = l_dbus_message_get_path(msg);
1231 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1232 true, MESH_AGENT_IFACE);
1234 INFO("Mesh: app path [%s]", dbus_path);
1236 l = g_slist_find_custom(mesh_apps, net_uuid,
1237 __mesh_compare_network_uuid);
1240 memset(&ev, 0, sizeof(ev));
1241 memcpy(ev.net_uuid, net_uuid, 16);
1244 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1245 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1247 struct hal_ev_mesh_provision_finished ev;
1248 memset(&ev, 0, sizeof(ev));
1249 memcpy(ev.net_uuid, app->uuid, 16);
1250 ev.status = BT_STATUS_FAIL;
1251 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1252 if (mesh_event_cb) {
1253 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1254 (void*)&ev, sizeof(ev));
1256 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1259 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1261 ev.auth_type = __mesh_get_authentication_type(str);
1263 l_dbus_message_ref(msg);
1265 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1266 (void*)&ev, sizeof(ev));
1271 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1272 struct l_dbus *dbus,
1273 struct l_dbus_message *msg,
1276 struct hal_ev_mesh_authentication_request ev;
1279 const char *dbus_path;
1283 dbus_path = l_dbus_message_get_path(msg);
1284 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1287 INFO("Mesh: app path [%s]", dbus_path);
1289 l = g_slist_find_custom(mesh_apps, net_uuid,
1290 __mesh_compare_network_uuid);
1293 memset(&ev, 0, sizeof(ev));
1294 memcpy(ev.net_uuid, net_uuid, 16);
1297 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1298 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1300 struct hal_ev_mesh_provision_finished ev;
1301 memset(&ev, 0, sizeof(ev));
1302 memcpy(ev.net_uuid, app->uuid, 16);
1303 ev.status = BT_STATUS_FAIL;
1304 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1306 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1307 (void*)&ev, sizeof(ev));
1308 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1311 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1313 ev.auth_type = __mesh_get_authentication_type(str);
1315 l_dbus_message_ref(msg);
1317 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1318 (void*)&ev, sizeof(ev));
1323 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1325 INFO("Mesh: Setup Agent interface properties & methods");
1326 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1327 __mesh_agent_capability_getter,
1329 /* TODO: Other properties */
1330 l_dbus_interface_method(interface, "DisplayString", 0,
1331 __mesh_agent_display_string_request,
1333 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1334 __mesh_agent_display_numeric_request,
1335 "", "su", "type", "number");
1336 l_dbus_interface_method(interface, "PromptNumeric", 0,
1337 __mesh_agent_prompt_numeric_request,
1338 "u", "s", "number", "type");
1339 l_dbus_interface_method(interface, "PromptStatic", 0,
1340 __mesh_agent_prompt_static_request,
1341 "ay", "s", "data", "type");
1344 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1346 meshcfg_el *elem = (meshcfg_el*) data;
1347 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1348 elem->index, elem->path);
1349 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1350 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1351 ERR("Mesh: Failed to register object %s", elem->path);
1355 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1360 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1361 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1362 ERR("Mesh: Unable to register agent interface");
1366 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1367 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1368 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1369 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1373 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1374 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1375 ERR("Mesh: Failed to add interface %s",
1376 L_DBUS_INTERFACE_PROPERTIES);
1383 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1389 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1390 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1391 ERR("Mesh: Failed to register interface %s",
1392 BT_HAL_MESH_APPLICATION_INTERFACE);
1396 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1397 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1398 ERR("Mesh: Failed to register interface %s",
1399 BT_HAL_MESH_PROVISIONER_INTERFACE);
1403 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1404 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1405 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1407 ERR("Mesh: Failed to register object %s", ptr->path);
1411 if (!__bt_hal_mesh_register_agent(ptr))
1414 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1415 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1416 ERR("Mesh: Failed to register interface %s",
1417 BT_HAL_MESH_ELEMENT_INTERFACE);
1421 INFO("Mesh: Number of elements to be registsred [%d]",
1422 g_slist_length(ptr->elements));
1424 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1426 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1427 if (!l_dbus_object_add_interface(dbus, ptr->path,
1428 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1429 ERR("Mesh: Failed to add interface %s",
1430 L_DBUS_INTERFACE_OBJECT_MANAGER);
1433 INFO("Mesh: Application Register completed");
1438 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1442 meshcfg_model *model_info = (meshcfg_model*) data;
1443 meshcfg_app *app = (meshcfg_app*) user_data;
1445 l = g_slist_find_custom(app->elements,
1446 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1450 elem = g_malloc0(sizeof(meshcfg_el));
1451 elem->index = model_info->elem_index;
1452 elem->path = g_strdup_printf("%s/elem%u",app->path, elem->index);
1453 app->elements = g_slist_append(app->elements, elem);
1454 INFO("Mesh: Created element index [%d] path [%s]",
1455 elem->index, elem->path);
1457 /* Add Model in the element */
1458 elem->models = g_slist_append(elem->models, model_info);
1459 INFO("Mesh: total models of the element with index [%d] is [%d]",
1460 elem->index, g_slist_length(elem->models));
1463 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1464 GSList *models, bool is_prov)
1467 meshcfg_app *app = NULL;
1468 char *uuid_str = NULL;
1470 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1472 app = g_malloc0(sizeof(meshcfg_app));
1473 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1475 app->cid = node->vendor_info.companyid;
1476 app->pid = node->vendor_info.vendorid;
1477 app->vid = node->vendor_info.versionid;
1478 app->crpl = node->vendor_info.crpl;
1481 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1482 app->agent_path = g_strdup_printf("/tizen/mesh/cfg/agent/%s", uuid_str);
1485 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1486 app->agent_path = g_strdup_printf("/tizen/mesh/node/agent/%s", uuid_str);
1488 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1491 app->is_prov = is_prov;
1492 INFO("Mesh: app created");
1496 static void __bt_hal_mesh_create_net_reply(
1497 struct l_dbus_proxy *proxy,
1498 struct l_dbus_message *msg, void *user_data)
1501 app = (meshcfg_app*) user_data;
1503 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1504 if (l_dbus_message_is_error(msg)) {
1507 l_dbus_message_get_error(msg, &name, NULL);
1508 ERR("Mesh: Failed to create network: %s", name);
1510 /* Send Network creation fail event */
1511 __send_network_attach_event(app, BT_STATUS_FAIL);
1513 /* Destroy mesh app object */
1514 __bt_hal_mesh_destroy_app_object(app);
1519 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1523 struct l_dbus_message_builder *builder;
1524 app = (meshcfg_app*) user_data;
1526 builder = l_dbus_message_builder_new(msg);
1528 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1529 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1530 __mesh_append_byte_array(builder, app->uuid, 16);
1531 l_dbus_message_builder_finalize(builder);
1532 l_dbus_message_builder_destroy(builder);
1535 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1537 struct hal_ev_mesh_scan_state_changed ev;
1539 memset(&ev, 0, sizeof(ev));
1540 memcpy(ev.net_uuid, app->uuid, 16);
1542 ev.status = BT_STATUS_SUCCESS;
1544 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1546 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1547 (void*)&ev, sizeof(ev));
1550 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1552 meshcfg_app *app = (meshcfg_app*) user_data;
1553 __mesh_trigger_scan_finished_event(app);
1557 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1561 l = g_slist_find_custom(mesh_apps, net_uuid,
1562 __mesh_compare_network_uuid);
1565 if (app->scan_timer_id > 0) {
1566 g_source_remove(app->scan_timer_id);
1567 app->scan_timer_id = 0;
1570 app->scan_timer_id = g_timeout_add_seconds(secs,
1571 __bt_mesh_scan_timer_cb, app);
1576 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1577 struct l_dbus_message *msg, void *user_data)
1579 struct hal_ev_mesh_scan_state_changed ev;
1580 const char *dbus_path;
1582 dbus_path = l_dbus_proxy_get_path(proxy);
1583 INFO("Mesh: DBUS path [%s]", dbus_path);
1584 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1586 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1587 INFO("Mesh: Scan duration [%u]", secs);
1589 memset(&ev, 0, sizeof(ev));
1590 memcpy(ev.net_uuid, net_uuid, 16);
1592 if (l_dbus_message_is_error(msg)) {
1594 l_dbus_message_get_error(msg, &name, NULL);
1595 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1596 ev.status = BT_STATUS_FAIL;
1598 INFO("Mesh: Unprovisioned scan started\n");
1599 ev.status = BT_STATUS_SUCCESS;
1600 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1603 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1605 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1606 (void*)&ev, sizeof(ev));
1610 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1611 const char *key, const char *signature,
1617 l_dbus_message_builder_enter_dict(builder, "sv");
1618 l_dbus_message_builder_append_basic(builder, 's', key);
1619 l_dbus_message_builder_enter_variant(builder, signature);
1620 l_dbus_message_builder_append_basic(builder, signature[0], data);
1621 l_dbus_message_builder_leave_variant(builder);
1622 l_dbus_message_builder_leave_dict(builder);
1625 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1627 struct l_dbus_message_builder *builder;
1628 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1629 INFO("Mesh: Scan duration [%u]", secs);
1631 builder = l_dbus_message_builder_new(msg);
1632 l_dbus_message_builder_enter_array(builder, "{sv}");
1633 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1634 l_dbus_message_builder_leave_array(builder);
1635 l_dbus_message_builder_finalize(builder);
1636 l_dbus_message_builder_destroy(builder);
1640 bt_status_t _bt_hal_mesh_network_set_caps(
1641 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1645 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1649 app->public_oob = caps->public_oob;
1650 app->static_oob = caps->static_oob;
1651 app->out_oob = caps->out_oob;
1652 app->in_oob = caps->in_oob;
1654 ERR("Mesh: app not found!!");
1655 return BT_STATUS_PARM_INVALID;
1658 return BT_STATUS_SUCCESS;
1661 static void __bt_hal_mesh_add_node_reply(
1662 struct l_dbus_proxy *proxy,
1663 struct l_dbus_message *msg,
1666 struct hal_ev_mesh_provision_status ev;
1667 const char *dbus_path;
1669 dbus_path = l_dbus_proxy_get_path(proxy);
1670 INFO("Mesh: DBUS path [%s]", dbus_path);
1671 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1673 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1675 INFO("Mesh: app path [%s]", dbus_path);
1677 memset(&ev, 0, sizeof(ev));
1678 memcpy(ev.net_uuid, net_uuid, 16);
1679 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1681 /* Free User data */
1682 g_free((void*)dev_uuid);
1685 if (l_dbus_message_is_error(msg)) {
1688 l_dbus_message_get_error(msg, &name, NULL);
1689 ERR("Mesh: Failed to start provisioning: %s", name);
1690 ev.status = BT_STATUS_FAIL;
1692 INFO("Mesh: Provisioning started\n");
1693 ev.status = BT_STATUS_SUCCESS;
1696 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1697 (void*)&ev, sizeof(ev));
1700 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1703 bt_uuid_t *dev = user_data;
1704 struct l_dbus_message_builder *builder;
1706 builder = l_dbus_message_builder_new(msg);
1707 __mesh_append_byte_array(builder, dev->uu, 16);
1708 l_dbus_message_builder_enter_array(builder, "{sv}");
1709 l_dbus_message_builder_leave_array(builder);
1710 l_dbus_message_builder_finalize(builder);
1711 l_dbus_message_builder_destroy(builder);
1716 bt_status_t _bt_hal_mesh_provision_device(
1717 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1722 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1725 dev = g_memdup((gpointer)dev_uuid, 16);
1727 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1728 __bt_hal_mesh_add_node_setup,
1729 __bt_hal_mesh_add_node_reply,
1731 return BT_STATUS_FAIL;
1733 ERR("Mesh: app not found!!");
1734 return BT_STATUS_PARM_INVALID;
1737 return BT_STATUS_SUCCESS;
1740 static void __bt_hal_mesh_subnet_key_setup(
1741 struct l_dbus_message *msg, void *user_data)
1743 struct subnet_key_request *req = user_data;
1744 uint16_t idx = (uint16_t) req->idx;
1746 l_dbus_message_set_arguments(msg, "q", idx);
1749 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1750 struct l_dbus_message *msg, void *user_data)
1752 struct hal_ev_mesh_netkey_execute_event ev;
1753 const char *dbus_path;
1755 struct subnet_key_request *req = user_data;
1756 const char *method = req->str;
1758 dbus_path = l_dbus_proxy_get_path(proxy);
1759 INFO("Mesh: DBUS path [%s]", dbus_path);
1760 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1762 memset(&ev, 0, sizeof(ev));
1763 memcpy(ev.net_uuid, net_uuid, 16);
1764 ev.key_idx = req->idx;
1768 if (l_dbus_message_is_error(msg)) {
1771 l_dbus_message_get_error(msg, &name, NULL);
1772 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
1773 ev.status = BT_STATUS_FAIL;
1776 ev.status = BT_STATUS_SUCCESS;
1778 if (!strcmp("CreateSubnet", method)) {
1779 ev.key_event = HAL_MESH_KEY_ADD;
1780 } else if (!strcmp("DeleteSubnet", method)) {
1781 ev.key_event = HAL_MESH_KEY_DELETE;
1782 } else if (!strcmp("UpdateSubnet", method)) {
1783 ev.key_event = HAL_MESH_KEY_UPDATE;
1787 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
1788 (void*)&ev, sizeof(ev));
1791 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
1792 uint16_t index, const char *key_execute_method)
1794 struct subnet_key_request *req;
1796 req = l_new(struct subnet_key_request, 1);
1797 req->str = key_execute_method;
1800 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1801 __bt_hal_mesh_subnet_key_setup,
1802 __bt_hal_mesh_subnet_key_reply,
1809 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
1812 struct app_key_request *req = user_data;
1813 uint16_t net_idx = (uint16_t) req->net_idx;
1814 uint16_t app_idx = (uint16_t) req->app_idx;
1816 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
1819 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
1820 struct l_dbus_message *msg, void *user_data)
1822 struct hal_ev_mesh_appkey_execute_event ev;
1823 const char *dbus_path;
1825 struct app_key_request *req = user_data;
1826 const char *method = req->str;
1828 dbus_path = l_dbus_proxy_get_path(proxy);
1829 INFO("Mesh: DBUS path [%s]", dbus_path);
1830 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1832 memset(&ev, 0, sizeof(ev));
1833 memcpy(ev.net_uuid, net_uuid, 16);
1834 ev.net_idx = req->net_idx;
1835 ev.app_idx = req->app_idx;
1839 if (l_dbus_message_is_error(msg)) {
1842 l_dbus_message_get_error(msg, &name, NULL);
1843 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
1844 ev.status = BT_STATUS_FAIL;
1847 ev.status = BT_STATUS_SUCCESS;
1849 if (!strcmp("CreateAppKey", method)) {
1850 ev.key_event = HAL_MESH_KEY_ADD;
1851 } else if (!strcmp("DeleteAppKey", method)) {
1852 ev.key_event = HAL_MESH_KEY_DELETE;
1853 } else if (!strcmp("UpdateAppKey", method)) {
1854 ev.key_event = HAL_MESH_KEY_UPDATE;
1858 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
1861 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
1862 uint16_t net_idx, uint16_t app_idx,
1863 const char *key_execute_method)
1865 struct app_key_request *req;
1867 req = l_new(struct app_key_request, 1);
1868 req->str = key_execute_method;
1869 req->net_idx = net_idx;
1870 req->app_idx = app_idx;
1872 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1873 __bt_hal_mesh_app_key_setup,
1874 __bt_hal_mesh_app_key_reply,
1881 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
1882 bt_mesh_key_op_e op, uint16_t netkey_idx)
1887 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1891 if (op == BT_MESH_KEY_CREATE)
1892 status = __mesh_subnet_netkey_command_execute(app,
1893 netkey_idx, "CreateSubnet");
1894 else if (op == BT_MESH_KEY_DELETE)
1895 status = __mesh_subnet_netkey_command_execute(app,
1896 netkey_idx, "DeleteSubnet");
1897 else if (op == BT_MESH_KEY_UPDATE)
1898 status = __mesh_subnet_netkey_command_execute(app,
1899 netkey_idx, "UpdateSubnet");
1901 return BT_STATUS_FAIL;
1904 ERR("Mesh: app not found!!");
1905 return BT_STATUS_PARM_INVALID;
1908 return BT_STATUS_SUCCESS;
1911 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
1912 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
1917 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1921 if (op == BT_MESH_KEY_CREATE)
1922 status = __mesh_subnet_appkey_command_execute(app,
1923 netkey_idx, appkey_idx, "CreateAppKey");
1924 else if (op == BT_MESH_KEY_DELETE)
1925 status = __mesh_subnet_appkey_command_execute(app,
1926 netkey_idx, appkey_idx, "DeleteAppKey");
1927 else if (op == BT_MESH_KEY_UPDATE)
1928 status = __mesh_subnet_appkey_command_execute(app,
1929 netkey_idx, appkey_idx, "UpdateAppKey");
1931 return BT_STATUS_FAIL;
1934 ERR("Mesh: app not found!!");
1935 return BT_STATUS_PARM_INVALID;
1938 return BT_STATUS_SUCCESS;
1941 bt_status_t _bt_hal_mesh_send_provision_data(
1942 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
1946 struct l_dbus_message *msg;
1947 struct l_dbus_message *reply;
1949 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1954 reply = l_dbus_message_new_method_return(msg);
1955 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
1956 l_dbus_send(dbus, reply);
1958 ERR("Mesh: app not found!!");
1959 return BT_STATUS_PARM_INVALID;
1961 return BT_STATUS_SUCCESS;
1964 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
1968 l = g_slist_find_custom(mesh_apps,
1969 net_uuid->uu, __mesh_compare_network_uuid);
1972 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
1973 "UnprovisionedScanCancel",
1974 NULL, NULL, NULL, NULL))
1975 return BT_STATUS_FAIL;
1977 ERR("Mesh: app not found!!");
1978 return BT_STATUS_PARM_INVALID;
1981 /* Stop Scan timer */
1982 if (app->scan_timer_id > 0) {
1983 g_source_remove(app->scan_timer_id);
1984 app->scan_timer_id = 0;
1987 /* Trigger Scan finished event */
1988 __mesh_trigger_scan_finished_event(app);
1990 return BT_STATUS_SUCCESS;
1993 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
1994 const char *auth_value)
1997 struct l_dbus_message *reply = NULL;
1998 struct l_dbus_message_builder *builder;
2001 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2002 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2003 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2004 INFO("Mesh: Authentication reply: Numeric ype");
2005 val_u32 = atoi(auth_value);
2006 reply = l_dbus_message_new_method_return(agent_msg);
2007 l_dbus_message_set_arguments(reply, "u", val_u32);
2008 /* For Alpha-Numeric */
2009 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT) {
2010 INFO("Mesh: Authentication reply: Alpha-Numeric ype");
2011 memset(alpha, 0x00, 16);
2012 memcpy(alpha, auth_value, strlen(auth_value));
2013 reply = l_dbus_message_new_method_return(agent_msg);
2014 builder = l_dbus_message_builder_new(reply);
2015 __mesh_append_byte_array(builder, alpha, 16);
2016 l_dbus_message_builder_finalize(builder);
2017 l_dbus_message_builder_destroy(builder);
2019 return BT_STATUS_SUCCESS;
2022 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2023 bt_hal_mesh_scan_param_t *param)
2027 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2030 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2031 __mesh_scan_setup, __mesh_scan_reply,
2032 L_UINT_TO_PTR(param->scan_time), NULL))
2033 return BT_STATUS_FAIL;
2035 ERR("Mesh: app not found!!");
2036 return BT_STATUS_PARM_INVALID;
2038 return BT_STATUS_SUCCESS;
2041 bt_status_t _bt_hal_mesh_create_network(
2042 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2046 INFO("Mesh: Create Network Request");
2047 /* Create DBUS APP */
2048 app = __bt_hal_mesh_create_app(node, models, is_prov);
2050 return BT_STATUS_FAIL;
2052 /* Register DBUS APP */
2053 if (!__bt_hal_mesh_register_application(app)) {
2057 if (app->token.u64 == 0) {
2058 INFO("Mesh: Create New Network");
2059 /* Create CFG Network */
2060 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2061 __bt_hal_mesh_create_net_setup,
2062 __bt_hal_mesh_create_net_reply, app,
2064 ERR("Mesh: Network Create failed!!");
2068 INFO("Mesh: Attach Node to Network");
2069 /* Attach to Network */
2070 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2071 __bt_hal_mesh_attach_node_setup,
2072 __bt_hal_mesh_attach_node_reply,
2075 ERR("Mesh: Node attach failed!!");
2080 INFO("Mesh: Node registration request scheudled");
2081 mesh_apps = g_slist_append(mesh_apps, app);
2082 INFO("Mesh: Total number of apps in list [%d]",
2083 g_slist_length(mesh_apps));
2084 return BT_STATUS_SUCCESS;
2086 ERR("Mesh: network can not be created!!");
2087 __bt_hal_mesh_destroy_app_object(app);
2088 return BT_STATUS_FAIL;
2091 static void __bt_hal_mesh_config_send(
2092 struct l_dbus_message *msg, void *user_data)
2094 struct configuration_request *req = user_data;
2095 struct l_dbus_message_builder *builder;
2097 builder = l_dbus_message_builder_new(msg);
2099 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2100 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2101 if (req->is_dev_key)
2102 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2104 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2105 __mesh_append_byte_array(builder, req->data, req->len);
2106 l_dbus_message_builder_finalize(builder);
2107 l_dbus_message_builder_destroy(builder);
2110 static void __bt_hal_mesh_key_config_send(
2111 struct l_dbus_message *msg, void *user_data)
2113 struct key_config_request *req = user_data;
2114 struct l_dbus_message_builder *builder;
2116 builder = l_dbus_message_builder_new(msg);
2118 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2119 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2120 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2121 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2122 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2123 l_dbus_message_builder_finalize(builder);
2124 l_dbus_message_builder_destroy(builder);
2127 bt_status_t _bt_hal_mesh_send_key_config_message(
2128 bt_uuid_t *network, uint16_t dest,
2129 bool is_netkey, bool is_update,
2130 uint16_t key_idx, uint16_t netkey_idx)
2134 struct key_config_request *req;
2137 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2138 /* Source is Config Client Local Node */
2139 int src_elem_idx = 0;
2140 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2143 l1 = g_slist_find_custom(app->elements,
2144 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2147 req = l_new(struct key_config_request, 1);
2148 req->ele_path = elem->path;
2150 req->key_req_idx = key_idx;
2151 req->idx = netkey_idx; /* Encryption Key index */
2152 req->update_req = is_update;
2154 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_method,
2155 __bt_hal_mesh_key_config_send, NULL,
2156 (void*)req, l_free))
2157 return BT_STATUS_FAIL;
2159 ERR("Mesh: app not found!!");
2160 return BT_STATUS_PARM_INVALID;
2163 return BT_STATUS_SUCCESS;
2166 bt_status_t _bt_hal_mesh_send_configuration_message(
2167 bt_uuid_t *network, uint16_t dest,
2168 bool is_dev_key, uint16_t netkey_idx,
2169 uint8_t *buf, int len)
2173 struct configuration_request *req;
2176 int src_elem_idx = 0;
2177 l = g_slist_find_custom(mesh_apps, network->uu,
2178 __mesh_compare_network_uuid);
2181 l1 = g_slist_find_custom(app->elements,
2182 GUINT_TO_POINTER(src_elem_idx),
2183 __compare_element_index);
2186 req = l_new(struct configuration_request, 1);
2187 req->ele_path = elem->path;
2189 req->idx = netkey_idx;
2193 req->is_dev_key = is_dev_key;
2195 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DevKeySend",
2196 __bt_hal_mesh_config_send, NULL,
2197 (void*)req, l_free))
2198 return BT_STATUS_FAIL;
2200 ERR("Mesh: app not found!!");
2201 return BT_STATUS_PARM_INVALID;
2204 return BT_STATUS_SUCCESS;