4 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
6 * @author: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
33 #include "bt-hal-mesh-dbus-handler.h"
34 #include "bt-hal-dbus-common-utils.h"
35 #include "bt-hal-internal.h"
37 #include <hardware/bt_mesh.h>
39 #define BT_HAL_UUID_LEN 16
40 #define BT_HAL_BLUEZ_MESH_NAME "org.bluez.mesh"
42 #define BT_HAL_MESH_NETWORK_INTERFACE "org.bluez.mesh.Network1"
43 #define BT_HAL_MESH_NODE_INTERFACE "org.bluez.mesh.Node1"
44 #define BT_HAL_MESH_MANAGEMENT_INTERFACE "org.bluez.mesh.Management1"
45 #define BT_HAL_MESH_ELEMENT_INTERFACE "org.bluez.mesh.Element1"
46 #define BT_HAL_MESH_APPLICATION_INTERFACE "org.bluez.mesh.Application1"
47 #define BT_HAL_MESH_PROVISION_AGENT_INTERFACE "org.bluez.mesh.ProvisionAgent1"
48 #define BT_HAL_MESH_PROVISIONER_INTERFACE "org.bluez.mesh.Provisioner1"
49 #define BT_HAL_MESH_ERROR_INTERFACE "org.bluez.mesh.Error"
51 #define BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE 2048
53 static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs";
54 static const char *dbus_err_fail = "org.freedesktop.DBus.Error.Failed";
56 static struct l_dbus *dbus = NULL;
57 static struct l_dbus_client *client = NULL;
59 static struct l_dbus_proxy *net_proxy = NULL;
60 static struct l_dbus_message *agent_msg;
62 static handle_stack_msg mesh_event_cb = NULL;
65 struct subnet_key_request {
70 struct app_key_request {
76 struct configuration_request {
86 struct key_config_request {
94 struct mesh_provision_auth_action {
96 bt_hal_mesh_auth_variant_e auth_type;
99 static struct mesh_provision_auth_action auth_table[] = {
100 { "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
101 { "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
102 { "vibrate", BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT},
103 { "in-numeric", BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT},
104 { "in-alpha", BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT},
105 { "twist", BT_HAL_MESH_AUTH_TWIST_COUNT_DISPLAY},
106 { "push", BT_HAL_MESH_AUTH_PUSH_COUNT_DISPLAY},
107 { "out-numeric", BT_HAL_MESH_AUTH_NUMERIC_DISPLAY},
108 { "out-alpha", BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY},
109 { "static-oob", BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT},
110 { "unknown", BT_HAL_MESH_UNKNOWN_AUTH_METHOD},
114 static uint8_t __bt_mesh_util_get_prov_error_code(char *prov_err_str)
118 if (!g_strcmp0(prov_err_str, "success"))
119 ret = BT_HAL_MESH_PROV_ERR_SUCCESS;
120 else if (!g_strcmp0(prov_err_str, "bad-pduread"))
121 ret = BT_HAL_MESH_PROV_ERR_INVALID_PDU;
122 else if (!g_strcmp0(prov_err_str, "confirmation-failed"))
123 ret = BT_HAL_MESH_PROV_ERR_CONFIRM_FAILED;
124 else if (!g_strcmp0(prov_err_str, "out-of-resources"))
125 ret = BT_HAL_MESH_PROV_ERR_INSUF_RESOURCE;
126 else if (!g_strcmp0(prov_err_str, "decryption-error"))
127 ret = BT_HAL_MESH_PROV_ERR_DECRYPT_FAILED;
128 else if (!g_strcmp0(prov_err_str, "cannot-assign-addresses"))
129 ret = BT_HAL_MESH_PROV_ERR_CANT_ASSIGN_ADDR;
130 else if (!g_strcmp0(prov_err_str, "timeout"))
131 ret = BT_HAL_MESH_PROV_ERR_TIMEOUT;
132 else if (!g_strcmp0(prov_err_str, "unexpected-error"))
133 ret = BT_HAL_MESH_PROV_ERR_UNEXPECTED_ERR;
138 static bt_hal_mesh_auth_variant_e __mesh_get_authentication_type(char *str)
140 int len = strlen(str);
141 int sz = L_ARRAY_SIZE(auth_table);
144 for (i = 0; i < sz; ++i)
145 if (len == strlen(auth_table[i].action) &&
146 !strcmp(str, auth_table[i].action))
149 return auth_table[i].auth_type;
151 ERR("Mesh : Not A Proper Authentication Type!");
152 return BT_HAL_MESH_UNKNOWN_AUTH_METHOD;
156 enum mesh_dbus_interface_e {
163 typedef enum mesh_dbus_interface_e mesh_dbus_interface_e;
165 struct meshcfg_model {
170 typedef struct meshcfg_model meshcfg_model;
178 typedef struct meshcfg_el meshcfg_el;
181 /* Remember Proxies & dbus paths */
184 struct l_dbus_proxy *proxy;
185 struct l_dbus_proxy *mgmt_proxy;
187 /* Local node Info */
204 struct l_dbus_message *msg;
208 typedef struct meshcfg_app meshcfg_app;
210 /* Will contain critical data related to local Mesh Network */
211 static GSList *mesh_apps = NULL;
214 struct meshcfg_node {
216 struct l_dbus_proxy *proxy;
217 struct l_dbus_proxy *mgmt_proxy;
224 typedef struct meshcfg_node meshcfg_node;
226 static void __mesh_append_byte_array(struct l_dbus_message_builder *builder,
227 unsigned char *data, unsigned int len)
231 l_dbus_message_builder_enter_array(builder, "y");
233 for (i = 0; i < len; i++)
234 l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
236 l_dbus_message_builder_leave_array(builder);
239 static gint __mesh_compare_network_uuid(gconstpointer data, gconstpointer user_data)
241 const meshcfg_app *app = (meshcfg_app*) data;
243 memcpy(uuid, (uint8_t*) user_data, 16);
245 return memcmp(uuid, app->uuid, sizeof(bt_uuid_t));
248 static unsigned char* __mesh_get_net_uuid_from_dbus_proxy_path(
249 const char *dbus_path)
254 memcpy(uuid, (void*)&dbus_path[20], sizeof(uuid));
256 INFO("Mesh: Net UUID string [%s]", uuid);
257 return l_util_from_hexstring(uuid, &sz);
260 static unsigned char* __mesh_get_net_uuid_from_path(
261 const char *dbus_path, bool is_prov,
262 mesh_dbus_interface_e iface)
269 case MESH_PROV_IFACE: {
270 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
272 return l_util_from_hexstring(uuid, &sz);
274 case MESH_AGENT_IFACE: {
275 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[23], 32);
277 return l_util_from_hexstring(uuid, &sz);
279 case MESH_ELEMENT_IFACE: {
280 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
282 return l_util_from_hexstring(uuid, &sz);
289 static void __mesh_hal_free_elements(gpointer data)
291 meshcfg_el *element = (meshcfg_el*) data;
294 g_free(element->path);
296 g_slist_free_full(element->models, g_free);
298 element->models = NULL;
302 static bool __bt_mesh_proxy_check(meshcfg_app *app)
304 /* Check meshd stack Vis up or not */
306 ERR("Mesh: DBUS is not UP!, possibly stack not Up!");
309 /* Check Network Proxy is added or not */
311 ERR("Mesh: Network proxy is not attached yet!");
316 /* Check App management proxyis added or not */
317 if (!app->mgmt_proxy) {
318 ERR("Mesh: Network proxy is not attached yet!");
321 /* Check App Node Proxy is added or not */
323 ERR("Mesh: Node proxy is not attached yet!");
330 static void __bt_hal_mesh_destroy_app_object(gpointer data)
333 meshcfg_app *app = (meshcfg_app*) data;
337 mesh_apps = g_slist_remove(mesh_apps, app);
340 INFO("Mesh: App path [%s] ", app->path);
343 if (app->agent_path) {
344 INFO("Mesh: Agent Path [%s]", app->agent_path);
345 g_free(app->agent_path);
349 INFO("Mesh: Total elements present in app [%d]",
350 g_slist_length(app->elements));
351 g_slist_free_full(app->elements, __mesh_hal_free_elements);
356 static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
358 ERR("MESH: D-Bus client connected\n");
361 INFO("Mesh: MeshD connected: dbus [%p]", dbus);
364 static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
366 ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
367 /* TODO: Send event to app about meshd termination & then remove all mesh apps */
368 INFO("Mesh: Total number of networks present [%d]",
369 g_slist_length(mesh_apps));
372 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
375 /* Set DBUS to NULL */
377 INFO("Mesh: dbus [%p]", dbus);
379 INFO("Mesh: net proxy [%p]", net_proxy);
383 INFO("Mesh: All apps cleaned up after meshd exited");
386 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
390 const meshcfg_app *app = (meshcfg_app*) data;
391 char *path = (char *) user_data;
392 INFO("Mesh: proxy path compare: path [%s]", path);
393 INFO("Mesh: App Path path [%s]", app->path);
397 app_uuid_path = l_util_hexstring(app->uuid, 16);
398 INFO("Mesh:App UUID string [%s]", app_uuid_path);
399 char **strings = g_strsplit(path, "node", 2);
401 INFO("Mesh:String 0 [%s]", strings[0]);
402 INFO("Mesh:String 1 [%s]", strings[1]);
403 ret = g_strcmp0(strings[1], app_uuid_path);
406 l_free(app_uuid_path);
410 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
412 const meshcfg_el *elem = data;
413 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
417 return (elem->index == elem_index ? 0: -1);
420 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
422 const char *interface = l_dbus_proxy_get_interface(proxy);
423 const char *path = l_dbus_proxy_get_path(proxy);
425 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
427 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
428 INFO("Mesh: Network Proxy added");
429 /* Save Global proxy */
432 INFO("Mesh: Net Proxy [%p]", net_proxy);
436 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
439 INFO("Mesh: Mgmt Proxy added");
440 INFO("Mesh: Number of mesh app present in list [%d]",
441 g_slist_length(mesh_apps));
442 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
445 app->mgmt_proxy = proxy;
447 ERR("Mesh: app not found for Mgmt proxy");
452 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
453 INFO("Mesh: Node Proxy added");
456 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
461 ERR("Mesh: app not found for Node proxy");
467 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
469 const char *interface = l_dbus_proxy_get_interface(proxy);
470 const char *path = l_dbus_proxy_get_path(proxy);
472 INFO("Proxy removed: %s (%s)\n", interface, path);
474 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
475 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
476 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
478 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
482 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
483 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
486 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
489 /*TODO: Send event to app about removal of a mesh local node */
490 __bt_hal_mesh_destroy_app_object(app);
492 ERR("Mesh: app not found for Mgmt proxy");
495 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
496 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
499 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
502 /*TODO: Send event to app about removal of
503 a mesh local node: first send event, then destroy mesh object */
504 __bt_hal_mesh_destroy_app_object(app);
506 ERR("Mesh: app not found for Mgmt proxy");
512 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
515 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
519 static void __mesh_ready_callback(void *user_data)
521 INFO("Mesh: Connected to D-Bus\n");
522 if (!l_dbus_object_manager_enable(dbus, "/"))
523 ERR("Mesh: Failed to register the ObjectManager\n");
526 bool _bt_hal_mesh_stack_init(void)
528 INFO("Mesh: Connect with meshd");
529 /* Connect with meshd */
530 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
534 INFO("Mesh: Got dbus [%p]", dbus);
536 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
539 client = l_dbus_client_new(dbus,
540 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
544 if (!l_dbus_client_set_connect_handler(client,
545 __mesh_client_connected, NULL, NULL))
548 if (!l_dbus_client_set_disconnect_handler(client,
549 __mesh_client_disconnected, NULL,
552 if (!l_dbus_client_set_proxy_handlers(client,
553 __mesh_proxy_added, __mesh_proxy_removed,
556 if (!l_dbus_client_set_ready_handler(client,
557 __mesh_dbus_client_ready, NULL, NULL))
560 INFO("Mesh: Stack Init watchers registered with meshd");
564 /* To send stack event to hal-mesh handler */
565 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
570 /* To send stack event to hal-mesh handler */
571 void _bt_hal_mesh_unregister_dbus_handler_cb()
573 mesh_event_cb = NULL;
576 static bool __mesh_get_companyid(struct l_dbus *dbus,
577 struct l_dbus_message *message,
578 struct l_dbus_message_builder *builder,
581 meshcfg_app *app = (meshcfg_app*) user_data;
585 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
590 static bool __mesh_get_productid(struct l_dbus *dbus,
591 struct l_dbus_message *message,
592 struct l_dbus_message_builder *builder,
595 meshcfg_app *app = (meshcfg_app*) user_data;
598 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
603 static bool __mesh_get_versionid(struct l_dbus *dbus,
604 struct l_dbus_message *message,
605 struct l_dbus_message_builder *builder,
608 meshcfg_app *app = (meshcfg_app*) user_data;
611 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
616 static bool __mesh_get_crpl(struct l_dbus *dbus,
617 struct l_dbus_message *message,
618 struct l_dbus_message_builder *builder,
621 meshcfg_app *app = (meshcfg_app*) user_data;
624 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
629 static void __send_network_attach_event(void *param, uint8_t status)
631 struct hal_ev_mesh_network_attached ev;
632 meshcfg_app *app = (meshcfg_app*)param;
634 memset(&ev, 0, sizeof(ev));
635 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
636 memcpy(ev.token, app->token.u8, 8);
640 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
641 (void*)&ev, sizeof(ev));
644 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
645 struct l_dbus_message *msg, void *user_data)
647 struct l_dbus_message_iter iter_cfg;
649 meshcfg_app *app = (meshcfg_app*) user_data;
650 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
651 app->path, app->agent_path);
653 if (l_dbus_message_is_error(msg)) {
655 l_dbus_message_get_error(msg, &name, NULL);
656 ERR("Mesh: Failed to attach node: %s", name);
661 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
665 INFO("Mesh: Attached with path %s\n", app->path);
666 __send_network_attach_event(app, BT_STATUS_SUCCESS);
669 __send_network_attach_event(app, BT_STATUS_FAIL);
670 /* Destroy mesh app object */
671 __bt_hal_mesh_destroy_app_object(app);
674 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
677 meshcfg_app *app = (meshcfg_app*) user_data;
679 l_dbus_message_set_arguments(msg, "ot", app->path,
680 l_get_be64(app->token.u8));
684 static void __bt_hal_mesh_attach_node(void *user_data)
686 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
687 __bt_hal_mesh_attach_node_setup,
688 __bt_hal_mesh_attach_node_reply,
691 ERR("Mesh: Node attach failed!!");
692 /* Node could not be attached */
693 __send_network_attach_event(user_data, BT_STATUS_FAIL);
694 /* Destroy mesh app object */
695 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
699 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
700 struct l_dbus_message *message,
706 meshcfg_app *app = (meshcfg_app*) user_data;
707 INFO("Mesh: Join Complete");
710 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
712 /* Send Network creation fail event */
713 __send_network_attach_event(app, BT_STATUS_FAIL);
715 /* Destroy mesh app object */
716 __bt_hal_mesh_destroy_app_object(app);
718 return l_dbus_message_new_error(message, dbus_err_args, NULL);
722 app->token.u64 = l_get_be64(&tmp);
723 str = l_util_hexstring(&app->token.u8[0], 8);
724 INFO("Mesh: Created new node with token %s\n", str);
727 /* Authenticate the node */
728 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
729 return l_dbus_message_new_method_return(message);
732 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
735 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
736 meshcfg_model *model_info = (meshcfg_model*) data;
738 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
741 static bool __mesh_model_getter(struct l_dbus *dbus,
742 struct l_dbus_message *message,
743 struct l_dbus_message_builder *builder,
746 meshcfg_el *element = (meshcfg_el*) user_data;
748 l_dbus_message_builder_enter_array(builder, "q");
749 g_slist_foreach(element->models,
750 __bt_hal_mesh_foreach_model_getter, builder);
752 l_dbus_message_builder_leave_array(builder);
757 /*TODO: Vendor Model handling is currently not Handled */
758 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
759 struct l_dbus_message *message,
760 struct l_dbus_message_builder *builder,
763 l_dbus_message_builder_enter_array(builder, "(qq)");
764 l_dbus_message_builder_leave_array(builder);
769 static bool __mesh_element_index_getter(struct l_dbus *dbus,
770 struct l_dbus_message *message,
771 struct l_dbus_message_builder *builder,
774 meshcfg_el *element = (meshcfg_el*) user_data;
775 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
781 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
782 struct l_dbus_message *msg, void *user_data)
784 struct l_dbus_message_iter iter;
789 const char *dbus_path;
792 dbus_path = l_dbus_message_get_path(msg);
793 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
794 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
795 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
797 INFO("Mesh: app path [%s]", dbus_path);
799 memset(buf, 0, sizeof(buf));
800 size = (uint16_t) sizeof(*ev);
801 memcpy(ev->net_uuid, net_uuid, 16);
804 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
806 ERR("Mesh: Cannot parse received message");
807 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
810 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
811 ERR("Mesh: Cannot parse received message: data");
812 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
815 INFO("Mesh: Received dev key message (len %u):", n);
816 ev->source_addr = src;
817 ev->is_remote_devkey = rmt;
818 ev->netkey_idx = idx;
820 memcpy(ev->data, data, n);
823 INFO("Mesh: Src [0x%2.2x]", src);
824 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
825 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
826 /* Send DevKeyMessage Received event */
828 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
830 return l_dbus_message_new_method_return(msg);
833 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
835 INFO("Mesh: Setup element interface properties & methods");
837 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
839 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
840 __mesh_vendor_model_getter, NULL);
841 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
844 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
845 __mesh_device_message_received, "", "qbqay", "source",
846 "remote", "net_index", "data");
847 /* TODO: Other methods */
850 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
851 struct l_dbus_message *msg,
854 struct l_dbus_message_iter iter, opts;
855 meshcfg_app *app = (meshcfg_app*) user_data;
860 const char *sig = "naya{sv}";
862 /* Find network uuid from dbus path */
863 struct hal_ev_mesh_scan_result ev;
865 if (!app->scan_timer_id) {
866 /* Scan is not running */
867 INFO("Got scan result, but scan is already stopped");
868 return l_dbus_message_new_method_return(msg);
870 memset(&ev, 0, sizeof(ev));
871 memcpy(ev.net_uuid, app->uuid, 16);
873 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
874 ERR("Mesh: Cannot parse scan results");
875 ev.status = BT_STATUS_FAIL;
877 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
879 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
882 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
884 ERR("Mesh: Cannot parse scan result: data");
885 ev.status = BT_STATUS_FAIL;
887 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
889 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
892 INFO("Mesh: Scan result:\n");
893 INFO("Mesh: Scan rssi = [%d]\n", rssi);
894 str = l_util_hexstring_upper(prov_data, 16);
895 INFO("Mesh: Scan UUID = [%s]\n", str);
899 str = l_util_hexstring_upper(prov_data + 16, 2);
900 INFO("Mesh: Scan OOB = [%s]\n", str);
905 str = l_util_hexstring_upper(prov_data + 18, 4);
906 INFO("Mesh: Scan URI hash = [%s]\n", str);
910 /* 16 octet Dev UUID */
911 memcpy(ev.dev_uuid, prov_data, 16);
913 /* 2 octet Dev OOB Info */
914 memcpy(ev.oob_info, prov_data + 16, 2);
916 /* 4 octet URI Hash */
917 memcpy(ev.uri_hash, prov_data + 18, 4);
921 ev.status = BT_STATUS_SUCCESS;
923 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
924 (void*)&ev, sizeof(ev));
926 return l_dbus_message_new_method_return(msg);
929 static struct l_dbus_message *__mesh_request_provisioner_call(
931 struct l_dbus_message *msg,
935 struct hal_ev_mesh_provision_finished ev;
936 struct hal_ev_mesh_provision_data_request req;
938 meshcfg_app *app = user_data;
940 INFO("Mesh: provisioning data requested app path [%s]",
942 uuid_string = l_util_hexstring(app->uuid, 16);
943 INFO("Mesh: Network UUID [%s]", uuid_string);
945 memset(&ev, 0, sizeof(ev));
946 memset(&req, 0, sizeof(req));
947 memcpy(ev.net_uuid, app->uuid, 16);
948 memcpy(req.net_uuid, app->uuid, 16);
951 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
952 ERR("Mesh: Cannot parse request for prov data");
954 ev.status = BT_STATUS_FAIL;
955 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
957 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
958 (void*)&ev, sizeof(ev));
959 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
965 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
966 (void*)&req, sizeof(req));
968 l_dbus_message_ref(msg);
972 static struct l_dbus_message *__mesh_node_add_completed(
974 struct l_dbus_message *msg,
977 struct l_dbus_message_iter iter;
982 struct hal_ev_mesh_provision_finished ev;
983 const char *dbus_path;
985 dbus_path = l_dbus_message_get_path(msg);
986 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
987 true, MESH_PROV_IFACE);
989 INFO("Mesh: app path [%s]", dbus_path);
991 memset(&ev, 0, sizeof(ev));
992 memcpy(ev.net_uuid, net_uuid, 16);
996 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
997 ERR("Mesh: Cannot parse add node complete message");
999 ev.status = BT_STATUS_FAIL;
1000 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1002 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1003 (void*)&ev, sizeof(ev));
1004 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1007 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1009 ERR("Mesh: Cannot parse add node complete message: uuid");
1011 ev.status = BT_STATUS_FAIL;
1012 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1014 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1015 (void*)&ev, sizeof(ev));
1016 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1020 ev.status = BT_STATUS_SUCCESS;
1021 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1022 memcpy(ev.dev_uuid, uuid, 16);
1023 ev.unicast = unicast;
1027 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1028 (void*)&ev, sizeof(ev));
1030 return l_dbus_message_new_method_return(msg);
1033 static struct l_dbus_message *__mesh_node_add_failed(
1034 struct l_dbus *dbus,
1035 struct l_dbus_message *msg,
1038 struct l_dbus_message_iter iter;
1042 struct hal_ev_mesh_provision_finished ev;
1043 const char *dbus_path;
1046 dbus_path = l_dbus_message_get_path(msg);
1047 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1048 true, MESH_PROV_IFACE);
1050 memset(&ev, 0, sizeof(ev));
1051 memcpy(ev.net_uuid, net_uuid, 16);
1054 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1055 ERR("Mesh: Cannot parse add node failed message");
1057 ev.status = BT_STATUS_FAIL;
1058 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1060 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1061 (void*)&ev, sizeof(ev));
1062 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1065 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1067 ERR("Mesh:Cannot parse add node failed message: uuid");
1068 ev.status = BT_STATUS_FAIL;
1069 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1071 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1072 (void*)&ev, sizeof(ev));
1073 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1076 INFO("Mesh: Provisioning failed:\n");
1077 str = l_util_hexstring_upper(uuid, 16);
1078 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1081 ev.status = BT_STATUS_FAIL;
1082 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1083 memcpy(ev.dev_uuid, uuid, 16);
1086 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1087 (void*)&ev, sizeof(ev));
1089 return l_dbus_message_new_method_return(msg);
1092 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1094 INFO("Mesh: Setup provisioner interface properties & methods");
1095 l_dbus_interface_method(interface, "ScanResult", 0,
1096 __mesh_scan_result_received, "",
1097 "naya{sv}", "rssi", "data", "options");
1099 l_dbus_interface_method(interface, "RequestProvData", 0,
1100 __mesh_request_provisioner_call,
1101 "qq", "y", "net_index", "unicast", "count");
1103 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1104 __mesh_node_add_completed, "", "ayqy",
1105 "uuid", "unicast", "count");
1107 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1108 __mesh_node_add_failed,
1109 "", "ays", "uuid", "reason");
1112 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1114 INFO("Mesh: Setup application interface properties & methods");
1116 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1117 __mesh_get_companyid,
1119 l_dbus_interface_property(iface, "VersionID", 0, "q",
1120 __mesh_get_versionid,
1122 l_dbus_interface_property(iface, "ProductID", 0, "q",
1123 __mesh_get_productid,
1125 l_dbus_interface_property(iface, "CRPL", 0, "q",
1126 __mesh_get_crpl, NULL);
1127 l_dbus_interface_method(iface, "JoinComplete", 0,
1128 __mesh_node_join_complete,
1134 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1135 struct l_dbus_message_builder *builder)
1137 if (app->in_oob & 0x08)
1138 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1139 if (app->in_oob & 0x04)
1140 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1141 if (app->in_oob & 0x02)
1142 l_dbus_message_builder_append_basic(builder, 's', "twist");
1143 if (app->in_oob & 0x01)
1144 l_dbus_message_builder_append_basic(builder, 's', "push");
1147 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1148 struct l_dbus_message_builder *builder)
1150 if (app->out_oob & 0x10)
1151 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1152 if (app->out_oob & 0x08)
1153 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1154 if (app->out_oob & 0x04)
1155 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1156 if (app->out_oob & 0x02)
1157 l_dbus_message_builder_append_basic(builder, 's', "beep");
1158 if (app->out_oob & 0x01)
1159 l_dbus_message_builder_append_basic(builder, 's', "blink");
1162 static bool __mesh_agent_capability_getter(
1163 struct l_dbus *dbus,struct l_dbus_message *message,
1164 struct l_dbus_message_builder *builder,
1169 INFO("Mesh: app path [%s]", app->path);
1170 INFO("Mesh: Agent path [%s]", app->agent_path);
1172 if (!l_dbus_message_builder_enter_array(builder, "s")) {
1176 __mesh_fill_out_capabilities(app, builder);
1177 __mesh_fill_in_capabilities(app, builder);
1179 if (app->static_oob)
1180 l_dbus_message_builder_append_basic(builder,
1184 l_dbus_message_builder_leave_array(builder);
1185 INFO("Mesh: __agent_capability_getter: Success");
1189 static struct l_dbus_message *__mesh_agent_display_string_request(
1190 struct l_dbus *dbus,
1191 struct l_dbus_message *msg,
1194 struct hal_ev_mesh_authentication_request ev;
1197 const char *dbus_path;
1200 INFO("Mesh: app path [%s]", app->path);
1201 INFO("Mesh: Agent path [%s]", app->agent_path);
1203 dbus_path = l_dbus_message_get_path(msg);
1204 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1205 true, MESH_AGENT_IFACE);
1207 INFO("Mesh: app path [%s]", dbus_path);
1209 memset(&ev, 0, sizeof(ev));
1210 memcpy(ev.net_uuid, net_uuid, 16);
1213 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1214 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1215 struct hal_ev_mesh_provision_finished ev;
1216 memset(&ev, 0, sizeof(ev));
1217 memcpy(ev.net_uuid, net_uuid, 16);
1218 ev.status = BT_STATUS_FAIL;
1219 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1221 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1222 (void*)&ev, sizeof(ev));
1226 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1229 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1230 ev.auth_type = __mesh_get_authentication_type(str);
1231 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1232 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1233 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1236 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1237 (void*)&ev, sizeof(ev));
1240 return l_dbus_message_new_method_return(msg);
1243 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1244 struct l_dbus *dbus,
1245 struct l_dbus_message *msg,
1249 struct hal_ev_mesh_authentication_request ev;
1253 const char *dbus_path;
1256 INFO("Mesh: app path [%s]", app->path);
1257 INFO("Mesh: Agent path [%s]", app->agent_path);
1259 dbus_path = l_dbus_message_get_path(msg);
1260 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1261 true, MESH_AGENT_IFACE);
1263 INFO("Mesh: app path [%s]", dbus_path);
1265 memset(&ev, 0, sizeof(ev));
1266 memcpy(ev.net_uuid, net_uuid, 16);
1269 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1270 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1271 struct hal_ev_mesh_provision_finished ev;
1272 memset(&ev, 0, sizeof(ev));
1273 memcpy(ev.net_uuid, net_uuid, 16);
1274 ev.status = BT_STATUS_FAIL;
1275 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1276 if (mesh_event_cb) {
1277 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1278 (void*)&ev, sizeof(ev));
1281 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1284 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1285 auth_value = l_strdup_printf("%u",n);
1286 ev.auth_type = __mesh_get_authentication_type(str);
1287 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1288 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1289 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1292 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1293 (void*)&ev, sizeof(ev));
1297 return l_dbus_message_new_method_return(msg);
1300 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1301 struct l_dbus *dbus,
1302 struct l_dbus_message *msg,
1305 struct hal_ev_mesh_authentication_request ev;
1308 const char *dbus_path;
1312 dbus_path = l_dbus_message_get_path(msg);
1313 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1314 true, MESH_AGENT_IFACE);
1316 INFO("Mesh: app path [%s]", dbus_path);
1318 l = g_slist_find_custom(mesh_apps, net_uuid,
1319 __mesh_compare_network_uuid);
1322 memset(&ev, 0, sizeof(ev));
1323 memcpy(ev.net_uuid, net_uuid, 16);
1326 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1327 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1329 struct hal_ev_mesh_provision_finished ev;
1330 memset(&ev, 0, sizeof(ev));
1331 memcpy(ev.net_uuid, app->uuid, 16);
1332 ev.status = BT_STATUS_FAIL;
1333 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1334 if (mesh_event_cb) {
1335 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1336 (void*)&ev, sizeof(ev));
1338 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1341 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1343 ev.auth_type = __mesh_get_authentication_type(str);
1344 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1345 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1347 l_dbus_message_ref(msg);
1349 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1350 (void*)&ev, sizeof(ev));
1355 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1356 struct l_dbus *dbus,
1357 struct l_dbus_message *msg,
1360 struct hal_ev_mesh_authentication_request ev;
1363 const char *dbus_path;
1367 dbus_path = l_dbus_message_get_path(msg);
1368 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1371 INFO("Mesh: app path [%s]", dbus_path);
1373 l = g_slist_find_custom(mesh_apps, net_uuid,
1374 __mesh_compare_network_uuid);
1377 memset(&ev, 0, sizeof(ev));
1378 memcpy(ev.net_uuid, net_uuid, 16);
1381 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1382 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1384 struct hal_ev_mesh_provision_finished ev;
1385 memset(&ev, 0, sizeof(ev));
1386 memcpy(ev.net_uuid, app->uuid, 16);
1387 ev.status = BT_STATUS_FAIL;
1388 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1390 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1391 (void*)&ev, sizeof(ev));
1392 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1395 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1397 ev.auth_type = __mesh_get_authentication_type(str);
1398 if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1399 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1401 l_dbus_message_ref(msg);
1403 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1404 (void*)&ev, sizeof(ev));
1409 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1411 INFO("Mesh: Setup Agent interface properties & methods");
1412 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1413 __mesh_agent_capability_getter,
1415 /* TODO: Other properties */
1416 l_dbus_interface_method(interface, "DisplayString", 0,
1417 __mesh_agent_display_string_request,
1419 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1420 __mesh_agent_display_numeric_request,
1421 "", "su", "type", "number");
1422 l_dbus_interface_method(interface, "PromptNumeric", 0,
1423 __mesh_agent_prompt_numeric_request,
1424 "u", "s", "number", "type");
1425 l_dbus_interface_method(interface, "PromptStatic", 0,
1426 __mesh_agent_prompt_static_request,
1427 "ay", "s", "data", "type");
1430 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1432 meshcfg_el *elem = (meshcfg_el*) data;
1433 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1434 elem->index, elem->path);
1435 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1436 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1437 ERR("Mesh: Failed to register object %s", elem->path);
1441 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1446 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1447 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1448 ERR("Mesh: Unable to register agent interface");
1452 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1453 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1454 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1455 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1459 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1460 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1461 ERR("Mesh: Failed to add interface %s",
1462 L_DBUS_INTERFACE_PROPERTIES);
1469 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1477 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1478 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1479 ERR("Mesh: Failed to register interface %s",
1480 BT_HAL_MESH_APPLICATION_INTERFACE);
1484 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1485 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1486 ERR("Mesh: Failed to register interface %s",
1487 BT_HAL_MESH_PROVISIONER_INTERFACE);
1491 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1492 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1493 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1495 ERR("Mesh: Failed to register object %s", ptr->path);
1499 if (!__bt_hal_mesh_register_agent(ptr))
1502 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1503 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1504 ERR("Mesh: Failed to register interface %s",
1505 BT_HAL_MESH_ELEMENT_INTERFACE);
1509 INFO("Mesh: Number of elements to be registsred [%d]",
1510 g_slist_length(ptr->elements));
1512 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1514 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1515 if (!l_dbus_object_add_interface(dbus, ptr->path,
1516 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1517 ERR("Mesh: Failed to add interface %s",
1518 L_DBUS_INTERFACE_OBJECT_MANAGER);
1521 INFO("Mesh: Application Register completed");
1526 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1530 meshcfg_model *model_info = (meshcfg_model*) data;
1531 meshcfg_app *app = (meshcfg_app*) user_data;
1533 l = g_slist_find_custom(app->elements,
1534 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1538 elem = g_malloc0(sizeof(meshcfg_el));
1539 elem->index = model_info->elem_index;
1540 elem->path = g_strdup_printf("%s/elem%u",app->path, elem->index);
1541 app->elements = g_slist_append(app->elements, elem);
1542 INFO("Mesh: Created element index [%d] path [%s]",
1543 elem->index, elem->path);
1545 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1546 model_info->model, elem->index);
1547 /* Add Model in the element */
1548 elem->models = g_slist_append(elem->models, model_info);
1549 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1550 elem->index, g_slist_length(elem->models));
1553 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1554 GSList *models, bool is_prov)
1557 meshcfg_app *app = NULL;
1558 char *uuid_str = NULL;
1560 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1562 app = g_malloc0(sizeof(meshcfg_app));
1563 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1565 app->cid = node->vendor_info.companyid;
1566 app->pid = node->vendor_info.vendorid;
1567 app->vid = node->vendor_info.versionid;
1568 app->crpl = node->vendor_info.crpl;
1571 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1572 app->agent_path = g_strdup_printf("%s/agent", app->path);
1575 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1576 app->agent_path = g_strdup_printf("%s/agent", app->path);
1578 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1581 app->is_prov = is_prov;
1582 INFO("Mesh: app created");
1586 static void __bt_hal_mesh_create_net_reply(
1587 struct l_dbus_proxy *proxy,
1588 struct l_dbus_message *msg, void *user_data)
1591 app = (meshcfg_app*) user_data;
1593 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1594 if (l_dbus_message_is_error(msg)) {
1597 l_dbus_message_get_error(msg, &name, NULL);
1598 ERR("Mesh: Failed to create network: %s", name);
1600 /* Send Network creation fail event */
1601 __send_network_attach_event(app, BT_STATUS_FAIL);
1603 /* Destroy mesh app object */
1604 __bt_hal_mesh_destroy_app_object(app);
1609 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1613 struct l_dbus_message_builder *builder;
1614 app = (meshcfg_app*) user_data;
1616 builder = l_dbus_message_builder_new(msg);
1618 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1619 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1620 __mesh_append_byte_array(builder, app->uuid, 16);
1621 l_dbus_message_builder_finalize(builder);
1622 l_dbus_message_builder_destroy(builder);
1625 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1627 struct hal_ev_mesh_scan_state_changed ev;
1629 memset(&ev, 0, sizeof(ev));
1630 memcpy(ev.net_uuid, app->uuid, 16);
1632 ev.status = BT_STATUS_SUCCESS;
1634 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1636 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1637 (void*)&ev, sizeof(ev));
1640 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1642 meshcfg_app *app = (meshcfg_app*) user_data;
1643 __mesh_trigger_scan_finished_event(app);
1647 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1651 l = g_slist_find_custom(mesh_apps, net_uuid,
1652 __mesh_compare_network_uuid);
1655 if (app->scan_timer_id > 0) {
1656 g_source_remove(app->scan_timer_id);
1657 app->scan_timer_id = 0;
1660 app->scan_timer_id = g_timeout_add_seconds(secs,
1661 __bt_mesh_scan_timer_cb, app);
1666 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1667 struct l_dbus_message *msg, void *user_data)
1669 struct hal_ev_mesh_scan_state_changed ev;
1670 const char *dbus_path;
1672 dbus_path = l_dbus_proxy_get_path(proxy);
1673 INFO("Mesh: DBUS path [%s]", dbus_path);
1674 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1676 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1677 INFO("Mesh: Scan duration [%u]", secs);
1679 memset(&ev, 0, sizeof(ev));
1680 memcpy(ev.net_uuid, net_uuid, 16);
1682 if (l_dbus_message_is_error(msg)) {
1684 l_dbus_message_get_error(msg, &name, NULL);
1685 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1686 ev.status = BT_STATUS_FAIL;
1688 INFO("Mesh: Unprovisioned scan started\n");
1689 ev.status = BT_STATUS_SUCCESS;
1690 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1693 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1695 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1696 (void*)&ev, sizeof(ev));
1700 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1701 const char *key, const char *signature,
1707 l_dbus_message_builder_enter_dict(builder, "sv");
1708 l_dbus_message_builder_append_basic(builder, 's', key);
1709 l_dbus_message_builder_enter_variant(builder, signature);
1710 l_dbus_message_builder_append_basic(builder, signature[0], data);
1711 l_dbus_message_builder_leave_variant(builder);
1712 l_dbus_message_builder_leave_dict(builder);
1715 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1717 struct l_dbus_message_builder *builder;
1718 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1719 INFO("Mesh: Scan duration [%u]", secs);
1721 builder = l_dbus_message_builder_new(msg);
1722 l_dbus_message_builder_enter_array(builder, "{sv}");
1723 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1724 l_dbus_message_builder_leave_array(builder);
1725 l_dbus_message_builder_finalize(builder);
1726 l_dbus_message_builder_destroy(builder);
1730 bt_status_t _bt_hal_mesh_network_set_caps(
1731 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1735 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1739 app->public_oob = caps->public_oob;
1740 app->static_oob = caps->static_oob;
1741 app->out_oob = caps->out_oob;
1742 app->in_oob = caps->in_oob;
1744 ERR("Mesh: app not found!!");
1745 return BT_STATUS_PARM_INVALID;
1748 return BT_STATUS_SUCCESS;
1751 static void __bt_hal_mesh_add_node_reply(
1752 struct l_dbus_proxy *proxy,
1753 struct l_dbus_message *msg,
1756 struct hal_ev_mesh_provision_status ev;
1757 const char *dbus_path;
1759 dbus_path = l_dbus_proxy_get_path(proxy);
1760 INFO("Mesh: DBUS path [%s]", dbus_path);
1761 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1763 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1765 INFO("Mesh: app path [%s]", dbus_path);
1767 memset(&ev, 0, sizeof(ev));
1768 memcpy(ev.net_uuid, net_uuid, 16);
1769 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1771 /* Free User data */
1772 g_free((void*)dev_uuid);
1775 if (l_dbus_message_is_error(msg)) {
1778 l_dbus_message_get_error(msg, &name, NULL);
1779 ERR("Mesh: Failed to start provisioning: %s", name);
1780 ev.status = BT_STATUS_FAIL;
1782 INFO("Mesh: Provisioning started\n");
1783 ev.status = BT_STATUS_SUCCESS;
1786 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1787 (void*)&ev, sizeof(ev));
1788 INFO("Mesh: Provisioning status sent");
1791 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1795 bt_uuid_t *dev = user_data;
1796 struct l_dbus_message_builder *builder;
1797 uuid = l_util_hexstring(dev->uu, 16);
1798 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1800 builder = l_dbus_message_builder_new(msg);
1801 __mesh_append_byte_array(builder, dev->uu, 16);
1802 l_dbus_message_builder_enter_array(builder, "{sv}");
1803 l_dbus_message_builder_leave_array(builder);
1804 l_dbus_message_builder_finalize(builder);
1805 l_dbus_message_builder_destroy(builder);
1808 bt_status_t _bt_hal_mesh_provision_device(
1809 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1814 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1817 dev = g_memdup((gpointer)dev_uuid, 16);
1818 INFO("Mesh: Schedule Add Node request to meshd");
1819 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1820 __bt_hal_mesh_add_node_setup,
1821 __bt_hal_mesh_add_node_reply,
1823 return BT_STATUS_FAIL;
1825 ERR("Mesh: app not found!!");
1826 return BT_STATUS_PARM_INVALID;
1829 return BT_STATUS_SUCCESS;
1832 static void __bt_hal_mesh_subnet_key_setup(
1833 struct l_dbus_message *msg, void *user_data)
1835 struct subnet_key_request *req = user_data;
1836 uint16_t idx = (uint16_t) req->idx;
1838 l_dbus_message_set_arguments(msg, "q", idx);
1841 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1842 struct l_dbus_message *msg, void *user_data)
1844 struct hal_ev_mesh_netkey_execute_event ev;
1845 const char *dbus_path;
1847 struct subnet_key_request *req = user_data;
1848 const char *method = req->str;
1850 dbus_path = l_dbus_proxy_get_path(proxy);
1851 INFO("Mesh: DBUS path [%s]", dbus_path);
1852 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1854 memset(&ev, 0, sizeof(ev));
1855 memcpy(ev.net_uuid, net_uuid, 16);
1856 ev.key_idx = req->idx;
1860 if (l_dbus_message_is_error(msg)) {
1863 l_dbus_message_get_error(msg, &name, NULL);
1864 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
1865 ev.status = BT_STATUS_FAIL;
1868 ev.status = BT_STATUS_SUCCESS;
1870 if (!strcmp("CreateSubnet", method)) {
1871 INFO("Mesh: Reply for CreateSubnet");
1872 ev.key_event = HAL_MESH_KEY_ADD;
1873 } else if (!strcmp("DeleteSubnet", method)) {
1874 INFO("Mesh: Reply for DeleteSubnet");
1875 ev.key_event = HAL_MESH_KEY_DELETE;
1876 } else if (!strcmp("UpdateSubnet", method)) {
1877 INFO("Mesh: Reply for UpdateSubnet");
1878 ev.key_event = HAL_MESH_KEY_UPDATE;
1882 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
1883 (void*)&ev, sizeof(ev));
1886 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
1887 uint16_t index, const char *key_execute_method)
1889 struct subnet_key_request *req;
1891 req = l_new(struct subnet_key_request, 1);
1892 req->str = key_execute_method;
1895 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1896 __bt_hal_mesh_subnet_key_setup,
1897 __bt_hal_mesh_subnet_key_reply,
1904 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
1907 struct app_key_request *req = user_data;
1908 uint16_t net_idx = (uint16_t) req->net_idx;
1909 uint16_t app_idx = (uint16_t) req->app_idx;
1911 if (g_strcmp0(req->str,"CreateAppKey") == 0)
1912 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
1914 l_dbus_message_set_arguments(msg, "q", app_idx);
1917 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
1918 struct l_dbus_message *msg, void *user_data)
1920 struct hal_ev_mesh_appkey_execute_event ev;
1921 const char *dbus_path;
1923 struct app_key_request *req = user_data;
1924 const char *method = req->str;
1926 dbus_path = l_dbus_proxy_get_path(proxy);
1927 INFO("Mesh: DBUS path [%s]", dbus_path);
1928 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1930 memset(&ev, 0, sizeof(ev));
1931 memcpy(ev.net_uuid, net_uuid, 16);
1932 ev.net_idx = req->net_idx;
1933 ev.app_idx = req->app_idx;
1937 if (l_dbus_message_is_error(msg)) {
1940 l_dbus_message_get_error(msg, &name, NULL);
1941 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
1942 ev.status = BT_STATUS_FAIL;
1944 ev.status = BT_STATUS_SUCCESS;
1946 if (!strcmp("CreateAppKey", method)) {
1947 INFO("Mesh: AppKey Create Reply");
1948 ev.key_event = HAL_MESH_KEY_ADD;
1949 } else if (!strcmp("DeleteAppKey", method)) {
1950 INFO("Mesh: AppKey Delete Reply");
1951 ev.key_event = HAL_MESH_KEY_DELETE;
1952 } else if (!strcmp("UpdateAppKey", method)) {
1953 INFO("Mesh: AppKey Update Reply");
1954 ev.key_event = HAL_MESH_KEY_UPDATE;
1958 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
1961 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
1962 uint16_t net_idx, uint16_t app_idx,
1963 const char *key_execute_method)
1965 struct app_key_request *req;
1967 req = l_new(struct app_key_request, 1);
1968 req->str = key_execute_method;
1969 req->net_idx = net_idx;
1970 req->app_idx = app_idx;
1972 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1973 __bt_hal_mesh_app_key_setup,
1974 __bt_hal_mesh_app_key_reply,
1981 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
1982 bt_mesh_key_op_e op, uint16_t netkey_idx)
1987 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1991 if (op == BT_MESH_KEY_CREATE)
1992 status = __mesh_subnet_netkey_command_execute(app,
1993 netkey_idx, "CreateSubnet");
1994 else if (op == BT_MESH_KEY_DELETE)
1995 status = __mesh_subnet_netkey_command_execute(app,
1996 netkey_idx, "DeleteSubnet");
1997 else if (op == BT_MESH_KEY_UPDATE)
1998 status = __mesh_subnet_netkey_command_execute(app,
1999 netkey_idx, "UpdateSubnet");
2001 return BT_STATUS_FAIL;
2004 ERR("Mesh: app not found!!");
2005 return BT_STATUS_PARM_INVALID;
2008 return BT_STATUS_SUCCESS;
2011 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2012 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2017 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2021 if (op == BT_MESH_KEY_CREATE)
2022 status = __mesh_subnet_appkey_command_execute(app,
2023 netkey_idx, appkey_idx, "CreateAppKey");
2024 else if (op == BT_MESH_KEY_DELETE)
2025 status = __mesh_subnet_appkey_command_execute(app,
2026 netkey_idx, appkey_idx, "DeleteAppKey");
2027 else if (op == BT_MESH_KEY_UPDATE) {
2028 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2029 netkey_idx, appkey_idx);
2030 status = __mesh_subnet_appkey_command_execute(app,
2031 netkey_idx, appkey_idx, "UpdateAppKey");
2034 return BT_STATUS_FAIL;
2037 ERR("Mesh: app not found!!");
2038 return BT_STATUS_PARM_INVALID;
2041 return BT_STATUS_SUCCESS;
2044 bt_status_t _bt_hal_mesh_send_provision_data(
2045 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2049 struct l_dbus_message *msg;
2050 struct l_dbus_message *reply;
2052 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2057 reply = l_dbus_message_new_method_return(msg);
2058 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2059 l_dbus_send(dbus, reply);
2061 ERR("Mesh: app not found!!");
2062 return BT_STATUS_PARM_INVALID;
2064 return BT_STATUS_SUCCESS;
2067 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2071 l = g_slist_find_custom(mesh_apps,
2072 net_uuid->uu, __mesh_compare_network_uuid);
2075 if (!__bt_mesh_proxy_check(app)) {
2076 ERR("Mesh: Proxy check failed!!");
2077 return BT_STATUS_FAIL;
2079 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2080 "UnprovisionedScanCancel",
2081 NULL, NULL, NULL, NULL))
2082 return BT_STATUS_FAIL;
2084 ERR("Mesh: app not found!!");
2085 return BT_STATUS_PARM_INVALID;
2088 /* Stop Scan timer */
2089 if (app->scan_timer_id > 0) {
2090 g_source_remove(app->scan_timer_id);
2091 app->scan_timer_id = 0;
2094 /* Trigger Scan finished event */
2095 __mesh_trigger_scan_finished_event(app);
2097 return BT_STATUS_SUCCESS;
2100 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2101 const char *auth_value)
2104 struct l_dbus_message *reply = NULL;
2105 struct l_dbus_message_builder *builder;
2107 bt_status_t ret = BT_STATUS_SUCCESS;
2111 if (!__bt_mesh_proxy_check(0)) {
2112 ERR("Mesh: Proxy check failed!!");
2113 return BT_STATUS_FAIL;
2115 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2116 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2117 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2118 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2119 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2120 INFO("Mesh: Authentication reply: Numeric Type");
2121 val_u32 = atoi(auth_value);
2122 reply = l_dbus_message_new_method_return(agent_msg);
2123 l_dbus_message_set_arguments(reply, "u", val_u32);
2125 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2126 l_dbus_send(dbus, reply);
2127 ret = BT_STATUS_SUCCESS;
2128 /* For Alpha-Numeric */
2129 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2130 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2131 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT ) {
2132 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2133 alpha = l_util_from_hexstring(auth_value, &sz);
2134 reply = l_dbus_message_new_method_return(agent_msg);
2135 builder = l_dbus_message_builder_new(reply);
2136 __mesh_append_byte_array(builder, alpha, 16);
2137 l_dbus_message_builder_finalize(builder);
2138 l_dbus_message_builder_destroy(builder);
2141 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2142 l_dbus_send(dbus, reply);
2143 ret = BT_STATUS_SUCCESS;
2148 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2149 bt_hal_mesh_scan_param_t *param)
2153 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2156 if (!__bt_mesh_proxy_check(app)) {
2157 ERR("Mesh: Proxy check failed!!");
2158 return BT_STATUS_FAIL;
2160 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2161 __mesh_scan_setup, __mesh_scan_reply,
2162 L_UINT_TO_PTR(param->scan_time), NULL))
2163 return BT_STATUS_FAIL;
2165 ERR("Mesh: app not found!!");
2166 return BT_STATUS_PARM_INVALID;
2168 return BT_STATUS_SUCCESS;
2171 bt_status_t _bt_hal_mesh_create_network(
2172 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2176 INFO("Mesh: Create Network Request");
2178 if (!__bt_mesh_proxy_check(0)) {
2179 ERR("Mesh: Proxy check failed!!");
2180 return BT_STATUS_FAIL;
2183 INFO("Mesh: Node Element count [%d]", node->num_elements);
2184 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2185 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2186 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2187 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2188 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2189 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2190 /* Create DBUS APP */
2191 app = __bt_hal_mesh_create_app(node, models, is_prov);
2193 return BT_STATUS_FAIL;
2195 /* Register DBUS APP */
2196 if (!__bt_hal_mesh_register_application(app)) {
2200 if (app->token.u64 == 0) {
2201 INFO("Mesh: Create New Network");
2202 /* Create CFG Network */
2203 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2204 __bt_hal_mesh_create_net_setup,
2205 __bt_hal_mesh_create_net_reply, app,
2207 ERR("Mesh: Network Create failed!!");
2211 INFO("Mesh: Attach Node to Network");
2212 /* Attach to Network */
2213 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2214 __bt_hal_mesh_attach_node_setup,
2215 __bt_hal_mesh_attach_node_reply,
2218 ERR("Mesh: Node attach failed!!");
2223 INFO("Mesh: Node registration request scheudled");
2224 mesh_apps = g_slist_append(mesh_apps, app);
2225 INFO("Mesh: Total number of apps in list [%d]",
2226 g_slist_length(mesh_apps));
2227 return BT_STATUS_SUCCESS;
2229 ERR("Mesh: network can not be created!!");
2230 __bt_hal_mesh_destroy_app_object(app);
2231 return BT_STATUS_FAIL;
2234 static void __bt_hal_mesh_config_send(
2235 struct l_dbus_message *msg, void *user_data)
2237 struct configuration_request *req = user_data;
2238 struct l_dbus_message_builder *builder;
2240 builder = l_dbus_message_builder_new(msg);
2242 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2243 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2244 if (req->is_dev_key)
2245 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2247 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2248 __mesh_append_byte_array(builder, req->data, req->len);
2249 l_dbus_message_builder_finalize(builder);
2250 l_dbus_message_builder_destroy(builder);
2253 static void __bt_hal_mesh_key_config_send(
2254 struct l_dbus_message *msg, void *user_data)
2256 struct key_config_request *req = user_data;
2257 struct l_dbus_message_builder *builder;
2259 builder = l_dbus_message_builder_new(msg);
2261 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2262 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2263 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2264 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2265 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2266 l_dbus_message_builder_finalize(builder);
2267 l_dbus_message_builder_destroy(builder);
2270 bt_status_t _bt_hal_mesh_send_key_config_message(
2271 bt_uuid_t *network, uint16_t dest,
2272 bool is_netkey, bool is_update,
2273 uint16_t key_idx, uint16_t netkey_idx)
2277 struct key_config_request *req;
2280 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2281 /* Source is Config Client Local Node */
2282 int src_elem_idx = 0;
2283 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2286 if (!__bt_mesh_proxy_check(app)) {
2287 ERR("Mesh: Proxy check failed!!");
2288 return BT_STATUS_FAIL;
2290 l1 = g_slist_find_custom(app->elements,
2291 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2293 return BT_STATUS_FAIL;
2296 req = l_new(struct key_config_request, 1);
2297 req->ele_path = elem->path;
2299 req->key_req_idx = key_idx;
2300 req->idx = netkey_idx; /* Encryption Key index */
2301 req->update_req = is_update;
2303 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2304 __bt_hal_mesh_key_config_send, NULL,
2305 (void*)req, l_free))
2306 return BT_STATUS_FAIL;
2308 ERR("Mesh: app not found!!");
2309 return BT_STATUS_PARM_INVALID;
2312 return BT_STATUS_SUCCESS;
2315 bt_status_t _bt_hal_mesh_send_configuration_message(
2316 bt_uuid_t *network, uint16_t dest,
2317 bool is_dev_key, uint16_t netkey_idx,
2318 uint8_t *buf, int len)
2322 struct configuration_request *req;
2325 int src_elem_idx = 0;
2326 l = g_slist_find_custom(mesh_apps, network->uu,
2327 __mesh_compare_network_uuid);
2330 if (!__bt_mesh_proxy_check(app)) {
2331 ERR("Mesh: Proxy check failed!!");
2332 return BT_STATUS_FAIL;
2334 l1 = g_slist_find_custom(app->elements,
2335 GUINT_TO_POINTER(src_elem_idx),
2336 __compare_element_index);
2338 return BT_STATUS_FAIL;
2341 req = l_new(struct configuration_request, 1);
2342 req->ele_path = elem->path;
2344 req->idx = netkey_idx;
2348 req->is_dev_key = is_dev_key;
2350 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2351 __bt_hal_mesh_config_send, NULL,
2352 (void*)req, l_free))
2353 return BT_STATUS_FAIL;
2355 ERR("Mesh: app not found!!");
2356 return BT_STATUS_PARM_INVALID;
2359 return BT_STATUS_SUCCESS;