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 struct mesh_remote_node_info {
104 uint8_t num_elements;
107 static struct mesh_provision_auth_action auth_table[] = {
108 { "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
109 { "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
110 { "vibrate", BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT},
111 { "in-numeric", BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT},
112 { "in-alpha", BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT},
113 { "twist", BT_HAL_MESH_AUTH_TWIST_COUNT_DISPLAY},
114 { "push", BT_HAL_MESH_AUTH_PUSH_COUNT_DISPLAY},
115 { "out-numeric", BT_HAL_MESH_AUTH_NUMERIC_DISPLAY},
116 { "out-alpha", BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY},
117 { "static-oob", BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT},
118 { "unknown", BT_HAL_MESH_UNKNOWN_AUTH_METHOD},
122 static uint8_t __bt_mesh_util_get_prov_error_code(char *prov_err_str)
126 if (!g_strcmp0(prov_err_str, "success"))
127 ret = BT_HAL_MESH_PROV_ERR_SUCCESS;
128 else if (!g_strcmp0(prov_err_str, "bad-pduread"))
129 ret = BT_HAL_MESH_PROV_ERR_INVALID_PDU;
130 else if (!g_strcmp0(prov_err_str, "confirmation-failed"))
131 ret = BT_HAL_MESH_PROV_ERR_CONFIRM_FAILED;
132 else if (!g_strcmp0(prov_err_str, "out-of-resources"))
133 ret = BT_HAL_MESH_PROV_ERR_INSUF_RESOURCE;
134 else if (!g_strcmp0(prov_err_str, "decryption-error"))
135 ret = BT_HAL_MESH_PROV_ERR_DECRYPT_FAILED;
136 else if (!g_strcmp0(prov_err_str, "cannot-assign-addresses"))
137 ret = BT_HAL_MESH_PROV_ERR_CANT_ASSIGN_ADDR;
138 else if (!g_strcmp0(prov_err_str, "timeout"))
139 ret = BT_HAL_MESH_PROV_ERR_TIMEOUT;
140 else if (!g_strcmp0(prov_err_str, "unexpected-error"))
141 ret = BT_HAL_MESH_PROV_ERR_UNEXPECTED_ERR;
146 static bt_hal_mesh_auth_variant_e __mesh_get_authentication_type(char *str)
148 int len = strlen(str);
149 int sz = L_ARRAY_SIZE(auth_table);
152 for (i = 0; i < sz; ++i)
153 if (len == strlen(auth_table[i].action) &&
154 !strcmp(str, auth_table[i].action))
157 return auth_table[i].auth_type;
159 ERR("Mesh : Not A Proper Authentication Type!");
160 return BT_HAL_MESH_UNKNOWN_AUTH_METHOD;
164 enum mesh_dbus_interface_e {
171 typedef enum mesh_dbus_interface_e mesh_dbus_interface_e;
173 struct meshcfg_model {
178 typedef struct meshcfg_model meshcfg_model;
186 typedef struct meshcfg_el meshcfg_el;
189 /* Remember Proxies & dbus paths */
192 struct l_dbus_proxy *proxy;
193 struct l_dbus_proxy *mgmt_proxy;
195 /* Local node Info */
212 struct l_dbus_message *msg;
216 typedef struct meshcfg_app meshcfg_app;
218 /* Will contain critical data related to local Mesh Network */
219 static GSList *mesh_apps = NULL;
222 struct meshcfg_node {
224 struct l_dbus_proxy *proxy;
225 struct l_dbus_proxy *mgmt_proxy;
232 typedef struct meshcfg_node meshcfg_node;
234 static void __mesh_append_byte_array(struct l_dbus_message_builder *builder,
235 unsigned char *data, unsigned int len)
239 l_dbus_message_builder_enter_array(builder, "y");
241 for (i = 0; i < len; i++)
242 l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
244 l_dbus_message_builder_leave_array(builder);
247 static gint __mesh_compare_network_uuid(gconstpointer data, gconstpointer user_data)
249 const meshcfg_app *app = (meshcfg_app*) data;
251 memcpy(uuid, (uint8_t*) user_data, 16);
253 return memcmp(uuid, app->uuid, sizeof(bt_uuid_t));
256 static unsigned char* __mesh_get_net_uuid_from_dbus_proxy_path(
257 const char *dbus_path)
262 memcpy(uuid, (void*)&dbus_path[20], sizeof(uuid));
264 INFO("Mesh: Net UUID string [%s]", uuid);
265 return l_util_from_hexstring(uuid, &sz);
268 static unsigned char* __mesh_get_net_uuid_from_path(
269 const char *dbus_path, bool is_prov,
270 mesh_dbus_interface_e iface)
277 case MESH_PROV_IFACE: {
278 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
280 return l_util_from_hexstring(uuid, &sz);
282 case MESH_AGENT_IFACE: {
283 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[23], 32);
285 return l_util_from_hexstring(uuid, &sz);
287 case MESH_ELEMENT_IFACE: {
288 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
290 return l_util_from_hexstring(uuid, &sz);
297 static void __mesh_hal_free_elements(gpointer data)
299 meshcfg_el *element = (meshcfg_el*) data;
302 g_free(element->path);
304 g_slist_free_full(element->models, g_free);
306 element->models = NULL;
310 static bool __bt_mesh_proxy_check(meshcfg_app *app)
312 /* Check meshd stack Vis up or not */
314 ERR("Mesh: DBUS is not UP!, possibly stack not Up!");
317 /* Check Network Proxy is added or not */
319 ERR("Mesh: Network proxy is not attached yet!");
324 /* Check App management proxyis added or not */
325 if (!app->mgmt_proxy) {
326 ERR("Mesh: Network proxy is not attached yet!");
329 /* Check App Node Proxy is added or not */
331 ERR("Mesh: Node proxy is not attached yet!");
338 static void __bt_hal_mesh_destroy_app_object(gpointer data)
341 meshcfg_app *app = (meshcfg_app*) data;
345 mesh_apps = g_slist_remove(mesh_apps, app);
348 INFO("Mesh: App path [%s] ", app->path);
351 if (app->agent_path) {
352 INFO("Mesh: Agent Path [%s]", app->agent_path);
353 g_free(app->agent_path);
357 INFO("Mesh: Total elements present in app [%d]",
358 g_slist_length(app->elements));
359 g_slist_free_full(app->elements, __mesh_hal_free_elements);
364 static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
366 ERR("MESH: D-Bus client connected\n");
369 INFO("Mesh: MeshD connected: dbus [%p]", dbus);
372 static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
374 ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
375 /* TODO: Send event to app about meshd termination & then remove all mesh apps */
376 INFO("Mesh: Total number of networks present [%d]",
377 g_slist_length(mesh_apps));
380 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
383 /* Set DBUS to NULL */
385 INFO("Mesh: dbus [%p]", dbus);
387 INFO("Mesh: net proxy [%p]", net_proxy);
391 INFO("Mesh: All apps cleaned up after meshd exited");
394 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
398 const meshcfg_app *app = (meshcfg_app*) data;
399 char *path = (char *) user_data;
403 app_uuid_path = l_util_hexstring(app->uuid, 16);
404 char **strings = g_strsplit(path, "node", 2);
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 __send_network_destroy_event(void *param, uint8_t status)
425 struct hal_ev_mesh_network_destroyed ev;
426 meshcfg_app *app = (meshcfg_app*)param;
428 memset(&ev, 0, sizeof(ev));
429 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
430 memcpy(ev.token, app->token.u8, 8);
434 mesh_event_cb(HAL_EV_MESH_NETWORK_DESTROYED,
435 (void*)&ev, sizeof(ev));
438 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
440 const char *interface = l_dbus_proxy_get_interface(proxy);
441 const char *path = l_dbus_proxy_get_path(proxy);
443 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
445 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
446 INFO("Mesh: Network Proxy added");
447 /* Save Global proxy */
450 INFO("Mesh: Net Proxy [%p]", net_proxy);
454 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
457 INFO("Mesh: Mgmt Proxy added");
458 INFO("Mesh: Number of mesh app present in list [%d]",
459 g_slist_length(mesh_apps));
460 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
463 app->mgmt_proxy = proxy;
465 ERR("Mesh: app not found for Mgmt proxy");
470 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
471 INFO("Mesh: Node Proxy added");
474 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
479 ERR("Mesh: app not found for Node proxy");
485 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
487 const char *interface = l_dbus_proxy_get_interface(proxy);
488 const char *path = l_dbus_proxy_get_path(proxy);
490 INFO("Proxy removed: %s (%s)\n", interface, path);
492 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
493 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
494 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
496 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
500 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
501 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
504 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
507 /* Send event to app about removal of a mesh local node */
508 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
509 __bt_hal_mesh_destroy_app_object(app);
511 ERR("Mesh: app not found for Mgmt proxy");
514 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
515 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
518 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
521 /* Send event to app about removal of a mesh local node */
522 __send_network_destroy_event(app, BT_STATUS_SUCCESS);
523 __bt_hal_mesh_destroy_app_object(app);
525 ERR("Mesh: app not found for Mgmt proxy");
531 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
534 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
538 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
539 bool queued, void *user_data)
541 if (success == false)
542 ERR("Mesh: Fail to acquire dbus name\n");
544 if (!l_dbus_object_manager_enable(dbus_obj, "/"))
545 ERR("Mesh: Failed to register the ObjectManager\n");
548 static void __mesh_ready_callback(void *user_data)
550 INFO("Mesh: Connected to D-Bus\n");
552 if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
553 __mesh_acquire_name_callback, NULL))
554 ERR("Mesh: Failed to own well-known name\n");
557 bool _bt_hal_mesh_stack_init(void)
559 INFO("Mesh: Connect with meshd");
560 /* Connect with meshd */
561 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
565 INFO("Mesh: Got dbus [%p]", dbus);
567 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
570 client = l_dbus_client_new(dbus,
571 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
575 if (!l_dbus_client_set_connect_handler(client,
576 __mesh_client_connected, NULL, NULL))
579 if (!l_dbus_client_set_disconnect_handler(client,
580 __mesh_client_disconnected, NULL,
583 if (!l_dbus_client_set_proxy_handlers(client,
584 __mesh_proxy_added, __mesh_proxy_removed,
587 if (!l_dbus_client_set_ready_handler(client,
588 __mesh_dbus_client_ready, NULL, NULL))
591 INFO("Mesh: Stack Init watchers registered with meshd");
595 void _bt_hal_mesh_stack_deinit(void)
597 INFO("Mesh: Stack Deinit");
600 l_dbus_client_destroy(client);
605 l_dbus_destroy(dbus);
612 INFO("Mesh: Number of meshapps present in memory [%d]",
613 g_slist_length(mesh_apps));
616 /* To send stack event to hal-mesh handler */
617 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
622 /* To send stack event to hal-mesh handler */
623 void _bt_hal_mesh_unregister_dbus_handler_cb()
625 mesh_event_cb = NULL;
628 static bool __mesh_get_companyid(struct l_dbus *dbus,
629 struct l_dbus_message *message,
630 struct l_dbus_message_builder *builder,
633 meshcfg_app *app = (meshcfg_app*) user_data;
637 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
642 static bool __mesh_get_productid(struct l_dbus *dbus,
643 struct l_dbus_message *message,
644 struct l_dbus_message_builder *builder,
647 meshcfg_app *app = (meshcfg_app*) user_data;
650 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
655 static bool __mesh_get_versionid(struct l_dbus *dbus,
656 struct l_dbus_message *message,
657 struct l_dbus_message_builder *builder,
660 meshcfg_app *app = (meshcfg_app*) user_data;
663 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
668 static bool __mesh_get_crpl(struct l_dbus *dbus,
669 struct l_dbus_message *message,
670 struct l_dbus_message_builder *builder,
673 meshcfg_app *app = (meshcfg_app*) user_data;
676 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
681 static void __send_network_attach_event(void *param, uint8_t status)
683 struct hal_ev_mesh_network_attached ev;
684 meshcfg_app *app = (meshcfg_app*)param;
686 memset(&ev, 0, sizeof(ev));
687 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
688 memcpy(ev.token, app->token.u8, 8);
692 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
693 (void*)&ev, sizeof(ev));
696 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
697 struct l_dbus_message *msg, void *user_data)
699 struct l_dbus_message_iter iter_cfg;
701 meshcfg_app *app = (meshcfg_app*) user_data;
702 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
703 app->path, app->agent_path);
705 if (l_dbus_message_is_error(msg)) {
707 l_dbus_message_get_error(msg, &name, NULL);
708 ERR("Mesh: Failed to attach node: %s", name);
713 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
717 INFO("Mesh: Attached with path %s\n", app->path);
718 __send_network_attach_event(app, BT_STATUS_SUCCESS);
721 __send_network_attach_event(app, BT_STATUS_FAIL);
722 /* Destroy mesh app object */
723 __bt_hal_mesh_destroy_app_object(app);
726 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
729 meshcfg_app *app = (meshcfg_app*) user_data;
731 l_dbus_message_set_arguments(msg, "ot", app->path,
732 l_get_be64(app->token.u8));
736 static void __bt_hal_mesh_attach_node(void *user_data)
738 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
739 __bt_hal_mesh_attach_node_setup,
740 __bt_hal_mesh_attach_node_reply,
743 ERR("Mesh: Node attach failed!!");
744 /* Node could not be attached */
745 __send_network_attach_event(user_data, BT_STATUS_FAIL);
746 /* Destroy mesh app object */
747 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
751 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
752 struct l_dbus_message *message,
758 meshcfg_app *app = (meshcfg_app*) user_data;
759 INFO("Mesh: Join Complete");
762 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
764 /* Send Network creation fail event */
765 __send_network_attach_event(app, BT_STATUS_FAIL);
767 /* Destroy mesh app object */
768 __bt_hal_mesh_destroy_app_object(app);
770 return l_dbus_message_new_error(message, dbus_err_args, NULL);
774 app->token.u64 = l_get_be64(&tmp);
775 str = l_util_hexstring(&app->token.u8[0], 8);
776 INFO("Mesh: Created new node with token %s\n", str);
779 /* Authenticate the node */
780 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
781 return l_dbus_message_new_method_return(message);
784 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
787 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
788 meshcfg_model *model_info = (meshcfg_model*) data;
790 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
793 static bool __mesh_model_getter(struct l_dbus *dbus,
794 struct l_dbus_message *message,
795 struct l_dbus_message_builder *builder,
798 meshcfg_el *element = (meshcfg_el*) user_data;
800 l_dbus_message_builder_enter_array(builder, "q");
801 g_slist_foreach(element->models,
802 __bt_hal_mesh_foreach_model_getter, builder);
804 l_dbus_message_builder_leave_array(builder);
809 /*TODO: Vendor Model handling is currently not Handled */
810 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
811 struct l_dbus_message *message,
812 struct l_dbus_message_builder *builder,
815 l_dbus_message_builder_enter_array(builder, "(qq)");
816 l_dbus_message_builder_leave_array(builder);
821 static bool __mesh_element_index_getter(struct l_dbus *dbus,
822 struct l_dbus_message *message,
823 struct l_dbus_message_builder *builder,
826 meshcfg_el *element = (meshcfg_el*) user_data;
827 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
833 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
834 struct l_dbus_message *msg, void *user_data)
836 struct l_dbus_message_iter iter;
841 const char *dbus_path;
844 dbus_path = l_dbus_message_get_path(msg);
845 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
846 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
847 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
849 INFO("Mesh: app path [%s]", dbus_path);
851 memset(buf, 0, sizeof(buf));
852 size = (uint16_t) sizeof(*ev);
853 memcpy(ev->net_uuid, net_uuid, 16);
856 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
858 ERR("Mesh: Cannot parse received message");
859 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
862 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
863 ERR("Mesh: Cannot parse received message: data");
864 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
867 INFO("Mesh: Received dev key message (len %u):", n);
868 ev->source_addr = src;
869 ev->is_remote_devkey = rmt;
870 ev->netkey_idx = idx;
872 memcpy(ev->data, data, n);
875 INFO("Mesh: Src [0x%2.2x]", src);
876 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
877 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
878 /* Send DevKeyMessage Received event */
880 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
881 return l_dbus_message_new_method_return(msg);
884 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
885 struct l_dbus_message *msg, void *user_data)
887 struct l_dbus_message_iter iter;
888 uint16_t src, idx, dst;
891 const char *dbus_path;
894 dbus_path = l_dbus_message_get_path(msg);
895 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
896 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
897 struct hal_ev_mesh_message_event *ev = (void *)buf;
899 INFO("Mesh: app path [%s]", dbus_path);
901 memset(buf, 0, sizeof(buf));
902 size = (uint16_t) sizeof(*ev);
903 memcpy(ev->net_uuid, net_uuid, 16);
906 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
908 ERR("Mesh: Cannot parse received message");
909 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
912 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
913 ERR("Mesh: Cannot parse received message: data");
914 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
917 INFO("Mesh: Received mesh message (len %u):", n);
918 ev->source_addr = src;
922 memcpy(ev->data, data, n);
925 INFO("Mesh: Src [0x%2.2x]", src);
926 INFO("Mesh: Dst [0x%2.2x]", dst);
927 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
928 /* Send Message Received event */
930 INFO("Mesh: Send message event");
931 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
933 return l_dbus_message_new_method_return(msg);
936 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
938 INFO("Mesh: Setup element interface properties & methods");
940 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
942 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
943 __mesh_vendor_model_getter, NULL);
944 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
947 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
948 __mesh_device_message_received, "", "qbqay", "source",
949 "remote", "net_index", "data");
950 l_dbus_interface_method(iface, "MessageReceived", 0,
951 __mesh_message_received, "", "qqvay", "source",
952 "key_index", "destination", "data");
953 /* TODO: Other methods */
956 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
957 struct l_dbus_message *msg,
960 struct l_dbus_message_iter iter, opts;
961 meshcfg_app *app = (meshcfg_app*) user_data;
966 const char *sig = "naya{sv}";
968 /* Find network uuid from dbus path */
969 struct hal_ev_mesh_scan_result ev;
971 if (!app->scan_timer_id) {
972 /* Scan is not running */
973 INFO("Got scan result, but scan is already stopped");
974 return l_dbus_message_new_method_return(msg);
976 memset(&ev, 0, sizeof(ev));
977 memcpy(ev.net_uuid, app->uuid, 16);
979 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
980 ERR("Mesh: Cannot parse scan results");
981 ev.status = BT_STATUS_FAIL;
983 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
984 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
987 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
989 ERR("Mesh: Cannot parse scan result: data");
990 ev.status = BT_STATUS_FAIL;
992 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
993 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
996 INFO("Mesh: Scan result:\n");
997 INFO("Mesh: Scan rssi = [%d]\n", rssi);
998 str = l_util_hexstring_upper(prov_data, 16);
999 INFO("Mesh: Scan UUID = [%s]\n", str);
1003 str = l_util_hexstring_upper(prov_data + 16, 2);
1004 INFO("Mesh: Scan OOB = [%s]\n", str);
1009 str = l_util_hexstring_upper(prov_data + 18, 4);
1010 INFO("Mesh: Scan URI hash = [%s]\n", str);
1014 /* 16 octet Dev UUID */
1015 memcpy(ev.dev_uuid, prov_data, 16);
1017 /* 2 octet Dev OOB Info */
1018 memcpy(ev.oob_info, prov_data + 16, 2);
1020 /* 4 octet URI Hash */
1021 memcpy(ev.uri_hash, prov_data + 18, 4);
1025 ev.status = BT_STATUS_SUCCESS;
1027 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1028 (void*)&ev, sizeof(ev));
1030 return l_dbus_message_new_method_return(msg);
1033 static struct l_dbus_message *__mesh_request_provisioner_call(
1034 struct l_dbus *dbus,
1035 struct l_dbus_message *msg,
1039 struct hal_ev_mesh_provision_finished ev;
1040 struct hal_ev_mesh_provision_data_request req;
1042 meshcfg_app *app = user_data;
1044 INFO("Mesh: provisioning data requested app path [%s]",
1046 uuid_string = l_util_hexstring(app->uuid, 16);
1047 INFO("Mesh: Network UUID [%s]", uuid_string);
1049 memset(&ev, 0, sizeof(ev));
1050 memset(&req, 0, sizeof(req));
1051 memcpy(ev.net_uuid, app->uuid, 16);
1052 memcpy(req.net_uuid, app->uuid, 16);
1053 l_free(uuid_string);
1055 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1056 ERR("Mesh: Cannot parse request for prov data");
1058 ev.status = BT_STATUS_FAIL;
1059 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1061 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1062 (void*)&ev, sizeof(ev));
1063 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1069 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1070 (void*)&req, sizeof(req));
1072 l_dbus_message_ref(msg);
1076 static struct l_dbus_message *__mesh_node_add_completed(
1077 struct l_dbus *dbus,
1078 struct l_dbus_message *msg,
1081 struct l_dbus_message_iter iter;
1086 struct hal_ev_mesh_provision_finished ev;
1087 const char *dbus_path;
1089 dbus_path = l_dbus_message_get_path(msg);
1090 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1091 true, MESH_PROV_IFACE);
1093 INFO("Mesh: app path [%s]", dbus_path);
1095 memset(&ev, 0, sizeof(ev));
1096 memcpy(ev.net_uuid, net_uuid, 16);
1100 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1101 ERR("Mesh: Cannot parse add node complete message");
1103 ev.status = BT_STATUS_FAIL;
1104 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1106 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1107 (void*)&ev, sizeof(ev));
1108 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1111 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1113 ERR("Mesh: Cannot parse add node complete message: uuid");
1115 ev.status = BT_STATUS_FAIL;
1116 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1118 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1119 (void*)&ev, sizeof(ev));
1120 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1124 ev.status = BT_STATUS_SUCCESS;
1125 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1126 memcpy(ev.dev_uuid, uuid, 16);
1127 ev.unicast = unicast;
1131 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1132 (void*)&ev, sizeof(ev));
1134 return l_dbus_message_new_method_return(msg);
1137 static struct l_dbus_message *__mesh_node_add_failed(
1138 struct l_dbus *dbus,
1139 struct l_dbus_message *msg,
1142 struct l_dbus_message_iter iter;
1146 struct hal_ev_mesh_provision_finished ev;
1147 const char *dbus_path;
1150 dbus_path = l_dbus_message_get_path(msg);
1151 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1152 true, MESH_PROV_IFACE);
1154 memset(&ev, 0, sizeof(ev));
1155 memcpy(ev.net_uuid, net_uuid, 16);
1158 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1159 ERR("Mesh: Cannot parse add node failed message");
1161 ev.status = BT_STATUS_FAIL;
1162 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1164 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1165 (void*)&ev, sizeof(ev));
1166 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1169 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1171 ERR("Mesh:Cannot parse add node failed message: uuid");
1172 ev.status = BT_STATUS_FAIL;
1173 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1175 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1176 (void*)&ev, sizeof(ev));
1177 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1180 INFO("Mesh: Provisioning failed:\n");
1181 str = l_util_hexstring_upper(uuid, 16);
1182 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1185 ev.status = BT_STATUS_FAIL;
1186 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1187 memcpy(ev.dev_uuid, uuid, 16);
1190 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1191 (void*)&ev, sizeof(ev));
1193 return l_dbus_message_new_method_return(msg);
1196 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1198 INFO("Mesh: Setup provisioner interface properties & methods");
1199 l_dbus_interface_method(interface, "ScanResult", 0,
1200 __mesh_scan_result_received, "",
1201 "naya{sv}", "rssi", "data", "options");
1203 l_dbus_interface_method(interface, "RequestProvData", 0,
1204 __mesh_request_provisioner_call,
1205 "qq", "y", "net_index", "unicast", "count");
1207 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1208 __mesh_node_add_completed, "", "ayqy",
1209 "uuid", "unicast", "count");
1211 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1212 __mesh_node_add_failed,
1213 "", "ays", "uuid", "reason");
1216 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1218 INFO("Mesh: Setup application interface properties & methods");
1220 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1221 __mesh_get_companyid,
1223 l_dbus_interface_property(iface, "VersionID", 0, "q",
1224 __mesh_get_versionid,
1226 l_dbus_interface_property(iface, "ProductID", 0, "q",
1227 __mesh_get_productid,
1229 l_dbus_interface_property(iface, "CRPL", 0, "q",
1230 __mesh_get_crpl, NULL);
1231 l_dbus_interface_method(iface, "JoinComplete", 0,
1232 __mesh_node_join_complete,
1238 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1239 struct l_dbus_message_builder *builder)
1241 if (app->in_oob & 0x08)
1242 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1243 if (app->in_oob & 0x04)
1244 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1245 if (app->in_oob & 0x02)
1246 l_dbus_message_builder_append_basic(builder, 's', "twist");
1247 if (app->in_oob & 0x01)
1248 l_dbus_message_builder_append_basic(builder, 's', "push");
1251 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1252 struct l_dbus_message_builder *builder)
1254 if (app->out_oob & 0x10)
1255 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1256 if (app->out_oob & 0x08)
1257 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1258 if (app->out_oob & 0x04)
1259 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1260 if (app->out_oob & 0x02)
1261 l_dbus_message_builder_append_basic(builder, 's', "beep");
1262 if (app->out_oob & 0x01)
1263 l_dbus_message_builder_append_basic(builder, 's', "blink");
1266 static bool __mesh_agent_capability_getter(
1267 struct l_dbus *dbus, struct l_dbus_message *message,
1268 struct l_dbus_message_builder *builder,
1273 INFO("Mesh: app path [%s]", app->path);
1274 INFO("Mesh: Agent path [%s]", app->agent_path);
1276 if (!l_dbus_message_builder_enter_array(builder, "s"))
1279 __mesh_fill_out_capabilities(app, builder);
1280 __mesh_fill_in_capabilities(app, builder);
1282 if (app->static_oob)
1283 l_dbus_message_builder_append_basic(builder,
1287 l_dbus_message_builder_leave_array(builder);
1288 INFO("Mesh: __agent_capability_getter: Success");
1292 static struct l_dbus_message *__mesh_agent_display_string_request(
1293 struct l_dbus *dbus,
1294 struct l_dbus_message *msg,
1297 struct hal_ev_mesh_authentication_request ev;
1300 const char *dbus_path;
1303 INFO("Mesh: app path [%s]", app->path);
1304 INFO("Mesh: Agent path [%s]", app->agent_path);
1306 dbus_path = l_dbus_message_get_path(msg);
1307 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1308 true, MESH_AGENT_IFACE);
1310 INFO("Mesh: app path [%s]", dbus_path);
1312 memset(&ev, 0, sizeof(ev));
1313 memcpy(ev.net_uuid, net_uuid, 16);
1316 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1317 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1318 struct hal_ev_mesh_provision_finished ev;
1319 memset(&ev, 0, sizeof(ev));
1320 memcpy(ev.net_uuid, net_uuid, 16);
1321 ev.status = BT_STATUS_FAIL;
1322 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1324 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1325 (void*)&ev, sizeof(ev));
1329 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1332 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1333 ev.auth_type = __mesh_get_authentication_type(str);
1334 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1335 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1336 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1339 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1340 (void*)&ev, sizeof(ev));
1343 return l_dbus_message_new_method_return(msg);
1346 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1347 struct l_dbus *dbus,
1348 struct l_dbus_message *msg,
1352 struct hal_ev_mesh_authentication_request ev;
1356 const char *dbus_path;
1359 INFO("Mesh: app path [%s]", app->path);
1360 INFO("Mesh: Agent path [%s]", app->agent_path);
1362 dbus_path = l_dbus_message_get_path(msg);
1363 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1364 true, MESH_AGENT_IFACE);
1366 INFO("Mesh: app path [%s]", dbus_path);
1368 memset(&ev, 0, sizeof(ev));
1369 memcpy(ev.net_uuid, net_uuid, 16);
1372 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1373 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1374 struct hal_ev_mesh_provision_finished ev;
1375 memset(&ev, 0, sizeof(ev));
1376 memcpy(ev.net_uuid, net_uuid, 16);
1377 ev.status = BT_STATUS_FAIL;
1378 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1379 if (mesh_event_cb) {
1380 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1381 (void*)&ev, sizeof(ev));
1384 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1387 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1388 auth_value = l_strdup_printf("%u", n);
1389 ev.auth_type = __mesh_get_authentication_type(str);
1390 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1391 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1392 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1395 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1396 (void*)&ev, sizeof(ev));
1400 return l_dbus_message_new_method_return(msg);
1403 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1404 struct l_dbus *dbus,
1405 struct l_dbus_message *msg,
1408 struct hal_ev_mesh_authentication_request ev;
1411 const char *dbus_path;
1415 dbus_path = l_dbus_message_get_path(msg);
1416 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1417 true, MESH_AGENT_IFACE);
1419 INFO("Mesh: app path [%s]", dbus_path);
1421 l = g_slist_find_custom(mesh_apps, net_uuid,
1422 __mesh_compare_network_uuid);
1429 memset(&ev, 0, sizeof(ev));
1430 memcpy(ev.net_uuid, net_uuid, 16);
1433 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1434 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1436 struct hal_ev_mesh_provision_finished ev;
1437 memset(&ev, 0, sizeof(ev));
1438 memcpy(ev.net_uuid, app->uuid, 16);
1439 ev.status = BT_STATUS_FAIL;
1440 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1441 if (mesh_event_cb) {
1442 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1443 (void*)&ev, sizeof(ev));
1445 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1448 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1450 ev.auth_type = __mesh_get_authentication_type(str);
1451 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1452 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1454 l_dbus_message_ref(msg);
1456 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1457 (void*)&ev, sizeof(ev));
1462 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1463 struct l_dbus *dbus,
1464 struct l_dbus_message *msg,
1467 struct hal_ev_mesh_authentication_request ev;
1470 const char *dbus_path;
1472 meshcfg_app *app = NULL;
1474 dbus_path = l_dbus_message_get_path(msg);
1475 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1478 INFO("Mesh: app path [%s]", dbus_path);
1480 l = g_slist_find_custom(mesh_apps, net_uuid,
1481 __mesh_compare_network_uuid);
1486 ERR("Mesh: app not found");
1490 memset(&ev, 0, sizeof(ev));
1491 memcpy(ev.net_uuid, net_uuid, 16);
1494 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1495 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1497 struct hal_ev_mesh_provision_finished ev;
1498 memset(&ev, 0, sizeof(ev));
1501 memcpy(ev.net_uuid, app->uuid, 16);
1503 ev.status = BT_STATUS_FAIL;
1504 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1506 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1507 (void*)&ev, sizeof(ev));
1508 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1511 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1513 ev.auth_type = __mesh_get_authentication_type(str);
1514 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1515 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1517 l_dbus_message_ref(msg);
1519 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1520 (void*)&ev, sizeof(ev));
1525 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1527 INFO("Mesh: Setup Agent interface properties & methods");
1528 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1529 __mesh_agent_capability_getter,
1531 /* TODO: Other properties */
1532 l_dbus_interface_method(interface, "DisplayString", 0,
1533 __mesh_agent_display_string_request,
1535 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1536 __mesh_agent_display_numeric_request,
1537 "", "su", "type", "number");
1538 l_dbus_interface_method(interface, "PromptNumeric", 0,
1539 __mesh_agent_prompt_numeric_request,
1540 "u", "s", "number", "type");
1541 l_dbus_interface_method(interface, "PromptStatic", 0,
1542 __mesh_agent_prompt_static_request,
1543 "ay", "s", "data", "type");
1546 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1548 meshcfg_el *elem = (meshcfg_el*) data;
1549 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1550 elem->index, elem->path);
1551 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1552 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1553 ERR("Mesh: Failed to register object %s", elem->path);
1557 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1562 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1563 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1564 ERR("Mesh: Unable to register agent interface");
1568 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1569 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1570 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1571 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1575 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1576 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1577 ERR("Mesh: Failed to add interface %s",
1578 L_DBUS_INTERFACE_PROPERTIES);
1585 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1593 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1594 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1595 ERR("Mesh: Failed to register interface %s",
1596 BT_HAL_MESH_APPLICATION_INTERFACE);
1600 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1601 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1602 ERR("Mesh: Failed to register interface %s",
1603 BT_HAL_MESH_PROVISIONER_INTERFACE);
1607 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1608 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1609 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1611 ERR("Mesh: Failed to register object %s", ptr->path);
1615 if (!__bt_hal_mesh_register_agent(ptr))
1618 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1619 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1620 ERR("Mesh: Failed to register interface %s",
1621 BT_HAL_MESH_ELEMENT_INTERFACE);
1625 INFO("Mesh: Number of elements to be registsred [%d]",
1626 g_slist_length(ptr->elements));
1628 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1630 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1631 if (!l_dbus_object_add_interface(dbus, ptr->path,
1632 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1633 ERR("Mesh: Failed to add interface %s",
1634 L_DBUS_INTERFACE_OBJECT_MANAGER);
1637 INFO("Mesh: Application Register completed");
1642 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1646 meshcfg_model *model_info = (meshcfg_model*) data;
1647 meshcfg_app *app = (meshcfg_app*) user_data;
1649 l = g_slist_find_custom(app->elements,
1650 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1654 elem = g_malloc0(sizeof(meshcfg_el));
1655 elem->index = model_info->elem_index;
1656 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1657 app->elements = g_slist_append(app->elements, elem);
1658 INFO("Mesh: Created element index [%d] path [%s]",
1659 elem->index, elem->path);
1661 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1662 model_info->model, elem->index);
1663 /* Add Model in the element */
1664 elem->models = g_slist_append(elem->models, model_info);
1665 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1666 elem->index, g_slist_length(elem->models));
1669 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1670 GSList *models, bool is_prov)
1673 meshcfg_app *app = NULL;
1674 char *uuid_str = NULL;
1676 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1678 app = g_malloc0(sizeof(meshcfg_app));
1679 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1681 app->cid = node->vendor_info.companyid;
1682 app->pid = node->vendor_info.vendorid;
1683 app->vid = node->vendor_info.versionid;
1684 app->crpl = node->vendor_info.crpl;
1687 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1688 app->agent_path = g_strdup_printf("%s/agent", app->path);
1691 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1692 app->agent_path = g_strdup_printf("%s/agent", app->path);
1694 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1697 app->is_prov = is_prov;
1698 INFO("Mesh: app created");
1702 static void __bt_hal_mesh_leave_net_reply(
1703 struct l_dbus_proxy *proxy,
1704 struct l_dbus_message *msg, void *user_data)
1707 app = (meshcfg_app*) user_data;
1709 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1710 if (l_dbus_message_is_error(msg)) {
1713 l_dbus_message_get_error(msg, &name, NULL);
1714 ERR("Mesh: Failed to leave network: %s", name);
1716 /* Send Network Destroy fail event */
1717 __send_network_destroy_event(app, BT_STATUS_FAIL);
1719 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1723 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1726 meshcfg_app *app = (meshcfg_app*) user_data;
1728 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1729 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1732 static void __bt_hal_mesh_release_net_reply(
1733 struct l_dbus_proxy *proxy,
1734 struct l_dbus_message *msg, void *user_data)
1737 app = (meshcfg_app*) user_data;
1739 INFO("Mesh:Release Network Reply from Meshd: app path [%s]", app->path);
1740 if (l_dbus_message_is_error(msg)) {
1743 l_dbus_message_get_error(msg, &name, NULL);
1744 ERR("Mesh: Failed to Release network: %s", name);
1747 INFO("Mesh: Release Network: Success, cleanup app after proxy removed");
1751 static void __bt_hal_mesh_release_net_setup(struct l_dbus_message *msg,
1754 meshcfg_app *app = (meshcfg_app*) user_data;
1756 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1757 INFO("Mesh: Release Network Setup app path [%s]", app->path);
1760 static void __bt_hal_mesh_create_net_reply(
1761 struct l_dbus_proxy *proxy,
1762 struct l_dbus_message *msg, void *user_data)
1765 app = (meshcfg_app*) user_data;
1767 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1768 if (l_dbus_message_is_error(msg)) {
1771 l_dbus_message_get_error(msg, &name, NULL);
1772 ERR("Mesh: Failed to create network: %s", name);
1774 /* Send Network creation fail event */
1775 __send_network_attach_event(app, BT_STATUS_FAIL);
1777 /* Destroy mesh app object */
1778 __bt_hal_mesh_destroy_app_object(app);
1783 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1787 struct l_dbus_message_builder *builder;
1788 app = (meshcfg_app*) user_data;
1790 builder = l_dbus_message_builder_new(msg);
1792 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1793 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1794 __mesh_append_byte_array(builder, app->uuid, 16);
1795 l_dbus_message_builder_finalize(builder);
1796 l_dbus_message_builder_destroy(builder);
1799 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1801 struct hal_ev_mesh_scan_state_changed ev;
1803 memset(&ev, 0, sizeof(ev));
1804 memcpy(ev.net_uuid, app->uuid, 16);
1806 ev.status = BT_STATUS_SUCCESS;
1808 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1810 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1811 (void*)&ev, sizeof(ev));
1814 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1816 meshcfg_app *app = (meshcfg_app*) user_data;
1817 __mesh_trigger_scan_finished_event(app);
1821 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1825 l = g_slist_find_custom(mesh_apps, net_uuid,
1826 __mesh_compare_network_uuid);
1831 if (app->scan_timer_id > 0) {
1832 g_source_remove(app->scan_timer_id);
1833 app->scan_timer_id = 0;
1836 app->scan_timer_id = g_timeout_add_seconds(secs,
1837 __bt_mesh_scan_timer_cb, app);
1842 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1843 struct l_dbus_message *msg, void *user_data)
1845 struct hal_ev_mesh_scan_state_changed ev;
1846 const char *dbus_path;
1848 dbus_path = l_dbus_proxy_get_path(proxy);
1849 INFO("Mesh: DBUS path [%s]", dbus_path);
1850 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1852 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1853 INFO("Mesh: Scan duration [%u]", secs);
1855 memset(&ev, 0, sizeof(ev));
1856 memcpy(ev.net_uuid, net_uuid, 16);
1858 if (l_dbus_message_is_error(msg)) {
1860 l_dbus_message_get_error(msg, &name, NULL);
1861 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1862 ev.status = BT_STATUS_FAIL;
1864 INFO("Mesh: Unprovisioned scan started\n");
1865 ev.status = BT_STATUS_SUCCESS;
1866 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1869 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1871 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1872 (void*)&ev, sizeof(ev));
1876 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1877 const char *key, const char *signature,
1883 l_dbus_message_builder_enter_dict(builder, "sv");
1884 l_dbus_message_builder_append_basic(builder, 's', key);
1885 l_dbus_message_builder_enter_variant(builder, signature);
1886 l_dbus_message_builder_append_basic(builder, signature[0], data);
1887 l_dbus_message_builder_leave_variant(builder);
1888 l_dbus_message_builder_leave_dict(builder);
1891 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1893 struct l_dbus_message_builder *builder;
1894 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1895 INFO("Mesh: Scan duration [%u]", secs);
1897 builder = l_dbus_message_builder_new(msg);
1898 l_dbus_message_builder_enter_array(builder, "{sv}");
1899 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1900 l_dbus_message_builder_leave_array(builder);
1901 l_dbus_message_builder_finalize(builder);
1902 l_dbus_message_builder_destroy(builder);
1906 bt_status_t _bt_hal_mesh_network_set_caps(
1907 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1911 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1915 app->public_oob = caps->public_oob;
1916 app->static_oob = caps->static_oob;
1917 app->out_oob = caps->out_oob;
1918 app->in_oob = caps->in_oob;
1920 ERR("Mesh: app not found!!");
1921 return BT_STATUS_PARM_INVALID;
1924 return BT_STATUS_SUCCESS;
1927 static void __bt_hal_mesh_add_node_reply(
1928 struct l_dbus_proxy *proxy,
1929 struct l_dbus_message *msg,
1932 struct hal_ev_mesh_provision_status ev;
1933 const char *dbus_path;
1935 dbus_path = l_dbus_proxy_get_path(proxy);
1936 INFO("Mesh: DBUS path [%s]", dbus_path);
1937 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1939 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1941 INFO("Mesh: app path [%s]", dbus_path);
1943 memset(&ev, 0, sizeof(ev));
1944 memcpy(ev.net_uuid, net_uuid, 16);
1945 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1947 /* Free User data */
1948 g_free((void*)dev_uuid);
1951 if (l_dbus_message_is_error(msg)) {
1954 l_dbus_message_get_error(msg, &name, NULL);
1955 ERR("Mesh: Failed to start provisioning: %s", name);
1956 ev.status = BT_STATUS_FAIL;
1958 INFO("Mesh: Provisioning started\n");
1959 ev.status = BT_STATUS_SUCCESS;
1962 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1963 (void*)&ev, sizeof(ev));
1964 INFO("Mesh: Provisioning status sent");
1967 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1971 bt_uuid_t *dev = user_data;
1972 struct l_dbus_message_builder *builder;
1973 uuid = l_util_hexstring(dev->uu, 16);
1974 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1976 builder = l_dbus_message_builder_new(msg);
1977 __mesh_append_byte_array(builder, dev->uu, 16);
1978 l_dbus_message_builder_enter_array(builder, "{sv}");
1979 l_dbus_message_builder_leave_array(builder);
1980 l_dbus_message_builder_finalize(builder);
1981 l_dbus_message_builder_destroy(builder);
1984 bt_status_t _bt_hal_mesh_provision_device(
1985 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1990 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1993 dev = g_memdup((gpointer)dev_uuid, 16);
1994 INFO("Mesh: Schedule Add Node request to meshd");
1995 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1996 __bt_hal_mesh_add_node_setup,
1997 __bt_hal_mesh_add_node_reply,
1999 return BT_STATUS_FAIL;
2001 ERR("Mesh: app not found!!");
2002 return BT_STATUS_PARM_INVALID;
2005 return BT_STATUS_SUCCESS;
2008 static void __bt_hal_mesh_subnet_key_setup(
2009 struct l_dbus_message *msg, void *user_data)
2011 struct subnet_key_request *req = user_data;
2012 uint16_t idx = (uint16_t) req->idx;
2014 l_dbus_message_set_arguments(msg, "q", idx);
2017 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
2018 struct l_dbus_message *msg, void *user_data)
2020 struct hal_ev_mesh_netkey_execute_event ev;
2021 const char *dbus_path;
2023 struct subnet_key_request *req = user_data;
2024 const char *method = req->str;
2026 dbus_path = l_dbus_proxy_get_path(proxy);
2027 INFO("Mesh: DBUS path [%s]", dbus_path);
2028 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2030 memset(&ev, 0, sizeof(ev));
2031 memcpy(ev.net_uuid, net_uuid, 16);
2032 ev.key_idx = req->idx;
2036 if (l_dbus_message_is_error(msg)) {
2039 l_dbus_message_get_error(msg, &name, NULL);
2040 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
2041 ev.status = BT_STATUS_FAIL;
2044 ev.status = BT_STATUS_SUCCESS;
2046 if (!strcmp("CreateSubnet", method)) {
2047 INFO("Mesh: Reply for CreateSubnet");
2048 ev.key_event = HAL_MESH_KEY_ADD;
2049 } else if (!strcmp("DeleteSubnet", method)) {
2050 INFO("Mesh: Reply for DeleteSubnet");
2051 ev.key_event = HAL_MESH_KEY_DELETE;
2052 } else if (!strcmp("UpdateSubnet", method)) {
2053 INFO("Mesh: Reply for UpdateSubnet");
2054 ev.key_event = HAL_MESH_KEY_UPDATE;
2058 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2059 (void*)&ev, sizeof(ev));
2062 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2063 uint16_t index, const char *key_execute_method)
2065 struct subnet_key_request *req;
2067 req = l_new(struct subnet_key_request, 1);
2068 req->str = key_execute_method;
2071 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2072 __bt_hal_mesh_subnet_key_setup,
2073 __bt_hal_mesh_subnet_key_reply,
2080 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2083 struct app_key_request *req = user_data;
2084 uint16_t net_idx = (uint16_t) req->net_idx;
2085 uint16_t app_idx = (uint16_t) req->app_idx;
2087 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2088 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2090 l_dbus_message_set_arguments(msg, "q", app_idx);
2093 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2094 struct l_dbus_message *msg, void *user_data)
2096 struct hal_ev_mesh_appkey_execute_event ev;
2097 const char *dbus_path;
2099 struct app_key_request *req = user_data;
2100 const char *method = req->str;
2102 dbus_path = l_dbus_proxy_get_path(proxy);
2103 INFO("Mesh: DBUS path [%s]", dbus_path);
2104 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2106 memset(&ev, 0, sizeof(ev));
2107 memcpy(ev.net_uuid, net_uuid, 16);
2108 ev.net_idx = req->net_idx;
2109 ev.app_idx = req->app_idx;
2113 if (l_dbus_message_is_error(msg)) {
2116 l_dbus_message_get_error(msg, &name, NULL);
2117 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2118 ev.status = BT_STATUS_FAIL;
2120 ev.status = BT_STATUS_SUCCESS;
2122 if (!strcmp("CreateAppKey", method)) {
2123 INFO("Mesh: AppKey Create Reply");
2124 ev.key_event = HAL_MESH_KEY_ADD;
2125 } else if (!strcmp("DeleteAppKey", method)) {
2126 INFO("Mesh: AppKey Delete Reply");
2127 ev.key_event = HAL_MESH_KEY_DELETE;
2128 } else if (!strcmp("UpdateAppKey", method)) {
2129 INFO("Mesh: AppKey Update Reply");
2130 ev.key_event = HAL_MESH_KEY_UPDATE;
2134 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2137 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2138 uint16_t net_idx, uint16_t app_idx,
2139 const char *key_execute_method)
2141 struct app_key_request *req;
2143 req = l_new(struct app_key_request, 1);
2144 req->str = key_execute_method;
2145 req->net_idx = net_idx;
2146 req->app_idx = app_idx;
2148 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2149 __bt_hal_mesh_app_key_setup,
2150 __bt_hal_mesh_app_key_reply,
2157 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2158 bt_mesh_key_op_e op, uint16_t netkey_idx)
2163 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2167 if (op == BT_MESH_KEY_CREATE)
2168 status = __mesh_subnet_netkey_command_execute(app,
2169 netkey_idx, "CreateSubnet");
2170 else if (op == BT_MESH_KEY_DELETE)
2171 status = __mesh_subnet_netkey_command_execute(app,
2172 netkey_idx, "DeleteSubnet");
2173 else if (op == BT_MESH_KEY_UPDATE)
2174 status = __mesh_subnet_netkey_command_execute(app,
2175 netkey_idx, "UpdateSubnet");
2177 return BT_STATUS_FAIL;
2180 ERR("Mesh: app not found!!");
2181 return BT_STATUS_PARM_INVALID;
2184 return BT_STATUS_SUCCESS;
2187 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2188 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2193 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2197 if (op == BT_MESH_KEY_CREATE)
2198 status = __mesh_subnet_appkey_command_execute(app,
2199 netkey_idx, appkey_idx, "CreateAppKey");
2200 else if (op == BT_MESH_KEY_DELETE)
2201 status = __mesh_subnet_appkey_command_execute(app,
2202 netkey_idx, appkey_idx, "DeleteAppKey");
2203 else if (op == BT_MESH_KEY_UPDATE) {
2204 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2205 netkey_idx, appkey_idx);
2206 status = __mesh_subnet_appkey_command_execute(app,
2207 netkey_idx, appkey_idx, "UpdateAppKey");
2210 return BT_STATUS_FAIL;
2213 ERR("Mesh: app not found!!");
2214 return BT_STATUS_PARM_INVALID;
2217 return BT_STATUS_SUCCESS;
2220 bt_status_t _bt_hal_mesh_send_provision_data(
2221 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2225 struct l_dbus_message *msg;
2226 struct l_dbus_message *reply;
2228 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2233 reply = l_dbus_message_new_method_return(msg);
2234 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2235 l_dbus_send(dbus, reply);
2237 ERR("Mesh: app not found!!");
2238 return BT_STATUS_PARM_INVALID;
2240 return BT_STATUS_SUCCESS;
2243 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2247 l = g_slist_find_custom(mesh_apps,
2248 net_uuid->uu, __mesh_compare_network_uuid);
2251 if (!__bt_mesh_proxy_check(app)) {
2252 ERR("Mesh: Proxy check failed!!");
2253 return BT_STATUS_FAIL;
2255 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2256 "UnprovisionedScanCancel",
2257 NULL, NULL, NULL, NULL))
2258 return BT_STATUS_FAIL;
2260 ERR("Mesh: app not found!!");
2261 return BT_STATUS_PARM_INVALID;
2264 /* Stop Scan timer */
2265 if (app->scan_timer_id > 0) {
2266 g_source_remove(app->scan_timer_id);
2267 app->scan_timer_id = 0;
2270 /* Trigger Scan finished event */
2271 __mesh_trigger_scan_finished_event(app);
2273 return BT_STATUS_SUCCESS;
2276 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2277 const char *auth_value)
2280 struct l_dbus_message *reply = NULL;
2281 struct l_dbus_message_builder *builder;
2283 bt_status_t ret = BT_STATUS_SUCCESS;
2287 if (!__bt_mesh_proxy_check(0)) {
2288 ERR("Mesh: Proxy check failed!!");
2289 return BT_STATUS_FAIL;
2291 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2292 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2293 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2294 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2295 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2296 INFO("Mesh: Authentication reply: Numeric Type");
2297 val_u32 = atoi(auth_value);
2298 reply = l_dbus_message_new_method_return(agent_msg);
2299 l_dbus_message_set_arguments(reply, "u", val_u32);
2301 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2302 l_dbus_send(dbus, reply);
2303 ret = BT_STATUS_SUCCESS;
2304 /* For Alpha-Numeric */
2305 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2306 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2307 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2308 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2309 alpha = l_util_from_hexstring(auth_value, &sz);
2310 reply = l_dbus_message_new_method_return(agent_msg);
2311 builder = l_dbus_message_builder_new(reply);
2312 __mesh_append_byte_array(builder, alpha, 16);
2313 l_dbus_message_builder_finalize(builder);
2314 l_dbus_message_builder_destroy(builder);
2317 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2318 l_dbus_send(dbus, reply);
2319 ret = BT_STATUS_SUCCESS;
2324 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2325 bt_hal_mesh_scan_param_t *param)
2329 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2332 if (!__bt_mesh_proxy_check(app)) {
2333 ERR("Mesh: Proxy check failed!!");
2334 return BT_STATUS_FAIL;
2336 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2337 __mesh_scan_setup, __mesh_scan_reply,
2338 L_UINT_TO_PTR(param->scan_time), NULL))
2339 return BT_STATUS_FAIL;
2341 ERR("Mesh: app not found!!");
2342 return BT_STATUS_PARM_INVALID;
2344 return BT_STATUS_SUCCESS;
2347 static void __bt_hal_mesh_delete_node_setup(struct l_dbus_message *msg,
2350 struct mesh_remote_node_info *node_info = \
2351 (struct mesh_remote_node_info*) user_data;
2353 l_dbus_message_set_arguments(msg, "qy",
2354 node_info->unicast, node_info->num_elements);
2355 INFO("Mesh: Delete Remote Node Setup params passed");
2358 static void __bt_hal_mesh_delete_node_reply(
2359 struct l_dbus_proxy *proxy,
2360 struct l_dbus_message *msg, void *user_data)
2362 INFO("Mesh: Delete Remote Node Reply from DBUS");
2365 bt_status_t _bt_hal_mesh_node_delete(bt_uuid_t *network,
2366 uint16_t unicast, uint16_t num_elements)
2370 struct mesh_remote_node_info *node_info;
2371 INFO("Mesh: Delete Remote Node");
2372 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2375 if (!__bt_mesh_proxy_check(app)) {
2376 ERR("Mesh: Proxy check failed!!");
2377 return BT_STATUS_FAIL;
2379 INFO("Mesh: Delete Remote Node Unicast [0x%2.2x] Num els [%u]",
2380 unicast, num_elements);
2382 /* Delete Remote Node Request */
2383 node_info = g_malloc0(sizeof(struct mesh_remote_node_info));
2384 node_info->unicast = unicast;
2385 node_info->num_elements = num_elements;
2387 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "DeleteRemoteNode",
2388 __bt_hal_mesh_delete_node_setup,
2389 __bt_hal_mesh_delete_node_reply, node_info,
2391 ERR("Mesh: Delete Remote Node Request failed!!");
2393 return BT_STATUS_FAIL;
2396 ERR("Mesh: App not found!!");
2397 return BT_STATUS_PARM_INVALID;
2399 INFO("Mesh: Delete Remote Node Call issued successfully!!");
2400 return BT_STATUS_SUCCESS;
2403 bt_status_t _bt_hal_mesh_network_release(bt_uuid_t *net_uuid)
2407 INFO("Mesh: Release Network");
2408 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2411 if (!__bt_mesh_proxy_check(app)) {
2412 ERR("Mesh: Proxy check failed!!");
2413 return BT_STATUS_FAIL;
2415 INFO("Mesh: Release Network");
2416 /* Create CFG Network */
2417 if (!l_dbus_proxy_method_call(net_proxy, "Release",
2418 __bt_hal_mesh_release_net_setup,
2419 __bt_hal_mesh_release_net_reply, app,
2421 ERR("Mesh: Network Release failed!!");
2422 return BT_STATUS_FAIL;
2425 ERR("Mesh: App not found!!");
2426 return BT_STATUS_PARM_INVALID;
2428 INFO("Mesh: Network Release Call issued successfully!!");
2429 return BT_STATUS_SUCCESS;
2432 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2436 INFO("Mesh: Destroy network");
2437 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2440 if (!__bt_mesh_proxy_check(app)) {
2441 ERR("Mesh: Proxy check failed!!");
2442 return BT_STATUS_FAIL;
2444 INFO("Mesh: Create New Network");
2445 /* Create CFG Network */
2446 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2447 __bt_hal_mesh_leave_net_setup,
2448 __bt_hal_mesh_leave_net_reply, app,
2450 ERR("Mesh: Network Leave failed!!");
2451 return BT_STATUS_FAIL;
2454 ERR("Mesh: App not found!!");
2455 return BT_STATUS_PARM_INVALID;
2457 INFO("Mesh: Network Leave Call issued successfully!!");
2458 return BT_STATUS_SUCCESS;
2461 bt_status_t _bt_hal_mesh_create_network(
2462 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2466 INFO("Mesh: Create Network Request");
2468 if (!__bt_mesh_proxy_check(0)) {
2469 ERR("Mesh: Proxy check failed!!");
2470 return BT_STATUS_FAIL;
2473 INFO("Mesh: Node Element count [%d]", node->num_elements);
2474 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2475 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2476 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2477 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2478 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2479 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2480 /* Create DBUS APP */
2481 app = __bt_hal_mesh_create_app(node, models, is_prov);
2483 return BT_STATUS_FAIL;
2485 /* Register DBUS APP */
2486 if (!__bt_hal_mesh_register_application(app))
2489 if (app->token.u64 == 0) {
2490 INFO("Mesh: Create New Network");
2491 /* Create CFG Network */
2492 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2493 __bt_hal_mesh_create_net_setup,
2494 __bt_hal_mesh_create_net_reply, app,
2496 ERR("Mesh: Network Create failed!!");
2500 INFO("Mesh: Attach Node to Network");
2501 /* Attach to Network */
2502 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2503 __bt_hal_mesh_attach_node_setup,
2504 __bt_hal_mesh_attach_node_reply,
2507 ERR("Mesh: Node attach failed!!");
2512 INFO("Mesh: Node registration request scheudled");
2513 mesh_apps = g_slist_append(mesh_apps, app);
2514 INFO("Mesh: Total number of apps in list [%d]",
2515 g_slist_length(mesh_apps));
2516 return BT_STATUS_SUCCESS;
2518 ERR("Mesh: network can not be created!!");
2519 __bt_hal_mesh_destroy_app_object(app);
2520 return BT_STATUS_FAIL;
2523 static void __bt_hal_mesh_config_send(
2524 struct l_dbus_message *msg, void *user_data)
2526 struct configuration_request *req = user_data;
2527 struct l_dbus_message_builder *builder;
2529 builder = l_dbus_message_builder_new(msg);
2531 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2532 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2533 if (req->is_dev_key)
2534 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2536 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2537 __mesh_append_byte_array(builder, req->data, req->len);
2538 l_dbus_message_builder_finalize(builder);
2539 l_dbus_message_builder_destroy(builder);
2542 static void __bt_hal_mesh_key_config_send(
2543 struct l_dbus_message *msg, void *user_data)
2545 struct key_config_request *req = user_data;
2546 struct l_dbus_message_builder *builder;
2548 builder = l_dbus_message_builder_new(msg);
2550 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2551 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2552 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2553 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2554 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2555 l_dbus_message_builder_finalize(builder);
2556 l_dbus_message_builder_destroy(builder);
2559 static void __bt_hal_mesh_model_execute_message(
2560 struct l_dbus_message *msg, void *user_data)
2562 struct configuration_request *req = user_data;
2563 struct l_dbus_message_builder *builder;
2565 builder = l_dbus_message_builder_new(msg);
2567 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2568 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2569 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2570 __mesh_append_byte_array(builder, req->data, req->len);
2571 l_dbus_message_builder_finalize(builder);
2572 l_dbus_message_builder_destroy(builder);
2575 bt_status_t _bt_hal_mesh_send_key_config_message(
2576 bt_uuid_t *network, uint16_t dest,
2577 bool is_netkey, bool is_update,
2578 uint16_t key_idx, uint16_t netkey_idx)
2582 struct key_config_request *req;
2585 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2586 /* Source is Config Client Local Node */
2587 int src_elem_idx = 0;
2588 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2591 if (!__bt_mesh_proxy_check(app)) {
2592 ERR("Mesh: Proxy check failed!!");
2593 return BT_STATUS_FAIL;
2595 l1 = g_slist_find_custom(app->elements,
2596 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2598 return BT_STATUS_FAIL;
2601 req = l_new(struct key_config_request, 1);
2602 req->ele_path = elem->path;
2604 req->key_req_idx = key_idx;
2605 req->idx = netkey_idx; /* Encryption Key index */
2606 req->update_req = is_update;
2608 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2609 __bt_hal_mesh_key_config_send, NULL,
2610 (void*)req, l_free))
2611 return BT_STATUS_FAIL;
2613 ERR("Mesh: app not found!!");
2614 return BT_STATUS_PARM_INVALID;
2617 return BT_STATUS_SUCCESS;
2620 bt_status_t _bt_hal_mesh_send_configuration_message(
2621 bt_uuid_t *network, uint16_t dest,
2622 bool is_dev_key, uint16_t netkey_idx,
2623 uint8_t *buf, int len)
2627 struct configuration_request *req;
2630 int src_elem_idx = 0;
2631 l = g_slist_find_custom(mesh_apps, network->uu,
2632 __mesh_compare_network_uuid);
2635 if (!__bt_mesh_proxy_check(app)) {
2636 ERR("Mesh: Proxy check failed!!");
2637 return BT_STATUS_FAIL;
2639 l1 = g_slist_find_custom(app->elements,
2640 GUINT_TO_POINTER(src_elem_idx),
2641 __compare_element_index);
2643 return BT_STATUS_FAIL;
2646 req = l_new(struct configuration_request, 1);
2647 req->ele_path = elem->path;
2649 req->idx = netkey_idx;
2653 req->is_dev_key = is_dev_key;
2655 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2656 __bt_hal_mesh_config_send, NULL,
2657 (void*)req, l_free))
2658 return BT_STATUS_FAIL;
2660 ERR("Mesh: app not found!!");
2661 return BT_STATUS_PARM_INVALID;
2664 return BT_STATUS_SUCCESS;
2667 bt_status_t _bt_hal_mesh_model_execute_message(
2668 bt_uuid_t *network, uint16_t dest,
2669 uint16_t appkey_idx, uint8_t *buf, int len)
2673 struct configuration_request *req;
2676 int src_elem_idx = 0;
2677 l = g_slist_find_custom(mesh_apps, network->uu,
2678 __mesh_compare_network_uuid);
2681 if (!__bt_mesh_proxy_check(app)) {
2682 ERR("Mesh: Proxy check failed!!");
2683 return BT_STATUS_FAIL;
2685 l1 = g_slist_find_custom(app->elements,
2686 GUINT_TO_POINTER(src_elem_idx),
2687 __compare_element_index);
2689 return BT_STATUS_FAIL;
2692 req = l_new(struct configuration_request, 1);
2693 req->ele_path = elem->path;
2695 req->idx = appkey_idx;
2699 req->is_dev_key = false;
2701 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2702 __bt_hal_mesh_model_execute_message,
2703 NULL, (void*)req, l_free))
2704 return BT_STATUS_FAIL;
2706 ERR("Mesh: app not found!!");
2707 return BT_STATUS_PARM_INVALID;
2710 return BT_STATUS_SUCCESS;