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 __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);
610 /* To send stack event to hal-mesh handler */
611 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
616 /* To send stack event to hal-mesh handler */
617 void _bt_hal_mesh_unregister_dbus_handler_cb()
619 mesh_event_cb = NULL;
622 static bool __mesh_get_companyid(struct l_dbus *dbus,
623 struct l_dbus_message *message,
624 struct l_dbus_message_builder *builder,
627 meshcfg_app *app = (meshcfg_app*) user_data;
631 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
636 static bool __mesh_get_productid(struct l_dbus *dbus,
637 struct l_dbus_message *message,
638 struct l_dbus_message_builder *builder,
641 meshcfg_app *app = (meshcfg_app*) user_data;
644 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
649 static bool __mesh_get_versionid(struct l_dbus *dbus,
650 struct l_dbus_message *message,
651 struct l_dbus_message_builder *builder,
654 meshcfg_app *app = (meshcfg_app*) user_data;
657 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
662 static bool __mesh_get_crpl(struct l_dbus *dbus,
663 struct l_dbus_message *message,
664 struct l_dbus_message_builder *builder,
667 meshcfg_app *app = (meshcfg_app*) user_data;
670 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
675 static void __send_network_attach_event(void *param, uint8_t status)
677 struct hal_ev_mesh_network_attached ev;
678 meshcfg_app *app = (meshcfg_app*)param;
680 memset(&ev, 0, sizeof(ev));
681 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
682 memcpy(ev.token, app->token.u8, 8);
686 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
687 (void*)&ev, sizeof(ev));
690 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
691 struct l_dbus_message *msg, void *user_data)
693 struct l_dbus_message_iter iter_cfg;
695 meshcfg_app *app = (meshcfg_app*) user_data;
696 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
697 app->path, app->agent_path);
699 if (l_dbus_message_is_error(msg)) {
701 l_dbus_message_get_error(msg, &name, NULL);
702 ERR("Mesh: Failed to attach node: %s", name);
707 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
711 INFO("Mesh: Attached with path %s\n", app->path);
712 __send_network_attach_event(app, BT_STATUS_SUCCESS);
715 __send_network_attach_event(app, BT_STATUS_FAIL);
716 /* Destroy mesh app object */
717 __bt_hal_mesh_destroy_app_object(app);
720 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
723 meshcfg_app *app = (meshcfg_app*) user_data;
725 l_dbus_message_set_arguments(msg, "ot", app->path,
726 l_get_be64(app->token.u8));
730 static void __bt_hal_mesh_attach_node(void *user_data)
732 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
733 __bt_hal_mesh_attach_node_setup,
734 __bt_hal_mesh_attach_node_reply,
737 ERR("Mesh: Node attach failed!!");
738 /* Node could not be attached */
739 __send_network_attach_event(user_data, BT_STATUS_FAIL);
740 /* Destroy mesh app object */
741 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
745 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
746 struct l_dbus_message *message,
752 meshcfg_app *app = (meshcfg_app*) user_data;
753 INFO("Mesh: Join Complete");
756 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
758 /* Send Network creation fail event */
759 __send_network_attach_event(app, BT_STATUS_FAIL);
761 /* Destroy mesh app object */
762 __bt_hal_mesh_destroy_app_object(app);
764 return l_dbus_message_new_error(message, dbus_err_args, NULL);
768 app->token.u64 = l_get_be64(&tmp);
769 str = l_util_hexstring(&app->token.u8[0], 8);
770 INFO("Mesh: Created new node with token %s\n", str);
773 /* Authenticate the node */
774 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
775 return l_dbus_message_new_method_return(message);
778 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
781 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
782 meshcfg_model *model_info = (meshcfg_model*) data;
784 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
787 static bool __mesh_model_getter(struct l_dbus *dbus,
788 struct l_dbus_message *message,
789 struct l_dbus_message_builder *builder,
792 meshcfg_el *element = (meshcfg_el*) user_data;
794 l_dbus_message_builder_enter_array(builder, "q");
795 g_slist_foreach(element->models,
796 __bt_hal_mesh_foreach_model_getter, builder);
798 l_dbus_message_builder_leave_array(builder);
803 /*TODO: Vendor Model handling is currently not Handled */
804 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
805 struct l_dbus_message *message,
806 struct l_dbus_message_builder *builder,
809 l_dbus_message_builder_enter_array(builder, "(qq)");
810 l_dbus_message_builder_leave_array(builder);
815 static bool __mesh_element_index_getter(struct l_dbus *dbus,
816 struct l_dbus_message *message,
817 struct l_dbus_message_builder *builder,
820 meshcfg_el *element = (meshcfg_el*) user_data;
821 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
827 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
828 struct l_dbus_message *msg, void *user_data)
830 struct l_dbus_message_iter iter;
835 const char *dbus_path;
838 dbus_path = l_dbus_message_get_path(msg);
839 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
840 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
841 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
843 INFO("Mesh: app path [%s]", dbus_path);
845 memset(buf, 0, sizeof(buf));
846 size = (uint16_t) sizeof(*ev);
847 memcpy(ev->net_uuid, net_uuid, 16);
850 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
852 ERR("Mesh: Cannot parse received message");
853 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
856 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
857 ERR("Mesh: Cannot parse received message: data");
858 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
861 INFO("Mesh: Received dev key message (len %u):", n);
862 ev->source_addr = src;
863 ev->is_remote_devkey = rmt;
864 ev->netkey_idx = idx;
866 memcpy(ev->data, data, n);
869 INFO("Mesh: Src [0x%2.2x]", src);
870 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
871 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
872 /* Send DevKeyMessage Received event */
874 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
875 return l_dbus_message_new_method_return(msg);
878 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
879 struct l_dbus_message *msg, void *user_data)
881 struct l_dbus_message_iter iter;
882 uint16_t src, idx, dst;
885 const char *dbus_path;
888 dbus_path = l_dbus_message_get_path(msg);
889 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
890 uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
891 struct hal_ev_mesh_message_event *ev = (void *)buf;
893 INFO("Mesh: app path [%s]", dbus_path);
895 memset(buf, 0, sizeof(buf));
896 size = (uint16_t) sizeof(*ev);
897 memcpy(ev->net_uuid, net_uuid, 16);
900 if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
902 ERR("Mesh: Cannot parse received message");
903 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
906 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
907 ERR("Mesh: Cannot parse received message: data");
908 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
911 INFO("Mesh: Received mesh message (len %u):", n);
912 ev->source_addr = src;
916 memcpy(ev->data, data, n);
919 INFO("Mesh: Src [0x%2.2x]", src);
920 INFO("Mesh: Dst [0x%2.2x]", dst);
921 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
922 /* Send Message Received event */
924 INFO("Mesh: Send message event");
925 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
927 return l_dbus_message_new_method_return(msg);
930 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
932 INFO("Mesh: Setup element interface properties & methods");
934 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
936 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
937 __mesh_vendor_model_getter, NULL);
938 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
941 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
942 __mesh_device_message_received, "", "qbqay", "source",
943 "remote", "net_index", "data");
944 l_dbus_interface_method(iface, "MessageReceived", 0,
945 __mesh_message_received, "", "qqvay", "source",
946 "key_index", "destination", "data");
947 /* TODO: Other methods */
950 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
951 struct l_dbus_message *msg,
954 struct l_dbus_message_iter iter, opts;
955 meshcfg_app *app = (meshcfg_app*) user_data;
960 const char *sig = "naya{sv}";
962 /* Find network uuid from dbus path */
963 struct hal_ev_mesh_scan_result ev;
965 if (!app->scan_timer_id) {
966 /* Scan is not running */
967 INFO("Got scan result, but scan is already stopped");
968 return l_dbus_message_new_method_return(msg);
970 memset(&ev, 0, sizeof(ev));
971 memcpy(ev.net_uuid, app->uuid, 16);
973 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
974 ERR("Mesh: Cannot parse scan results");
975 ev.status = BT_STATUS_FAIL;
977 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
978 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
981 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
983 ERR("Mesh: Cannot parse scan result: data");
984 ev.status = BT_STATUS_FAIL;
986 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
987 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
990 INFO("Mesh: Scan result:\n");
991 INFO("Mesh: Scan rssi = [%d]\n", rssi);
992 str = l_util_hexstring_upper(prov_data, 16);
993 INFO("Mesh: Scan UUID = [%s]\n", str);
997 str = l_util_hexstring_upper(prov_data + 16, 2);
998 INFO("Mesh: Scan OOB = [%s]\n", str);
1003 str = l_util_hexstring_upper(prov_data + 18, 4);
1004 INFO("Mesh: Scan URI hash = [%s]\n", str);
1008 /* 16 octet Dev UUID */
1009 memcpy(ev.dev_uuid, prov_data, 16);
1011 /* 2 octet Dev OOB Info */
1012 memcpy(ev.oob_info, prov_data + 16, 2);
1014 /* 4 octet URI Hash */
1015 memcpy(ev.uri_hash, prov_data + 18, 4);
1019 ev.status = BT_STATUS_SUCCESS;
1021 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
1022 (void*)&ev, sizeof(ev));
1024 return l_dbus_message_new_method_return(msg);
1027 static struct l_dbus_message *__mesh_request_provisioner_call(
1028 struct l_dbus *dbus,
1029 struct l_dbus_message *msg,
1033 struct hal_ev_mesh_provision_finished ev;
1034 struct hal_ev_mesh_provision_data_request req;
1036 meshcfg_app *app = user_data;
1038 INFO("Mesh: provisioning data requested app path [%s]",
1040 uuid_string = l_util_hexstring(app->uuid, 16);
1041 INFO("Mesh: Network UUID [%s]", uuid_string);
1043 memset(&ev, 0, sizeof(ev));
1044 memset(&req, 0, sizeof(req));
1045 memcpy(ev.net_uuid, app->uuid, 16);
1046 memcpy(req.net_uuid, app->uuid, 16);
1047 l_free(uuid_string);
1049 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1050 ERR("Mesh: Cannot parse request for prov data");
1052 ev.status = BT_STATUS_FAIL;
1053 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1055 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1056 (void*)&ev, sizeof(ev));
1057 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1063 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1064 (void*)&req, sizeof(req));
1066 l_dbus_message_ref(msg);
1070 static struct l_dbus_message *__mesh_node_add_completed(
1071 struct l_dbus *dbus,
1072 struct l_dbus_message *msg,
1075 struct l_dbus_message_iter iter;
1080 struct hal_ev_mesh_provision_finished ev;
1081 const char *dbus_path;
1083 dbus_path = l_dbus_message_get_path(msg);
1084 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1085 true, MESH_PROV_IFACE);
1087 INFO("Mesh: app path [%s]", dbus_path);
1089 memset(&ev, 0, sizeof(ev));
1090 memcpy(ev.net_uuid, net_uuid, 16);
1094 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1095 ERR("Mesh: Cannot parse add node complete message");
1097 ev.status = BT_STATUS_FAIL;
1098 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1100 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1101 (void*)&ev, sizeof(ev));
1102 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1105 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1107 ERR("Mesh: Cannot parse add node complete message: uuid");
1109 ev.status = BT_STATUS_FAIL;
1110 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1112 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1113 (void*)&ev, sizeof(ev));
1114 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1118 ev.status = BT_STATUS_SUCCESS;
1119 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1120 memcpy(ev.dev_uuid, uuid, 16);
1121 ev.unicast = unicast;
1125 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1126 (void*)&ev, sizeof(ev));
1128 return l_dbus_message_new_method_return(msg);
1131 static struct l_dbus_message *__mesh_node_add_failed(
1132 struct l_dbus *dbus,
1133 struct l_dbus_message *msg,
1136 struct l_dbus_message_iter iter;
1140 struct hal_ev_mesh_provision_finished ev;
1141 const char *dbus_path;
1144 dbus_path = l_dbus_message_get_path(msg);
1145 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1146 true, MESH_PROV_IFACE);
1148 memset(&ev, 0, sizeof(ev));
1149 memcpy(ev.net_uuid, net_uuid, 16);
1152 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1153 ERR("Mesh: Cannot parse add node failed message");
1155 ev.status = BT_STATUS_FAIL;
1156 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1158 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1159 (void*)&ev, sizeof(ev));
1160 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1163 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1165 ERR("Mesh:Cannot parse add node failed message: uuid");
1166 ev.status = BT_STATUS_FAIL;
1167 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1169 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1170 (void*)&ev, sizeof(ev));
1171 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1174 INFO("Mesh: Provisioning failed:\n");
1175 str = l_util_hexstring_upper(uuid, 16);
1176 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1179 ev.status = BT_STATUS_FAIL;
1180 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1181 memcpy(ev.dev_uuid, uuid, 16);
1184 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1185 (void*)&ev, sizeof(ev));
1187 return l_dbus_message_new_method_return(msg);
1190 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1192 INFO("Mesh: Setup provisioner interface properties & methods");
1193 l_dbus_interface_method(interface, "ScanResult", 0,
1194 __mesh_scan_result_received, "",
1195 "naya{sv}", "rssi", "data", "options");
1197 l_dbus_interface_method(interface, "RequestProvData", 0,
1198 __mesh_request_provisioner_call,
1199 "qq", "y", "net_index", "unicast", "count");
1201 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1202 __mesh_node_add_completed, "", "ayqy",
1203 "uuid", "unicast", "count");
1205 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1206 __mesh_node_add_failed,
1207 "", "ays", "uuid", "reason");
1210 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1212 INFO("Mesh: Setup application interface properties & methods");
1214 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1215 __mesh_get_companyid,
1217 l_dbus_interface_property(iface, "VersionID", 0, "q",
1218 __mesh_get_versionid,
1220 l_dbus_interface_property(iface, "ProductID", 0, "q",
1221 __mesh_get_productid,
1223 l_dbus_interface_property(iface, "CRPL", 0, "q",
1224 __mesh_get_crpl, NULL);
1225 l_dbus_interface_method(iface, "JoinComplete", 0,
1226 __mesh_node_join_complete,
1232 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1233 struct l_dbus_message_builder *builder)
1235 if (app->in_oob & 0x08)
1236 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1237 if (app->in_oob & 0x04)
1238 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1239 if (app->in_oob & 0x02)
1240 l_dbus_message_builder_append_basic(builder, 's', "twist");
1241 if (app->in_oob & 0x01)
1242 l_dbus_message_builder_append_basic(builder, 's', "push");
1245 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1246 struct l_dbus_message_builder *builder)
1248 if (app->out_oob & 0x10)
1249 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1250 if (app->out_oob & 0x08)
1251 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1252 if (app->out_oob & 0x04)
1253 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1254 if (app->out_oob & 0x02)
1255 l_dbus_message_builder_append_basic(builder, 's', "beep");
1256 if (app->out_oob & 0x01)
1257 l_dbus_message_builder_append_basic(builder, 's', "blink");
1260 static bool __mesh_agent_capability_getter(
1261 struct l_dbus *dbus, struct l_dbus_message *message,
1262 struct l_dbus_message_builder *builder,
1267 INFO("Mesh: app path [%s]", app->path);
1268 INFO("Mesh: Agent path [%s]", app->agent_path);
1270 if (!l_dbus_message_builder_enter_array(builder, "s"))
1273 __mesh_fill_out_capabilities(app, builder);
1274 __mesh_fill_in_capabilities(app, builder);
1276 if (app->static_oob)
1277 l_dbus_message_builder_append_basic(builder,
1281 l_dbus_message_builder_leave_array(builder);
1282 INFO("Mesh: __agent_capability_getter: Success");
1286 static struct l_dbus_message *__mesh_agent_display_string_request(
1287 struct l_dbus *dbus,
1288 struct l_dbus_message *msg,
1291 struct hal_ev_mesh_authentication_request ev;
1294 const char *dbus_path;
1297 INFO("Mesh: app path [%s]", app->path);
1298 INFO("Mesh: Agent path [%s]", app->agent_path);
1300 dbus_path = l_dbus_message_get_path(msg);
1301 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1302 true, MESH_AGENT_IFACE);
1304 INFO("Mesh: app path [%s]", dbus_path);
1306 memset(&ev, 0, sizeof(ev));
1307 memcpy(ev.net_uuid, net_uuid, 16);
1310 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1311 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1312 struct hal_ev_mesh_provision_finished ev;
1313 memset(&ev, 0, sizeof(ev));
1314 memcpy(ev.net_uuid, net_uuid, 16);
1315 ev.status = BT_STATUS_FAIL;
1316 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1318 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1319 (void*)&ev, sizeof(ev));
1323 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1326 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1327 ev.auth_type = __mesh_get_authentication_type(str);
1328 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1329 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1330 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1333 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1334 (void*)&ev, sizeof(ev));
1337 return l_dbus_message_new_method_return(msg);
1340 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1341 struct l_dbus *dbus,
1342 struct l_dbus_message *msg,
1346 struct hal_ev_mesh_authentication_request ev;
1350 const char *dbus_path;
1353 INFO("Mesh: app path [%s]", app->path);
1354 INFO("Mesh: Agent path [%s]", app->agent_path);
1356 dbus_path = l_dbus_message_get_path(msg);
1357 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1358 true, MESH_AGENT_IFACE);
1360 INFO("Mesh: app path [%s]", dbus_path);
1362 memset(&ev, 0, sizeof(ev));
1363 memcpy(ev.net_uuid, net_uuid, 16);
1366 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1367 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1368 struct hal_ev_mesh_provision_finished ev;
1369 memset(&ev, 0, sizeof(ev));
1370 memcpy(ev.net_uuid, net_uuid, 16);
1371 ev.status = BT_STATUS_FAIL;
1372 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1373 if (mesh_event_cb) {
1374 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1375 (void*)&ev, sizeof(ev));
1378 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1381 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1382 auth_value = l_strdup_printf("%u", n);
1383 ev.auth_type = __mesh_get_authentication_type(str);
1384 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1385 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1386 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1389 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1390 (void*)&ev, sizeof(ev));
1394 return l_dbus_message_new_method_return(msg);
1397 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1398 struct l_dbus *dbus,
1399 struct l_dbus_message *msg,
1402 struct hal_ev_mesh_authentication_request ev;
1405 const char *dbus_path;
1409 dbus_path = l_dbus_message_get_path(msg);
1410 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1411 true, MESH_AGENT_IFACE);
1413 INFO("Mesh: app path [%s]", dbus_path);
1415 l = g_slist_find_custom(mesh_apps, net_uuid,
1416 __mesh_compare_network_uuid);
1419 memset(&ev, 0, sizeof(ev));
1420 memcpy(ev.net_uuid, net_uuid, 16);
1423 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1424 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1426 struct hal_ev_mesh_provision_finished ev;
1427 memset(&ev, 0, sizeof(ev));
1428 memcpy(ev.net_uuid, app->uuid, 16);
1429 ev.status = BT_STATUS_FAIL;
1430 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1431 if (mesh_event_cb) {
1432 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1433 (void*)&ev, sizeof(ev));
1435 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1438 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1440 ev.auth_type = __mesh_get_authentication_type(str);
1441 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1442 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1444 l_dbus_message_ref(msg);
1446 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1447 (void*)&ev, sizeof(ev));
1452 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1453 struct l_dbus *dbus,
1454 struct l_dbus_message *msg,
1457 struct hal_ev_mesh_authentication_request ev;
1460 const char *dbus_path;
1464 dbus_path = l_dbus_message_get_path(msg);
1465 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1468 INFO("Mesh: app path [%s]", dbus_path);
1470 l = g_slist_find_custom(mesh_apps, net_uuid,
1471 __mesh_compare_network_uuid);
1474 memset(&ev, 0, sizeof(ev));
1475 memcpy(ev.net_uuid, net_uuid, 16);
1478 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1479 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1481 struct hal_ev_mesh_provision_finished ev;
1482 memset(&ev, 0, sizeof(ev));
1483 memcpy(ev.net_uuid, app->uuid, 16);
1484 ev.status = BT_STATUS_FAIL;
1485 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1487 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1488 (void*)&ev, sizeof(ev));
1489 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1492 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1494 ev.auth_type = __mesh_get_authentication_type(str);
1495 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1496 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1498 l_dbus_message_ref(msg);
1500 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1501 (void*)&ev, sizeof(ev));
1506 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1508 INFO("Mesh: Setup Agent interface properties & methods");
1509 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1510 __mesh_agent_capability_getter,
1512 /* TODO: Other properties */
1513 l_dbus_interface_method(interface, "DisplayString", 0,
1514 __mesh_agent_display_string_request,
1516 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1517 __mesh_agent_display_numeric_request,
1518 "", "su", "type", "number");
1519 l_dbus_interface_method(interface, "PromptNumeric", 0,
1520 __mesh_agent_prompt_numeric_request,
1521 "u", "s", "number", "type");
1522 l_dbus_interface_method(interface, "PromptStatic", 0,
1523 __mesh_agent_prompt_static_request,
1524 "ay", "s", "data", "type");
1527 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1529 meshcfg_el *elem = (meshcfg_el*) data;
1530 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1531 elem->index, elem->path);
1532 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1533 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1534 ERR("Mesh: Failed to register object %s", elem->path);
1538 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1543 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1544 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1545 ERR("Mesh: Unable to register agent interface");
1549 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1550 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1551 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1552 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1556 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1557 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1558 ERR("Mesh: Failed to add interface %s",
1559 L_DBUS_INTERFACE_PROPERTIES);
1566 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1574 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1575 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1576 ERR("Mesh: Failed to register interface %s",
1577 BT_HAL_MESH_APPLICATION_INTERFACE);
1581 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1582 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1583 ERR("Mesh: Failed to register interface %s",
1584 BT_HAL_MESH_PROVISIONER_INTERFACE);
1588 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1589 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1590 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1592 ERR("Mesh: Failed to register object %s", ptr->path);
1596 if (!__bt_hal_mesh_register_agent(ptr))
1599 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1600 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1601 ERR("Mesh: Failed to register interface %s",
1602 BT_HAL_MESH_ELEMENT_INTERFACE);
1606 INFO("Mesh: Number of elements to be registsred [%d]",
1607 g_slist_length(ptr->elements));
1609 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1611 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1612 if (!l_dbus_object_add_interface(dbus, ptr->path,
1613 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1614 ERR("Mesh: Failed to add interface %s",
1615 L_DBUS_INTERFACE_OBJECT_MANAGER);
1618 INFO("Mesh: Application Register completed");
1623 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1627 meshcfg_model *model_info = (meshcfg_model*) data;
1628 meshcfg_app *app = (meshcfg_app*) user_data;
1630 l = g_slist_find_custom(app->elements,
1631 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1635 elem = g_malloc0(sizeof(meshcfg_el));
1636 elem->index = model_info->elem_index;
1637 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1638 app->elements = g_slist_append(app->elements, elem);
1639 INFO("Mesh: Created element index [%d] path [%s]",
1640 elem->index, elem->path);
1642 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1643 model_info->model, elem->index);
1644 /* Add Model in the element */
1645 elem->models = g_slist_append(elem->models, model_info);
1646 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1647 elem->index, g_slist_length(elem->models));
1650 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1651 GSList *models, bool is_prov)
1654 meshcfg_app *app = NULL;
1655 char *uuid_str = NULL;
1657 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1659 app = g_malloc0(sizeof(meshcfg_app));
1660 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1662 app->cid = node->vendor_info.companyid;
1663 app->pid = node->vendor_info.vendorid;
1664 app->vid = node->vendor_info.versionid;
1665 app->crpl = node->vendor_info.crpl;
1668 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1669 app->agent_path = g_strdup_printf("%s/agent", app->path);
1672 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1673 app->agent_path = g_strdup_printf("%s/agent", app->path);
1675 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1678 app->is_prov = is_prov;
1679 INFO("Mesh: app created");
1683 static void __bt_hal_mesh_leave_net_reply(
1684 struct l_dbus_proxy *proxy,
1685 struct l_dbus_message *msg, void *user_data)
1688 app = (meshcfg_app*) user_data;
1690 INFO("Mesh: Leave Network Reply from Meshd: app path [%s]", app->path);
1691 if (l_dbus_message_is_error(msg)) {
1694 l_dbus_message_get_error(msg, &name, NULL);
1695 ERR("Mesh: Failed to leave network: %s", name);
1697 /* Send Network Destroy fail event */
1698 __send_network_destroy_event(app, BT_STATUS_FAIL);
1700 INFO("Mesh: Leave Network: Success, cleanup app after proxy removed");
1704 static void __bt_hal_mesh_leave_net_setup(struct l_dbus_message *msg,
1707 meshcfg_app *app = (meshcfg_app*) user_data;
1709 l_dbus_message_set_arguments(msg, "t", l_get_be64(app->token.u8));
1710 INFO("Mesh: Leave Network Setup app path [%s]", app->path);
1713 static void __bt_hal_mesh_create_net_reply(
1714 struct l_dbus_proxy *proxy,
1715 struct l_dbus_message *msg, void *user_data)
1718 app = (meshcfg_app*) user_data;
1720 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1721 if (l_dbus_message_is_error(msg)) {
1724 l_dbus_message_get_error(msg, &name, NULL);
1725 ERR("Mesh: Failed to create network: %s", name);
1727 /* Send Network creation fail event */
1728 __send_network_attach_event(app, BT_STATUS_FAIL);
1730 /* Destroy mesh app object */
1731 __bt_hal_mesh_destroy_app_object(app);
1736 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1740 struct l_dbus_message_builder *builder;
1741 app = (meshcfg_app*) user_data;
1743 builder = l_dbus_message_builder_new(msg);
1745 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1746 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1747 __mesh_append_byte_array(builder, app->uuid, 16);
1748 l_dbus_message_builder_finalize(builder);
1749 l_dbus_message_builder_destroy(builder);
1752 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1754 struct hal_ev_mesh_scan_state_changed ev;
1756 memset(&ev, 0, sizeof(ev));
1757 memcpy(ev.net_uuid, app->uuid, 16);
1759 ev.status = BT_STATUS_SUCCESS;
1761 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1763 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1764 (void*)&ev, sizeof(ev));
1767 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1769 meshcfg_app *app = (meshcfg_app*) user_data;
1770 __mesh_trigger_scan_finished_event(app);
1774 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1778 l = g_slist_find_custom(mesh_apps, net_uuid,
1779 __mesh_compare_network_uuid);
1782 if (app->scan_timer_id > 0) {
1783 g_source_remove(app->scan_timer_id);
1784 app->scan_timer_id = 0;
1787 app->scan_timer_id = g_timeout_add_seconds(secs,
1788 __bt_mesh_scan_timer_cb, app);
1793 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1794 struct l_dbus_message *msg, void *user_data)
1796 struct hal_ev_mesh_scan_state_changed ev;
1797 const char *dbus_path;
1799 dbus_path = l_dbus_proxy_get_path(proxy);
1800 INFO("Mesh: DBUS path [%s]", dbus_path);
1801 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1803 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1804 INFO("Mesh: Scan duration [%u]", secs);
1806 memset(&ev, 0, sizeof(ev));
1807 memcpy(ev.net_uuid, net_uuid, 16);
1809 if (l_dbus_message_is_error(msg)) {
1811 l_dbus_message_get_error(msg, &name, NULL);
1812 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1813 ev.status = BT_STATUS_FAIL;
1815 INFO("Mesh: Unprovisioned scan started\n");
1816 ev.status = BT_STATUS_SUCCESS;
1817 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1820 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1822 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1823 (void*)&ev, sizeof(ev));
1827 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1828 const char *key, const char *signature,
1834 l_dbus_message_builder_enter_dict(builder, "sv");
1835 l_dbus_message_builder_append_basic(builder, 's', key);
1836 l_dbus_message_builder_enter_variant(builder, signature);
1837 l_dbus_message_builder_append_basic(builder, signature[0], data);
1838 l_dbus_message_builder_leave_variant(builder);
1839 l_dbus_message_builder_leave_dict(builder);
1842 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1844 struct l_dbus_message_builder *builder;
1845 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1846 INFO("Mesh: Scan duration [%u]", secs);
1848 builder = l_dbus_message_builder_new(msg);
1849 l_dbus_message_builder_enter_array(builder, "{sv}");
1850 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1851 l_dbus_message_builder_leave_array(builder);
1852 l_dbus_message_builder_finalize(builder);
1853 l_dbus_message_builder_destroy(builder);
1857 bt_status_t _bt_hal_mesh_network_set_caps(
1858 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1862 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1866 app->public_oob = caps->public_oob;
1867 app->static_oob = caps->static_oob;
1868 app->out_oob = caps->out_oob;
1869 app->in_oob = caps->in_oob;
1871 ERR("Mesh: app not found!!");
1872 return BT_STATUS_PARM_INVALID;
1875 return BT_STATUS_SUCCESS;
1878 static void __bt_hal_mesh_add_node_reply(
1879 struct l_dbus_proxy *proxy,
1880 struct l_dbus_message *msg,
1883 struct hal_ev_mesh_provision_status ev;
1884 const char *dbus_path;
1886 dbus_path = l_dbus_proxy_get_path(proxy);
1887 INFO("Mesh: DBUS path [%s]", dbus_path);
1888 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1890 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1892 INFO("Mesh: app path [%s]", dbus_path);
1894 memset(&ev, 0, sizeof(ev));
1895 memcpy(ev.net_uuid, net_uuid, 16);
1896 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1898 /* Free User data */
1899 g_free((void*)dev_uuid);
1902 if (l_dbus_message_is_error(msg)) {
1905 l_dbus_message_get_error(msg, &name, NULL);
1906 ERR("Mesh: Failed to start provisioning: %s", name);
1907 ev.status = BT_STATUS_FAIL;
1909 INFO("Mesh: Provisioning started\n");
1910 ev.status = BT_STATUS_SUCCESS;
1913 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1914 (void*)&ev, sizeof(ev));
1915 INFO("Mesh: Provisioning status sent");
1918 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1922 bt_uuid_t *dev = user_data;
1923 struct l_dbus_message_builder *builder;
1924 uuid = l_util_hexstring(dev->uu, 16);
1925 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1927 builder = l_dbus_message_builder_new(msg);
1928 __mesh_append_byte_array(builder, dev->uu, 16);
1929 l_dbus_message_builder_enter_array(builder, "{sv}");
1930 l_dbus_message_builder_leave_array(builder);
1931 l_dbus_message_builder_finalize(builder);
1932 l_dbus_message_builder_destroy(builder);
1935 bt_status_t _bt_hal_mesh_provision_device(
1936 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1941 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1944 dev = g_memdup((gpointer)dev_uuid, 16);
1945 INFO("Mesh: Schedule Add Node request to meshd");
1946 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1947 __bt_hal_mesh_add_node_setup,
1948 __bt_hal_mesh_add_node_reply,
1950 return BT_STATUS_FAIL;
1952 ERR("Mesh: app not found!!");
1953 return BT_STATUS_PARM_INVALID;
1956 return BT_STATUS_SUCCESS;
1959 static void __bt_hal_mesh_subnet_key_setup(
1960 struct l_dbus_message *msg, void *user_data)
1962 struct subnet_key_request *req = user_data;
1963 uint16_t idx = (uint16_t) req->idx;
1965 l_dbus_message_set_arguments(msg, "q", idx);
1968 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1969 struct l_dbus_message *msg, void *user_data)
1971 struct hal_ev_mesh_netkey_execute_event ev;
1972 const char *dbus_path;
1974 struct subnet_key_request *req = user_data;
1975 const char *method = req->str;
1977 dbus_path = l_dbus_proxy_get_path(proxy);
1978 INFO("Mesh: DBUS path [%s]", dbus_path);
1979 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1981 memset(&ev, 0, sizeof(ev));
1982 memcpy(ev.net_uuid, net_uuid, 16);
1983 ev.key_idx = req->idx;
1987 if (l_dbus_message_is_error(msg)) {
1990 l_dbus_message_get_error(msg, &name, NULL);
1991 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
1992 ev.status = BT_STATUS_FAIL;
1995 ev.status = BT_STATUS_SUCCESS;
1997 if (!strcmp("CreateSubnet", method)) {
1998 INFO("Mesh: Reply for CreateSubnet");
1999 ev.key_event = HAL_MESH_KEY_ADD;
2000 } else if (!strcmp("DeleteSubnet", method)) {
2001 INFO("Mesh: Reply for DeleteSubnet");
2002 ev.key_event = HAL_MESH_KEY_DELETE;
2003 } else if (!strcmp("UpdateSubnet", method)) {
2004 INFO("Mesh: Reply for UpdateSubnet");
2005 ev.key_event = HAL_MESH_KEY_UPDATE;
2009 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
2010 (void*)&ev, sizeof(ev));
2013 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
2014 uint16_t index, const char *key_execute_method)
2016 struct subnet_key_request *req;
2018 req = l_new(struct subnet_key_request, 1);
2019 req->str = key_execute_method;
2022 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2023 __bt_hal_mesh_subnet_key_setup,
2024 __bt_hal_mesh_subnet_key_reply,
2031 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
2034 struct app_key_request *req = user_data;
2035 uint16_t net_idx = (uint16_t) req->net_idx;
2036 uint16_t app_idx = (uint16_t) req->app_idx;
2038 if (g_strcmp0(req->str, "CreateAppKey") == 0)
2039 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
2041 l_dbus_message_set_arguments(msg, "q", app_idx);
2044 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
2045 struct l_dbus_message *msg, void *user_data)
2047 struct hal_ev_mesh_appkey_execute_event ev;
2048 const char *dbus_path;
2050 struct app_key_request *req = user_data;
2051 const char *method = req->str;
2053 dbus_path = l_dbus_proxy_get_path(proxy);
2054 INFO("Mesh: DBUS path [%s]", dbus_path);
2055 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
2057 memset(&ev, 0, sizeof(ev));
2058 memcpy(ev.net_uuid, net_uuid, 16);
2059 ev.net_idx = req->net_idx;
2060 ev.app_idx = req->app_idx;
2064 if (l_dbus_message_is_error(msg)) {
2067 l_dbus_message_get_error(msg, &name, NULL);
2068 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2069 ev.status = BT_STATUS_FAIL;
2071 ev.status = BT_STATUS_SUCCESS;
2073 if (!strcmp("CreateAppKey", method)) {
2074 INFO("Mesh: AppKey Create Reply");
2075 ev.key_event = HAL_MESH_KEY_ADD;
2076 } else if (!strcmp("DeleteAppKey", method)) {
2077 INFO("Mesh: AppKey Delete Reply");
2078 ev.key_event = HAL_MESH_KEY_DELETE;
2079 } else if (!strcmp("UpdateAppKey", method)) {
2080 INFO("Mesh: AppKey Update Reply");
2081 ev.key_event = HAL_MESH_KEY_UPDATE;
2085 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2088 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2089 uint16_t net_idx, uint16_t app_idx,
2090 const char *key_execute_method)
2092 struct app_key_request *req;
2094 req = l_new(struct app_key_request, 1);
2095 req->str = key_execute_method;
2096 req->net_idx = net_idx;
2097 req->app_idx = app_idx;
2099 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2100 __bt_hal_mesh_app_key_setup,
2101 __bt_hal_mesh_app_key_reply,
2108 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2109 bt_mesh_key_op_e op, uint16_t netkey_idx)
2114 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2118 if (op == BT_MESH_KEY_CREATE)
2119 status = __mesh_subnet_netkey_command_execute(app,
2120 netkey_idx, "CreateSubnet");
2121 else if (op == BT_MESH_KEY_DELETE)
2122 status = __mesh_subnet_netkey_command_execute(app,
2123 netkey_idx, "DeleteSubnet");
2124 else if (op == BT_MESH_KEY_UPDATE)
2125 status = __mesh_subnet_netkey_command_execute(app,
2126 netkey_idx, "UpdateSubnet");
2128 return BT_STATUS_FAIL;
2131 ERR("Mesh: app not found!!");
2132 return BT_STATUS_PARM_INVALID;
2135 return BT_STATUS_SUCCESS;
2138 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2139 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2144 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2148 if (op == BT_MESH_KEY_CREATE)
2149 status = __mesh_subnet_appkey_command_execute(app,
2150 netkey_idx, appkey_idx, "CreateAppKey");
2151 else if (op == BT_MESH_KEY_DELETE)
2152 status = __mesh_subnet_appkey_command_execute(app,
2153 netkey_idx, appkey_idx, "DeleteAppKey");
2154 else if (op == BT_MESH_KEY_UPDATE) {
2155 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2156 netkey_idx, appkey_idx);
2157 status = __mesh_subnet_appkey_command_execute(app,
2158 netkey_idx, appkey_idx, "UpdateAppKey");
2161 return BT_STATUS_FAIL;
2164 ERR("Mesh: app not found!!");
2165 return BT_STATUS_PARM_INVALID;
2168 return BT_STATUS_SUCCESS;
2171 bt_status_t _bt_hal_mesh_send_provision_data(
2172 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2176 struct l_dbus_message *msg;
2177 struct l_dbus_message *reply;
2179 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2184 reply = l_dbus_message_new_method_return(msg);
2185 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2186 l_dbus_send(dbus, reply);
2188 ERR("Mesh: app not found!!");
2189 return BT_STATUS_PARM_INVALID;
2191 return BT_STATUS_SUCCESS;
2194 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2198 l = g_slist_find_custom(mesh_apps,
2199 net_uuid->uu, __mesh_compare_network_uuid);
2202 if (!__bt_mesh_proxy_check(app)) {
2203 ERR("Mesh: Proxy check failed!!");
2204 return BT_STATUS_FAIL;
2206 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2207 "UnprovisionedScanCancel",
2208 NULL, NULL, NULL, NULL))
2209 return BT_STATUS_FAIL;
2211 ERR("Mesh: app not found!!");
2212 return BT_STATUS_PARM_INVALID;
2215 /* Stop Scan timer */
2216 if (app->scan_timer_id > 0) {
2217 g_source_remove(app->scan_timer_id);
2218 app->scan_timer_id = 0;
2221 /* Trigger Scan finished event */
2222 __mesh_trigger_scan_finished_event(app);
2224 return BT_STATUS_SUCCESS;
2227 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2228 const char *auth_value)
2231 struct l_dbus_message *reply = NULL;
2232 struct l_dbus_message_builder *builder;
2234 bt_status_t ret = BT_STATUS_SUCCESS;
2238 if (!__bt_mesh_proxy_check(0)) {
2239 ERR("Mesh: Proxy check failed!!");
2240 return BT_STATUS_FAIL;
2242 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2243 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2244 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2245 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2246 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2247 INFO("Mesh: Authentication reply: Numeric Type");
2248 val_u32 = atoi(auth_value);
2249 reply = l_dbus_message_new_method_return(agent_msg);
2250 l_dbus_message_set_arguments(reply, "u", val_u32);
2252 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2253 l_dbus_send(dbus, reply);
2254 ret = BT_STATUS_SUCCESS;
2255 /* For Alpha-Numeric */
2256 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2257 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2258 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2259 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2260 alpha = l_util_from_hexstring(auth_value, &sz);
2261 reply = l_dbus_message_new_method_return(agent_msg);
2262 builder = l_dbus_message_builder_new(reply);
2263 __mesh_append_byte_array(builder, alpha, 16);
2264 l_dbus_message_builder_finalize(builder);
2265 l_dbus_message_builder_destroy(builder);
2268 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2269 l_dbus_send(dbus, reply);
2270 ret = BT_STATUS_SUCCESS;
2275 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2276 bt_hal_mesh_scan_param_t *param)
2280 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2283 if (!__bt_mesh_proxy_check(app)) {
2284 ERR("Mesh: Proxy check failed!!");
2285 return BT_STATUS_FAIL;
2287 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2288 __mesh_scan_setup, __mesh_scan_reply,
2289 L_UINT_TO_PTR(param->scan_time), NULL))
2290 return BT_STATUS_FAIL;
2292 ERR("Mesh: app not found!!");
2293 return BT_STATUS_PARM_INVALID;
2295 return BT_STATUS_SUCCESS;
2298 bt_status_t _bt_hal_mesh_network_destroy(bt_uuid_t *net_uuid)
2302 INFO("Mesh: Destroy network");
2303 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2306 if (!__bt_mesh_proxy_check(app)) {
2307 ERR("Mesh: Proxy check failed!!");
2308 return BT_STATUS_FAIL;
2310 INFO("Mesh: Create New Network");
2311 /* Create CFG Network */
2312 if (!l_dbus_proxy_method_call(net_proxy, "Leave",
2313 __bt_hal_mesh_leave_net_setup,
2314 __bt_hal_mesh_leave_net_reply, app,
2316 ERR("Mesh: Network Leave failed!!");
2317 return BT_STATUS_FAIL;
2320 ERR("Mesh: App not found!!");
2321 return BT_STATUS_PARM_INVALID;
2323 INFO("Mesh: Network Leave Call issued successfully!!");
2324 return BT_STATUS_SUCCESS;
2327 bt_status_t _bt_hal_mesh_create_network(
2328 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2332 INFO("Mesh: Create Network Request");
2334 if (!__bt_mesh_proxy_check(0)) {
2335 ERR("Mesh: Proxy check failed!!");
2336 return BT_STATUS_FAIL;
2339 INFO("Mesh: Node Element count [%d]", node->num_elements);
2340 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2341 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2342 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2343 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2344 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2345 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2346 /* Create DBUS APP */
2347 app = __bt_hal_mesh_create_app(node, models, is_prov);
2349 return BT_STATUS_FAIL;
2351 /* Register DBUS APP */
2352 if (!__bt_hal_mesh_register_application(app))
2355 if (app->token.u64 == 0) {
2356 INFO("Mesh: Create New Network");
2357 /* Create CFG Network */
2358 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2359 __bt_hal_mesh_create_net_setup,
2360 __bt_hal_mesh_create_net_reply, app,
2362 ERR("Mesh: Network Create failed!!");
2366 INFO("Mesh: Attach Node to Network");
2367 /* Attach to Network */
2368 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2369 __bt_hal_mesh_attach_node_setup,
2370 __bt_hal_mesh_attach_node_reply,
2373 ERR("Mesh: Node attach failed!!");
2378 INFO("Mesh: Node registration request scheudled");
2379 mesh_apps = g_slist_append(mesh_apps, app);
2380 INFO("Mesh: Total number of apps in list [%d]",
2381 g_slist_length(mesh_apps));
2382 return BT_STATUS_SUCCESS;
2384 ERR("Mesh: network can not be created!!");
2385 __bt_hal_mesh_destroy_app_object(app);
2386 return BT_STATUS_FAIL;
2389 static void __bt_hal_mesh_config_send(
2390 struct l_dbus_message *msg, void *user_data)
2392 struct configuration_request *req = user_data;
2393 struct l_dbus_message_builder *builder;
2395 builder = l_dbus_message_builder_new(msg);
2397 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2398 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2399 if (req->is_dev_key)
2400 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2402 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2403 __mesh_append_byte_array(builder, req->data, req->len);
2404 l_dbus_message_builder_finalize(builder);
2405 l_dbus_message_builder_destroy(builder);
2408 static void __bt_hal_mesh_key_config_send(
2409 struct l_dbus_message *msg, void *user_data)
2411 struct key_config_request *req = user_data;
2412 struct l_dbus_message_builder *builder;
2414 builder = l_dbus_message_builder_new(msg);
2416 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2417 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2418 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2419 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2420 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2421 l_dbus_message_builder_finalize(builder);
2422 l_dbus_message_builder_destroy(builder);
2425 static void __bt_hal_mesh_model_execute_message(
2426 struct l_dbus_message *msg, void *user_data)
2428 struct configuration_request *req = user_data;
2429 struct l_dbus_message_builder *builder;
2431 builder = l_dbus_message_builder_new(msg);
2433 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2434 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2435 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2436 __mesh_append_byte_array(builder, req->data, req->len);
2437 l_dbus_message_builder_finalize(builder);
2438 l_dbus_message_builder_destroy(builder);
2441 bt_status_t _bt_hal_mesh_send_key_config_message(
2442 bt_uuid_t *network, uint16_t dest,
2443 bool is_netkey, bool is_update,
2444 uint16_t key_idx, uint16_t netkey_idx)
2448 struct key_config_request *req;
2451 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2452 /* Source is Config Client Local Node */
2453 int src_elem_idx = 0;
2454 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2457 if (!__bt_mesh_proxy_check(app)) {
2458 ERR("Mesh: Proxy check failed!!");
2459 return BT_STATUS_FAIL;
2461 l1 = g_slist_find_custom(app->elements,
2462 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2464 return BT_STATUS_FAIL;
2467 req = l_new(struct key_config_request, 1);
2468 req->ele_path = elem->path;
2470 req->key_req_idx = key_idx;
2471 req->idx = netkey_idx; /* Encryption Key index */
2472 req->update_req = is_update;
2474 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2475 __bt_hal_mesh_key_config_send, NULL,
2476 (void*)req, l_free))
2477 return BT_STATUS_FAIL;
2479 ERR("Mesh: app not found!!");
2480 return BT_STATUS_PARM_INVALID;
2483 return BT_STATUS_SUCCESS;
2486 bt_status_t _bt_hal_mesh_send_configuration_message(
2487 bt_uuid_t *network, uint16_t dest,
2488 bool is_dev_key, uint16_t netkey_idx,
2489 uint8_t *buf, int len)
2493 struct configuration_request *req;
2496 int src_elem_idx = 0;
2497 l = g_slist_find_custom(mesh_apps, network->uu,
2498 __mesh_compare_network_uuid);
2501 if (!__bt_mesh_proxy_check(app)) {
2502 ERR("Mesh: Proxy check failed!!");
2503 return BT_STATUS_FAIL;
2505 l1 = g_slist_find_custom(app->elements,
2506 GUINT_TO_POINTER(src_elem_idx),
2507 __compare_element_index);
2509 return BT_STATUS_FAIL;
2512 req = l_new(struct configuration_request, 1);
2513 req->ele_path = elem->path;
2515 req->idx = netkey_idx;
2519 req->is_dev_key = is_dev_key;
2521 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2522 __bt_hal_mesh_config_send, NULL,
2523 (void*)req, l_free))
2524 return BT_STATUS_FAIL;
2526 ERR("Mesh: app not found!!");
2527 return BT_STATUS_PARM_INVALID;
2530 return BT_STATUS_SUCCESS;
2533 bt_status_t _bt_hal_mesh_model_execute_message(
2534 bt_uuid_t *network, uint16_t dest,
2535 uint16_t appkey_idx, uint8_t *buf, int len)
2539 struct configuration_request *req;
2542 int src_elem_idx = 0;
2543 l = g_slist_find_custom(mesh_apps, network->uu,
2544 __mesh_compare_network_uuid);
2547 if (!__bt_mesh_proxy_check(app)) {
2548 ERR("Mesh: Proxy check failed!!");
2549 return BT_STATUS_FAIL;
2551 l1 = g_slist_find_custom(app->elements,
2552 GUINT_TO_POINTER(src_elem_idx),
2553 __compare_element_index);
2555 return BT_STATUS_FAIL;
2558 req = l_new(struct configuration_request, 1);
2559 req->ele_path = elem->path;
2561 req->idx = appkey_idx;
2565 req->is_dev_key = false;
2567 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2568 __bt_hal_mesh_model_execute_message,
2569 NULL, (void*)req, l_free))
2570 return BT_STATUS_FAIL;
2572 ERR("Mesh: app not found!!");
2573 return BT_STATUS_PARM_INVALID;
2576 return BT_STATUS_SUCCESS;