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},
113 static uint8_t __bt_mesh_util_get_prov_error_code(char *prov_err_str)
117 if (!g_strcmp0(prov_err_str, "success"))
118 ret = BT_HAL_MESH_PROV_ERR_SUCCESS;
119 else if (!g_strcmp0(prov_err_str, "bad-pduread"))
120 ret = BT_HAL_MESH_PROV_ERR_INVALID_PDU;
121 else if (!g_strcmp0(prov_err_str, "confirmation-failed"))
122 ret = BT_HAL_MESH_PROV_ERR_CONFIRM_FAILED;
123 else if (!g_strcmp0(prov_err_str, "out-of-resources"))
124 ret = BT_HAL_MESH_PROV_ERR_INSUF_RESOURCE;
125 else if (!g_strcmp0(prov_err_str, "decryption-error"))
126 ret = BT_HAL_MESH_PROV_ERR_DECRYPT_FAILED;
127 else if (!g_strcmp0(prov_err_str, "cannot-assign-addresses"))
128 ret = BT_HAL_MESH_PROV_ERR_CANT_ASSIGN_ADDR;
129 else if (!g_strcmp0(prov_err_str, "timeout"))
130 ret = BT_HAL_MESH_PROV_ERR_TIMEOUT;
131 else if (!g_strcmp0(prov_err_str, "unexpected-error"))
132 ret = BT_HAL_MESH_PROV_ERR_UNEXPECTED_ERR;
137 static bt_hal_mesh_auth_variant_e __mesh_get_authentication_type(char *str)
139 int len = strlen(str);
140 int sz = L_ARRAY_SIZE(auth_table);
143 for (i = 0; i < sz; ++i)
144 if (len == strlen(auth_table[i].action) &&
145 !strcmp(str, auth_table[i].action))
148 return auth_table[i].auth_type;
151 enum mesh_dbus_interface_e {
158 typedef enum mesh_dbus_interface_e mesh_dbus_interface_e;
160 struct meshcfg_model {
165 typedef struct meshcfg_model meshcfg_model;
173 typedef struct meshcfg_el meshcfg_el;
176 /* Remember Proxies & dbus paths */
179 struct l_dbus_proxy *proxy;
180 struct l_dbus_proxy *mgmt_proxy;
182 /* Local node Info */
199 struct l_dbus_message *msg;
203 typedef struct meshcfg_app meshcfg_app;
205 /* Will contain critical data related to local Mesh Network */
206 static GSList *mesh_apps = NULL;
209 struct meshcfg_node {
211 struct l_dbus_proxy *proxy;
212 struct l_dbus_proxy *mgmt_proxy;
219 typedef struct meshcfg_node meshcfg_node;
221 static void __mesh_append_byte_array(struct l_dbus_message_builder *builder,
222 unsigned char *data, unsigned int len)
226 l_dbus_message_builder_enter_array(builder, "y");
228 for (i = 0; i < len; i++)
229 l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
231 l_dbus_message_builder_leave_array(builder);
234 static gint __mesh_compare_network_uuid(gconstpointer data, gconstpointer user_data)
236 const meshcfg_app *app = (meshcfg_app*) data;
238 memcpy(uuid, (uint8_t*) user_data, 16);
240 return memcmp(uuid, app->uuid, sizeof(bt_uuid_t));
243 static unsigned char* __mesh_get_net_uuid_from_dbus_proxy_path(
244 const char *dbus_path)
249 memcpy(uuid, (void*)&dbus_path[20], sizeof(uuid));
251 INFO("Mesh: Net UUID string [%s]", uuid);
252 return l_util_from_hexstring(uuid, &sz);
255 static unsigned char* __mesh_get_net_uuid_from_path(
256 const char *dbus_path, bool is_prov,
257 mesh_dbus_interface_e iface)
264 case MESH_PROV_IFACE: {
265 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
267 return l_util_from_hexstring(uuid, &sz);
269 case MESH_AGENT_IFACE: {
270 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[23], 32);
272 return l_util_from_hexstring(uuid, &sz);
274 case MESH_ELEMENT_IFACE: {
275 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
277 return l_util_from_hexstring(uuid, &sz);
284 static void __mesh_hal_free_elements(gpointer data)
286 meshcfg_el *element = (meshcfg_el*) data;
289 g_free(element->path);
291 g_slist_free_full(element->models, g_free);
293 element->models = NULL;
297 static bool __bt_mesh_proxy_check(meshcfg_app *app)
299 /* Check meshd stack Vis up or not */
301 ERR("Mesh: DBUS is not UP!, possibly stack not Up!");
304 /* Check Network Proxy is added or not */
306 ERR("Mesh: Network proxy is not attached yet!");
311 /* Check App management proxyis added or not */
312 if (!app->mgmt_proxy) {
313 ERR("Mesh: Network proxy is not attached yet!");
316 /* Check App Node Proxy is added or not */
318 ERR("Mesh: Node proxy is not attached yet!");
325 static void __bt_hal_mesh_destroy_app_object(gpointer data)
328 meshcfg_app *app = (meshcfg_app*) data;
332 mesh_apps = g_slist_remove(mesh_apps, app);
335 INFO("Mesh: App path [%s] ", app->path);
338 if (app->agent_path) {
339 INFO("Mesh: Agent Path [%s]", app->agent_path);
340 g_free(app->agent_path);
344 INFO("Mesh: Total elements present in app [%d]",
345 g_slist_length(app->elements));
346 g_slist_free_full(app->elements, __mesh_hal_free_elements);
351 static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
353 ERR("MESH: D-Bus client connected\n");
356 INFO("Mesh: MeshD connected: dbus [%p]", dbus);
359 static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
361 ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
362 /* TODO: Send event to app about meshd termination & then remove all mesh apps */
363 INFO("Mesh: Total number of networks present [%d]",
364 g_slist_length(mesh_apps));
367 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
370 /* Set DBUS to NULL */
372 INFO("Mesh: dbus [%p]", dbus);
374 INFO("Mesh: net proxy [%p]", net_proxy);
378 INFO("Mesh: All apps cleaned up after meshd exited");
381 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
385 const meshcfg_app *app = (meshcfg_app*) data;
386 char *path = (char *) user_data;
387 INFO("Mesh: proxy path compare: path [%s]", path);
388 INFO("Mesh: App Path path [%s]", app->path);
392 app_uuid_path = l_util_hexstring(app->uuid, 16);
393 INFO("Mesh:App UUID string [%s]", app_uuid_path);
394 char **strings = g_strsplit(path, "node", 2);
396 INFO("Mesh:String 0 [%s]", strings[0]);
397 INFO("Mesh:String 1 [%s]", strings[1]);
398 ret = g_strcmp0(strings[1], app_uuid_path);
401 l_free(app_uuid_path);
405 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
407 const meshcfg_el *elem = data;
408 uint16_t elem_index = GPOINTER_TO_UINT(user_data);
412 return (elem->index == elem_index ? 0: -1);
415 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
417 const char *interface = l_dbus_proxy_get_interface(proxy);
418 const char *path = l_dbus_proxy_get_path(proxy);
420 INFO("MESH: Proxy added: %s (%s)\n", interface, path);
422 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
423 INFO("Mesh: Network Proxy added");
424 /* Save Global proxy */
427 INFO("Mesh: Net Proxy [%p]", net_proxy);
431 if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
434 INFO("Mesh: Mgmt Proxy added");
435 INFO("Mesh: Number of mesh app present in list [%d]",
436 g_slist_length(mesh_apps));
437 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
440 app->mgmt_proxy = proxy;
442 ERR("Mesh: app not found for Mgmt proxy");
447 if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
448 INFO("Mesh: Node Proxy added");
451 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
456 ERR("Mesh: app not found for Node proxy");
462 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
464 const char *interface = l_dbus_proxy_get_interface(proxy);
465 const char *path = l_dbus_proxy_get_path(proxy);
467 INFO("Proxy removed: %s (%s)\n", interface, path);
469 if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
470 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
471 /*TODO: Send event to app about stop of Mesh service & then remove all apps */
473 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
477 } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
478 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
481 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
484 /*TODO: Send event to app about removal of a mesh local node */
485 __bt_hal_mesh_destroy_app_object(app);
487 ERR("Mesh: app not found for Mgmt proxy");
490 } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
491 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
494 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
497 /*TODO: Send event to app about removal of
498 a mesh local node: first send event, then destroy mesh object */
499 __bt_hal_mesh_destroy_app_object(app);
501 ERR("Mesh: app not found for Mgmt proxy");
507 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
510 INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
514 static void __mesh_ready_callback(void *user_data)
516 INFO("Mesh: Connected to D-Bus\n");
517 if (!l_dbus_object_manager_enable(dbus, "/"))
518 ERR("Mesh: Failed to register the ObjectManager\n");
521 bool _bt_hal_mesh_stack_init(void)
523 INFO("Mesh: Connect with meshd");
524 /* Connect with meshd */
525 dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
529 INFO("Mesh: Got dbus [%p]", dbus);
531 if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
534 client = l_dbus_client_new(dbus,
535 BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
539 if (!l_dbus_client_set_connect_handler(client,
540 __mesh_client_connected, NULL, NULL))
543 if (!l_dbus_client_set_disconnect_handler(client,
544 __mesh_client_disconnected, NULL,
547 if (!l_dbus_client_set_proxy_handlers(client,
548 __mesh_proxy_added, __mesh_proxy_removed,
551 if (!l_dbus_client_set_ready_handler(client,
552 __mesh_dbus_client_ready, NULL, NULL))
555 INFO("Mesh: Stack Init watchers registered with meshd");
559 /* To send stack event to hal-mesh handler */
560 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
565 /* To send stack event to hal-mesh handler */
566 void _bt_hal_mesh_unregister_dbus_handler_cb()
568 mesh_event_cb = NULL;
571 static bool __mesh_get_companyid(struct l_dbus *dbus,
572 struct l_dbus_message *message,
573 struct l_dbus_message_builder *builder,
576 meshcfg_app *app = (meshcfg_app*) user_data;
580 l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
585 static bool __mesh_get_productid(struct l_dbus *dbus,
586 struct l_dbus_message *message,
587 struct l_dbus_message_builder *builder,
590 meshcfg_app *app = (meshcfg_app*) user_data;
593 l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
598 static bool __mesh_get_versionid(struct l_dbus *dbus,
599 struct l_dbus_message *message,
600 struct l_dbus_message_builder *builder,
603 meshcfg_app *app = (meshcfg_app*) user_data;
606 l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
611 static bool __mesh_get_crpl(struct l_dbus *dbus,
612 struct l_dbus_message *message,
613 struct l_dbus_message_builder *builder,
616 meshcfg_app *app = (meshcfg_app*) user_data;
619 l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
624 static void __send_network_attach_event(void *param, uint8_t status)
626 struct hal_ev_mesh_network_attached ev;
627 meshcfg_app *app = (meshcfg_app*)param;
629 memset(&ev, 0, sizeof(ev));
630 memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
631 memcpy(ev.token, app->token.u8, 8);
635 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
636 (void*)&ev, sizeof(ev));
639 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
640 struct l_dbus_message *msg, void *user_data)
642 struct l_dbus_message_iter iter_cfg;
644 meshcfg_app *app = (meshcfg_app*) user_data;
645 INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
646 app->path, app->agent_path);
648 if (l_dbus_message_is_error(msg)) {
650 l_dbus_message_get_error(msg, &name, NULL);
651 ERR("Mesh: Failed to attach node: %s", name);
656 if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
660 INFO("Mesh: Attached with path %s\n", app->path);
661 __send_network_attach_event(app, BT_STATUS_SUCCESS);
664 __send_network_attach_event(app, BT_STATUS_FAIL);
665 /* Destroy mesh app object */
666 __bt_hal_mesh_destroy_app_object(app);
669 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
672 meshcfg_app *app = (meshcfg_app*) user_data;
674 l_dbus_message_set_arguments(msg, "ot", app->path,
675 l_get_be64(app->token.u8));
679 static void __bt_hal_mesh_attach_node(void *user_data)
681 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
682 __bt_hal_mesh_attach_node_setup,
683 __bt_hal_mesh_attach_node_reply,
686 ERR("Mesh: Node attach failed!!");
687 /* Node could not be attached */
688 __send_network_attach_event(user_data, BT_STATUS_FAIL);
689 /* Destroy mesh app object */
690 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
694 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
695 struct l_dbus_message *message,
701 meshcfg_app *app = (meshcfg_app*) user_data;
702 INFO("Mesh: Join Complete");
705 if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
707 /* Send Network creation fail event */
708 __send_network_attach_event(app, BT_STATUS_FAIL);
710 /* Destroy mesh app object */
711 __bt_hal_mesh_destroy_app_object(app);
713 return l_dbus_message_new_error(message, dbus_err_args, NULL);
717 app->token.u64 = l_get_be64(&tmp);
718 str = l_util_hexstring(&app->token.u8[0], 8);
719 INFO("Mesh: Created new node with token %s\n", str);
722 /* Authenticate the node */
723 l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
724 return l_dbus_message_new_method_return(message);
727 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
730 struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
731 meshcfg_model *model_info = (meshcfg_model*) data;
733 l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
736 static bool __mesh_model_getter(struct l_dbus *dbus,
737 struct l_dbus_message *message,
738 struct l_dbus_message_builder *builder,
741 meshcfg_el *element = (meshcfg_el*) user_data;
743 l_dbus_message_builder_enter_array(builder, "q");
744 g_slist_foreach(element->models,
745 __bt_hal_mesh_foreach_model_getter, builder);
747 l_dbus_message_builder_leave_array(builder);
752 /*TODO: Vendor Model handling is currently not Handled */
753 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
754 struct l_dbus_message *message,
755 struct l_dbus_message_builder *builder,
758 l_dbus_message_builder_enter_array(builder, "(qq)");
759 l_dbus_message_builder_leave_array(builder);
764 static bool __mesh_element_index_getter(struct l_dbus *dbus,
765 struct l_dbus_message *message,
766 struct l_dbus_message_builder *builder,
769 meshcfg_el *element = (meshcfg_el*) user_data;
770 l_dbus_message_builder_append_basic(builder, 'y', &element->index);
776 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
777 struct l_dbus_message *msg, void *user_data)
779 struct l_dbus_message_iter iter;
784 const char *dbus_path;
787 dbus_path = l_dbus_message_get_path(msg);
788 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true, MESH_ELEMENT_IFACE);
789 uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
790 struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
792 INFO("Mesh: app path [%s]", dbus_path);
794 memset(buf, 0, sizeof(buf));
795 size = (uint16_t) sizeof(*ev);
796 memcpy(ev->net_uuid, net_uuid, 16);
799 if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
801 ERR("Mesh: Cannot parse received message");
802 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
805 if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
806 ERR("Mesh: Cannot parse received message: data");
807 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
810 INFO("Mesh: Received dev key message (len %u):", n);
811 ev->source_addr = src;
812 ev->is_remote_devkey = rmt;
813 ev->netkey_idx = idx;
815 memcpy(ev->data, data, n);
818 INFO("Mesh: Src [0x%2.2x]", src);
819 INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
820 INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
821 /* Send DevKeyMessage Received event */
823 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
825 return l_dbus_message_new_method_return(msg);
828 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
830 INFO("Mesh: Setup element interface properties & methods");
832 l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
834 l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
835 __mesh_vendor_model_getter, NULL);
836 l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
839 l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
840 __mesh_device_message_received, "", "qbqay", "source",
841 "remote", "net_index", "data");
842 /* TODO: Other methods */
845 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
846 struct l_dbus_message *msg,
849 struct l_dbus_message_iter iter, opts;
850 meshcfg_app *app = (meshcfg_app*) user_data;
855 const char *sig = "naya{sv}";
857 /* Find network uuid from dbus path */
858 struct hal_ev_mesh_scan_result ev;
860 if (!app->scan_timer_id) {
861 /* Scan is not running */
862 INFO("Got scan result, but scan is already stopped");
863 return l_dbus_message_new_method_return(msg);
865 memset(&ev, 0, sizeof(ev));
866 memcpy(ev.net_uuid, app->uuid, 16);
868 if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
869 ERR("Mesh: Cannot parse scan results");
870 ev.status = BT_STATUS_FAIL;
872 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
874 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
877 if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
879 ERR("Mesh: Cannot parse scan result: data");
880 ev.status = BT_STATUS_FAIL;
882 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
884 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
887 INFO("Mesh: Scan result:\n");
888 INFO("Mesh: Scan rssi = [%d]\n", rssi);
889 str = l_util_hexstring_upper(prov_data, 16);
890 INFO("Mesh: Scan UUID = [%s]\n", str);
894 str = l_util_hexstring_upper(prov_data + 16, 2);
895 INFO("Mesh: Scan OOB = [%s]\n", str);
900 str = l_util_hexstring_upper(prov_data + 18, 4);
901 INFO("Mesh: Scan URI hash = [%s]\n", str);
905 /* 16 octet Dev UUID */
906 memcpy(ev.dev_uuid, prov_data, 16);
908 /* 2 octet Dev OOB Info */
909 memcpy(ev.oob_info, prov_data + 16, 2);
911 /* 4 octet URI Hash */
912 memcpy(ev.uri_hash, prov_data + 18, 4);
916 ev.status = BT_STATUS_SUCCESS;
918 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
919 (void*)&ev, sizeof(ev));
921 return l_dbus_message_new_method_return(msg);
924 static struct l_dbus_message *__mesh_request_provisioner_call(
926 struct l_dbus_message *msg,
930 struct hal_ev_mesh_provision_finished ev;
931 struct hal_ev_mesh_provision_data_request req;
933 meshcfg_app *app = user_data;
935 INFO("Mesh: provisioning data requested app path [%s]",
937 uuid_string = l_util_hexstring(app->uuid, 16);
938 INFO("Mesh: Network UUID [%s]", uuid_string);
940 memset(&ev, 0, sizeof(ev));
941 memset(&req, 0, sizeof(req));
942 memcpy(ev.net_uuid, app->uuid, 16);
943 memcpy(req.net_uuid, app->uuid, 16);
946 if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
947 ERR("Mesh: Cannot parse request for prov data");
949 ev.status = BT_STATUS_FAIL;
950 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
952 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
953 (void*)&ev, sizeof(ev));
954 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
960 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
961 (void*)&req, sizeof(req));
963 l_dbus_message_ref(msg);
967 static struct l_dbus_message *__mesh_node_add_completed(
969 struct l_dbus_message *msg,
972 struct l_dbus_message_iter iter;
977 struct hal_ev_mesh_provision_finished ev;
978 const char *dbus_path;
980 dbus_path = l_dbus_message_get_path(msg);
981 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
982 true, MESH_PROV_IFACE);
984 INFO("Mesh: app path [%s]", dbus_path);
986 memset(&ev, 0, sizeof(ev));
987 memcpy(ev.net_uuid, net_uuid, 16);
991 if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
992 ERR("Mesh: Cannot parse add node complete message");
994 ev.status = BT_STATUS_FAIL;
995 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
997 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
998 (void*)&ev, sizeof(ev));
999 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1002 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1004 ERR("Mesh: Cannot parse add node complete message: uuid");
1006 ev.status = BT_STATUS_FAIL;
1007 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1009 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1010 (void*)&ev, sizeof(ev));
1011 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1015 ev.status = BT_STATUS_SUCCESS;
1016 ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1017 memcpy(ev.dev_uuid, uuid, 16);
1018 ev.unicast = unicast;
1022 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1023 (void*)&ev, sizeof(ev));
1025 return l_dbus_message_new_method_return(msg);
1028 static struct l_dbus_message *__mesh_node_add_failed(
1029 struct l_dbus *dbus,
1030 struct l_dbus_message *msg,
1033 struct l_dbus_message_iter iter;
1037 struct hal_ev_mesh_provision_finished ev;
1038 const char *dbus_path;
1041 dbus_path = l_dbus_message_get_path(msg);
1042 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1043 true, MESH_PROV_IFACE);
1045 memset(&ev, 0, sizeof(ev));
1046 memcpy(ev.net_uuid, net_uuid, 16);
1049 if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1050 ERR("Mesh: Cannot parse add node failed message");
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);
1060 if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1062 ERR("Mesh:Cannot parse add node failed message: uuid");
1063 ev.status = BT_STATUS_FAIL;
1064 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1066 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1067 (void*)&ev, sizeof(ev));
1068 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1071 INFO("Mesh: Provisioning failed:\n");
1072 str = l_util_hexstring_upper(uuid, 16);
1073 INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1076 ev.status = BT_STATUS_FAIL;
1077 ev.reason = __bt_mesh_util_get_prov_error_code(str);
1078 memcpy(ev.dev_uuid, uuid, 16);
1081 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1082 (void*)&ev, sizeof(ev));
1084 return l_dbus_message_new_method_return(msg);
1087 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1089 INFO("Mesh: Setup provisioner interface properties & methods");
1090 l_dbus_interface_method(interface, "ScanResult", 0,
1091 __mesh_scan_result_received, "",
1092 "naya{sv}", "rssi", "data", "options");
1094 l_dbus_interface_method(interface, "RequestProvData", 0,
1095 __mesh_request_provisioner_call,
1096 "qq", "y", "net_index", "unicast", "count");
1098 l_dbus_interface_method(interface, "AddNodeComplete", 0,
1099 __mesh_node_add_completed, "", "ayqy",
1100 "uuid", "unicast", "count");
1102 l_dbus_interface_method(interface, "AddNodeFailed", 0,
1103 __mesh_node_add_failed,
1104 "", "ays", "uuid", "reason");
1107 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1109 INFO("Mesh: Setup application interface properties & methods");
1111 l_dbus_interface_property(iface, "CompanyID", 0, "q",
1112 __mesh_get_companyid,
1114 l_dbus_interface_property(iface, "VersionID", 0, "q",
1115 __mesh_get_versionid,
1117 l_dbus_interface_property(iface, "ProductID", 0, "q",
1118 __mesh_get_productid,
1120 l_dbus_interface_property(iface, "CRPL", 0, "q",
1121 __mesh_get_crpl, NULL);
1122 l_dbus_interface_method(iface, "JoinComplete", 0,
1123 __mesh_node_join_complete,
1129 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1130 struct l_dbus_message_builder *builder)
1132 if (app->in_oob & 0x08)
1133 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1134 if (app->in_oob & 0x04)
1135 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1136 if (app->in_oob & 0x02)
1137 l_dbus_message_builder_append_basic(builder, 's', "twist");
1138 if (app->in_oob & 0x01)
1139 l_dbus_message_builder_append_basic(builder, 's', "push");
1142 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1143 struct l_dbus_message_builder *builder)
1145 if (app->out_oob & 0x10)
1146 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1147 if (app->out_oob & 0x08)
1148 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1149 if (app->out_oob & 0x04)
1150 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1151 if (app->out_oob & 0x02)
1152 l_dbus_message_builder_append_basic(builder, 's', "beep");
1153 if (app->out_oob & 0x01)
1154 l_dbus_message_builder_append_basic(builder, 's', "blink");
1157 static bool __mesh_agent_capability_getter(
1158 struct l_dbus *dbus,struct l_dbus_message *message,
1159 struct l_dbus_message_builder *builder,
1164 INFO("Mesh: app path [%s]", app->path);
1165 INFO("Mesh: Agent path [%s]", app->agent_path);
1167 if (!l_dbus_message_builder_enter_array(builder, "s")) {
1171 __mesh_fill_out_capabilities(app, builder);
1172 __mesh_fill_in_capabilities(app, builder);
1174 if (app->static_oob)
1175 l_dbus_message_builder_append_basic(builder,
1179 l_dbus_message_builder_leave_array(builder);
1180 INFO("Mesh: __agent_capability_getter: Success");
1184 static struct l_dbus_message *__mesh_agent_display_string_request(
1185 struct l_dbus *dbus,
1186 struct l_dbus_message *msg,
1189 struct hal_ev_mesh_authentication_request ev;
1192 const char *dbus_path;
1195 INFO("Mesh: app path [%s]", app->path);
1196 INFO("Mesh: Agent path [%s]", app->agent_path);
1198 dbus_path = l_dbus_message_get_path(msg);
1199 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1200 true, MESH_AGENT_IFACE);
1202 INFO("Mesh: app path [%s]", dbus_path);
1204 memset(&ev, 0, sizeof(ev));
1205 memcpy(ev.net_uuid, net_uuid, 16);
1208 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1209 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1210 struct hal_ev_mesh_provision_finished ev;
1211 memset(&ev, 0, sizeof(ev));
1212 memcpy(ev.net_uuid, net_uuid, 16);
1213 ev.status = BT_STATUS_FAIL;
1214 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1216 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1217 (void*)&ev, sizeof(ev));
1221 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1224 INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1225 ev.auth_type = BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY;
1226 g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1229 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1230 (void*)&ev, sizeof(ev));
1233 return l_dbus_message_new_method_return(msg);
1236 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1237 struct l_dbus *dbus,
1238 struct l_dbus_message *msg,
1242 struct hal_ev_mesh_authentication_request ev;
1246 const char *dbus_path;
1249 INFO("Mesh: app path [%s]", app->path);
1250 INFO("Mesh: Agent path [%s]", app->agent_path);
1252 dbus_path = l_dbus_message_get_path(msg);
1253 net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1254 true, MESH_AGENT_IFACE);
1256 INFO("Mesh: app path [%s]", dbus_path);
1258 memset(&ev, 0, sizeof(ev));
1259 memcpy(ev.net_uuid, net_uuid, 16);
1262 if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1263 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1264 struct hal_ev_mesh_provision_finished ev;
1265 memset(&ev, 0, sizeof(ev));
1266 memcpy(ev.net_uuid, net_uuid, 16);
1267 ev.status = BT_STATUS_FAIL;
1268 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1269 if (mesh_event_cb) {
1270 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1271 (void*)&ev, sizeof(ev));
1274 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1277 INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1278 auth_value = l_strdup_printf("%u",n);
1279 ev.auth_type = __mesh_get_authentication_type(str);
1280 g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1283 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1284 (void*)&ev, sizeof(ev));
1288 return l_dbus_message_new_method_return(msg);
1291 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1292 struct l_dbus *dbus,
1293 struct l_dbus_message *msg,
1296 struct hal_ev_mesh_authentication_request ev;
1299 const char *dbus_path;
1303 dbus_path = l_dbus_message_get_path(msg);
1304 net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1305 true, MESH_AGENT_IFACE);
1307 INFO("Mesh: app path [%s]", dbus_path);
1309 l = g_slist_find_custom(mesh_apps, net_uuid,
1310 __mesh_compare_network_uuid);
1313 memset(&ev, 0, sizeof(ev));
1314 memcpy(ev.net_uuid, net_uuid, 16);
1317 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1318 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1320 struct hal_ev_mesh_provision_finished ev;
1321 memset(&ev, 0, sizeof(ev));
1322 memcpy(ev.net_uuid, app->uuid, 16);
1323 ev.status = BT_STATUS_FAIL;
1324 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1325 if (mesh_event_cb) {
1326 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1327 (void*)&ev, sizeof(ev));
1329 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1332 INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1334 ev.auth_type = __mesh_get_authentication_type(str);
1336 l_dbus_message_ref(msg);
1338 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1339 (void*)&ev, sizeof(ev));
1344 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1345 struct l_dbus *dbus,
1346 struct l_dbus_message *msg,
1349 struct hal_ev_mesh_authentication_request ev;
1352 const char *dbus_path;
1356 dbus_path = l_dbus_message_get_path(msg);
1357 net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1360 INFO("Mesh: app path [%s]", dbus_path);
1362 l = g_slist_find_custom(mesh_apps, net_uuid,
1363 __mesh_compare_network_uuid);
1366 memset(&ev, 0, sizeof(ev));
1367 memcpy(ev.net_uuid, net_uuid, 16);
1370 if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1371 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1373 struct hal_ev_mesh_provision_finished ev;
1374 memset(&ev, 0, sizeof(ev));
1375 memcpy(ev.net_uuid, app->uuid, 16);
1376 ev.status = BT_STATUS_FAIL;
1377 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1379 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1380 (void*)&ev, sizeof(ev));
1381 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1384 INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1386 ev.auth_type = __mesh_get_authentication_type(str);
1388 l_dbus_message_ref(msg);
1390 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1391 (void*)&ev, sizeof(ev));
1396 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1398 INFO("Mesh: Setup Agent interface properties & methods");
1399 l_dbus_interface_property(interface, "Capabilities", 0, "as",
1400 __mesh_agent_capability_getter,
1402 /* TODO: Other properties */
1403 l_dbus_interface_method(interface, "DisplayString", 0,
1404 __mesh_agent_display_string_request,
1406 l_dbus_interface_method(interface, "DisplayNumeric", 0,
1407 __mesh_agent_display_numeric_request,
1408 "", "su", "type", "number");
1409 l_dbus_interface_method(interface, "PromptNumeric", 0,
1410 __mesh_agent_prompt_numeric_request,
1411 "u", "s", "number", "type");
1412 l_dbus_interface_method(interface, "PromptStatic", 0,
1413 __mesh_agent_prompt_static_request,
1414 "ay", "s", "data", "type");
1417 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1419 meshcfg_el *elem = (meshcfg_el*) data;
1420 INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1421 elem->index, elem->path);
1422 if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1423 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1424 ERR("Mesh: Failed to register object %s", elem->path);
1428 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1433 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1434 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1435 ERR("Mesh: Unable to register agent interface");
1439 INFO("Mesh: Register Agent path [%s]", ptr->agent_path);
1440 if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1441 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1442 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1446 if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1447 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1448 ERR("Mesh: Failed to add interface %s",
1449 L_DBUS_INTERFACE_PROPERTIES);
1456 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1464 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1465 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1466 ERR("Mesh: Failed to register interface %s",
1467 BT_HAL_MESH_APPLICATION_INTERFACE);
1471 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1472 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1473 ERR("Mesh: Failed to register interface %s",
1474 BT_HAL_MESH_PROVISIONER_INTERFACE);
1478 if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1479 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1480 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1482 ERR("Mesh: Failed to register object %s", ptr->path);
1486 if (!__bt_hal_mesh_register_agent(ptr))
1489 if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1490 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1491 ERR("Mesh: Failed to register interface %s",
1492 BT_HAL_MESH_ELEMENT_INTERFACE);
1496 INFO("Mesh: Number of elements to be registsred [%d]",
1497 g_slist_length(ptr->elements));
1499 g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1501 INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1502 if (!l_dbus_object_add_interface(dbus, ptr->path,
1503 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1504 ERR("Mesh: Failed to add interface %s",
1505 L_DBUS_INTERFACE_OBJECT_MANAGER);
1508 INFO("Mesh: Application Register completed");
1513 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1517 meshcfg_model *model_info = (meshcfg_model*) data;
1518 meshcfg_app *app = (meshcfg_app*) user_data;
1520 l = g_slist_find_custom(app->elements,
1521 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1525 elem = g_malloc0(sizeof(meshcfg_el));
1526 elem->index = model_info->elem_index;
1527 elem->path = g_strdup_printf("%s/elem%u",app->path, elem->index);
1528 app->elements = g_slist_append(app->elements, elem);
1529 INFO("Mesh: Created element index [%d] path [%s]",
1530 elem->index, elem->path);
1532 INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1533 model_info->model, elem->index);
1534 /* Add Model in the element */
1535 elem->models = g_slist_append(elem->models, model_info);
1536 INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1537 elem->index, g_slist_length(elem->models));
1540 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1541 GSList *models, bool is_prov)
1544 meshcfg_app *app = NULL;
1545 char *uuid_str = NULL;
1547 uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1549 app = g_malloc0(sizeof(meshcfg_app));
1550 memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1552 app->cid = node->vendor_info.companyid;
1553 app->pid = node->vendor_info.vendorid;
1554 app->vid = node->vendor_info.versionid;
1555 app->crpl = node->vendor_info.crpl;
1558 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1559 app->agent_path = g_strdup_printf("%s/agent", app->path);
1562 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1563 app->agent_path = g_strdup_printf("%s/agent", app->path);
1565 g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1568 app->is_prov = is_prov;
1569 INFO("Mesh: app created");
1573 static void __bt_hal_mesh_create_net_reply(
1574 struct l_dbus_proxy *proxy,
1575 struct l_dbus_message *msg, void *user_data)
1578 app = (meshcfg_app*) user_data;
1580 INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1581 if (l_dbus_message_is_error(msg)) {
1584 l_dbus_message_get_error(msg, &name, NULL);
1585 ERR("Mesh: Failed to create network: %s", name);
1587 /* Send Network creation fail event */
1588 __send_network_attach_event(app, BT_STATUS_FAIL);
1590 /* Destroy mesh app object */
1591 __bt_hal_mesh_destroy_app_object(app);
1596 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1600 struct l_dbus_message_builder *builder;
1601 app = (meshcfg_app*) user_data;
1603 builder = l_dbus_message_builder_new(msg);
1605 INFO("Mesh: Create Network Setup app path [%s]", app->path);
1606 l_dbus_message_builder_append_basic(builder, 'o', app->path);
1607 __mesh_append_byte_array(builder, app->uuid, 16);
1608 l_dbus_message_builder_finalize(builder);
1609 l_dbus_message_builder_destroy(builder);
1612 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1614 struct hal_ev_mesh_scan_state_changed ev;
1616 memset(&ev, 0, sizeof(ev));
1617 memcpy(ev.net_uuid, app->uuid, 16);
1619 ev.status = BT_STATUS_SUCCESS;
1621 ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1623 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1624 (void*)&ev, sizeof(ev));
1627 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1629 meshcfg_app *app = (meshcfg_app*) user_data;
1630 __mesh_trigger_scan_finished_event(app);
1634 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1638 l = g_slist_find_custom(mesh_apps, net_uuid,
1639 __mesh_compare_network_uuid);
1642 if (app->scan_timer_id > 0) {
1643 g_source_remove(app->scan_timer_id);
1644 app->scan_timer_id = 0;
1647 app->scan_timer_id = g_timeout_add_seconds(secs,
1648 __bt_mesh_scan_timer_cb, app);
1653 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1654 struct l_dbus_message *msg, void *user_data)
1656 struct hal_ev_mesh_scan_state_changed ev;
1657 const char *dbus_path;
1659 dbus_path = l_dbus_proxy_get_path(proxy);
1660 INFO("Mesh: DBUS path [%s]", dbus_path);
1661 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1663 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1664 INFO("Mesh: Scan duration [%u]", secs);
1666 memset(&ev, 0, sizeof(ev));
1667 memcpy(ev.net_uuid, net_uuid, 16);
1669 if (l_dbus_message_is_error(msg)) {
1671 l_dbus_message_get_error(msg, &name, NULL);
1672 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1673 ev.status = BT_STATUS_FAIL;
1675 INFO("Mesh: Unprovisioned scan started\n");
1676 ev.status = BT_STATUS_SUCCESS;
1677 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1680 ev.state = HAL_MESH_SCAN_STATE_STARTED;
1682 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1683 (void*)&ev, sizeof(ev));
1687 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1688 const char *key, const char *signature,
1694 l_dbus_message_builder_enter_dict(builder, "sv");
1695 l_dbus_message_builder_append_basic(builder, 's', key);
1696 l_dbus_message_builder_enter_variant(builder, signature);
1697 l_dbus_message_builder_append_basic(builder, signature[0], data);
1698 l_dbus_message_builder_leave_variant(builder);
1699 l_dbus_message_builder_leave_dict(builder);
1702 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1704 struct l_dbus_message_builder *builder;
1705 uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1706 INFO("Mesh: Scan duration [%u]", secs);
1708 builder = l_dbus_message_builder_new(msg);
1709 l_dbus_message_builder_enter_array(builder, "{sv}");
1710 append_dict_entry_basic(builder, "Seconds", "q", &secs);
1711 l_dbus_message_builder_leave_array(builder);
1712 l_dbus_message_builder_finalize(builder);
1713 l_dbus_message_builder_destroy(builder);
1717 bt_status_t _bt_hal_mesh_network_set_caps(
1718 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1722 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1726 app->public_oob = caps->public_oob;
1727 app->static_oob = caps->static_oob;
1728 app->out_oob = caps->out_oob;
1729 app->in_oob = caps->in_oob;
1731 ERR("Mesh: app not found!!");
1732 return BT_STATUS_PARM_INVALID;
1735 return BT_STATUS_SUCCESS;
1738 static void __bt_hal_mesh_add_node_reply(
1739 struct l_dbus_proxy *proxy,
1740 struct l_dbus_message *msg,
1743 struct hal_ev_mesh_provision_status ev;
1744 const char *dbus_path;
1746 dbus_path = l_dbus_proxy_get_path(proxy);
1747 INFO("Mesh: DBUS path [%s]", dbus_path);
1748 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1750 bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1752 INFO("Mesh: app path [%s]", dbus_path);
1754 memset(&ev, 0, sizeof(ev));
1755 memcpy(ev.net_uuid, net_uuid, 16);
1756 memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1758 /* Free User data */
1759 g_free((void*)dev_uuid);
1762 if (l_dbus_message_is_error(msg)) {
1765 l_dbus_message_get_error(msg, &name, NULL);
1766 ERR("Mesh: Failed to start provisioning: %s", name);
1767 ev.status = BT_STATUS_FAIL;
1769 INFO("Mesh: Provisioning started\n");
1770 ev.status = BT_STATUS_SUCCESS;
1773 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1774 (void*)&ev, sizeof(ev));
1775 INFO("Mesh: Provisioning status sent");
1778 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1782 bt_uuid_t *dev = user_data;
1783 struct l_dbus_message_builder *builder;
1784 uuid = l_util_hexstring(dev->uu, 16);
1785 INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1787 builder = l_dbus_message_builder_new(msg);
1788 __mesh_append_byte_array(builder, dev->uu, 16);
1789 l_dbus_message_builder_enter_array(builder, "{sv}");
1790 l_dbus_message_builder_leave_array(builder);
1791 l_dbus_message_builder_finalize(builder);
1792 l_dbus_message_builder_destroy(builder);
1795 bt_status_t _bt_hal_mesh_provision_device(
1796 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1801 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1804 dev = g_memdup((gpointer)dev_uuid, 16);
1805 INFO("Mesh: Schedule Add Node request to meshd");
1806 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1807 __bt_hal_mesh_add_node_setup,
1808 __bt_hal_mesh_add_node_reply,
1810 return BT_STATUS_FAIL;
1812 ERR("Mesh: app not found!!");
1813 return BT_STATUS_PARM_INVALID;
1816 return BT_STATUS_SUCCESS;
1819 static void __bt_hal_mesh_subnet_key_setup(
1820 struct l_dbus_message *msg, void *user_data)
1822 struct subnet_key_request *req = user_data;
1823 uint16_t idx = (uint16_t) req->idx;
1825 l_dbus_message_set_arguments(msg, "q", idx);
1828 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1829 struct l_dbus_message *msg, void *user_data)
1831 struct hal_ev_mesh_netkey_execute_event ev;
1832 const char *dbus_path;
1834 struct subnet_key_request *req = user_data;
1835 const char *method = req->str;
1837 dbus_path = l_dbus_proxy_get_path(proxy);
1838 INFO("Mesh: DBUS path [%s]", dbus_path);
1839 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1841 memset(&ev, 0, sizeof(ev));
1842 memcpy(ev.net_uuid, net_uuid, 16);
1843 ev.key_idx = req->idx;
1847 if (l_dbus_message_is_error(msg)) {
1850 l_dbus_message_get_error(msg, &name, NULL);
1851 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
1852 ev.status = BT_STATUS_FAIL;
1855 ev.status = BT_STATUS_SUCCESS;
1857 if (!strcmp("CreateSubnet", method)) {
1858 INFO("Mesh: Reply for CreateSubnet");
1859 ev.key_event = HAL_MESH_KEY_ADD;
1860 } else if (!strcmp("DeleteSubnet", method)) {
1861 INFO("Mesh: Reply for DeleteSubnet");
1862 ev.key_event = HAL_MESH_KEY_DELETE;
1863 } else if (!strcmp("UpdateSubnet", method)) {
1864 INFO("Mesh: Reply for UpdateSubnet");
1865 ev.key_event = HAL_MESH_KEY_UPDATE;
1869 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
1870 (void*)&ev, sizeof(ev));
1873 static bool __mesh_subnet_netkey_command_execute(meshcfg_app *app,
1874 uint16_t index, const char *key_execute_method)
1876 struct subnet_key_request *req;
1878 req = l_new(struct subnet_key_request, 1);
1879 req->str = key_execute_method;
1882 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1883 __bt_hal_mesh_subnet_key_setup,
1884 __bt_hal_mesh_subnet_key_reply,
1891 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
1894 struct app_key_request *req = user_data;
1895 uint16_t net_idx = (uint16_t) req->net_idx;
1896 uint16_t app_idx = (uint16_t) req->app_idx;
1898 if (g_strcmp0(req->str,"CreateAppKey") == 0)
1899 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
1901 l_dbus_message_set_arguments(msg, "q", app_idx);
1904 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
1905 struct l_dbus_message *msg, void *user_data)
1907 struct hal_ev_mesh_appkey_execute_event ev;
1908 const char *dbus_path;
1910 struct app_key_request *req = user_data;
1911 const char *method = req->str;
1913 dbus_path = l_dbus_proxy_get_path(proxy);
1914 INFO("Mesh: DBUS path [%s]", dbus_path);
1915 net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1917 memset(&ev, 0, sizeof(ev));
1918 memcpy(ev.net_uuid, net_uuid, 16);
1919 ev.net_idx = req->net_idx;
1920 ev.app_idx = req->app_idx;
1924 if (l_dbus_message_is_error(msg)) {
1927 l_dbus_message_get_error(msg, &name, NULL);
1928 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
1929 ev.status = BT_STATUS_FAIL;
1931 ev.status = BT_STATUS_SUCCESS;
1933 if (!strcmp("CreateAppKey", method)) {
1934 INFO("Mesh: AppKey Create Reply");
1935 ev.key_event = HAL_MESH_KEY_ADD;
1936 } else if (!strcmp("DeleteAppKey", method)) {
1937 INFO("Mesh: AppKey Delete Reply");
1938 ev.key_event = HAL_MESH_KEY_DELETE;
1939 } else if (!strcmp("UpdateAppKey", method)) {
1940 INFO("Mesh: AppKey Update Reply");
1941 ev.key_event = HAL_MESH_KEY_UPDATE;
1945 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
1948 static bool __mesh_subnet_appkey_command_execute(meshcfg_app *app,
1949 uint16_t net_idx, uint16_t app_idx,
1950 const char *key_execute_method)
1952 struct app_key_request *req;
1954 req = l_new(struct app_key_request, 1);
1955 req->str = key_execute_method;
1956 req->net_idx = net_idx;
1957 req->app_idx = app_idx;
1959 if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1960 __bt_hal_mesh_app_key_setup,
1961 __bt_hal_mesh_app_key_reply,
1968 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
1969 bt_mesh_key_op_e op, uint16_t netkey_idx)
1974 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1978 if (op == BT_MESH_KEY_CREATE)
1979 status = __mesh_subnet_netkey_command_execute(app,
1980 netkey_idx, "CreateSubnet");
1981 else if (op == BT_MESH_KEY_DELETE)
1982 status = __mesh_subnet_netkey_command_execute(app,
1983 netkey_idx, "DeleteSubnet");
1984 else if (op == BT_MESH_KEY_UPDATE)
1985 status = __mesh_subnet_netkey_command_execute(app,
1986 netkey_idx, "UpdateSubnet");
1988 return BT_STATUS_FAIL;
1991 ERR("Mesh: app not found!!");
1992 return BT_STATUS_PARM_INVALID;
1995 return BT_STATUS_SUCCESS;
1998 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
1999 bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2004 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2008 if (op == BT_MESH_KEY_CREATE)
2009 status = __mesh_subnet_appkey_command_execute(app,
2010 netkey_idx, appkey_idx, "CreateAppKey");
2011 else if (op == BT_MESH_KEY_DELETE)
2012 status = __mesh_subnet_appkey_command_execute(app,
2013 netkey_idx, appkey_idx, "DeleteAppKey");
2014 else if (op == BT_MESH_KEY_UPDATE) {
2015 INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2016 netkey_idx, appkey_idx);
2017 status = __mesh_subnet_appkey_command_execute(app,
2018 netkey_idx, appkey_idx, "UpdateAppKey");
2021 return BT_STATUS_FAIL;
2024 ERR("Mesh: app not found!!");
2025 return BT_STATUS_PARM_INVALID;
2028 return BT_STATUS_SUCCESS;
2031 bt_status_t _bt_hal_mesh_send_provision_data(
2032 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2036 struct l_dbus_message *msg;
2037 struct l_dbus_message *reply;
2039 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2044 reply = l_dbus_message_new_method_return(msg);
2045 l_dbus_message_set_arguments(reply, "qq", netkey_idx, unicast);
2046 l_dbus_send(dbus, reply);
2048 ERR("Mesh: app not found!!");
2049 return BT_STATUS_PARM_INVALID;
2051 return BT_STATUS_SUCCESS;
2054 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2058 l = g_slist_find_custom(mesh_apps,
2059 net_uuid->uu, __mesh_compare_network_uuid);
2062 if (!__bt_mesh_proxy_check(app)) {
2063 ERR("Mesh: Proxy check failed!!");
2064 return BT_STATUS_FAIL;
2066 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2067 "UnprovisionedScanCancel",
2068 NULL, NULL, NULL, NULL))
2069 return BT_STATUS_FAIL;
2071 ERR("Mesh: app not found!!");
2072 return BT_STATUS_PARM_INVALID;
2075 /* Stop Scan timer */
2076 if (app->scan_timer_id > 0) {
2077 g_source_remove(app->scan_timer_id);
2078 app->scan_timer_id = 0;
2081 /* Trigger Scan finished event */
2082 __mesh_trigger_scan_finished_event(app);
2084 return BT_STATUS_SUCCESS;
2087 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2088 const char *auth_value)
2091 struct l_dbus_message *reply = NULL;
2092 struct l_dbus_message_builder *builder;
2094 bt_status_t ret = BT_STATUS_SUCCESS;
2098 if (!__bt_mesh_proxy_check(0)) {
2099 ERR("Mesh: Proxy check failed!!");
2100 return BT_STATUS_FAIL;
2102 INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2103 INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2104 /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2105 if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2106 auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2107 INFO("Mesh: Authentication reply: Numeric Type");
2108 val_u32 = atoi(auth_value);
2109 reply = l_dbus_message_new_method_return(agent_msg);
2110 l_dbus_message_set_arguments(reply, "u", val_u32);
2112 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2113 l_dbus_send(dbus, reply);
2114 ret = BT_STATUS_SUCCESS;
2115 /* For Alpha-Numeric */
2116 } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2117 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2118 auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT ) {
2119 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2120 alpha = l_util_from_hexstring(auth_value, &sz);
2121 reply = l_dbus_message_new_method_return(agent_msg);
2122 builder = l_dbus_message_builder_new(reply);
2123 __mesh_append_byte_array(builder, alpha, 16);
2124 l_dbus_message_builder_finalize(builder);
2125 l_dbus_message_builder_destroy(builder);
2128 reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2129 l_dbus_send(dbus, reply);
2130 ret = BT_STATUS_SUCCESS;
2135 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2136 bt_hal_mesh_scan_param_t *param)
2140 l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2143 if (!__bt_mesh_proxy_check(app)) {
2144 ERR("Mesh: Proxy check failed!!");
2145 return BT_STATUS_FAIL;
2147 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2148 __mesh_scan_setup, __mesh_scan_reply,
2149 L_UINT_TO_PTR(param->scan_time), NULL))
2150 return BT_STATUS_FAIL;
2152 ERR("Mesh: app not found!!");
2153 return BT_STATUS_PARM_INVALID;
2155 return BT_STATUS_SUCCESS;
2158 bt_status_t _bt_hal_mesh_create_network(
2159 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2163 INFO("Mesh: Create Network Request");
2165 if (!__bt_mesh_proxy_check(0)) {
2166 ERR("Mesh: Proxy check failed!!");
2167 return BT_STATUS_FAIL;
2170 INFO("Mesh: Node Element count [%d]", node->num_elements);
2171 INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2172 INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2173 INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2174 INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2175 INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2176 INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2177 /* Create DBUS APP */
2178 app = __bt_hal_mesh_create_app(node, models, is_prov);
2180 return BT_STATUS_FAIL;
2182 /* Register DBUS APP */
2183 if (!__bt_hal_mesh_register_application(app)) {
2187 if (app->token.u64 == 0) {
2188 INFO("Mesh: Create New Network");
2189 /* Create CFG Network */
2190 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2191 __bt_hal_mesh_create_net_setup,
2192 __bt_hal_mesh_create_net_reply, app,
2194 ERR("Mesh: Network Create failed!!");
2198 INFO("Mesh: Attach Node to Network");
2199 /* Attach to Network */
2200 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2201 __bt_hal_mesh_attach_node_setup,
2202 __bt_hal_mesh_attach_node_reply,
2205 ERR("Mesh: Node attach failed!!");
2210 INFO("Mesh: Node registration request scheudled");
2211 mesh_apps = g_slist_append(mesh_apps, app);
2212 INFO("Mesh: Total number of apps in list [%d]",
2213 g_slist_length(mesh_apps));
2214 return BT_STATUS_SUCCESS;
2216 ERR("Mesh: network can not be created!!");
2217 __bt_hal_mesh_destroy_app_object(app);
2218 return BT_STATUS_FAIL;
2221 static void __bt_hal_mesh_config_send(
2222 struct l_dbus_message *msg, void *user_data)
2224 struct configuration_request *req = user_data;
2225 struct l_dbus_message_builder *builder;
2227 builder = l_dbus_message_builder_new(msg);
2229 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2230 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2231 if (req->is_dev_key)
2232 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2234 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2235 __mesh_append_byte_array(builder, req->data, req->len);
2236 l_dbus_message_builder_finalize(builder);
2237 l_dbus_message_builder_destroy(builder);
2240 static void __bt_hal_mesh_key_config_send(
2241 struct l_dbus_message *msg, void *user_data)
2243 struct key_config_request *req = user_data;
2244 struct l_dbus_message_builder *builder;
2246 builder = l_dbus_message_builder_new(msg);
2248 l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2249 l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2250 l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2251 l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2252 l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2253 l_dbus_message_builder_finalize(builder);
2254 l_dbus_message_builder_destroy(builder);
2257 bt_status_t _bt_hal_mesh_send_key_config_message(
2258 bt_uuid_t *network, uint16_t dest,
2259 bool is_netkey, bool is_update,
2260 uint16_t key_idx, uint16_t netkey_idx)
2264 struct key_config_request *req;
2267 const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2268 /* Source is Config Client Local Node */
2269 int src_elem_idx = 0;
2270 l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2273 if (!__bt_mesh_proxy_check(app)) {
2274 ERR("Mesh: Proxy check failed!!");
2275 return BT_STATUS_FAIL;
2277 l1 = g_slist_find_custom(app->elements,
2278 GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2281 req = l_new(struct key_config_request, 1);
2282 req->ele_path = elem->path;
2284 req->key_req_idx = key_idx;
2285 req->idx = netkey_idx; /* Encryption Key index */
2286 req->update_req = is_update;
2288 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2289 __bt_hal_mesh_key_config_send, NULL,
2290 (void*)req, l_free))
2291 return BT_STATUS_FAIL;
2293 ERR("Mesh: app not found!!");
2294 return BT_STATUS_PARM_INVALID;
2297 return BT_STATUS_SUCCESS;
2300 bt_status_t _bt_hal_mesh_send_configuration_message(
2301 bt_uuid_t *network, uint16_t dest,
2302 bool is_dev_key, uint16_t netkey_idx,
2303 uint8_t *buf, int len)
2307 struct configuration_request *req;
2310 int src_elem_idx = 0;
2311 l = g_slist_find_custom(mesh_apps, network->uu,
2312 __mesh_compare_network_uuid);
2315 if (!__bt_mesh_proxy_check(app)) {
2316 ERR("Mesh: Proxy check failed!!");
2317 return BT_STATUS_FAIL;
2319 l1 = g_slist_find_custom(app->elements,
2320 GUINT_TO_POINTER(src_elem_idx),
2321 __compare_element_index);
2324 req = l_new(struct configuration_request, 1);
2325 req->ele_path = elem->path;
2327 req->idx = netkey_idx;
2331 req->is_dev_key = is_dev_key;
2333 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2334 __bt_hal_mesh_config_send, NULL,
2335 (void*)req, l_free))
2336 return BT_STATUS_FAIL;
2338 ERR("Mesh: app not found!!");
2339 return BT_STATUS_PARM_INVALID;
2342 return BT_STATUS_SUCCESS;