4 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
6 * @author: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
33 #include "bt-hal-mesh-dbus-handler.h"
34 #include "bt-hal-dbus-common-utils.h"
35 #include "bt-hal-internal.h"
37 #include <hardware/bt_mesh.h>
39 #define BT_HAL_MESH_DBUS_NAME "org.projectx.bt.mesh"
41 #define BT_HAL_UUID_LEN 16
42 #define BT_HAL_BLUEZ_MESH_NAME "org.bluez.mesh"
44 #define BT_HAL_MESH_NETWORK_INTERFACE "org.bluez.mesh.Network1"
45 #define BT_HAL_MESH_NODE_INTERFACE "org.bluez.mesh.Node1"
46 #define BT_HAL_MESH_MANAGEMENT_INTERFACE "org.bluez.mesh.Management1"
47 #define BT_HAL_MESH_ELEMENT_INTERFACE "org.bluez.mesh.Element1"
48 #define BT_HAL_MESH_APPLICATION_INTERFACE "org.bluez.mesh.Application1"
49 #define BT_HAL_MESH_PROVISION_AGENT_INTERFACE "org.bluez.mesh.ProvisionAgent1"
50 #define BT_HAL_MESH_PROVISIONER_INTERFACE "org.bluez.mesh.Provisioner1"
51 #define BT_HAL_MESH_ERROR_INTERFACE "org.bluez.mesh.Error"
53 #define BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE 2048
54 #define BT_HAL_MESH_MAX_MSG_BUF_SIZE 2048
56 static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs";
57 static const char *dbus_err_fail = "org.freedesktop.DBus.Error.Failed";
59 static struct l_dbus *dbus = NULL;
60 static struct l_dbus_client *client = NULL;
62 static struct l_dbus_proxy *net_proxy = NULL;
63 static struct l_dbus_message *agent_msg;
65 static handle_stack_msg mesh_event_cb = NULL;
68 struct subnet_key_request {
73 struct app_key_request {
79 struct configuration_request {
89 struct key_config_request {
97 struct mesh_provision_auth_action {
99 bt_hal_mesh_auth_variant_e auth_type;
102 static struct mesh_provision_auth_action auth_table[] = {
103 { "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
104 { "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
105 { "vibrate", BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT},
106 { "in-numeric", BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT},
107 { "in-alpha", BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT},
108 { "twist", BT_HAL_MESH_AUTH_TWIST_COUNT_DISPLAY},
109 { "push", BT_HAL_MESH_AUTH_PUSH_COUNT_DISPLAY},
110 { "out-numeric", BT_HAL_MESH_AUTH_NUMERIC_DISPLAY},
111 { "out-alpha", BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY},
112 { "static-oob", BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT},
113 { "unknown", BT_HAL_MESH_UNKNOWN_AUTH_METHOD},
117 static uint8_t __bt_mesh_util_get_prov_error_code(char *prov_err_str)
121 if (!g_strcmp0(prov_err_str, "success"))
122 ret = BT_HAL_MESH_PROV_ERR_SUCCESS;
123 else if (!g_strcmp0(prov_err_str, "bad-pduread"))
124 ret = BT_HAL_MESH_PROV_ERR_INVALID_PDU;
125 else if (!g_strcmp0(prov_err_str, "confirmation-failed"))
126 ret = BT_HAL_MESH_PROV_ERR_CONFIRM_FAILED;
127 else if (!g_strcmp0(prov_err_str, "out-of-resources"))
128 ret = BT_HAL_MESH_PROV_ERR_INSUF_RESOURCE;
129 else if (!g_strcmp0(prov_err_str, "decryption-error"))
130 ret = BT_HAL_MESH_PROV_ERR_DECRYPT_FAILED;
131 else if (!g_strcmp0(prov_err_str, "cannot-assign-addresses"))
132 ret = BT_HAL_MESH_PROV_ERR_CANT_ASSIGN_ADDR;
133 else if (!g_strcmp0(prov_err_str, "timeout"))
134 ret = BT_HAL_MESH_PROV_ERR_TIMEOUT;
135 else if (!g_strcmp0(prov_err_str, "unexpected-error"))
136 ret = BT_HAL_MESH_PROV_ERR_UNEXPECTED_ERR;
141 static bt_hal_mesh_auth_variant_e __mesh_get_authentication_type(char *str)
143 int len = strlen(str);
144 int sz = L_ARRAY_SIZE(auth_table);
147 for (i = 0; i < sz; ++i)
148 if (len == strlen(auth_table[i].action) &&
149 !strcmp(str, auth_table[i].action))
152 return auth_table[i].auth_type;
154 ERR("Mesh : Not A Proper Authentication Type!");
155 return BT_HAL_MESH_UNKNOWN_AUTH_METHOD;
159 enum mesh_dbus_interface_e {
166 typedef enum mesh_dbus_interface_e mesh_dbus_interface_e;
168 struct meshcfg_model {
173 typedef struct meshcfg_model meshcfg_model;
181 typedef struct meshcfg_el meshcfg_el;
184 /* Remember Proxies & dbus paths */
187 struct l_dbus_proxy *proxy;
188 struct l_dbus_proxy *mgmt_proxy;
190 /* Local node Info */
207 struct l_dbus_message *msg;
211 typedef struct meshcfg_app meshcfg_app;
213 /* Will contain critical data related to local Mesh Network */
214 static GSList *mesh_apps = NULL;
217 struct meshcfg_node {
219 struct l_dbus_proxy *proxy;
220 struct l_dbus_proxy *mgmt_proxy;
227 typedef struct meshcfg_node meshcfg_node;
229 static void __mesh_append_byte_array(struct l_dbus_message_builder *builder,
230 unsigned char *data, unsigned int len)
234 l_dbus_message_builder_enter_array(builder, "y");
236 for (i = 0; i < len; i++)
237 l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
239 l_dbus_message_builder_leave_array(builder);
242 static gint __mesh_compare_network_uuid(gconstpointer data, gconstpointer user_data)
244 const meshcfg_app *app = (meshcfg_app*) data;
246 memcpy(uuid, (uint8_t*) user_data, 16);
248 return memcmp(uuid, app->uuid, sizeof(bt_uuid_t));
251 static unsigned char* __mesh_get_net_uuid_from_dbus_proxy_path(
252 const char *dbus_path)
257 memcpy(uuid, (void*)&dbus_path[20], sizeof(uuid));
259 INFO("Mesh: Net UUID string [%s]", uuid);
260 return l_util_from_hexstring(uuid, &sz);
263 static unsigned char* __mesh_get_net_uuid_from_path(
264 const char *dbus_path, bool is_prov,
265 mesh_dbus_interface_e iface)
272 case MESH_PROV_IFACE: {
273 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
275 return l_util_from_hexstring(uuid, &sz);
277 case MESH_AGENT_IFACE: {
278 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[23], 32);
280 return l_util_from_hexstring(uuid, &sz);
282 case MESH_ELEMENT_IFACE: {
283 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
285 return l_util_from_hexstring(uuid, &sz);
292 static void __mesh_hal_free_elements(gpointer data)
294 meshcfg_el *element = (meshcfg_el*) data;
297 g_free(element->path);
299 g_slist_free_full(element->models, g_free);
301 element->models = NULL;
305 static bool __bt_mesh_proxy_check(meshcfg_app *app)
307 /* Check meshd stack Vis up or not */
309 ERR("Mesh: DBUS is not UP!, possibly stack not Up!");
312 /* Check Network Proxy is added or not */
314 ERR("Mesh: Network proxy is not attached yet!");
319 /* Check App management proxyis added or not */
320 if (!app->mgmt_proxy) {
321 ERR("Mesh: Network proxy is not attached yet!");
324 /* Check App Node Proxy is added or not */
326 ERR("Mesh: Node proxy is not attached yet!");
333 static void __bt_hal_mesh_destroy_app_object(gpointer data)
336 meshcfg_app *app = (meshcfg_app*) data;
340 mesh_apps = g_slist_remove(mesh_apps, app);
343 INFO("Mesh: App path [%s] ", app->path);
346 if (app->agent_path) {
347 INFO("Mesh: Agent Path [%s]", app->agent_path);
348 g_free(app->agent_path);
352 INFO("Mesh: Total elements present in app [%d]",
353 g_slist_length(app->elements));
354 g_slist_free_full(app->elements, __mesh_hal_free_elements);
359 static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
361 ERR("MESH: D-Bus client connected\n");
364 INFO("Mesh: MeshD connected: dbus [%p]", dbus);
367 static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
369 ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
370 /* TODO: Send event to app about meshd termination & then remove all mesh apps */
371 INFO("Mesh: Total number of networks present [%d]",
372 g_slist_length(mesh_apps));
375 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
378 /* Set DBUS to NULL */
380 INFO("Mesh: dbus [%p]", dbus);
382 INFO("Mesh: net proxy [%p]", net_proxy);
386 INFO("Mesh: All apps cleaned up after meshd exited");
389 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
393 const meshcfg_app *app = (meshcfg_app*) data;
394 char *path = (char *) user_data;
395 INFO("Mesh: proxy path compare: path [%s]", path);
396 INFO("Mesh: App Path path [%s]", app->path);
400 app_uuid_path = l_util_hexstring(app->uuid, 16);
401 INFO("Mesh:App UUID string [%s]", app_uuid_path);
402 char **strings = g_strsplit(path, "node", 2);
404 INFO("Mesh:String 0 [%s]", strings[0]);
405 INFO("Mesh:String 1 [%s]", strings[1]);
406 ret = g_strcmp0(strings[1], app_uuid_path);
409 l_free(app_uuid_path);
413 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
415 const meshcfg_el *elem = data;
416 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
420 return (elem->index == elem_index ? 0 : -1);
423 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
425 const char *interface = l_dbus_proxy_get_interface(proxy);
426 const char *path = l_dbus_proxy_get_path(proxy);
428 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
430 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
431 INFO("Mesh: Network Proxy added");
432 /* Save Global proxy */
435 INFO("Mesh: Net Proxy [%p]", net_proxy);
439 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
442 INFO("Mesh: Mgmt Proxy added");
443 INFO("Mesh: Number of mesh app present in list [%d]",
444 g_slist_length(mesh_apps));
445 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
448 app->mgmt_proxy = proxy;
450 ERR("Mesh: app not found for Mgmt proxy");
455 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
456 INFO("Mesh: Node Proxy added");
459 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
464 ERR("Mesh: app not found for Node proxy");
470 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
472 const char *interface = l_dbus_proxy_get_interface(proxy);
473 const char *path = l_dbus_proxy_get_path(proxy);
475 INFO("Proxy removed: %s (%s)\n", interface, path);
477 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
478 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
479 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
481 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
485 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
486 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
489 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
492 /*TODO: Send event to app about removal of a mesh local node */
493 __bt_hal_mesh_destroy_app_object(app);
495 ERR("Mesh: app not found for Mgmt proxy");
498 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
499 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
502 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
505 /*TODO: Send event to app about removal of
506 a mesh local node: first send event, then destroy mesh object */
507 __bt_hal_mesh_destroy_app_object(app);
509 ERR("Mesh: app not found for Mgmt proxy");
515 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
518 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
522 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
523 bool queued, void *user_data)
525 if (success == false)
526 ERR("Mesh: Fail to acquire dbus name\n");
528 if (!l_dbus_object_manager_enable(dbus_obj, "/"))
529 ERR("Mesh: Failed to register the ObjectManager\n");
532 static void __mesh_ready_callback(void *user_data)
534 INFO("Mesh: Connected to D-Bus\n");
536 if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
537 __mesh_acquire_name_callback, NULL))
538 ERR("Mesh: Failed to own well-known name\n");
541 bool _bt_hal_mesh_stack_init(void)
543 INFO("Mesh: Connect with meshd");
544 /* Connect with meshd */
545 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
549 INFO("Mesh: Got dbus [%p]", dbus);
551 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
554 client = l_dbus_client_new(dbus,
555 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
559 if (!l_dbus_client_set_connect_handler(client,
560 __mesh_client_connected, NULL, NULL))
563 if (!l_dbus_client_set_disconnect_handler(client,
564 __mesh_client_disconnected, NULL,
567 if (!l_dbus_client_set_proxy_handlers(client,
568 __mesh_proxy_added, __mesh_proxy_removed,
571 if (!l_dbus_client_set_ready_handler(client,
572 __mesh_dbus_client_ready, NULL, NULL))
575 INFO("Mesh: Stack Init watchers registered with meshd");
579 void _bt_hal_mesh_stack_deinit(void)
581 INFO("Mesh: Stack Deinit");
584 l_dbus_client_destroy(client);
589 l_dbus_destroy(dbus);
594 /* To send stack event to hal-mesh handler */
595 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
600 /* To send stack event to hal-mesh handler */
601 void _bt_hal_mesh_unregister_dbus_handler_cb()
603 mesh_event_cb = NULL;
606 static bool __mesh_get_companyid(struct l_dbus *dbus,
607 struct l_dbus_message *message,
608 struct l_dbus_message_builder *builder,
611 meshcfg_app *app = (meshcfg_app*) user_data;
615 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
620 static bool __mesh_get_productid(struct l_dbus *dbus,
621 struct l_dbus_message *message,
622 struct l_dbus_message_builder *builder,
625 meshcfg_app *app = (meshcfg_app*) user_data;
628 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
633 static bool __mesh_get_versionid(struct l_dbus *dbus,
634 struct l_dbus_message *message,
635 struct l_dbus_message_builder *builder,
638 meshcfg_app *app = (meshcfg_app*) user_data;
641 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
646 static bool __mesh_get_crpl(struct l_dbus *dbus,
647 struct l_dbus_message *message,
648 struct l_dbus_message_builder *builder,
651 meshcfg_app *app = (meshcfg_app*) user_data;
654 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
659 static void __send_network_attach_event(void *param, uint8_t status)
661 struct hal_ev_mesh_network_attached ev;
662 meshcfg_app *app = (meshcfg_app*)param;
664 memset(&ev, 0, sizeof(ev));
665 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
666 memcpy(ev.token, app->token.u8, 8);
670 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
671 (void*)&ev, sizeof(ev));
674 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
675 struct l_dbus_message *msg, void *user_data)
677 struct l_dbus_message_iter iter_cfg;
679 meshcfg_app *app = (meshcfg_app*) user_data;
680 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
681 app->path, app->agent_path);
683 if (l_dbus_message_is_error(msg)) {
685 l_dbus_message_get_error(msg, &name, NULL);
686 ERR("Mesh: Failed to attach node: %s", name);
691 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
695 INFO("Mesh: Attached with path %s\n", app->path);
696 __send_network_attach_event(app, BT_STATUS_SUCCESS);
699 __send_network_attach_event(app, BT_STATUS_FAIL);
700 /* Destroy mesh app object */
701 __bt_hal_mesh_destroy_app_object(app);
704 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
707 meshcfg_app *app = (meshcfg_app*) user_data;
709 l_dbus_message_set_arguments(msg, "ot", app->path,
710 l_get_be64(app->token.u8));
714 static void __bt_hal_mesh_attach_node(void *user_data)
716 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
717 __bt_hal_mesh_attach_node_setup,
718 __bt_hal_mesh_attach_node_reply,
721 ERR("Mesh: Node attach failed!!");
722 /* Node could not be attached */
723 __send_network_attach_event(user_data, BT_STATUS_FAIL);
724 /* Destroy mesh app object */
725 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
729 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
730 struct l_dbus_message *message,
736 meshcfg_app *app = (meshcfg_app*) user_data;
737 INFO("Mesh: Join Complete");
740 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
742 /* Send Network creation fail event */
743 __send_network_attach_event(app, BT_STATUS_FAIL);
745 /* Destroy mesh app object */
746 __bt_hal_mesh_destroy_app_object(app);
748 return l_dbus_message_new_error(message, dbus_err_args, NULL);
752 app->token.u64 = l_get_be64(&tmp);
753 str = l_util_hexstring(&app->token.u8[0], 8);
754 INFO("Mesh: Created new node with token %s\n", str);
757 /* Authenticate the node */
758 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
759 return l_dbus_message_new_method_return(message);
762 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
765 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
766 meshcfg_model *model_info = (meshcfg_model*) data;
768 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
771 static bool __mesh_model_getter(struct l_dbus *dbus,
772 struct l_dbus_message *message,
773 struct l_dbus_message_builder *builder,
776 meshcfg_el *element = (meshcfg_el*) user_data;
778 l_dbus_message_builder_enter_array(builder, "q");
779 g_slist_foreach(element->models,
780 __bt_hal_mesh_foreach_model_getter, builder);
782 l_dbus_message_builder_leave_array(builder);
787 /*TODO: Vendor Model handling is currently not Handled */
788 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
789 struct l_dbus_message *message,
790 struct l_dbus_message_builder *builder,
793 l_dbus_message_builder_enter_array(builder, "(qq)");
794 l_dbus_message_builder_leave_array(builder);
799 static bool __mesh_element_index_getter(struct l_dbus *dbus,
800 struct l_dbus_message *message,
801 struct l_dbus_message_builder *builder,
804 meshcfg_el *element = (meshcfg_el*) user_data;
805 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
811 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
812 struct l_dbus_message *msg, void *user_data)
814 struct l_dbus_message_iter iter;
819 const char *dbus_path;
822 dbus_path = l_dbus_message_get_path(msg);
823 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
824 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
825 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
827 INFO("Mesh: app path [%s]", dbus_path);
829 memset(buf, 0, sizeof(buf));
830 size = (uint16_t) sizeof(*ev);
831 memcpy(ev->net_uuid, net_uuid, 16);
834 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
836 ERR("Mesh: Cannot parse received message");
837 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
840 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
841 ERR("Mesh: Cannot parse received message: data");
842 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
845 INFO("Mesh: Received dev key message (len %u):", n);
846 ev->source_addr = src;
847 ev->is_remote_devkey = rmt;
848 ev->netkey_idx = idx;
850 memcpy(ev->data, data, n);
853 INFO("Mesh: Src [0x%2.2x]", src);
854 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
855 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
856 /* Send DevKeyMessage Received event */
858 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
859 return l_dbus_message_new_method_return(msg);
862 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
863 struct l_dbus_message *msg, void *user_data)
865 struct l_dbus_message_iter iter;
866 uint16_t src, idx, dst;
869 const char *dbus_path;
872 dbus_path = l_dbus_message_get_path(msg);
873 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
874 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
875 struct hal_ev_mesh_message_event *ev = (void *)buf;
877 INFO("Mesh: app path [%s]", dbus_path);
879 memset(buf, 0, sizeof(buf));
880 size = (uint16_t) sizeof(*ev);
881 memcpy(ev->net_uuid, net_uuid, 16);
884 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
886 ERR("Mesh: Cannot parse received message");
887 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
890 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
891 ERR("Mesh: Cannot parse received message: data");
892 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
895 INFO("Mesh: Received mesh message (len %u):", n);
896 ev->source_addr = src;
900 memcpy(ev->data, data, n);
903 INFO("Mesh: Src [0x%2.2x]", src);
904 INFO("Mesh: Dst [0x%2.2x]", dst);
905 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
906 /* Send Message Received event */
908 INFO("Mesh: Send message event");
909 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
911 return l_dbus_message_new_method_return(msg);
914 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
916 INFO("Mesh: Setup element interface properties & methods");
918 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
920 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
921 __mesh_vendor_model_getter, NULL);
922 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
925 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
926 __mesh_device_message_received, "", "qbqay", "source",
927 "remote", "net_index", "data");
928 l_dbus_interface_method(iface, "MessageReceived", 0,
929 __mesh_message_received, "", "qqvay", "source",
930 "key_index", "destination", "data");
931 /* TODO: Other methods */
934 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
935 struct l_dbus_message *msg,
938 struct l_dbus_message_iter iter, opts;
939 meshcfg_app *app = (meshcfg_app*) user_data;
944 const char *sig = "naya{sv}";
946 /* Find network uuid from dbus path */
947 struct hal_ev_mesh_scan_result ev;
949 if (!app->scan_timer_id) {
950 /* Scan is not running */
951 INFO("Got scan result, but scan is already stopped");
952 return l_dbus_message_new_method_return(msg);
954 memset(&ev, 0, sizeof(ev));
955 memcpy(ev.net_uuid, app->uuid, 16);
957 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
958 ERR("Mesh: Cannot parse scan results");
959 ev.status = BT_STATUS_FAIL;
961 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
962 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
965 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
967 ERR("Mesh: Cannot parse scan result: data");
968 ev.status = BT_STATUS_FAIL;
970 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
971 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
974 INFO("Mesh: Scan result:\n");
975 INFO("Mesh: Scan rssi = [%d]\n", rssi);
976 str = l_util_hexstring_upper(prov_data, 16);
977 INFO("Mesh: Scan UUID = [%s]\n", str);
981 str = l_util_hexstring_upper(prov_data + 16, 2);
982 INFO("Mesh: Scan OOB = [%s]\n", str);
987 str = l_util_hexstring_upper(prov_data + 18, 4);
988 INFO("Mesh: Scan URI hash = [%s]\n", str);
992 /* 16 octet Dev UUID */
993 memcpy(ev.dev_uuid, prov_data, 16);
995 /* 2 octet Dev OOB Info */
996 memcpy(ev.oob_info, prov_data + 16, 2);
998 /* 4 octet URI Hash */
999 memcpy(ev.uri_hash, prov_data + 18, 4);
1003 ev.status = BT_STATUS_SUCCESS;
1005 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1006 (void*)&ev, sizeof(ev));
1008 return l_dbus_message_new_method_return(msg);
1011 static struct l_dbus_message *__mesh_request_provisioner_call(
1012 struct l_dbus *dbus,
1013 struct l_dbus_message *msg,
1017 struct hal_ev_mesh_provision_finished ev;
1018 struct hal_ev_mesh_provision_data_request req;
1020 meshcfg_app *app = user_data;
1022 INFO("Mesh: provisioning data requested app path [%s]",
1024 uuid_string = l_util_hexstring(app->uuid, 16);
1025 INFO("Mesh: Network UUID [%s]", uuid_string);
1027 memset(&ev, 0, sizeof(ev));
1028 memset(&req, 0, sizeof(req));
1029 memcpy(ev.net_uuid, app->uuid, 16);
1030 memcpy(req.net_uuid, app->uuid, 16);
1031 l_free(uuid_string);
1033 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1034 ERR("Mesh: Cannot parse request for prov data");
1036 ev.status = BT_STATUS_FAIL;
1037 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1039 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1040 (void*)&ev, sizeof(ev));
1041 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1047 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1048 (void*)&req, sizeof(req));
1050 l_dbus_message_ref(msg);
1054 static struct l_dbus_message *__mesh_node_add_completed(
1055 struct l_dbus *dbus,
1056 struct l_dbus_message *msg,
1059 struct l_dbus_message_iter iter;
1064 struct hal_ev_mesh_provision_finished ev;
1065 const char *dbus_path;
1067 dbus_path = l_dbus_message_get_path(msg);
1068 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1069 true, MESH_PROV_IFACE);
1071 INFO("Mesh: app path [%s]", dbus_path);
1073 memset(&ev, 0, sizeof(ev));
1074 memcpy(ev.net_uuid, net_uuid, 16);
1078 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1079 ERR("Mesh: Cannot parse add node complete message");
1081 ev.status = BT_STATUS_FAIL;
1082 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1084 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1085 (void*)&ev, sizeof(ev));
1086 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1089 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1091 ERR("Mesh: Cannot parse add node complete message: uuid");
1093 ev.status = BT_STATUS_FAIL;
1094 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1096 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1097 (void*)&ev, sizeof(ev));
1098 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1102 ev.status = BT_STATUS_SUCCESS;
1103 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1104 memcpy(ev.dev_uuid, uuid, 16);
1105 ev.unicast = unicast;
1109 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1110 (void*)&ev, sizeof(ev));
1112 return l_dbus_message_new_method_return(msg);
1115 static struct l_dbus_message *__mesh_node_add_failed(
1116 struct l_dbus *dbus,
1117 struct l_dbus_message *msg,
1120 struct l_dbus_message_iter iter;
1124 struct hal_ev_mesh_provision_finished ev;
1125 const char *dbus_path;
1128 dbus_path = l_dbus_message_get_path(msg);
1129 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1130 true, MESH_PROV_IFACE);
1132 memset(&ev, 0, sizeof(ev));
1133 memcpy(ev.net_uuid, net_uuid, 16);
1136 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1137 ERR("Mesh: Cannot parse add node failed message");
1139 ev.status = BT_STATUS_FAIL;
1140 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1142 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1143 (void*)&ev, sizeof(ev));
1144 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1147 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1149 ERR("Mesh:Cannot parse add node failed message: uuid");
1150 ev.status = BT_STATUS_FAIL;
1151 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1153 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1154 (void*)&ev, sizeof(ev));
1155 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1158 INFO("Mesh: Provisioning failed:\n");
1159 str = l_util_hexstring_upper(uuid, 16);
1160 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1163 ev.status = BT_STATUS_FAIL;
1164 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1165 memcpy(ev.dev_uuid, uuid, 16);
1168 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1169 (void*)&ev, sizeof(ev));
1171 return l_dbus_message_new_method_return(msg);
1174 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1176 INFO("Mesh: Setup provisioner interface properties & methods");
1177 l_dbus_interface_method(interface, "ScanResult", 0,
1178 __mesh_scan_result_received, "",
1179 "naya{sv}", "rssi", "data", "options");
1181 l_dbus_interface_method(interface, "RequestProvData", 0,
1182 __mesh_request_provisioner_call,
1183 "qq", "y", "net_index", "unicast", "count");
1185 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1186 __mesh_node_add_completed, "", "ayqy",
1187 "uuid", "unicast", "count");
1189 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1190 __mesh_node_add_failed,
1191 "", "ays", "uuid", "reason");
1194 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1196 INFO("Mesh: Setup application interface properties & methods");
1198 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1199 __mesh_get_companyid,
1201 l_dbus_interface_property(iface, "VersionID", 0, "q",
1202 __mesh_get_versionid,
1204 l_dbus_interface_property(iface, "ProductID", 0, "q",
1205 __mesh_get_productid,
1207 l_dbus_interface_property(iface, "CRPL", 0, "q",
1208 __mesh_get_crpl, NULL);
1209 l_dbus_interface_method(iface, "JoinComplete", 0,
1210 __mesh_node_join_complete,
1216 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1217 struct l_dbus_message_builder *builder)
1219 if (app->in_oob & 0x08)
1220 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1221 if (app->in_oob & 0x04)
1222 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1223 if (app->in_oob & 0x02)
1224 l_dbus_message_builder_append_basic(builder, 's', "twist");
1225 if (app->in_oob & 0x01)
1226 l_dbus_message_builder_append_basic(builder, 's', "push");
1229 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1230 struct l_dbus_message_builder *builder)
1232 if (app->out_oob & 0x10)
1233 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1234 if (app->out_oob & 0x08)
1235 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1236 if (app->out_oob & 0x04)
1237 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1238 if (app->out_oob & 0x02)
1239 l_dbus_message_builder_append_basic(builder, 's', "beep");
1240 if (app->out_oob & 0x01)
1241 l_dbus_message_builder_append_basic(builder, 's', "blink");
1244 static bool __mesh_agent_capability_getter(
1245 struct l_dbus *dbus, struct l_dbus_message *message,
1246 struct l_dbus_message_builder *builder,
1251 INFO("Mesh: app path [%s]", app->path);
1252 INFO("Mesh: Agent path [%s]", app->agent_path);
1254 if (!l_dbus_message_builder_enter_array(builder, "s"))
1257 __mesh_fill_out_capabilities(app, builder);
1258 __mesh_fill_in_capabilities(app, builder);
1260 if (app->static_oob)
1261 l_dbus_message_builder_append_basic(builder,
1265 l_dbus_message_builder_leave_array(builder);
1266 INFO("Mesh: __agent_capability_getter: Success");
1270 static struct l_dbus_message *__mesh_agent_display_string_request(
1271 struct l_dbus *dbus,
1272 struct l_dbus_message *msg,
1275 struct hal_ev_mesh_authentication_request ev;
1278 const char *dbus_path;
1281 INFO("Mesh: app path [%s]", app->path);
1282 INFO("Mesh: Agent path [%s]", app->agent_path);
1284 dbus_path = l_dbus_message_get_path(msg);
1285 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1286 true, MESH_AGENT_IFACE);
1288 INFO("Mesh: app path [%s]", dbus_path);
1290 memset(&ev, 0, sizeof(ev));
1291 memcpy(ev.net_uuid, net_uuid, 16);
1294 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1295 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1296 struct hal_ev_mesh_provision_finished ev;
1297 memset(&ev, 0, sizeof(ev));
1298 memcpy(ev.net_uuid, net_uuid, 16);
1299 ev.status = BT_STATUS_FAIL;
1300 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1302 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1303 (void*)&ev, sizeof(ev));
1307 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1310 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1311 ev.auth_type = __mesh_get_authentication_type(str);
1312 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1313 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1314 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1317 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1318 (void*)&ev, sizeof(ev));
1321 return l_dbus_message_new_method_return(msg);
1324 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1325 struct l_dbus *dbus,
1326 struct l_dbus_message *msg,
1330 struct hal_ev_mesh_authentication_request ev;
1334 const char *dbus_path;
1337 INFO("Mesh: app path [%s]", app->path);
1338 INFO("Mesh: Agent path [%s]", app->agent_path);
1340 dbus_path = l_dbus_message_get_path(msg);
1341 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1342 true, MESH_AGENT_IFACE);
1344 INFO("Mesh: app path [%s]", dbus_path);
1346 memset(&ev, 0, sizeof(ev));
1347 memcpy(ev.net_uuid, net_uuid, 16);
1350 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1351 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1352 struct hal_ev_mesh_provision_finished ev;
1353 memset(&ev, 0, sizeof(ev));
1354 memcpy(ev.net_uuid, net_uuid, 16);
1355 ev.status = BT_STATUS_FAIL;
1356 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1357 if (mesh_event_cb) {
1358 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1359 (void*)&ev, sizeof(ev));
1362 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1365 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1366 auth_value = l_strdup_printf("%u", n);
1367 ev.auth_type = __mesh_get_authentication_type(str);
1368 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1369 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1370 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1373 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1374 (void*)&ev, sizeof(ev));
1378 return l_dbus_message_new_method_return(msg);
1381 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1382 struct l_dbus *dbus,
1383 struct l_dbus_message *msg,
1386 struct hal_ev_mesh_authentication_request ev;
1389 const char *dbus_path;
1393 dbus_path = l_dbus_message_get_path(msg);
1394 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1395 true, MESH_AGENT_IFACE);
1397 INFO("Mesh: app path [%s]", dbus_path);
1399 l = g_slist_find_custom(mesh_apps, net_uuid,
1400 __mesh_compare_network_uuid);
1403 memset(&ev, 0, sizeof(ev));
1404 memcpy(ev.net_uuid, net_uuid, 16);
1407 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1408 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1410 struct hal_ev_mesh_provision_finished ev;
1411 memset(&ev, 0, sizeof(ev));
1412 memcpy(ev.net_uuid, app->uuid, 16);
1413 ev.status = BT_STATUS_FAIL;
1414 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1415 if (mesh_event_cb) {
1416 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1417 (void*)&ev, sizeof(ev));
1419 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1422 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1424 ev.auth_type = __mesh_get_authentication_type(str);
1425 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1426 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1428 l_dbus_message_ref(msg);
1430 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1431 (void*)&ev, sizeof(ev));
1436 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1437 struct l_dbus *dbus,
1438 struct l_dbus_message *msg,
1441 struct hal_ev_mesh_authentication_request ev;
1444 const char *dbus_path;
1448 dbus_path = l_dbus_message_get_path(msg);
1449 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1452 INFO("Mesh: app path [%s]", dbus_path);
1454 l = g_slist_find_custom(mesh_apps, net_uuid,
1455 __mesh_compare_network_uuid);
1458 memset(&ev, 0, sizeof(ev));
1459 memcpy(ev.net_uuid, net_uuid, 16);
1462 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1463 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1465 struct hal_ev_mesh_provision_finished ev;
1466 memset(&ev, 0, sizeof(ev));
1467 memcpy(ev.net_uuid, app->uuid, 16);
1468 ev.status = BT_STATUS_FAIL;
1469 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1471 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1472 (void*)&ev, sizeof(ev));
1473 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1476 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1478 ev.auth_type = __mesh_get_authentication_type(str);
1479 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1480 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1482 l_dbus_message_ref(msg);
1484 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1485 (void*)&ev, sizeof(ev));
1490 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1492 INFO("Mesh: Setup Agent interface properties & methods");
1493 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1494 __mesh_agent_capability_getter,
1496 /* TODO: Other properties */
1497 l_dbus_interface_method(interface, "DisplayString", 0,
1498 __mesh_agent_display_string_request,
1500 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1501 __mesh_agent_display_numeric_request,
1502 "", "su", "type", "number");
1503 l_dbus_interface_method(interface, "PromptNumeric", 0,
1504 __mesh_agent_prompt_numeric_request,
1505 "u", "s", "number", "type");
1506 l_dbus_interface_method(interface, "PromptStatic", 0,
1507 __mesh_agent_prompt_static_request,
1508 "ay", "s", "data", "type");
1511 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1513 meshcfg_el *elem = (meshcfg_el*) data;
1514 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1515 elem->index, elem->path);
1516 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1517 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1518 ERR("Mesh: Failed to register object %s", elem->path);
1522 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1527 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1528 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1529 ERR("Mesh: Unable to register agent interface");
1533 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1534 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1535 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1536 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1540 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1541 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1542 ERR("Mesh: Failed to add interface %s",
1543 L_DBUS_INTERFACE_PROPERTIES);
1550 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1558 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1559 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1560 ERR("Mesh: Failed to register interface %s",
1561 BT_HAL_MESH_APPLICATION_INTERFACE);
1565 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1566 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1567 ERR("Mesh: Failed to register interface %s",
1568 BT_HAL_MESH_PROVISIONER_INTERFACE);
1572 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1573 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1574 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1576 ERR("Mesh: Failed to register object %s", ptr->path);
1580 if (!__bt_hal_mesh_register_agent(ptr))
1583 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1584 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1585 ERR("Mesh: Failed to register interface %s",
1586 BT_HAL_MESH_ELEMENT_INTERFACE);
1590 INFO("Mesh: Number of elements to be registsred [%d]",
1591 g_slist_length(ptr->elements));
1593 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1595 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1596 if (!l_dbus_object_add_interface(dbus, ptr->path,
1597 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1598 ERR("Mesh: Failed to add interface %s",
1599 L_DBUS_INTERFACE_OBJECT_MANAGER);
1602 INFO("Mesh: Application Register completed");
1607 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1611 meshcfg_model *model_info = (meshcfg_model*) data;
1612 meshcfg_app *app = (meshcfg_app*) user_data;
1614 l = g_slist_find_custom(app->elements,
1615 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1619 elem = g_malloc0(sizeof(meshcfg_el));
1620 elem->index = model_info->elem_index;
1621 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1622 app->elements = g_slist_append(app->elements, elem);
1623 INFO("Mesh: Created element index [%d] path [%s]",
1624 elem->index, elem->path);
1626 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1627 model_info->model, elem->index);
1628 /* Add Model in the element */
1629 elem->models = g_slist_append(elem->models, model_info);
1630 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1631 elem->index, g_slist_length(elem->models));
1634 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1635 GSList *models, bool is_prov)
1638 meshcfg_app *app = NULL;
1639 char *uuid_str = NULL;
1641 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1643 app = g_malloc0(sizeof(meshcfg_app));
1644 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1646 app->cid = node->vendor_info.companyid;
1647 app->pid = node->vendor_info.vendorid;
1648 app->vid = node->vendor_info.versionid;
1649 app->crpl = node->vendor_info.crpl;
1652 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1653 app->agent_path = g_strdup_printf("%s/agent", app->path);
1656 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1657 app->agent_path = g_strdup_printf("%s/agent", app->path);
1659 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1662 app->is_prov = is_prov;
1663 INFO("Mesh: app created");
1667 static void __bt_hal_mesh_create_net_reply(
1668 struct l_dbus_proxy *proxy,
1669 struct l_dbus_message *msg, void *user_data)
1672 app = (meshcfg_app*) user_data;
1674 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1675 if (l_dbus_message_is_error(msg)) {
1678 l_dbus_message_get_error(msg, &name, NULL);
1679 ERR("Mesh: Failed to create network: %s", name);
1681 /* Send Network creation fail event */
1682 __send_network_attach_event(app, BT_STATUS_FAIL);
1684 /* Destroy mesh app object */
1685 __bt_hal_mesh_destroy_app_object(app);
1690 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1694 struct l_dbus_message_builder *builder;
1695 app = (meshcfg_app*) user_data;
1697 builder = l_dbus_message_builder_new(msg);
1699 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1700 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1701 __mesh_append_byte_array(builder, app->uuid, 16);
1702 l_dbus_message_builder_finalize(builder);
1703 l_dbus_message_builder_destroy(builder);
1706 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1708 struct hal_ev_mesh_scan_state_changed ev;
1710 memset(&ev, 0, sizeof(ev));
1711 memcpy(ev.net_uuid, app->uuid, 16);
1713 ev.status = BT_STATUS_SUCCESS;
1715 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1717 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1718 (void*)&ev, sizeof(ev));
1721 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1723 meshcfg_app *app = (meshcfg_app*) user_data;
1724 __mesh_trigger_scan_finished_event(app);
1728 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1732 l = g_slist_find_custom(mesh_apps, net_uuid,
1733 __mesh_compare_network_uuid);
1736 if (app->scan_timer_id > 0) {
1737 g_source_remove(app->scan_timer_id);
1738 app->scan_timer_id = 0;
1741 app->scan_timer_id = g_timeout_add_seconds(secs,
1742 __bt_mesh_scan_timer_cb, app);
1747 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1748 struct l_dbus_message *msg, void *user_data)
1750 struct hal_ev_mesh_scan_state_changed ev;
1751 const char *dbus_path;
1753 dbus_path = l_dbus_proxy_get_path(proxy);
1754 INFO("Mesh: DBUS path [%s]", dbus_path);
1755 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1757 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1758 INFO("Mesh: Scan duration [%u]", secs);
1760 memset(&ev, 0, sizeof(ev));
1761 memcpy(ev.net_uuid, net_uuid, 16);
1763 if (l_dbus_message_is_error(msg)) {
1765 l_dbus_message_get_error(msg, &name, NULL);
1766 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1767 ev.status = BT_STATUS_FAIL;
1769 INFO("Mesh: Unprovisioned scan started\n");
1770 ev.status = BT_STATUS_SUCCESS;
1771 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1774 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1776 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1777 (void*)&ev, sizeof(ev));
1781 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1782 const char *key, const char *signature,
1788 l_dbus_message_builder_enter_dict(builder, "sv");
1789 l_dbus_message_builder_append_basic(builder, 's', key);
1790 l_dbus_message_builder_enter_variant(builder, signature);
1791 l_dbus_message_builder_append_basic(builder, signature[0], data);
1792 l_dbus_message_builder_leave_variant(builder);
1793 l_dbus_message_builder_leave_dict(builder);
1796 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1798 struct l_dbus_message_builder *builder;
1799 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1800 INFO("Mesh: Scan duration [%u]", secs);
1802 builder = l_dbus_message_builder_new(msg);
1803 l_dbus_message_builder_enter_array(builder, "{sv}");
1804 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1805 l_dbus_message_builder_leave_array(builder);
1806 l_dbus_message_builder_finalize(builder);
1807 l_dbus_message_builder_destroy(builder);
1811 bt_status_t _bt_hal_mesh_network_set_caps(
1812 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1816 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1820 app->public_oob = caps->public_oob;
1821 app->static_oob = caps->static_oob;
1822 app->out_oob = caps->out_oob;
1823 app->in_oob = caps->in_oob;
1825 ERR("Mesh: app not found!!");
1826 return BT_STATUS_PARM_INVALID;
1829 return BT_STATUS_SUCCESS;
1832 static void __bt_hal_mesh_add_node_reply(
1833 struct l_dbus_proxy *proxy,
1834 struct l_dbus_message *msg,
1837 struct hal_ev_mesh_provision_status ev;
1838 const char *dbus_path;
1840 dbus_path = l_dbus_proxy_get_path(proxy);
1841 INFO("Mesh: DBUS path [%s]", dbus_path);
1842 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1844 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1846 INFO("Mesh: app path [%s]", dbus_path);
1848 memset(&ev, 0, sizeof(ev));
1849 memcpy(ev.net_uuid, net_uuid, 16);
1850 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1852 /* Free User data */
1853 g_free((void*)dev_uuid);
1856 if (l_dbus_message_is_error(msg)) {
1859 l_dbus_message_get_error(msg, &name, NULL);
1860 ERR("Mesh: Failed to start provisioning: %s", name);
1861 ev.status = BT_STATUS_FAIL;
1863 INFO("Mesh: Provisioning started\n");
1864 ev.status = BT_STATUS_SUCCESS;
1867 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1868 (void*)&ev, sizeof(ev));
1869 INFO("Mesh: Provisioning status sent");
1872 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1876 bt_uuid_t *dev = user_data;
1877 struct l_dbus_message_builder *builder;
1878 uuid = l_util_hexstring(dev->uu, 16);
1879 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1881 builder = l_dbus_message_builder_new(msg);
1882 __mesh_append_byte_array(builder, dev->uu, 16);
1883 l_dbus_message_builder_enter_array(builder, "{sv}");
1884 l_dbus_message_builder_leave_array(builder);
1885 l_dbus_message_builder_finalize(builder);
1886 l_dbus_message_builder_destroy(builder);
1889 bt_status_t _bt_hal_mesh_provision_device(
1890 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1895 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1898 dev = g_memdup((gpointer)dev_uuid, 16);
1899 INFO("Mesh: Schedule Add Node request to meshd");
1900 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1901 __bt_hal_mesh_add_node_setup,
1902 __bt_hal_mesh_add_node_reply,
1904 return BT_STATUS_FAIL;
1906 ERR("Mesh: app not found!!");
1907 return BT_STATUS_PARM_INVALID;
1910 return BT_STATUS_SUCCESS;
1913 static void __bt_hal_mesh_subnet_key_setup(
1914 struct l_dbus_message *msg, void *user_data)
1916 struct subnet_key_request *req = user_data;
1917 uint16_t idx = (uint16_t) req->idx;
1919 l_dbus_message_set_arguments(msg, "q", idx);
1922 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1923 struct l_dbus_message *msg, void *user_data)
1925 struct hal_ev_mesh_netkey_execute_event ev;
1926 const char *dbus_path;
1928 struct subnet_key_request *req = user_data;
1929 const char *method = req->str;
1931 dbus_path = l_dbus_proxy_get_path(proxy);
1932 INFO("Mesh: DBUS path [%s]", dbus_path);
1933 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1935 memset(&ev, 0, sizeof(ev));
1936 memcpy(ev.net_uuid, net_uuid, 16);
1937 ev.key_idx = req->idx;
1941 if (l_dbus_message_is_error(msg)) {
1944 l_dbus_message_get_error(msg, &name, NULL);
1945 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
1946 ev.status = BT_STATUS_FAIL;
1949 ev.status = BT_STATUS_SUCCESS;
1951 if (!strcmp("CreateSubnet", method)) {
1952 INFO("Mesh: Reply for CreateSubnet");
1953 ev.key_event = HAL_MESH_KEY_ADD;
1954 } else if (!strcmp("DeleteSubnet", method)) {
1955 INFO("Mesh: Reply for DeleteSubnet");
1956 ev.key_event = HAL_MESH_KEY_DELETE;
1957 } else if (!strcmp("UpdateSubnet", method)) {
1958 INFO("Mesh: Reply for UpdateSubnet");
1959 ev.key_event = HAL_MESH_KEY_UPDATE;
1963 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
1964 (void*)&ev, sizeof(ev));
1967 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
1968 uint16_t index, const char *key_execute_method)
1970 struct subnet_key_request *req;
1972 req = l_new(struct subnet_key_request, 1);
1973 req->str = key_execute_method;
1976 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1977 __bt_hal_mesh_subnet_key_setup,
1978 __bt_hal_mesh_subnet_key_reply,
1985 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
1988 struct app_key_request *req = user_data;
1989 uint16_t net_idx = (uint16_t) req->net_idx;
1990 uint16_t app_idx = (uint16_t) req->app_idx;
1992 if (g_strcmp0(req->str, "CreateAppKey") == 0)
1993 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
1995 l_dbus_message_set_arguments(msg, "q", app_idx);
1998 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
1999 struct l_dbus_message *msg, void *user_data)
2001 struct hal_ev_mesh_appkey_execute_event ev;
2002 const char *dbus_path;
2004 struct app_key_request *req = user_data;
2005 const char *method = req->str;
2007 dbus_path = l_dbus_proxy_get_path(proxy);
2008 INFO("Mesh: DBUS path [%s]", dbus_path);
2009 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2011 memset(&ev, 0, sizeof(ev));
2012 memcpy(ev.net_uuid, net_uuid, 16);
2013 ev.net_idx = req->net_idx;
2014 ev.app_idx = req->app_idx;
2018 if (l_dbus_message_is_error(msg)) {
2021 l_dbus_message_get_error(msg, &name, NULL);
2022 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2023 ev.status = BT_STATUS_FAIL;
2025 ev.status = BT_STATUS_SUCCESS;
2027 if (!strcmp("CreateAppKey", method)) {
2028 INFO("Mesh: AppKey Create Reply");
2029 ev.key_event = HAL_MESH_KEY_ADD;
2030 } else if (!strcmp("DeleteAppKey", method)) {
2031 INFO("Mesh: AppKey Delete Reply");
2032 ev.key_event = HAL_MESH_KEY_DELETE;
2033 } else if (!strcmp("UpdateAppKey", method)) {
2034 INFO("Mesh: AppKey Update Reply");
2035 ev.key_event = HAL_MESH_KEY_UPDATE;
2039 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2042 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2043 uint16_t net_idx, uint16_t app_idx,
2044 const char *key_execute_method)
2046 struct app_key_request *req;
2048 req = l_new(struct app_key_request, 1);
2049 req->str = key_execute_method;
2050 req->net_idx = net_idx;
2051 req->app_idx = app_idx;
2053 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2054 __bt_hal_mesh_app_key_setup,
2055 __bt_hal_mesh_app_key_reply,
2062 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2063 bt_mesh_key_op_e op, uint16_t netkey_idx)
2068 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2072 if (op == BT_MESH_KEY_CREATE)
2073 status = __mesh_subnet_netkey_command_execute(app,
2074 netkey_idx, "CreateSubnet");
2075 else if (op == BT_MESH_KEY_DELETE)
2076 status = __mesh_subnet_netkey_command_execute(app,
2077 netkey_idx, "DeleteSubnet");
2078 else if (op == BT_MESH_KEY_UPDATE)
2079 status = __mesh_subnet_netkey_command_execute(app,
2080 netkey_idx, "UpdateSubnet");
2082 return BT_STATUS_FAIL;
2085 ERR("Mesh: app not found!!");
2086 return BT_STATUS_PARM_INVALID;
2089 return BT_STATUS_SUCCESS;
2092 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2093 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2098 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2102 if (op == BT_MESH_KEY_CREATE)
2103 status = __mesh_subnet_appkey_command_execute(app,
2104 netkey_idx, appkey_idx, "CreateAppKey");
2105 else if (op == BT_MESH_KEY_DELETE)
2106 status = __mesh_subnet_appkey_command_execute(app,
2107 netkey_idx, appkey_idx, "DeleteAppKey");
2108 else if (op == BT_MESH_KEY_UPDATE) {
2109 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2110 netkey_idx, appkey_idx);
2111 status = __mesh_subnet_appkey_command_execute(app,
2112 netkey_idx, appkey_idx, "UpdateAppKey");
2115 return BT_STATUS_FAIL;
2118 ERR("Mesh: app not found!!");
2119 return BT_STATUS_PARM_INVALID;
2122 return BT_STATUS_SUCCESS;
2125 bt_status_t _bt_hal_mesh_send_provision_data(
2126 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2130 struct l_dbus_message *msg;
2131 struct l_dbus_message *reply;
2133 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2138 reply = l_dbus_message_new_method_return(msg);
2139 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2140 l_dbus_send(dbus, reply);
2142 ERR("Mesh: app not found!!");
2143 return BT_STATUS_PARM_INVALID;
2145 return BT_STATUS_SUCCESS;
2148 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2152 l = g_slist_find_custom(mesh_apps,
2153 net_uuid->uu, __mesh_compare_network_uuid);
2156 if (!__bt_mesh_proxy_check(app)) {
2157 ERR("Mesh: Proxy check failed!!");
2158 return BT_STATUS_FAIL;
2160 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2161 "UnprovisionedScanCancel",
2162 NULL, NULL, NULL, NULL))
2163 return BT_STATUS_FAIL;
2165 ERR("Mesh: app not found!!");
2166 return BT_STATUS_PARM_INVALID;
2169 /* Stop Scan timer */
2170 if (app->scan_timer_id > 0) {
2171 g_source_remove(app->scan_timer_id);
2172 app->scan_timer_id = 0;
2175 /* Trigger Scan finished event */
2176 __mesh_trigger_scan_finished_event(app);
2178 return BT_STATUS_SUCCESS;
2181 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2182 const char *auth_value)
2185 struct l_dbus_message *reply = NULL;
2186 struct l_dbus_message_builder *builder;
2188 bt_status_t ret = BT_STATUS_SUCCESS;
2192 if (!__bt_mesh_proxy_check(0)) {
2193 ERR("Mesh: Proxy check failed!!");
2194 return BT_STATUS_FAIL;
2196 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2197 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2198 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2199 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2200 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2201 INFO("Mesh: Authentication reply: Numeric Type");
2202 val_u32 = atoi(auth_value);
2203 reply = l_dbus_message_new_method_return(agent_msg);
2204 l_dbus_message_set_arguments(reply, "u", val_u32);
2206 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2207 l_dbus_send(dbus, reply);
2208 ret = BT_STATUS_SUCCESS;
2209 /* For Alpha-Numeric */
2210 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2211 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2212 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2213 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2214 alpha = l_util_from_hexstring(auth_value, &sz);
2215 reply = l_dbus_message_new_method_return(agent_msg);
2216 builder = l_dbus_message_builder_new(reply);
2217 __mesh_append_byte_array(builder, alpha, 16);
2218 l_dbus_message_builder_finalize(builder);
2219 l_dbus_message_builder_destroy(builder);
2222 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2223 l_dbus_send(dbus, reply);
2224 ret = BT_STATUS_SUCCESS;
2229 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2230 bt_hal_mesh_scan_param_t *param)
2234 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2237 if (!__bt_mesh_proxy_check(app)) {
2238 ERR("Mesh: Proxy check failed!!");
2239 return BT_STATUS_FAIL;
2241 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2242 __mesh_scan_setup, __mesh_scan_reply,
2243 L_UINT_TO_PTR(param->scan_time), NULL))
2244 return BT_STATUS_FAIL;
2246 ERR("Mesh: app not found!!");
2247 return BT_STATUS_PARM_INVALID;
2249 return BT_STATUS_SUCCESS;
2252 bt_status_t _bt_hal_mesh_create_network(
2253 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2257 INFO("Mesh: Create Network Request");
2259 if (!__bt_mesh_proxy_check(0)) {
2260 ERR("Mesh: Proxy check failed!!");
2261 return BT_STATUS_FAIL;
2264 INFO("Mesh: Node Element count [%d]", node->num_elements);
2265 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2266 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2267 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2268 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2269 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2270 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2271 /* Create DBUS APP */
2272 app = __bt_hal_mesh_create_app(node, models, is_prov);
2274 return BT_STATUS_FAIL;
2276 /* Register DBUS APP */
2277 if (!__bt_hal_mesh_register_application(app))
2280 if (app->token.u64 == 0) {
2281 INFO("Mesh: Create New Network");
2282 /* Create CFG Network */
2283 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2284 __bt_hal_mesh_create_net_setup,
2285 __bt_hal_mesh_create_net_reply, app,
2287 ERR("Mesh: Network Create failed!!");
2291 INFO("Mesh: Attach Node to Network");
2292 /* Attach to Network */
2293 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2294 __bt_hal_mesh_attach_node_setup,
2295 __bt_hal_mesh_attach_node_reply,
2298 ERR("Mesh: Node attach failed!!");
2303 INFO("Mesh: Node registration request scheudled");
2304 mesh_apps = g_slist_append(mesh_apps, app);
2305 INFO("Mesh: Total number of apps in list [%d]",
2306 g_slist_length(mesh_apps));
2307 return BT_STATUS_SUCCESS;
2309 ERR("Mesh: network can not be created!!");
2310 __bt_hal_mesh_destroy_app_object(app);
2311 return BT_STATUS_FAIL;
2314 static void __bt_hal_mesh_config_send(
2315 struct l_dbus_message *msg, void *user_data)
2317 struct configuration_request *req = user_data;
2318 struct l_dbus_message_builder *builder;
2320 builder = l_dbus_message_builder_new(msg);
2322 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2323 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2324 if (req->is_dev_key)
2325 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2327 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2328 __mesh_append_byte_array(builder, req->data, req->len);
2329 l_dbus_message_builder_finalize(builder);
2330 l_dbus_message_builder_destroy(builder);
2333 static void __bt_hal_mesh_key_config_send(
2334 struct l_dbus_message *msg, void *user_data)
2336 struct key_config_request *req = user_data;
2337 struct l_dbus_message_builder *builder;
2339 builder = l_dbus_message_builder_new(msg);
2341 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2342 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2343 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2344 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2345 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2346 l_dbus_message_builder_finalize(builder);
2347 l_dbus_message_builder_destroy(builder);
2350 static void __bt_hal_mesh_model_execute_message(
2351 struct l_dbus_message *msg, void *user_data)
2353 struct configuration_request *req = user_data;
2354 struct l_dbus_message_builder *builder;
2356 builder = l_dbus_message_builder_new(msg);
2358 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2359 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2360 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2361 __mesh_append_byte_array(builder, req->data, req->len);
2362 l_dbus_message_builder_finalize(builder);
2363 l_dbus_message_builder_destroy(builder);
2366 bt_status_t _bt_hal_mesh_send_key_config_message(
2367 bt_uuid_t *network, uint16_t dest,
2368 bool is_netkey, bool is_update,
2369 uint16_t key_idx, uint16_t netkey_idx)
2373 struct key_config_request *req;
2376 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2377 /* Source is Config Client Local Node */
2378 int src_elem_idx = 0;
2379 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2382 if (!__bt_mesh_proxy_check(app)) {
2383 ERR("Mesh: Proxy check failed!!");
2384 return BT_STATUS_FAIL;
2386 l1 = g_slist_find_custom(app->elements,
2387 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2389 return BT_STATUS_FAIL;
2392 req = l_new(struct key_config_request, 1);
2393 req->ele_path = elem->path;
2395 req->key_req_idx = key_idx;
2396 req->idx = netkey_idx; /* Encryption Key index */
2397 req->update_req = is_update;
2399 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2400 __bt_hal_mesh_key_config_send, NULL,
2401 (void*)req, l_free))
2402 return BT_STATUS_FAIL;
2404 ERR("Mesh: app not found!!");
2405 return BT_STATUS_PARM_INVALID;
2408 return BT_STATUS_SUCCESS;
2411 bt_status_t _bt_hal_mesh_send_configuration_message(
2412 bt_uuid_t *network, uint16_t dest,
2413 bool is_dev_key, uint16_t netkey_idx,
2414 uint8_t *buf, int len)
2418 struct configuration_request *req;
2421 int src_elem_idx = 0;
2422 l = g_slist_find_custom(mesh_apps, network->uu,
2423 __mesh_compare_network_uuid);
2426 if (!__bt_mesh_proxy_check(app)) {
2427 ERR("Mesh: Proxy check failed!!");
2428 return BT_STATUS_FAIL;
2430 l1 = g_slist_find_custom(app->elements,
2431 GUINT_TO_POINTER(src_elem_idx),
2432 __compare_element_index);
2434 return BT_STATUS_FAIL;
2437 req = l_new(struct configuration_request, 1);
2438 req->ele_path = elem->path;
2440 req->idx = netkey_idx;
2444 req->is_dev_key = is_dev_key;
2446 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2447 __bt_hal_mesh_config_send, NULL,
2448 (void*)req, l_free))
2449 return BT_STATUS_FAIL;
2451 ERR("Mesh: app not found!!");
2452 return BT_STATUS_PARM_INVALID;
2455 return BT_STATUS_SUCCESS;
2458 bt_status_t _bt_hal_mesh_model_execute_message(
2459 bt_uuid_t *network, uint16_t dest,
2460 uint16_t appkey_idx, uint8_t *buf, int len)
2464 struct configuration_request *req;
2467 int src_elem_idx = 0;
2468 l = g_slist_find_custom(mesh_apps, network->uu,
2469 __mesh_compare_network_uuid);
2472 if (!__bt_mesh_proxy_check(app)) {
2473 ERR("Mesh: Proxy check failed!!");
2474 return BT_STATUS_FAIL;
2476 l1 = g_slist_find_custom(app->elements,
2477 GUINT_TO_POINTER(src_elem_idx),
2478 __compare_element_index);
2480 return BT_STATUS_FAIL;
2483 req = l_new(struct configuration_request, 1);
2484 req->ele_path = elem->path;
2486 req->idx = appkey_idx;
2490 req->is_dev_key = false;
2492 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2493 __bt_hal_mesh_model_execute_message,
2494 NULL, (void*)req, l_free))
2495 return BT_STATUS_FAIL;
2497 ERR("Mesh: app not found!!");
2498 return BT_STATUS_PARM_INVALID;
2501 return BT_STATUS_SUCCESS;