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 /* To send stack event to hal-mesh handler */
580 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
585 /* To send stack event to hal-mesh handler */
586 void _bt_hal_mesh_unregister_dbus_handler_cb()
588 mesh_event_cb = NULL;
591 static bool __mesh_get_companyid(struct l_dbus *dbus,
592 struct l_dbus_message *message,
593 struct l_dbus_message_builder *builder,
596 meshcfg_app *app = (meshcfg_app*) user_data;
600 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
605 static bool __mesh_get_productid(struct l_dbus *dbus,
606 struct l_dbus_message *message,
607 struct l_dbus_message_builder *builder,
610 meshcfg_app *app = (meshcfg_app*) user_data;
613 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
618 static bool __mesh_get_versionid(struct l_dbus *dbus,
619 struct l_dbus_message *message,
620 struct l_dbus_message_builder *builder,
623 meshcfg_app *app = (meshcfg_app*) user_data;
626 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
631 static bool __mesh_get_crpl(struct l_dbus *dbus,
632 struct l_dbus_message *message,
633 struct l_dbus_message_builder *builder,
636 meshcfg_app *app = (meshcfg_app*) user_data;
639 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
644 static void __send_network_attach_event(void *param, uint8_t status)
646 struct hal_ev_mesh_network_attached ev;
647 meshcfg_app *app = (meshcfg_app*)param;
649 memset(&ev, 0, sizeof(ev));
650 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
651 memcpy(ev.token, app->token.u8, 8);
655 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
656 (void*)&ev, sizeof(ev));
659 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
660 struct l_dbus_message *msg, void *user_data)
662 struct l_dbus_message_iter iter_cfg;
664 meshcfg_app *app = (meshcfg_app*) user_data;
665 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
666 app->path, app->agent_path);
668 if (l_dbus_message_is_error(msg)) {
670 l_dbus_message_get_error(msg, &name, NULL);
671 ERR("Mesh: Failed to attach node: %s", name);
676 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
680 INFO("Mesh: Attached with path %s\n", app->path);
681 __send_network_attach_event(app, BT_STATUS_SUCCESS);
684 __send_network_attach_event(app, BT_STATUS_FAIL);
685 /* Destroy mesh app object */
686 __bt_hal_mesh_destroy_app_object(app);
689 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
692 meshcfg_app *app = (meshcfg_app*) user_data;
694 l_dbus_message_set_arguments(msg, "ot", app->path,
695 l_get_be64(app->token.u8));
699 static void __bt_hal_mesh_attach_node(void *user_data)
701 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
702 __bt_hal_mesh_attach_node_setup,
703 __bt_hal_mesh_attach_node_reply,
706 ERR("Mesh: Node attach failed!!");
707 /* Node could not be attached */
708 __send_network_attach_event(user_data, BT_STATUS_FAIL);
709 /* Destroy mesh app object */
710 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
714 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
715 struct l_dbus_message *message,
721 meshcfg_app *app = (meshcfg_app*) user_data;
722 INFO("Mesh: Join Complete");
725 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
727 /* Send Network creation fail event */
728 __send_network_attach_event(app, BT_STATUS_FAIL);
730 /* Destroy mesh app object */
731 __bt_hal_mesh_destroy_app_object(app);
733 return l_dbus_message_new_error(message, dbus_err_args, NULL);
737 app->token.u64 = l_get_be64(&tmp);
738 str = l_util_hexstring(&app->token.u8[0], 8);
739 INFO("Mesh: Created new node with token %s\n", str);
742 /* Authenticate the node */
743 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
744 return l_dbus_message_new_method_return(message);
747 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
750 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
751 meshcfg_model *model_info = (meshcfg_model*) data;
753 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
756 static bool __mesh_model_getter(struct l_dbus *dbus,
757 struct l_dbus_message *message,
758 struct l_dbus_message_builder *builder,
761 meshcfg_el *element = (meshcfg_el*) user_data;
763 l_dbus_message_builder_enter_array(builder, "q");
764 g_slist_foreach(element->models,
765 __bt_hal_mesh_foreach_model_getter, builder);
767 l_dbus_message_builder_leave_array(builder);
772 /*TODO: Vendor Model handling is currently not Handled */
773 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
774 struct l_dbus_message *message,
775 struct l_dbus_message_builder *builder,
778 l_dbus_message_builder_enter_array(builder, "(qq)");
779 l_dbus_message_builder_leave_array(builder);
784 static bool __mesh_element_index_getter(struct l_dbus *dbus,
785 struct l_dbus_message *message,
786 struct l_dbus_message_builder *builder,
789 meshcfg_el *element = (meshcfg_el*) user_data;
790 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
796 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
797 struct l_dbus_message *msg, void *user_data)
799 struct l_dbus_message_iter iter;
804 const char *dbus_path;
807 dbus_path = l_dbus_message_get_path(msg);
808 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
809 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
810 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
812 INFO("Mesh: app path [%s]", dbus_path);
814 memset(buf, 0, sizeof(buf));
815 size = (uint16_t) sizeof(*ev);
816 memcpy(ev->net_uuid, net_uuid, 16);
819 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
821 ERR("Mesh: Cannot parse received message");
822 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
825 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
826 ERR("Mesh: Cannot parse received message: data");
827 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
830 INFO("Mesh: Received dev key message (len %u):", n);
831 ev->source_addr = src;
832 ev->is_remote_devkey = rmt;
833 ev->netkey_idx = idx;
835 memcpy(ev->data, data, n);
838 INFO("Mesh: Src [0x%2.2x]", src);
839 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
840 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
841 /* Send DevKeyMessage Received event */
843 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
845 return l_dbus_message_new_method_return(msg);
848 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
849 struct l_dbus_message *msg, void *user_data)
851 struct l_dbus_message_iter iter;
852 uint16_t src, idx, dst;
855 const char *dbus_path;
858 dbus_path = l_dbus_message_get_path(msg);
859 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
860 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
861 struct hal_ev_mesh_message_event *ev = (void *)buf;
863 INFO("Mesh: app path [%s]", dbus_path);
865 memset(buf, 0, sizeof(buf));
866 size = (uint16_t) sizeof(*ev);
867 memcpy(ev->net_uuid, net_uuid, 16);
870 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
872 ERR("Mesh: Cannot parse received message");
873 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
876 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
877 ERR("Mesh: Cannot parse received message: data");
878 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
881 INFO("Mesh: Received mesh message (len %u):", n);
882 ev->source_addr = src;
886 memcpy(ev->data, data, n);
889 INFO("Mesh: Src [0x%2.2x]", src);
890 INFO("Mesh: Dst [0x%2.2x]", dst);
891 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
892 /* Send Message Received event */
894 INFO("Mesh: Send message event");
896 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
898 return l_dbus_message_new_method_return(msg);
901 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
903 INFO("Mesh: Setup element interface properties & methods");
905 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
907 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
908 __mesh_vendor_model_getter, NULL);
909 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
912 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
913 __mesh_device_message_received, "", "qbqay", "source",
914 "remote", "net_index", "data");
915 l_dbus_interface_method(iface, "MessageReceived", 0,
916 __mesh_message_received, "", "qqvay", "source",
917 "key_index", "destination", "data");
918 /* TODO: Other methods */
921 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
922 struct l_dbus_message *msg,
925 struct l_dbus_message_iter iter, opts;
926 meshcfg_app *app = (meshcfg_app*) user_data;
931 const char *sig = "naya{sv}";
933 /* Find network uuid from dbus path */
934 struct hal_ev_mesh_scan_result ev;
936 if (!app->scan_timer_id) {
937 /* Scan is not running */
938 INFO("Got scan result, but scan is already stopped");
939 return l_dbus_message_new_method_return(msg);
941 memset(&ev, 0, sizeof(ev));
942 memcpy(ev.net_uuid, app->uuid, 16);
944 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
945 ERR("Mesh: Cannot parse scan results");
946 ev.status = BT_STATUS_FAIL;
948 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
950 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
953 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
955 ERR("Mesh: Cannot parse scan result: data");
956 ev.status = BT_STATUS_FAIL;
958 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
960 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
963 INFO("Mesh: Scan result:\n");
964 INFO("Mesh: Scan rssi = [%d]\n", rssi);
965 str = l_util_hexstring_upper(prov_data, 16);
966 INFO("Mesh: Scan UUID = [%s]\n", str);
970 str = l_util_hexstring_upper(prov_data + 16, 2);
971 INFO("Mesh: Scan OOB = [%s]\n", str);
976 str = l_util_hexstring_upper(prov_data + 18, 4);
977 INFO("Mesh: Scan URI hash = [%s]\n", str);
981 /* 16 octet Dev UUID */
982 memcpy(ev.dev_uuid, prov_data, 16);
984 /* 2 octet Dev OOB Info */
985 memcpy(ev.oob_info, prov_data + 16, 2);
987 /* 4 octet URI Hash */
988 memcpy(ev.uri_hash, prov_data + 18, 4);
992 ev.status = BT_STATUS_SUCCESS;
994 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
995 (void*)&ev, sizeof(ev));
997 return l_dbus_message_new_method_return(msg);
1000 static struct l_dbus_message *__mesh_request_provisioner_call(
1001 struct l_dbus *dbus,
1002 struct l_dbus_message *msg,
1006 struct hal_ev_mesh_provision_finished ev;
1007 struct hal_ev_mesh_provision_data_request req;
1009 meshcfg_app *app = user_data;
1011 INFO("Mesh: provisioning data requested app path [%s]",
1013 uuid_string = l_util_hexstring(app->uuid, 16);
1014 INFO("Mesh: Network UUID [%s]", uuid_string);
1016 memset(&ev, 0, sizeof(ev));
1017 memset(&req, 0, sizeof(req));
1018 memcpy(ev.net_uuid, app->uuid, 16);
1019 memcpy(req.net_uuid, app->uuid, 16);
1020 l_free(uuid_string);
1022 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1023 ERR("Mesh: Cannot parse request for prov data");
1025 ev.status = BT_STATUS_FAIL;
1026 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1028 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1029 (void*)&ev, sizeof(ev));
1030 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1036 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1037 (void*)&req, sizeof(req));
1039 l_dbus_message_ref(msg);
1043 static struct l_dbus_message *__mesh_node_add_completed(
1044 struct l_dbus *dbus,
1045 struct l_dbus_message *msg,
1048 struct l_dbus_message_iter iter;
1053 struct hal_ev_mesh_provision_finished ev;
1054 const char *dbus_path;
1056 dbus_path = l_dbus_message_get_path(msg);
1057 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1058 true, MESH_PROV_IFACE);
1060 INFO("Mesh: app path [%s]", dbus_path);
1062 memset(&ev, 0, sizeof(ev));
1063 memcpy(ev.net_uuid, net_uuid, 16);
1067 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1068 ERR("Mesh: Cannot parse add node complete message");
1070 ev.status = BT_STATUS_FAIL;
1071 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1073 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1074 (void*)&ev, sizeof(ev));
1075 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1078 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1080 ERR("Mesh: Cannot parse add node complete message: uuid");
1082 ev.status = BT_STATUS_FAIL;
1083 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1085 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1086 (void*)&ev, sizeof(ev));
1087 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1091 ev.status = BT_STATUS_SUCCESS;
1092 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1093 memcpy(ev.dev_uuid, uuid, 16);
1094 ev.unicast = unicast;
1098 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1099 (void*)&ev, sizeof(ev));
1101 return l_dbus_message_new_method_return(msg);
1104 static struct l_dbus_message *__mesh_node_add_failed(
1105 struct l_dbus *dbus,
1106 struct l_dbus_message *msg,
1109 struct l_dbus_message_iter iter;
1113 struct hal_ev_mesh_provision_finished ev;
1114 const char *dbus_path;
1117 dbus_path = l_dbus_message_get_path(msg);
1118 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1119 true, MESH_PROV_IFACE);
1121 memset(&ev, 0, sizeof(ev));
1122 memcpy(ev.net_uuid, net_uuid, 16);
1125 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1126 ERR("Mesh: Cannot parse add node failed message");
1128 ev.status = BT_STATUS_FAIL;
1129 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1131 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1132 (void*)&ev, sizeof(ev));
1133 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1136 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1138 ERR("Mesh:Cannot parse add node failed message: uuid");
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 INFO("Mesh: Provisioning failed:\n");
1148 str = l_util_hexstring_upper(uuid, 16);
1149 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1152 ev.status = BT_STATUS_FAIL;
1153 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1154 memcpy(ev.dev_uuid, uuid, 16);
1157 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1158 (void*)&ev, sizeof(ev));
1160 return l_dbus_message_new_method_return(msg);
1163 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1165 INFO("Mesh: Setup provisioner interface properties & methods");
1166 l_dbus_interface_method(interface, "ScanResult", 0,
1167 __mesh_scan_result_received, "",
1168 "naya{sv}", "rssi", "data", "options");
1170 l_dbus_interface_method(interface, "RequestProvData", 0,
1171 __mesh_request_provisioner_call,
1172 "qq", "y", "net_index", "unicast", "count");
1174 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1175 __mesh_node_add_completed, "", "ayqy",
1176 "uuid", "unicast", "count");
1178 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1179 __mesh_node_add_failed,
1180 "", "ays", "uuid", "reason");
1183 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1185 INFO("Mesh: Setup application interface properties & methods");
1187 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1188 __mesh_get_companyid,
1190 l_dbus_interface_property(iface, "VersionID", 0, "q",
1191 __mesh_get_versionid,
1193 l_dbus_interface_property(iface, "ProductID", 0, "q",
1194 __mesh_get_productid,
1196 l_dbus_interface_property(iface, "CRPL", 0, "q",
1197 __mesh_get_crpl, NULL);
1198 l_dbus_interface_method(iface, "JoinComplete", 0,
1199 __mesh_node_join_complete,
1205 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1206 struct l_dbus_message_builder *builder)
1208 if (app->in_oob & 0x08)
1209 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1210 if (app->in_oob & 0x04)
1211 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1212 if (app->in_oob & 0x02)
1213 l_dbus_message_builder_append_basic(builder, 's', "twist");
1214 if (app->in_oob & 0x01)
1215 l_dbus_message_builder_append_basic(builder, 's', "push");
1218 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1219 struct l_dbus_message_builder *builder)
1221 if (app->out_oob & 0x10)
1222 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1223 if (app->out_oob & 0x08)
1224 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1225 if (app->out_oob & 0x04)
1226 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1227 if (app->out_oob & 0x02)
1228 l_dbus_message_builder_append_basic(builder, 's', "beep");
1229 if (app->out_oob & 0x01)
1230 l_dbus_message_builder_append_basic(builder, 's', "blink");
1233 static bool __mesh_agent_capability_getter(
1234 struct l_dbus *dbus,struct l_dbus_message *message,
1235 struct l_dbus_message_builder *builder,
1240 INFO("Mesh: app path [%s]", app->path);
1241 INFO("Mesh: Agent path [%s]", app->agent_path);
1243 if (!l_dbus_message_builder_enter_array(builder, "s")) {
1247 __mesh_fill_out_capabilities(app, builder);
1248 __mesh_fill_in_capabilities(app, builder);
1250 if (app->static_oob)
1251 l_dbus_message_builder_append_basic(builder,
1255 l_dbus_message_builder_leave_array(builder);
1256 INFO("Mesh: __agent_capability_getter: Success");
1260 static struct l_dbus_message *__mesh_agent_display_string_request(
1261 struct l_dbus *dbus,
1262 struct l_dbus_message *msg,
1265 struct hal_ev_mesh_authentication_request ev;
1268 const char *dbus_path;
1271 INFO("Mesh: app path [%s]", app->path);
1272 INFO("Mesh: Agent path [%s]", app->agent_path);
1274 dbus_path = l_dbus_message_get_path(msg);
1275 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1276 true, MESH_AGENT_IFACE);
1278 INFO("Mesh: app path [%s]", dbus_path);
1280 memset(&ev, 0, sizeof(ev));
1281 memcpy(ev.net_uuid, net_uuid, 16);
1284 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1285 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1286 struct hal_ev_mesh_provision_finished ev;
1287 memset(&ev, 0, sizeof(ev));
1288 memcpy(ev.net_uuid, net_uuid, 16);
1289 ev.status = BT_STATUS_FAIL;
1290 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1292 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1293 (void*)&ev, sizeof(ev));
1297 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1300 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1301 ev.auth_type = __mesh_get_authentication_type(str);
1302 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1303 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1304 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1307 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1308 (void*)&ev, sizeof(ev));
1311 return l_dbus_message_new_method_return(msg);
1314 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1315 struct l_dbus *dbus,
1316 struct l_dbus_message *msg,
1320 struct hal_ev_mesh_authentication_request ev;
1324 const char *dbus_path;
1327 INFO("Mesh: app path [%s]", app->path);
1328 INFO("Mesh: Agent path [%s]", app->agent_path);
1330 dbus_path = l_dbus_message_get_path(msg);
1331 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1332 true, MESH_AGENT_IFACE);
1334 INFO("Mesh: app path [%s]", dbus_path);
1336 memset(&ev, 0, sizeof(ev));
1337 memcpy(ev.net_uuid, net_uuid, 16);
1340 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1341 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1342 struct hal_ev_mesh_provision_finished ev;
1343 memset(&ev, 0, sizeof(ev));
1344 memcpy(ev.net_uuid, net_uuid, 16);
1345 ev.status = BT_STATUS_FAIL;
1346 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1347 if (mesh_event_cb) {
1348 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1349 (void*)&ev, sizeof(ev));
1352 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1355 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1356 auth_value = l_strdup_printf("%u",n);
1357 ev.auth_type = __mesh_get_authentication_type(str);
1358 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1359 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1360 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1363 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1364 (void*)&ev, sizeof(ev));
1368 return l_dbus_message_new_method_return(msg);
1371 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1372 struct l_dbus *dbus,
1373 struct l_dbus_message *msg,
1376 struct hal_ev_mesh_authentication_request ev;
1379 const char *dbus_path;
1383 dbus_path = l_dbus_message_get_path(msg);
1384 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1385 true, MESH_AGENT_IFACE);
1387 INFO("Mesh: app path [%s]", dbus_path);
1389 l = g_slist_find_custom(mesh_apps, net_uuid,
1390 __mesh_compare_network_uuid);
1393 memset(&ev, 0, sizeof(ev));
1394 memcpy(ev.net_uuid, net_uuid, 16);
1397 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1398 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1400 struct hal_ev_mesh_provision_finished ev;
1401 memset(&ev, 0, sizeof(ev));
1402 memcpy(ev.net_uuid, app->uuid, 16);
1403 ev.status = BT_STATUS_FAIL;
1404 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1405 if (mesh_event_cb) {
1406 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1407 (void*)&ev, sizeof(ev));
1409 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1412 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1414 ev.auth_type = __mesh_get_authentication_type(str);
1415 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1416 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1418 l_dbus_message_ref(msg);
1420 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1421 (void*)&ev, sizeof(ev));
1426 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1427 struct l_dbus *dbus,
1428 struct l_dbus_message *msg,
1431 struct hal_ev_mesh_authentication_request ev;
1434 const char *dbus_path;
1438 dbus_path = l_dbus_message_get_path(msg);
1439 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1442 INFO("Mesh: app path [%s]", dbus_path);
1444 l = g_slist_find_custom(mesh_apps, net_uuid,
1445 __mesh_compare_network_uuid);
1448 memset(&ev, 0, sizeof(ev));
1449 memcpy(ev.net_uuid, net_uuid, 16);
1452 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1453 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1455 struct hal_ev_mesh_provision_finished ev;
1456 memset(&ev, 0, sizeof(ev));
1457 memcpy(ev.net_uuid, app->uuid, 16);
1458 ev.status = BT_STATUS_FAIL;
1459 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1461 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1462 (void*)&ev, sizeof(ev));
1463 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1466 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1468 ev.auth_type = __mesh_get_authentication_type(str);
1469 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1470 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1472 l_dbus_message_ref(msg);
1474 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1475 (void*)&ev, sizeof(ev));
1480 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1482 INFO("Mesh: Setup Agent interface properties & methods");
1483 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1484 __mesh_agent_capability_getter,
1486 /* TODO: Other properties */
1487 l_dbus_interface_method(interface, "DisplayString", 0,
1488 __mesh_agent_display_string_request,
1490 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1491 __mesh_agent_display_numeric_request,
1492 "", "su", "type", "number");
1493 l_dbus_interface_method(interface, "PromptNumeric", 0,
1494 __mesh_agent_prompt_numeric_request,
1495 "u", "s", "number", "type");
1496 l_dbus_interface_method(interface, "PromptStatic", 0,
1497 __mesh_agent_prompt_static_request,
1498 "ay", "s", "data", "type");
1501 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1503 meshcfg_el *elem = (meshcfg_el*) data;
1504 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1505 elem->index, elem->path);
1506 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1507 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1508 ERR("Mesh: Failed to register object %s", elem->path);
1512 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1517 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1518 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1519 ERR("Mesh: Unable to register agent interface");
1523 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1524 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1525 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1526 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1530 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1531 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1532 ERR("Mesh: Failed to add interface %s",
1533 L_DBUS_INTERFACE_PROPERTIES);
1540 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1548 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1549 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1550 ERR("Mesh: Failed to register interface %s",
1551 BT_HAL_MESH_APPLICATION_INTERFACE);
1555 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1556 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1557 ERR("Mesh: Failed to register interface %s",
1558 BT_HAL_MESH_PROVISIONER_INTERFACE);
1562 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1563 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1564 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1566 ERR("Mesh: Failed to register object %s", ptr->path);
1570 if (!__bt_hal_mesh_register_agent(ptr))
1573 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1574 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1575 ERR("Mesh: Failed to register interface %s",
1576 BT_HAL_MESH_ELEMENT_INTERFACE);
1580 INFO("Mesh: Number of elements to be registsred [%d]",
1581 g_slist_length(ptr->elements));
1583 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1585 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1586 if (!l_dbus_object_add_interface(dbus, ptr->path,
1587 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1588 ERR("Mesh: Failed to add interface %s",
1589 L_DBUS_INTERFACE_OBJECT_MANAGER);
1592 INFO("Mesh: Application Register completed");
1597 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1601 meshcfg_model *model_info = (meshcfg_model*) data;
1602 meshcfg_app *app = (meshcfg_app*) user_data;
1604 l = g_slist_find_custom(app->elements,
1605 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1609 elem = g_malloc0(sizeof(meshcfg_el));
1610 elem->index = model_info->elem_index;
1611 elem->path = g_strdup_printf("%s/elem%u",app->path, elem->index);
1612 app->elements = g_slist_append(app->elements, elem);
1613 INFO("Mesh: Created element index [%d] path [%s]",
1614 elem->index, elem->path);
1616 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1617 model_info->model, elem->index);
1618 /* Add Model in the element */
1619 elem->models = g_slist_append(elem->models, model_info);
1620 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1621 elem->index, g_slist_length(elem->models));
1624 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1625 GSList *models, bool is_prov)
1628 meshcfg_app *app = NULL;
1629 char *uuid_str = NULL;
1631 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1633 app = g_malloc0(sizeof(meshcfg_app));
1634 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1636 app->cid = node->vendor_info.companyid;
1637 app->pid = node->vendor_info.vendorid;
1638 app->vid = node->vendor_info.versionid;
1639 app->crpl = node->vendor_info.crpl;
1642 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1643 app->agent_path = g_strdup_printf("%s/agent", app->path);
1646 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1647 app->agent_path = g_strdup_printf("%s/agent", app->path);
1649 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1652 app->is_prov = is_prov;
1653 INFO("Mesh: app created");
1657 static void __bt_hal_mesh_create_net_reply(
1658 struct l_dbus_proxy *proxy,
1659 struct l_dbus_message *msg, void *user_data)
1662 app = (meshcfg_app*) user_data;
1664 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1665 if (l_dbus_message_is_error(msg)) {
1668 l_dbus_message_get_error(msg, &name, NULL);
1669 ERR("Mesh: Failed to create network: %s", name);
1671 /* Send Network creation fail event */
1672 __send_network_attach_event(app, BT_STATUS_FAIL);
1674 /* Destroy mesh app object */
1675 __bt_hal_mesh_destroy_app_object(app);
1680 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1684 struct l_dbus_message_builder *builder;
1685 app = (meshcfg_app*) user_data;
1687 builder = l_dbus_message_builder_new(msg);
1689 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1690 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1691 __mesh_append_byte_array(builder, app->uuid, 16);
1692 l_dbus_message_builder_finalize(builder);
1693 l_dbus_message_builder_destroy(builder);
1696 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1698 struct hal_ev_mesh_scan_state_changed ev;
1700 memset(&ev, 0, sizeof(ev));
1701 memcpy(ev.net_uuid, app->uuid, 16);
1703 ev.status = BT_STATUS_SUCCESS;
1705 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1707 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1708 (void*)&ev, sizeof(ev));
1711 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1713 meshcfg_app *app = (meshcfg_app*) user_data;
1714 __mesh_trigger_scan_finished_event(app);
1718 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1722 l = g_slist_find_custom(mesh_apps, net_uuid,
1723 __mesh_compare_network_uuid);
1726 if (app->scan_timer_id > 0) {
1727 g_source_remove(app->scan_timer_id);
1728 app->scan_timer_id = 0;
1731 app->scan_timer_id = g_timeout_add_seconds(secs,
1732 __bt_mesh_scan_timer_cb, app);
1737 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1738 struct l_dbus_message *msg, void *user_data)
1740 struct hal_ev_mesh_scan_state_changed ev;
1741 const char *dbus_path;
1743 dbus_path = l_dbus_proxy_get_path(proxy);
1744 INFO("Mesh: DBUS path [%s]", dbus_path);
1745 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1747 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1748 INFO("Mesh: Scan duration [%u]", secs);
1750 memset(&ev, 0, sizeof(ev));
1751 memcpy(ev.net_uuid, net_uuid, 16);
1753 if (l_dbus_message_is_error(msg)) {
1755 l_dbus_message_get_error(msg, &name, NULL);
1756 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1757 ev.status = BT_STATUS_FAIL;
1759 INFO("Mesh: Unprovisioned scan started\n");
1760 ev.status = BT_STATUS_SUCCESS;
1761 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1764 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1766 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1767 (void*)&ev, sizeof(ev));
1771 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1772 const char *key, const char *signature,
1778 l_dbus_message_builder_enter_dict(builder, "sv");
1779 l_dbus_message_builder_append_basic(builder, 's', key);
1780 l_dbus_message_builder_enter_variant(builder, signature);
1781 l_dbus_message_builder_append_basic(builder, signature[0], data);
1782 l_dbus_message_builder_leave_variant(builder);
1783 l_dbus_message_builder_leave_dict(builder);
1786 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1788 struct l_dbus_message_builder *builder;
1789 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1790 INFO("Mesh: Scan duration [%u]", secs);
1792 builder = l_dbus_message_builder_new(msg);
1793 l_dbus_message_builder_enter_array(builder, "{sv}");
1794 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1795 l_dbus_message_builder_leave_array(builder);
1796 l_dbus_message_builder_finalize(builder);
1797 l_dbus_message_builder_destroy(builder);
1801 bt_status_t _bt_hal_mesh_network_set_caps(
1802 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1806 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1810 app->public_oob = caps->public_oob;
1811 app->static_oob = caps->static_oob;
1812 app->out_oob = caps->out_oob;
1813 app->in_oob = caps->in_oob;
1815 ERR("Mesh: app not found!!");
1816 return BT_STATUS_PARM_INVALID;
1819 return BT_STATUS_SUCCESS;
1822 static void __bt_hal_mesh_add_node_reply(
1823 struct l_dbus_proxy *proxy,
1824 struct l_dbus_message *msg,
1827 struct hal_ev_mesh_provision_status ev;
1828 const char *dbus_path;
1830 dbus_path = l_dbus_proxy_get_path(proxy);
1831 INFO("Mesh: DBUS path [%s]", dbus_path);
1832 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1834 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1836 INFO("Mesh: app path [%s]", dbus_path);
1838 memset(&ev, 0, sizeof(ev));
1839 memcpy(ev.net_uuid, net_uuid, 16);
1840 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1842 /* Free User data */
1843 g_free((void*)dev_uuid);
1846 if (l_dbus_message_is_error(msg)) {
1849 l_dbus_message_get_error(msg, &name, NULL);
1850 ERR("Mesh: Failed to start provisioning: %s", name);
1851 ev.status = BT_STATUS_FAIL;
1853 INFO("Mesh: Provisioning started\n");
1854 ev.status = BT_STATUS_SUCCESS;
1857 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1858 (void*)&ev, sizeof(ev));
1859 INFO("Mesh: Provisioning status sent");
1862 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1866 bt_uuid_t *dev = user_data;
1867 struct l_dbus_message_builder *builder;
1868 uuid = l_util_hexstring(dev->uu, 16);
1869 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1871 builder = l_dbus_message_builder_new(msg);
1872 __mesh_append_byte_array(builder, dev->uu, 16);
1873 l_dbus_message_builder_enter_array(builder, "{sv}");
1874 l_dbus_message_builder_leave_array(builder);
1875 l_dbus_message_builder_finalize(builder);
1876 l_dbus_message_builder_destroy(builder);
1879 bt_status_t _bt_hal_mesh_provision_device(
1880 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1885 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1888 dev = g_memdup((gpointer)dev_uuid, 16);
1889 INFO("Mesh: Schedule Add Node request to meshd");
1890 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1891 __bt_hal_mesh_add_node_setup,
1892 __bt_hal_mesh_add_node_reply,
1894 return BT_STATUS_FAIL;
1896 ERR("Mesh: app not found!!");
1897 return BT_STATUS_PARM_INVALID;
1900 return BT_STATUS_SUCCESS;
1903 static void __bt_hal_mesh_subnet_key_setup(
1904 struct l_dbus_message *msg, void *user_data)
1906 struct subnet_key_request *req = user_data;
1907 uint16_t idx = (uint16_t) req->idx;
1909 l_dbus_message_set_arguments(msg, "q", idx);
1912 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1913 struct l_dbus_message *msg, void *user_data)
1915 struct hal_ev_mesh_netkey_execute_event ev;
1916 const char *dbus_path;
1918 struct subnet_key_request *req = user_data;
1919 const char *method = req->str;
1921 dbus_path = l_dbus_proxy_get_path(proxy);
1922 INFO("Mesh: DBUS path [%s]", dbus_path);
1923 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1925 memset(&ev, 0, sizeof(ev));
1926 memcpy(ev.net_uuid, net_uuid, 16);
1927 ev.key_idx = req->idx;
1931 if (l_dbus_message_is_error(msg)) {
1934 l_dbus_message_get_error(msg, &name, NULL);
1935 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
1936 ev.status = BT_STATUS_FAIL;
1939 ev.status = BT_STATUS_SUCCESS;
1941 if (!strcmp("CreateSubnet", method)) {
1942 INFO("Mesh: Reply for CreateSubnet");
1943 ev.key_event = HAL_MESH_KEY_ADD;
1944 } else if (!strcmp("DeleteSubnet", method)) {
1945 INFO("Mesh: Reply for DeleteSubnet");
1946 ev.key_event = HAL_MESH_KEY_DELETE;
1947 } else if (!strcmp("UpdateSubnet", method)) {
1948 INFO("Mesh: Reply for UpdateSubnet");
1949 ev.key_event = HAL_MESH_KEY_UPDATE;
1953 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
1954 (void*)&ev, sizeof(ev));
1957 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
1958 uint16_t index, const char *key_execute_method)
1960 struct subnet_key_request *req;
1962 req = l_new(struct subnet_key_request, 1);
1963 req->str = key_execute_method;
1966 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1967 __bt_hal_mesh_subnet_key_setup,
1968 __bt_hal_mesh_subnet_key_reply,
1975 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
1978 struct app_key_request *req = user_data;
1979 uint16_t net_idx = (uint16_t) req->net_idx;
1980 uint16_t app_idx = (uint16_t) req->app_idx;
1982 if (g_strcmp0(req->str,"CreateAppKey") == 0)
1983 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
1985 l_dbus_message_set_arguments(msg, "q", app_idx);
1988 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
1989 struct l_dbus_message *msg, void *user_data)
1991 struct hal_ev_mesh_appkey_execute_event ev;
1992 const char *dbus_path;
1994 struct app_key_request *req = user_data;
1995 const char *method = req->str;
1997 dbus_path = l_dbus_proxy_get_path(proxy);
1998 INFO("Mesh: DBUS path [%s]", dbus_path);
1999 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2001 memset(&ev, 0, sizeof(ev));
2002 memcpy(ev.net_uuid, net_uuid, 16);
2003 ev.net_idx = req->net_idx;
2004 ev.app_idx = req->app_idx;
2008 if (l_dbus_message_is_error(msg)) {
2011 l_dbus_message_get_error(msg, &name, NULL);
2012 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2013 ev.status = BT_STATUS_FAIL;
2015 ev.status = BT_STATUS_SUCCESS;
2017 if (!strcmp("CreateAppKey", method)) {
2018 INFO("Mesh: AppKey Create Reply");
2019 ev.key_event = HAL_MESH_KEY_ADD;
2020 } else if (!strcmp("DeleteAppKey", method)) {
2021 INFO("Mesh: AppKey Delete Reply");
2022 ev.key_event = HAL_MESH_KEY_DELETE;
2023 } else if (!strcmp("UpdateAppKey", method)) {
2024 INFO("Mesh: AppKey Update Reply");
2025 ev.key_event = HAL_MESH_KEY_UPDATE;
2029 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2032 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2033 uint16_t net_idx, uint16_t app_idx,
2034 const char *key_execute_method)
2036 struct app_key_request *req;
2038 req = l_new(struct app_key_request, 1);
2039 req->str = key_execute_method;
2040 req->net_idx = net_idx;
2041 req->app_idx = app_idx;
2043 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2044 __bt_hal_mesh_app_key_setup,
2045 __bt_hal_mesh_app_key_reply,
2052 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2053 bt_mesh_key_op_e op, uint16_t netkey_idx)
2058 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2062 if (op == BT_MESH_KEY_CREATE)
2063 status = __mesh_subnet_netkey_command_execute(app,
2064 netkey_idx, "CreateSubnet");
2065 else if (op == BT_MESH_KEY_DELETE)
2066 status = __mesh_subnet_netkey_command_execute(app,
2067 netkey_idx, "DeleteSubnet");
2068 else if (op == BT_MESH_KEY_UPDATE)
2069 status = __mesh_subnet_netkey_command_execute(app,
2070 netkey_idx, "UpdateSubnet");
2072 return BT_STATUS_FAIL;
2075 ERR("Mesh: app not found!!");
2076 return BT_STATUS_PARM_INVALID;
2079 return BT_STATUS_SUCCESS;
2082 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2083 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2088 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2092 if (op == BT_MESH_KEY_CREATE)
2093 status = __mesh_subnet_appkey_command_execute(app,
2094 netkey_idx, appkey_idx, "CreateAppKey");
2095 else if (op == BT_MESH_KEY_DELETE)
2096 status = __mesh_subnet_appkey_command_execute(app,
2097 netkey_idx, appkey_idx, "DeleteAppKey");
2098 else if (op == BT_MESH_KEY_UPDATE) {
2099 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2100 netkey_idx, appkey_idx);
2101 status = __mesh_subnet_appkey_command_execute(app,
2102 netkey_idx, appkey_idx, "UpdateAppKey");
2105 return BT_STATUS_FAIL;
2108 ERR("Mesh: app not found!!");
2109 return BT_STATUS_PARM_INVALID;
2112 return BT_STATUS_SUCCESS;
2115 bt_status_t _bt_hal_mesh_send_provision_data(
2116 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2120 struct l_dbus_message *msg;
2121 struct l_dbus_message *reply;
2123 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2128 reply = l_dbus_message_new_method_return(msg);
2129 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2130 l_dbus_send(dbus, reply);
2132 ERR("Mesh: app not found!!");
2133 return BT_STATUS_PARM_INVALID;
2135 return BT_STATUS_SUCCESS;
2138 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2142 l = g_slist_find_custom(mesh_apps,
2143 net_uuid->uu, __mesh_compare_network_uuid);
2146 if (!__bt_mesh_proxy_check(app)) {
2147 ERR("Mesh: Proxy check failed!!");
2148 return BT_STATUS_FAIL;
2150 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2151 "UnprovisionedScanCancel",
2152 NULL, NULL, NULL, NULL))
2153 return BT_STATUS_FAIL;
2155 ERR("Mesh: app not found!!");
2156 return BT_STATUS_PARM_INVALID;
2159 /* Stop Scan timer */
2160 if (app->scan_timer_id > 0) {
2161 g_source_remove(app->scan_timer_id);
2162 app->scan_timer_id = 0;
2165 /* Trigger Scan finished event */
2166 __mesh_trigger_scan_finished_event(app);
2168 return BT_STATUS_SUCCESS;
2171 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2172 const char *auth_value)
2175 struct l_dbus_message *reply = NULL;
2176 struct l_dbus_message_builder *builder;
2178 bt_status_t ret = BT_STATUS_SUCCESS;
2182 if (!__bt_mesh_proxy_check(0)) {
2183 ERR("Mesh: Proxy check failed!!");
2184 return BT_STATUS_FAIL;
2186 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2187 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2188 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2189 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2190 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2191 INFO("Mesh: Authentication reply: Numeric Type");
2192 val_u32 = atoi(auth_value);
2193 reply = l_dbus_message_new_method_return(agent_msg);
2194 l_dbus_message_set_arguments(reply, "u", val_u32);
2196 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2197 l_dbus_send(dbus, reply);
2198 ret = BT_STATUS_SUCCESS;
2199 /* For Alpha-Numeric */
2200 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2201 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2202 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT ) {
2203 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2204 alpha = l_util_from_hexstring(auth_value, &sz);
2205 reply = l_dbus_message_new_method_return(agent_msg);
2206 builder = l_dbus_message_builder_new(reply);
2207 __mesh_append_byte_array(builder, alpha, 16);
2208 l_dbus_message_builder_finalize(builder);
2209 l_dbus_message_builder_destroy(builder);
2212 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2213 l_dbus_send(dbus, reply);
2214 ret = BT_STATUS_SUCCESS;
2219 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2220 bt_hal_mesh_scan_param_t *param)
2224 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2227 if (!__bt_mesh_proxy_check(app)) {
2228 ERR("Mesh: Proxy check failed!!");
2229 return BT_STATUS_FAIL;
2231 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2232 __mesh_scan_setup, __mesh_scan_reply,
2233 L_UINT_TO_PTR(param->scan_time), NULL))
2234 return BT_STATUS_FAIL;
2236 ERR("Mesh: app not found!!");
2237 return BT_STATUS_PARM_INVALID;
2239 return BT_STATUS_SUCCESS;
2242 bt_status_t _bt_hal_mesh_create_network(
2243 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2247 INFO("Mesh: Create Network Request");
2249 if (!__bt_mesh_proxy_check(0)) {
2250 ERR("Mesh: Proxy check failed!!");
2251 return BT_STATUS_FAIL;
2254 INFO("Mesh: Node Element count [%d]", node->num_elements);
2255 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2256 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2257 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2258 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2259 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2260 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2261 /* Create DBUS APP */
2262 app = __bt_hal_mesh_create_app(node, models, is_prov);
2264 return BT_STATUS_FAIL;
2266 /* Register DBUS APP */
2267 if (!__bt_hal_mesh_register_application(app)) {
2271 if (app->token.u64 == 0) {
2272 INFO("Mesh: Create New Network");
2273 /* Create CFG Network */
2274 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2275 __bt_hal_mesh_create_net_setup,
2276 __bt_hal_mesh_create_net_reply, app,
2278 ERR("Mesh: Network Create failed!!");
2282 INFO("Mesh: Attach Node to Network");
2283 /* Attach to Network */
2284 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2285 __bt_hal_mesh_attach_node_setup,
2286 __bt_hal_mesh_attach_node_reply,
2289 ERR("Mesh: Node attach failed!!");
2294 INFO("Mesh: Node registration request scheudled");
2295 mesh_apps = g_slist_append(mesh_apps, app);
2296 INFO("Mesh: Total number of apps in list [%d]",
2297 g_slist_length(mesh_apps));
2298 return BT_STATUS_SUCCESS;
2300 ERR("Mesh: network can not be created!!");
2301 __bt_hal_mesh_destroy_app_object(app);
2302 return BT_STATUS_FAIL;
2305 static void __bt_hal_mesh_config_send(
2306 struct l_dbus_message *msg, void *user_data)
2308 struct configuration_request *req = user_data;
2309 struct l_dbus_message_builder *builder;
2311 builder = l_dbus_message_builder_new(msg);
2313 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2314 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2315 if (req->is_dev_key)
2316 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2318 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2319 __mesh_append_byte_array(builder, req->data, req->len);
2320 l_dbus_message_builder_finalize(builder);
2321 l_dbus_message_builder_destroy(builder);
2324 static void __bt_hal_mesh_key_config_send(
2325 struct l_dbus_message *msg, void *user_data)
2327 struct key_config_request *req = user_data;
2328 struct l_dbus_message_builder *builder;
2330 builder = l_dbus_message_builder_new(msg);
2332 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2333 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2334 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2335 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2336 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2337 l_dbus_message_builder_finalize(builder);
2338 l_dbus_message_builder_destroy(builder);
2341 static void __bt_hal_mesh_model_execute_message(
2342 struct l_dbus_message *msg, void *user_data)
2344 struct configuration_request *req = user_data;
2345 struct l_dbus_message_builder *builder;
2347 builder = l_dbus_message_builder_new(msg);
2349 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2350 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2351 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2352 __mesh_append_byte_array(builder, req->data, req->len);
2353 l_dbus_message_builder_finalize(builder);
2354 l_dbus_message_builder_destroy(builder);
2357 bt_status_t _bt_hal_mesh_send_key_config_message(
2358 bt_uuid_t *network, uint16_t dest,
2359 bool is_netkey, bool is_update,
2360 uint16_t key_idx, uint16_t netkey_idx)
2364 struct key_config_request *req;
2367 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2368 /* Source is Config Client Local Node */
2369 int src_elem_idx = 0;
2370 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2373 if (!__bt_mesh_proxy_check(app)) {
2374 ERR("Mesh: Proxy check failed!!");
2375 return BT_STATUS_FAIL;
2377 l1 = g_slist_find_custom(app->elements,
2378 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2380 return BT_STATUS_FAIL;
2383 req = l_new(struct key_config_request, 1);
2384 req->ele_path = elem->path;
2386 req->key_req_idx = key_idx;
2387 req->idx = netkey_idx; /* Encryption Key index */
2388 req->update_req = is_update;
2390 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2391 __bt_hal_mesh_key_config_send, NULL,
2392 (void*)req, l_free))
2393 return BT_STATUS_FAIL;
2395 ERR("Mesh: app not found!!");
2396 return BT_STATUS_PARM_INVALID;
2399 return BT_STATUS_SUCCESS;
2402 bt_status_t _bt_hal_mesh_send_configuration_message(
2403 bt_uuid_t *network, uint16_t dest,
2404 bool is_dev_key, uint16_t netkey_idx,
2405 uint8_t *buf, int len)
2409 struct configuration_request *req;
2412 int src_elem_idx = 0;
2413 l = g_slist_find_custom(mesh_apps, network->uu,
2414 __mesh_compare_network_uuid);
2417 if (!__bt_mesh_proxy_check(app)) {
2418 ERR("Mesh: Proxy check failed!!");
2419 return BT_STATUS_FAIL;
2421 l1 = g_slist_find_custom(app->elements,
2422 GUINT_TO_POINTER(src_elem_idx),
2423 __compare_element_index);
2425 return BT_STATUS_FAIL;
2428 req = l_new(struct configuration_request, 1);
2429 req->ele_path = elem->path;
2431 req->idx = netkey_idx;
2435 req->is_dev_key = is_dev_key;
2437 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2438 __bt_hal_mesh_config_send, NULL,
2439 (void*)req, l_free))
2440 return BT_STATUS_FAIL;
2442 ERR("Mesh: app not found!!");
2443 return BT_STATUS_PARM_INVALID;
2446 return BT_STATUS_SUCCESS;
2449 bt_status_t _bt_hal_mesh_model_execute_message(
2450 bt_uuid_t *network, uint16_t dest,
2451 uint16_t appkey_idx, uint8_t *buf, int len)
2455 struct configuration_request *req;
2458 int src_elem_idx = 0;
2459 l = g_slist_find_custom(mesh_apps, network->uu,
2460 __mesh_compare_network_uuid);
2463 if (!__bt_mesh_proxy_check(app)) {
2464 ERR("Mesh: Proxy check failed!!");
2465 return BT_STATUS_FAIL;
2467 l1 = g_slist_find_custom(app->elements,
2468 GUINT_TO_POINTER(src_elem_idx),
2469 __compare_element_index);
2471 return BT_STATUS_FAIL;
2474 req = l_new(struct configuration_request, 1);
2475 req->ele_path = elem->path;
2477 req->idx = appkey_idx;
2481 req->is_dev_key = false;
2483 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2484 __bt_hal_mesh_model_execute_message,
2485 NULL, (void*)req, l_free))
2486 return BT_STATUS_FAIL;
2488 ERR("Mesh: app not found!!");
2489 return BT_STATUS_PARM_INVALID;
2492 return BT_STATUS_SUCCESS;