Mesh: Fix coding style
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-mesh-dbus-handler.c
1 /*
2  * Bluetooth HAL
3  *
4  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * @author: Anupam Roy <anupam.r@samsung.com>
7  *
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
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <string.h>
26
27 #include <glib.h>
28 #include <gio/gio.h>
29 #include <dlog.h>
30 #include <vconf.h>
31 #include <ell/ell.h>
32
33 #include "bt-hal-mesh-dbus-handler.h"
34 #include "bt-hal-dbus-common-utils.h"
35 #include "bt-hal-internal.h"
36
37 #include <hardware/bt_mesh.h>
38
39 #define BT_HAL_MESH_DBUS_NAME "org.projectx.bt.mesh"
40
41 #define BT_HAL_UUID_LEN 16
42 #define BT_HAL_BLUEZ_MESH_NAME "org.bluez.mesh"
43
44 #define BT_HAL_MESH_NETWORK_INTERFACE "org.bluez.mesh.Network1"
45 #define BT_HAL_MESH_NODE_INTERFACE "org.bluez.mesh.Node1"
46 #define BT_HAL_MESH_MANAGEMENT_INTERFACE "org.bluez.mesh.Management1"
47 #define BT_HAL_MESH_ELEMENT_INTERFACE "org.bluez.mesh.Element1"
48 #define BT_HAL_MESH_APPLICATION_INTERFACE "org.bluez.mesh.Application1"
49 #define BT_HAL_MESH_PROVISION_AGENT_INTERFACE "org.bluez.mesh.ProvisionAgent1"
50 #define BT_HAL_MESH_PROVISIONER_INTERFACE "org.bluez.mesh.Provisioner1"
51 #define BT_HAL_MESH_ERROR_INTERFACE "org.bluez.mesh.Error"
52
53 #define BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE 2048
54 #define BT_HAL_MESH_MAX_MSG_BUF_SIZE 2048
55
56 static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs";
57 static const char *dbus_err_fail = "org.freedesktop.DBus.Error.Failed";
58
59 static struct l_dbus *dbus = NULL;
60 static struct l_dbus_client *client = NULL;
61
62 static struct l_dbus_proxy *net_proxy = NULL;
63 static struct l_dbus_message *agent_msg;
64
65 static handle_stack_msg mesh_event_cb = NULL;
66
67
68 struct subnet_key_request {
69         uint16_t idx;
70         const char *str;
71 };
72
73 struct app_key_request {
74         uint16_t net_idx;
75         uint16_t app_idx;
76         const char *str;
77 };
78
79 struct configuration_request {
80         const char *ele_path;
81         bool rmt;
82         bool is_dev_key;
83         uint16_t dst;
84         uint16_t idx;
85         uint8_t *data;
86         uint16_t len;
87 };
88
89 struct key_config_request {
90         const char *ele_path;
91         uint16_t dst;
92         uint16_t key_req_idx;
93         uint16_t idx;
94         bool update_req;
95 };
96
97 struct mesh_provision_auth_action {
98         const char *action;
99         bt_hal_mesh_auth_variant_e auth_type;
100 };
101
102 static struct mesh_provision_auth_action auth_table[] = {
103         { "blink", BT_HAL_MESH_AUTH_REQ_BLINK_COUNT_INPUT},
104         { "beep", BT_HAL_MESH_AUTH_REQ_BEEP_COUNT_INPUT},
105         { "vibrate", BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT},
106         { "in-numeric", BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT},
107         { "in-alpha", BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT},
108         { "twist", BT_HAL_MESH_AUTH_TWIST_COUNT_DISPLAY},
109         { "push", BT_HAL_MESH_AUTH_PUSH_COUNT_DISPLAY},
110         { "out-numeric", BT_HAL_MESH_AUTH_NUMERIC_DISPLAY},
111         { "out-alpha", BT_HAL_MESH_AUTH_ALPHANUMERIC_DISPLAY},
112         { "static-oob", BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT},
113         { "unknown", BT_HAL_MESH_UNKNOWN_AUTH_METHOD},
114 };
115
116
117 static uint8_t __bt_mesh_util_get_prov_error_code(char *prov_err_str)
118 {
119         uint8_t ret = 0;
120
121         if (!g_strcmp0(prov_err_str, "success"))
122                 ret = BT_HAL_MESH_PROV_ERR_SUCCESS;
123         else if (!g_strcmp0(prov_err_str, "bad-pduread"))
124                 ret = BT_HAL_MESH_PROV_ERR_INVALID_PDU;
125         else if (!g_strcmp0(prov_err_str, "confirmation-failed"))
126                 ret = BT_HAL_MESH_PROV_ERR_CONFIRM_FAILED;
127         else if (!g_strcmp0(prov_err_str, "out-of-resources"))
128                 ret = BT_HAL_MESH_PROV_ERR_INSUF_RESOURCE;
129         else if (!g_strcmp0(prov_err_str, "decryption-error"))
130                 ret = BT_HAL_MESH_PROV_ERR_DECRYPT_FAILED;
131         else if (!g_strcmp0(prov_err_str, "cannot-assign-addresses"))
132                 ret = BT_HAL_MESH_PROV_ERR_CANT_ASSIGN_ADDR;
133         else if (!g_strcmp0(prov_err_str, "timeout"))
134                 ret = BT_HAL_MESH_PROV_ERR_TIMEOUT;
135         else if (!g_strcmp0(prov_err_str, "unexpected-error"))
136                 ret = BT_HAL_MESH_PROV_ERR_UNEXPECTED_ERR;
137
138         return ret;
139 }
140
141 static bt_hal_mesh_auth_variant_e  __mesh_get_authentication_type(char *str)
142 {
143         int len = strlen(str);
144         int sz = L_ARRAY_SIZE(auth_table);
145         int i;
146
147         for (i = 0; i < sz; ++i)
148                 if (len == strlen(auth_table[i].action) &&
149                                 !strcmp(str, auth_table[i].action))
150                         break;
151         if (i < sz) {
152                 return auth_table[i].auth_type;
153         } else {
154                 ERR("Mesh : Not A Proper Authentication Type!");
155                 return BT_HAL_MESH_UNKNOWN_AUTH_METHOD;
156         }
157 }
158
159 enum mesh_dbus_interface_e {
160         MESH_APP_IFACE,
161         MESH_PROV_IFACE,
162         MESH_AGENT_IFACE,
163         MESH_ELEMENT_IFACE,
164 };
165
166 typedef enum mesh_dbus_interface_e mesh_dbus_interface_e;
167
168 struct meshcfg_model {
169         uint16_t elem_index;
170         uint32_t model;
171 };
172
173 typedef struct meshcfg_model meshcfg_model;
174
175 struct meshcfg_el {
176         char *path;
177         uint16_t index;
178         GSList *models;
179 };
180
181 typedef struct meshcfg_el meshcfg_el;
182
183 struct meshcfg_app {
184         /* Remember Proxies & dbus paths */
185         char *path;
186         char *agent_path;
187         struct l_dbus_proxy *proxy;
188         struct l_dbus_proxy *mgmt_proxy;
189
190         /* Local node Info */
191         GSList *elements;
192         uint16_t cid;
193         uint16_t pid;
194         uint16_t vid;
195         uint16_t crpl;
196         uint8_t uuid[16];
197         union {
198                 uint64_t u64;
199                 uint8_t u8[8];
200         } token;
201         bool is_prov;
202         /* Caps */
203         bool static_oob;
204         bool public_oob;
205         uint16_t out_oob;
206         uint16_t in_oob;
207         struct l_dbus_message *msg;
208         guint scan_timer_id;
209 };
210
211 typedef struct meshcfg_app meshcfg_app;
212
213 /* Will contain critical data related to local Mesh Network */
214 static GSList *mesh_apps = NULL;
215
216
217 struct meshcfg_node {
218         const char *path;
219         struct l_dbus_proxy *proxy;
220         struct l_dbus_proxy *mgmt_proxy;
221         union {
222                 uint64_t u64;
223                 uint8_t u8[8];
224         } token;
225 };
226
227 typedef struct meshcfg_node meshcfg_node;
228
229 static void __mesh_append_byte_array(struct l_dbus_message_builder *builder,
230                 unsigned char *data, unsigned int len)
231 {
232         unsigned int i;
233
234         l_dbus_message_builder_enter_array(builder, "y");
235
236         for (i = 0; i < len; i++)
237                 l_dbus_message_builder_append_basic(builder, 'y', &(data[i]));
238
239         l_dbus_message_builder_leave_array(builder);
240 }
241
242 static gint __mesh_compare_network_uuid(gconstpointer data, gconstpointer user_data)
243 {
244         const meshcfg_app *app = (meshcfg_app*) data;
245         uint8_t uuid[16];
246         memcpy(uuid, (uint8_t*) user_data, 16);
247
248         return memcmp(uuid, app->uuid, sizeof(bt_uuid_t));
249 }
250
251 static unsigned char* __mesh_get_net_uuid_from_dbus_proxy_path(
252                 const char *dbus_path)
253 {
254         char uuid[33];
255         size_t sz;
256
257         memcpy(uuid, (void*)&dbus_path[20], sizeof(uuid));
258         uuid[32] = '\0';
259         INFO("Mesh: Net UUID string [%s]", uuid);
260         return l_util_from_hexstring(uuid, &sz);
261 }
262
263 static unsigned char* __mesh_get_net_uuid_from_path(
264                 const char *dbus_path, bool is_prov,
265                         mesh_dbus_interface_e iface)
266 {
267         char uuid[33];
268         size_t sz;
269
270         switch (iface) {
271         case MESH_APP_IFACE:
272         case MESH_PROV_IFACE:  {
273                 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
274                 uuid[32] = '\0';
275                 return l_util_from_hexstring(uuid, &sz);
276         }
277         case MESH_AGENT_IFACE: {
278                 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[23], 32);
279                 uuid[32] = '\0';
280                 return l_util_from_hexstring(uuid, &sz);
281         }
282         case MESH_ELEMENT_IFACE: {
283                 memcpy(uuid, is_prov ? (void*) &dbus_path[16] : (void*) &dbus_path[17], 32);
284                 uuid[32] = '\0';
285                 return l_util_from_hexstring(uuid, &sz);
286         }
287         default:
288                 return NULL;
289         }
290 }
291
292 static void __mesh_hal_free_elements(gpointer data)
293 {
294         meshcfg_el *element = (meshcfg_el*) data;
295         if (!element)
296                 return;
297         g_free(element->path);
298         if (element->models)
299                 g_slist_free_full(element->models, g_free);
300
301         element->models = NULL;
302         g_free(element);
303 }
304
305 static bool __bt_mesh_proxy_check(meshcfg_app *app)
306 {
307         /* Check meshd stack Vis up or not */
308         if (!dbus) {
309                 ERR("Mesh: DBUS is not UP!, possibly stack not Up!");
310                 return false;
311         }
312         /* Check Network Proxy is added or not */
313         if (!net_proxy) {
314                 ERR("Mesh: Network proxy is not attached yet!");
315                 return false;
316         }
317
318         if (app) {
319                 /* Check App management proxyis added or not */
320                 if (!app->mgmt_proxy) {
321                         ERR("Mesh: Network proxy is not attached yet!");
322                         return false;
323                 }
324                 /* Check App  Node Proxy is added or not */
325                 if (!app->proxy) {
326                         ERR("Mesh: Node proxy is not attached yet!");
327                         return false;
328                 }
329         }
330         return true;
331 }
332
333 static void __bt_hal_mesh_destroy_app_object(gpointer data)
334 {
335
336         meshcfg_app *app = (meshcfg_app*) data;
337         if (!app)
338                 return;
339
340         mesh_apps = g_slist_remove(mesh_apps, app);
341
342         if (app->path) {
343                 INFO("Mesh: App path [%s] ", app->path);
344                 g_free(app->path);
345         }
346         if (app->agent_path) {
347                 INFO("Mesh: Agent Path [%s]", app->agent_path);
348                 g_free(app->agent_path);
349         }
350
351         if (app->elements) {
352                 INFO("Mesh: Total elements present in app [%d]",
353                                 g_slist_length(app->elements));
354                 g_slist_free_full(app->elements, __mesh_hal_free_elements);
355         }
356         g_free(app);
357 }
358
359 static void __mesh_client_connected(struct l_dbus *dbus_obj, void *user_data)
360 {
361         ERR("MESH: D-Bus client connected\n");
362         dbus = dbus_obj;
363         if (dbus)
364                 INFO("Mesh: MeshD connected: dbus [%p]", dbus);
365 }
366
367 static void __mesh_client_disconnected(struct l_dbus *dbus_obj, void *user_data)
368 {
369         ERR("MESH: D-Bus client disconnected, possibly meshd exited \n");
370         /* TODO: Send event to app about meshd termination  & then remove all mesh apps */
371         INFO("Mesh: Total number of networks present [%d]",
372                         g_slist_length(mesh_apps));
373
374         if (mesh_apps) {
375                 g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
376                 mesh_apps = NULL;
377         }
378         /* Set DBUS to NULL */
379         if (dbus)
380                 INFO("Mesh: dbus [%p]", dbus);
381         if (net_proxy)
382                 INFO("Mesh: net proxy [%p]", net_proxy);
383
384         dbus = NULL;
385         net_proxy = NULL;
386         INFO("Mesh: All apps cleaned up after meshd exited");
387 }
388
389 static gint __compare_proxy_path(gconstpointer data, gconstpointer user_data)
390 {
391         int ret = 0;
392         char *app_uuid_path;
393         const meshcfg_app *app = (meshcfg_app*) data;
394         char *path = (char *) user_data;
395         INFO("Mesh: proxy path compare: path [%s]", path);
396         INFO("Mesh: App Path  path [%s]", app->path);
397         if (!path)
398                 return -1;
399
400         app_uuid_path = l_util_hexstring(app->uuid, 16);
401         INFO("Mesh:App UUID string [%s]", app_uuid_path);
402         char **strings =  g_strsplit(path, "node", 2);
403
404         INFO("Mesh:String 0 [%s]", strings[0]);
405         INFO("Mesh:String 1 [%s]", strings[1]);
406         ret = g_strcmp0(strings[1], app_uuid_path);
407         g_free(strings[0]);
408         g_free(strings[1]);
409         l_free(app_uuid_path);
410         return ret;
411 }
412
413 static gint __compare_element_index(gconstpointer data, gconstpointer user_data)
414 {
415         const meshcfg_el *elem = data;
416         uint16_t elem_index = GPOINTER_TO_UINT(user_data);
417         if (!elem)
418                 return 1;
419
420         return (elem->index == elem_index ? 0 : -1);
421 }
422
423 static void __mesh_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
424 {
425         const char *interface = l_dbus_proxy_get_interface(proxy);
426         const char *path = l_dbus_proxy_get_path(proxy);
427
428         INFO("MESH: Proxy added: %s (%s)\n", interface, path);
429
430         if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
431                 INFO("Mesh: Network Proxy added");
432                 /* Save Global proxy */
433                 net_proxy = proxy;
434                 if (net_proxy)
435                         INFO("Mesh: Net Proxy [%p]", net_proxy);
436                 return;
437         }
438
439         if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
440                 GSList *l;
441                 meshcfg_app *app;
442                 INFO("Mesh: Mgmt Proxy added");
443                 INFO("Mesh: Number of mesh app present in list [%d]",
444                         g_slist_length(mesh_apps));
445                 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
446                 if (l) {
447                         app = l->data;
448                         app->mgmt_proxy = proxy;
449                 } else {
450                         ERR("Mesh: app not found for Mgmt proxy");
451                 }
452                 return;
453         }
454
455         if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
456                 INFO("Mesh: Node Proxy added");
457                 GSList *l;
458                 meshcfg_app *app;
459                 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
460                 if (l) {
461                         app = l->data;
462                         app->proxy = proxy;
463                 } else {
464                         ERR("Mesh: app not found for Node proxy");
465                 }
466                 return;
467         }
468 }
469
470 static void __mesh_proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
471 {
472         const char *interface = l_dbus_proxy_get_interface(proxy);
473         const char *path = l_dbus_proxy_get_path(proxy);
474
475         INFO("Proxy removed: %s (%s)\n", interface, path);
476
477         if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
478                 INFO("Mesh: Network Interface removed,, possibly meshd terminated.\n");
479                 /*TODO: Send event to app about stop of Mesh service  & then remove all apps */
480                 if (mesh_apps) {
481                         g_slist_free_full(mesh_apps, __bt_hal_mesh_destroy_app_object);
482                         mesh_apps = NULL;
483                         return;
484                 }
485         } else if (!strcmp(interface, BT_HAL_MESH_NODE_INTERFACE)) {
486                 INFO("Mesh: Node Interface removed,, possibly node has left network.\n");
487                 GSList *l;
488                 meshcfg_app *app;
489                 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
490                 if (l) {
491                         app = l->data;
492                         /*TODO: Send event to app about removal of a mesh local node */
493                         __bt_hal_mesh_destroy_app_object(app);
494                 } else {
495                         ERR("Mesh: app not found for Mgmt proxy");
496                 }
497                 return;
498         } else if (!strcmp(interface, BT_HAL_MESH_MANAGEMENT_INTERFACE)) {
499                 INFO("Mesh: Managament Interface removed,, possibly node has left network.\n");
500                 GSList *l;
501                 meshcfg_app *app;
502                 l = g_slist_find_custom(mesh_apps, path, __compare_proxy_path);
503                 if (l) {
504                         app = l->data;
505                         /*TODO: Send event to app about removal of
506                         a mesh local node: first send event, then destroy mesh object */
507                         __bt_hal_mesh_destroy_app_object(app);
508                 } else {
509                         ERR("Mesh: app not found for Mgmt proxy");
510                 }
511                 return;
512         }
513 }
514
515 static void __mesh_dbus_client_ready(struct l_dbus_client *client_obj,
516                 void *user_data)
517 {
518         INFO("Mesh: D-Bus client ready: bluetooth-meshd connected \n");
519         client = client_obj;
520 }
521
522 static void __mesh_acquire_name_callback(struct l_dbus *dbus_obj, bool success,
523                                         bool queued, void *user_data)
524 {
525         if (success == false)
526                 ERR("Mesh: Fail to acquire dbus name\n");
527
528         if (!l_dbus_object_manager_enable(dbus_obj, "/"))
529                 ERR("Mesh: Failed to register the ObjectManager\n");
530 }
531
532 static void __mesh_ready_callback(void *user_data)
533 {
534         INFO("Mesh: Connected to D-Bus\n");
535
536         if (!l_dbus_name_acquire(dbus, BT_HAL_MESH_DBUS_NAME, false, false, false,
537                                 __mesh_acquire_name_callback, NULL))
538                 ERR("Mesh: Failed to own well-known name\n");
539 }
540
541 bool _bt_hal_mesh_stack_init(void)
542 {
543         INFO("Mesh: Connect with meshd");
544         /* Connect with meshd */
545         dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
546         if (!dbus)
547                 return false;
548
549         INFO("Mesh: Got dbus [%p]", dbus);
550
551         if (!l_dbus_set_ready_handler(dbus, __mesh_ready_callback, NULL, NULL))
552                 return false;
553
554         client = l_dbus_client_new(dbus,
555                         BT_HAL_BLUEZ_MESH_NAME, "/org/bluez/mesh");
556         if (!client)
557                 return false;
558
559         if (!l_dbus_client_set_connect_handler(client,
560                                 __mesh_client_connected, NULL, NULL))
561                 return false;
562
563         if (!l_dbus_client_set_disconnect_handler(client,
564                                 __mesh_client_disconnected, NULL,
565                                 NULL))
566                 return false;
567         if (!l_dbus_client_set_proxy_handlers(client,
568                                 __mesh_proxy_added, __mesh_proxy_removed,
569                                 NULL, NULL, NULL))
570                 return false;
571         if (!l_dbus_client_set_ready_handler(client,
572                                 __mesh_dbus_client_ready, NULL, NULL))
573                 return false;
574
575         INFO("Mesh: Stack Init watchers registered with  meshd");
576         return true;
577 }
578
579 /* To send stack event to hal-mesh handler */
580 void _bt_hal_mesh_register_dbus_handler_cb(handle_stack_msg cb)
581 {
582         mesh_event_cb = cb;
583 }
584
585 /* To send stack event to hal-mesh handler */
586 void _bt_hal_mesh_unregister_dbus_handler_cb()
587 {
588         mesh_event_cb = NULL;
589 }
590
591 static bool __mesh_get_companyid(struct l_dbus *dbus,
592                 struct l_dbus_message *message,
593                         struct l_dbus_message_builder *builder,
594                                 void *user_data)
595 {
596         meshcfg_app *app = (meshcfg_app*) user_data;
597         if (!app)
598                 return false;
599
600         l_dbus_message_builder_append_basic(builder, 'q', &app->cid);
601
602         return true;
603 }
604
605 static bool __mesh_get_productid(struct l_dbus *dbus,
606                 struct l_dbus_message *message,
607                         struct l_dbus_message_builder *builder,
608                                 void *user_data)
609 {
610         meshcfg_app *app = (meshcfg_app*) user_data;
611         if (!app)
612                 return false;
613         l_dbus_message_builder_append_basic(builder, 'q', &app->pid);
614
615         return true;
616 }
617
618 static bool __mesh_get_versionid(struct l_dbus *dbus,
619                 struct l_dbus_message *message,
620                         struct l_dbus_message_builder *builder,
621                                 void *user_data)
622 {
623         meshcfg_app *app = (meshcfg_app*) user_data;
624         if (!app)
625                 return false;
626         l_dbus_message_builder_append_basic(builder, 'q', &app->vid);
627
628         return true;
629 }
630
631 static bool __mesh_get_crpl(struct l_dbus *dbus,
632                 struct l_dbus_message *message,
633                         struct l_dbus_message_builder *builder,
634                                 void *user_data)
635 {
636         meshcfg_app *app = (meshcfg_app*) user_data;
637         if (!app)
638                 return false;
639         l_dbus_message_builder_append_basic(builder, 'q', &app->crpl);
640
641         return true;
642 }
643
644 static void __send_network_attach_event(void *param, uint8_t status)
645 {
646         struct hal_ev_mesh_network_attached ev;
647         meshcfg_app *app = (meshcfg_app*)param;
648
649         memset(&ev, 0, sizeof(ev));
650         memcpy(ev.uuid, app->uuid, sizeof(app->uuid));
651         memcpy(ev.token, app->token.u8, 8);
652
653         ev.status = status;
654         if (mesh_event_cb)
655                 mesh_event_cb(HAL_EV_MESH_NETWORK_ATTACHED,
656                         (void*)&ev, sizeof(ev));
657 }
658
659 static void __bt_hal_mesh_attach_node_reply(struct l_dbus_proxy *proxy,
660                 struct l_dbus_message *msg, void *user_data)
661 {
662         struct l_dbus_message_iter iter_cfg;
663         char *path;
664         meshcfg_app *app = (meshcfg_app*) user_data;
665         INFO("Mesh: Attach Node Reply: App path [%s] Agent Path [%s]",
666                 app->path, app->agent_path);
667
668         if (l_dbus_message_is_error(msg)) {
669                 const char *name;
670                 l_dbus_message_get_error(msg, &name, NULL);
671                 ERR("Mesh: Failed to attach node: %s", name);
672                 goto failed;
673
674         }
675
676         if (!l_dbus_message_get_arguments(msg, "oa(ya(qa{sv}))",
677                                 &path, &iter_cfg))
678                 goto failed;
679
680         INFO("Mesh: Attached with path %s\n", app->path);
681         __send_network_attach_event(app, BT_STATUS_SUCCESS);
682         return;
683 failed:
684         __send_network_attach_event(app, BT_STATUS_FAIL);
685         /* Destroy mesh app object */
686         __bt_hal_mesh_destroy_app_object(app);
687 }
688
689 static void __bt_hal_mesh_attach_node_setup(struct l_dbus_message *msg,
690                 void *user_data)
691 {
692         meshcfg_app *app = (meshcfg_app*) user_data;
693
694         l_dbus_message_set_arguments(msg, "ot", app->path,
695                         l_get_be64(app->token.u8));
696 }
697
698
699 static void __bt_hal_mesh_attach_node(void *user_data)
700 {
701         if (!l_dbus_proxy_method_call(net_proxy, "Attach",
702                                 __bt_hal_mesh_attach_node_setup,
703                                 __bt_hal_mesh_attach_node_reply,
704                                 user_data,
705                                 NULL)) {
706                 ERR("Mesh: Node attach failed!!");
707                 /* Node could not be attached */
708                 __send_network_attach_event(user_data, BT_STATUS_FAIL);
709                 /* Destroy mesh app object */
710                 __bt_hal_mesh_destroy_app_object((meshcfg_app*)user_data);
711         }
712 }
713
714 static struct l_dbus_message *__mesh_node_join_complete(struct l_dbus *dbus,
715                 struct l_dbus_message *message,
716                         void *user_data)
717 {
718         char *str;
719         uint64_t tmp;
720
721         meshcfg_app *app = (meshcfg_app*) user_data;
722         INFO("Mesh: Join Complete");
723
724         /* Return error */
725         if (!l_dbus_message_get_arguments(message, "t", &tmp)) {
726
727                 /* Send Network creation fail event */
728                 __send_network_attach_event(app, BT_STATUS_FAIL);
729
730                 /* Destroy mesh app object */
731                 __bt_hal_mesh_destroy_app_object(app);
732
733                 return l_dbus_message_new_error(message, dbus_err_args, NULL);
734         }
735
736         /* Save token */
737         app->token.u64 = l_get_be64(&tmp);
738         str = l_util_hexstring(&app->token.u8[0], 8);
739         INFO("Mesh: Created new node with token %s\n", str);
740         l_free(str);
741
742         /* Authenticate the node */
743         l_idle_oneshot(__bt_hal_mesh_attach_node, app, NULL);
744         return l_dbus_message_new_method_return(message);
745 }
746
747 static void __bt_hal_mesh_foreach_model_getter(gpointer data,
748                 gpointer user_data)
749 {
750         struct l_dbus_message_builder *builder = (struct l_dbus_message_builder *) user_data;
751         meshcfg_model *model_info = (meshcfg_model*) data;
752
753         l_dbus_message_builder_append_basic(builder, 'q', &model_info->model);
754 }
755
756 static bool __mesh_model_getter(struct l_dbus *dbus,
757                 struct l_dbus_message *message,
758                         struct l_dbus_message_builder *builder,
759                                 void *user_data)
760 {
761         meshcfg_el *element = (meshcfg_el*) user_data;
762
763         l_dbus_message_builder_enter_array(builder, "q");
764         g_slist_foreach(element->models,
765                 __bt_hal_mesh_foreach_model_getter, builder);
766
767         l_dbus_message_builder_leave_array(builder);
768
769         return true;
770 }
771
772 /*TODO: Vendor Model handling is currently not Handled */
773 static bool __mesh_vendor_model_getter(struct l_dbus *dbus,
774                 struct l_dbus_message *message,
775                         struct l_dbus_message_builder *builder,
776                                 void *user_data)
777 {
778         l_dbus_message_builder_enter_array(builder, "(qq)");
779         l_dbus_message_builder_leave_array(builder);
780
781         return true;
782 }
783
784 static bool __mesh_element_index_getter(struct l_dbus *dbus,
785                 struct l_dbus_message *message,
786                         struct l_dbus_message_builder *builder,
787                                 void *user_data)
788 {
789         meshcfg_el *element = (meshcfg_el*) user_data;
790         l_dbus_message_builder_append_basic(builder, 'y', &element->index);
791
792         return true;
793 }
794
795
796 static struct l_dbus_message *__mesh_device_message_received(struct l_dbus *dbus,
797                 struct l_dbus_message *msg, void *user_data)
798 {
799         struct l_dbus_message_iter iter;
800         uint16_t src, idx;
801         uint8_t *data;
802         uint32_t n;
803         bool rmt;
804         const char *dbus_path;
805         uint16_t size;
806         uint8_t *net_uuid;
807         dbus_path =  l_dbus_message_get_path(msg);
808         net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,  MESH_ELEMENT_IFACE);
809         uint8_t buf[BT_HAL_MESH_MAX_DEVKEY_BUF_SIZE];
810         struct hal_ev_mesh_devkey_message_event *ev = (void *)buf;
811
812         INFO("Mesh: app path [%s]", dbus_path);
813
814         memset(buf, 0, sizeof(buf));
815         size = (uint16_t) sizeof(*ev);
816         memcpy(ev->net_uuid, net_uuid, 16);
817         g_free(net_uuid);
818
819         if (!l_dbus_message_get_arguments(msg, "qbqay", &src, &rmt, &idx,
820                                 &iter)) {
821                 ERR("Mesh: Cannot parse received message");
822                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
823         }
824
825         if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
826                 ERR("Mesh: Cannot parse received message: data");
827                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
828         }
829
830         INFO("Mesh: Received dev key message (len %u):", n);
831         ev->source_addr = src;
832         ev->is_remote_devkey = rmt;
833         ev->netkey_idx = idx;
834         ev->data_len = n;
835         memcpy(ev->data, data, n);
836         size += n;
837
838         INFO("Mesh: Src [0x%2.2x]", src);
839         INFO("Mesh: Is Remote [%s]", rmt ? "YES" : "NO");
840         INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
841         /* Send DevKeyMessage Received event */
842         if (mesh_event_cb)
843                 mesh_event_cb(HAL_EV_MESH_DEVKEY_MESSAGE_EVENT, (void*)buf, size);
844         return l_dbus_message_new_method_return(msg);
845 }
846
847 static struct l_dbus_message *__mesh_message_received(struct l_dbus *dbus,
848                 struct l_dbus_message *msg, void *user_data)
849 {
850         struct l_dbus_message_iter iter;
851         uint16_t src, idx, dst;
852         uint8_t *data;
853         uint32_t n;
854         const char *dbus_path;
855         uint16_t size;
856         uint8_t *net_uuid;
857         dbus_path =  l_dbus_message_get_path(msg);
858         net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,  MESH_ELEMENT_IFACE);
859         uint8_t buf[BT_HAL_MESH_MAX_MSG_BUF_SIZE];
860         struct hal_ev_mesh_message_event *ev = (void *)buf;
861
862         INFO("Mesh: app path [%s]", dbus_path);
863
864         memset(buf, 0, sizeof(buf));
865         size = (uint16_t) sizeof(*ev);
866         memcpy(ev->net_uuid, net_uuid, 16);
867         g_free(net_uuid);
868
869         if (!l_dbus_message_get_arguments(msg, "qqvay", &src, &idx, &dst,
870                                 &iter)) {
871                 ERR("Mesh: Cannot parse received message");
872                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
873         }
874
875         if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
876                 ERR("Mesh: Cannot parse received message: data");
877                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
878         }
879
880         INFO("Mesh: Received mesh message (len %u):", n);
881         ev->source_addr = src;
882         ev->dest_addr = dst;
883         ev->key_idx = idx;
884         ev->data_len = n;
885         memcpy(ev->data, data, n);
886         size += n;
887
888         INFO("Mesh: Src [0x%2.2x]", src);
889         INFO("Mesh: Dst [0x%2.2x]", dst);
890         INFO("Mesh: NetKey Idx [0x%2.2x]", idx);
891         /* Send Message Received event */
892         if (mesh_event_cb) {
893                 INFO("Mesh: Send message event");
894                 mesh_event_cb(HAL_EV_MESH_MESSAGE_EVENT, (void*)buf, size);
895         }
896         return l_dbus_message_new_method_return(msg);
897 }
898
899 static void __bt_hal_mesh_setup_ele_iface(struct l_dbus_interface *iface)
900 {
901         INFO("Mesh: Setup element interface properties & methods");
902         /* Properties */
903         l_dbus_interface_property(iface, "Index", 0, "y", __mesh_element_index_getter,
904                         NULL);
905         l_dbus_interface_property(iface, "VendorModels", 0, "a(qq)",
906                         __mesh_vendor_model_getter, NULL);
907         l_dbus_interface_property(iface, "Models", 0, "aq", __mesh_model_getter, NULL);
908
909         /* Methods */
910         l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
911                         __mesh_device_message_received, "", "qbqay", "source",
912                         "remote", "net_index", "data");
913         l_dbus_interface_method(iface, "MessageReceived", 0,
914                         __mesh_message_received, "", "qqvay", "source",
915                         "key_index", "destination", "data");
916         /* TODO: Other methods */
917 }
918
919 static struct l_dbus_message *__mesh_scan_result_received(struct l_dbus *dbus,
920                 struct l_dbus_message *msg,
921                         void *user_data)
922 {
923         struct l_dbus_message_iter iter, opts;
924         meshcfg_app *app = (meshcfg_app*) user_data;
925         int16_t rssi;
926         uint32_t n;
927         uint8_t *prov_data;
928         char *str;
929         const char *sig = "naya{sv}";
930
931         /* Find network uuid from dbus path */
932         struct hal_ev_mesh_scan_result ev;
933
934         if (!app->scan_timer_id) {
935                 /* Scan is not running */
936                 INFO("Got scan result, but scan is already stopped");
937                 return l_dbus_message_new_method_return(msg);
938         }
939         memset(&ev, 0, sizeof(ev));
940         memcpy(ev.net_uuid, app->uuid, 16);
941
942         if (!l_dbus_message_get_arguments(msg, sig, &rssi, &iter, &opts)) {
943                 ERR("Mesh: Cannot parse scan results");
944                 ev.status = BT_STATUS_FAIL;
945                 if (mesh_event_cb)
946                         mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
947                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
948         }
949
950         if (!l_dbus_message_iter_get_fixed_array(&iter, &prov_data, &n) ||
951                         n < 16) {
952                 ERR("Mesh: Cannot parse scan result: data");
953                 ev.status = BT_STATUS_FAIL;
954                 if (mesh_event_cb)
955                         mesh_event_cb(HAL_EV_MESH_SCAN_RESULT, (void*)&ev, sizeof(ev));
956                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
957         }
958
959         INFO("Mesh: Scan result:\n");
960         INFO("Mesh: Scan rssi = [%d]\n", rssi);
961         str = l_util_hexstring_upper(prov_data, 16);
962         INFO("Mesh: Scan UUID = [%s]\n",  str);
963         l_free(str);
964
965         if (n >= 18) {
966                 str = l_util_hexstring_upper(prov_data + 16, 2);
967                 INFO("Mesh: Scan OOB = [%s]\n", str);
968                 l_free(str);
969         }
970
971         if (n >= 22) {
972                 str = l_util_hexstring_upper(prov_data + 18, 4);
973                 INFO("Mesh: Scan URI hash = [%s]\n", str);
974                 l_free(str);
975         }
976
977         /* 16 octet Dev UUID */
978         memcpy(ev.dev_uuid, prov_data, 16);
979
980         /* 2 octet Dev OOB Info */
981         memcpy(ev.oob_info, prov_data + 16, 2);
982
983         /* 4 octet URI Hash */
984         memcpy(ev.uri_hash, prov_data + 18, 4);
985
986         ev.rssi = rssi;
987
988         ev.status = BT_STATUS_SUCCESS;
989         if (mesh_event_cb)
990                 mesh_event_cb(HAL_EV_MESH_SCAN_RESULT,
991                         (void*)&ev, sizeof(ev));
992
993         return l_dbus_message_new_method_return(msg);
994 }
995
996 static struct l_dbus_message *__mesh_request_provisioner_call(
997                 struct l_dbus *dbus,
998                         struct l_dbus_message *msg,
999                                 void *user_data)
1000 {
1001         uint8_t cnt;
1002         struct hal_ev_mesh_provision_finished ev;
1003         struct hal_ev_mesh_provision_data_request req;
1004         char *uuid_string;
1005         meshcfg_app *app = user_data;
1006
1007         INFO("Mesh: provisioning data requested app path [%s]",
1008                 app->path);
1009         uuid_string = l_util_hexstring(app->uuid, 16);
1010         INFO("Mesh: Network UUID [%s]", uuid_string);
1011
1012         memset(&ev, 0, sizeof(ev));
1013         memset(&req, 0, sizeof(req));
1014         memcpy(ev.net_uuid, app->uuid, 16);
1015         memcpy(req.net_uuid, app->uuid, 16);
1016         l_free(uuid_string);
1017
1018         if (!l_dbus_message_get_arguments(msg, "y", &cnt)) {
1019                 ERR("Mesh: Cannot parse request for prov data");
1020                 /* Send Event */
1021                 ev.status = BT_STATUS_FAIL;
1022                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1023                 if (mesh_event_cb)
1024                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1025                                 (void*)&ev, sizeof(ev));
1026                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1027         }
1028
1029         app->msg = msg;
1030         req.count = cnt;
1031         if (mesh_event_cb)
1032                 mesh_event_cb(HAL_EV_MESH_PROVISIONING_DATA_REQUEST,
1033                         (void*)&req, sizeof(req));
1034
1035         l_dbus_message_ref(msg);
1036         return NULL;
1037 }
1038
1039 static struct l_dbus_message *__mesh_node_add_completed(
1040                 struct l_dbus *dbus,
1041                         struct l_dbus_message *msg,
1042                                 void *user_data)
1043 {
1044         struct l_dbus_message_iter iter;
1045         int16_t unicast;
1046         uint8_t cnt;
1047         uint32_t n;
1048         uint8_t *uuid;
1049         struct hal_ev_mesh_provision_finished ev;
1050         const char *dbus_path;
1051         uint8_t *net_uuid;
1052         dbus_path =  l_dbus_message_get_path(msg);
1053         net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1054                         true,  MESH_PROV_IFACE);
1055
1056         INFO("Mesh: app path [%s]", dbus_path);
1057
1058         memset(&ev, 0, sizeof(ev));
1059         memcpy(ev.net_uuid, net_uuid, 16);
1060
1061         g_free(net_uuid);
1062
1063         if (!l_dbus_message_get_arguments(msg, "ayqy", &iter, &unicast, &cnt)) {
1064                 ERR("Mesh: Cannot parse add node complete message");
1065                 /* Send Event */
1066                 ev.status = BT_STATUS_FAIL;
1067                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1068                 if (mesh_event_cb)
1069                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1070                                 (void*)&ev, sizeof(ev));
1071                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1072         }
1073
1074         if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1075                         n != 16) {
1076                 ERR("Mesh: Cannot parse add node complete message: uuid");
1077                 /* Send Event */
1078                 ev.status = BT_STATUS_FAIL;
1079                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1080                 if (mesh_event_cb)
1081                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1082                                 (void*)&ev, sizeof(ev));
1083                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1084         }
1085
1086         /* Send Event */
1087         ev.status = BT_STATUS_SUCCESS;
1088         ev.reason = BT_HAL_MESH_PROV_ERR_SUCCESS;
1089         memcpy(ev.dev_uuid, uuid, 16);
1090         ev.unicast = unicast;
1091         ev.count = cnt;
1092
1093         if (mesh_event_cb)
1094                 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1095                         (void*)&ev, sizeof(ev));
1096
1097         return l_dbus_message_new_method_return(msg);
1098 }
1099
1100 static struct l_dbus_message *__mesh_node_add_failed(
1101                 struct l_dbus *dbus,
1102                         struct l_dbus_message *msg,
1103                                 void *user_data)
1104 {
1105         struct l_dbus_message_iter iter;
1106         uint32_t n;
1107         uint8_t *uuid;
1108         char *str, *reason;
1109         struct hal_ev_mesh_provision_finished ev;
1110         const char *dbus_path;
1111
1112         uint8_t *net_uuid;
1113         dbus_path =  l_dbus_message_get_path(msg);
1114         net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1115                         true,  MESH_PROV_IFACE);
1116
1117         memset(&ev, 0, sizeof(ev));
1118         memcpy(ev.net_uuid, net_uuid, 16);
1119
1120         g_free(net_uuid);
1121         if (!l_dbus_message_get_arguments(msg, "ays", &iter, &reason)) {
1122                 ERR("Mesh: Cannot parse add node failed message");
1123                 /* Send Event */
1124                 ev.status = BT_STATUS_FAIL;
1125                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1126                 if (mesh_event_cb)
1127                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1128                                 (void*)&ev, sizeof(ev));
1129                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1130         }
1131
1132         if (!l_dbus_message_iter_get_fixed_array(&iter, &uuid, &n) ||
1133                         n != 16) {
1134                 ERR("Mesh:Cannot parse add node failed message: uuid");
1135                 ev.status = BT_STATUS_FAIL;
1136                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1137                 if (mesh_event_cb)
1138                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1139                                 (void*)&ev, sizeof(ev));
1140                 return l_dbus_message_new_error(msg, dbus_err_args, NULL);
1141         }
1142
1143         INFO("Mesh: Provisioning failed:\n");
1144         str = l_util_hexstring_upper(uuid, 16);
1145         INFO("Mesh: UUID = [%s] Reason [%s]", str, reason);
1146         l_free(str);
1147
1148         ev.status = BT_STATUS_FAIL;
1149         ev.reason = __bt_mesh_util_get_prov_error_code(str);
1150         memcpy(ev.dev_uuid, uuid, 16);
1151
1152         if (mesh_event_cb)
1153                 mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1154                         (void*)&ev, sizeof(ev));
1155
1156         return l_dbus_message_new_method_return(msg);
1157 }
1158
1159 static void __bt_hal_mesh_setup_prov_iface(struct l_dbus_interface *interface)
1160 {
1161         INFO("Mesh: Setup provisioner interface properties & methods");
1162         l_dbus_interface_method(interface, "ScanResult", 0,
1163                         __mesh_scan_result_received, "",
1164                         "naya{sv}", "rssi", "data", "options");
1165
1166         l_dbus_interface_method(interface, "RequestProvData", 0,
1167                         __mesh_request_provisioner_call,
1168                         "qq", "y", "net_index", "unicast", "count");
1169
1170         l_dbus_interface_method(interface, "AddNodeComplete", 0,
1171                         __mesh_node_add_completed, "", "ayqy",
1172                         "uuid", "unicast", "count");
1173
1174         l_dbus_interface_method(interface, "AddNodeFailed", 0,
1175                         __mesh_node_add_failed,
1176                         "", "ays", "uuid", "reason");
1177 }
1178
1179 static void __bt_hal_mesh_setup_app_iface(struct l_dbus_interface *iface)
1180 {
1181         INFO("Mesh: Setup application interface properties & methods");
1182
1183         l_dbus_interface_property(iface, "CompanyID", 0, "q",
1184                         __mesh_get_companyid,
1185                         NULL);
1186         l_dbus_interface_property(iface, "VersionID", 0, "q",
1187                         __mesh_get_versionid,
1188                         NULL);
1189         l_dbus_interface_property(iface, "ProductID", 0, "q",
1190                         __mesh_get_productid,
1191                         NULL);
1192         l_dbus_interface_property(iface, "CRPL", 0, "q",
1193                         __mesh_get_crpl, NULL);
1194         l_dbus_interface_method(iface, "JoinComplete", 0,
1195                         __mesh_node_join_complete,
1196                         "", "t", "token");
1197
1198         /* TODO: Methods */
1199 }
1200
1201 static void __mesh_fill_in_capabilities(meshcfg_app *app,
1202                  struct l_dbus_message_builder *builder)
1203 {
1204         if (app->in_oob & 0x08)
1205                 l_dbus_message_builder_append_basic(builder, 's', "in-alpha");
1206         if (app->in_oob & 0x04)
1207                 l_dbus_message_builder_append_basic(builder, 's', "in-numeric");
1208         if (app->in_oob & 0x02)
1209                 l_dbus_message_builder_append_basic(builder, 's', "twist");
1210         if (app->in_oob & 0x01)
1211                 l_dbus_message_builder_append_basic(builder, 's', "push");
1212 }
1213
1214 static void __mesh_fill_out_capabilities(meshcfg_app *app,
1215                  struct l_dbus_message_builder *builder)
1216 {
1217         if (app->out_oob & 0x10)
1218                 l_dbus_message_builder_append_basic(builder, 's', "out-alpha");
1219         if (app->out_oob & 0x08)
1220                 l_dbus_message_builder_append_basic(builder, 's', "out-numeric");
1221         if (app->out_oob & 0x04)
1222                 l_dbus_message_builder_append_basic(builder, 's', "vibrate");
1223         if (app->out_oob & 0x02)
1224                 l_dbus_message_builder_append_basic(builder, 's', "beep");
1225         if (app->out_oob & 0x01)
1226                 l_dbus_message_builder_append_basic(builder, 's', "blink");
1227 }
1228
1229 static bool __mesh_agent_capability_getter(
1230                 struct l_dbus *dbus, struct l_dbus_message *message,
1231                         struct l_dbus_message_builder *builder,
1232                                 void *user_data)
1233 {
1234         meshcfg_app *app;
1235         app = user_data;
1236         INFO("Mesh: app path [%s]", app->path);
1237         INFO("Mesh: Agent path [%s]", app->agent_path);
1238
1239         if (!l_dbus_message_builder_enter_array(builder, "s"))
1240                 return false;
1241
1242         __mesh_fill_out_capabilities(app, builder);
1243         __mesh_fill_in_capabilities(app, builder);
1244
1245         if (app->static_oob)
1246                 l_dbus_message_builder_append_basic(builder,
1247                         's', "static-oob");
1248
1249
1250         l_dbus_message_builder_leave_array(builder);
1251         INFO("Mesh: __agent_capability_getter: Success");
1252         return true;
1253 }
1254
1255 static struct l_dbus_message *__mesh_agent_display_string_request(
1256                 struct l_dbus *dbus,
1257                         struct l_dbus_message *msg,
1258                                 void *user_data)
1259 {
1260         struct hal_ev_mesh_authentication_request ev;
1261         char *str;
1262         uint8_t *net_uuid;
1263         const char *dbus_path;
1264         meshcfg_app *app;
1265         app = user_data;
1266         INFO("Mesh: app path [%s]", app->path);
1267         INFO("Mesh: Agent path [%s]", app->agent_path);
1268
1269         dbus_path =  l_dbus_message_get_path(msg);
1270         net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1271                         true,  MESH_AGENT_IFACE);
1272
1273         INFO("Mesh: app path [%s]", dbus_path);
1274
1275         memset(&ev, 0, sizeof(ev));
1276         memcpy(ev.net_uuid, net_uuid, 16);
1277
1278
1279         if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1280                 ERR("Mesh: Cannot parse \"DisplayString\" arguments");
1281                 struct hal_ev_mesh_provision_finished ev;
1282                 memset(&ev, 0, sizeof(ev));
1283                 memcpy(ev.net_uuid, net_uuid, 16);
1284                 ev.status = BT_STATUS_FAIL;
1285                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1286                 if (mesh_event_cb)
1287                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1288                                 (void*)&ev, sizeof(ev));
1289
1290                 g_free(net_uuid);
1291
1292                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1293         }
1294
1295         INFO("Mesh:[OUT] AlphaNumeric Authentication: Value [%s]", str);
1296         ev.auth_type = __mesh_get_authentication_type(str);
1297         if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1298                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1299         g_strlcpy(ev.auth_value, str, sizeof(ev.auth_value));
1300
1301         if (mesh_event_cb)
1302                 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1303                         (void*)&ev, sizeof(ev));
1304
1305         g_free(net_uuid);
1306         return l_dbus_message_new_method_return(msg);
1307 }
1308
1309 static struct l_dbus_message *__mesh_agent_display_numeric_request(
1310                 struct l_dbus *dbus,
1311                         struct l_dbus_message *msg,
1312                                 void *user_data)
1313 {
1314         uint32_t n;
1315         struct hal_ev_mesh_authentication_request ev;
1316         char *str;
1317         char *auth_value;
1318         uint8_t *net_uuid;
1319         const char *dbus_path;
1320         meshcfg_app *app;
1321         app = user_data;
1322         INFO("Mesh: app path [%s]", app->path);
1323         INFO("Mesh: Agent path [%s]", app->agent_path);
1324
1325         dbus_path =  l_dbus_message_get_path(msg);
1326         net_uuid = __mesh_get_net_uuid_from_path(app->agent_path,
1327                                 true,  MESH_AGENT_IFACE);
1328
1329         INFO("Mesh: app path [%s]", dbus_path);
1330
1331         memset(&ev, 0, sizeof(ev));
1332         memcpy(ev.net_uuid, net_uuid, 16);
1333
1334
1335         if (!l_dbus_message_get_arguments(msg, "su", &str, &n)) {
1336                 ERR("Mesh: Cannot parse \"DisplayNumeric\" arguments");
1337                 struct hal_ev_mesh_provision_finished ev;
1338                 memset(&ev, 0, sizeof(ev));
1339                 memcpy(ev.net_uuid, net_uuid, 16);
1340                 ev.status = BT_STATUS_FAIL;
1341                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1342                 if (mesh_event_cb) {
1343                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1344                                 (void*)&ev, sizeof(ev));
1345                 }
1346                 g_free(net_uuid);
1347                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1348         }
1349
1350         INFO("Mesh:[OUT] Numeric Authentication type [%s] value [%u]", str, n);
1351         auth_value = l_strdup_printf("%u", n);
1352         ev.auth_type = __mesh_get_authentication_type(str);
1353         if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1354                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1355         g_strlcpy(ev.auth_value, auth_value, sizeof(ev.auth_value));
1356
1357         if (mesh_event_cb)
1358                 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1359                         (void*)&ev, sizeof(ev));
1360
1361         g_free(net_uuid);
1362
1363         return l_dbus_message_new_method_return(msg);
1364 }
1365
1366 static struct l_dbus_message *__mesh_agent_prompt_numeric_request(
1367                 struct l_dbus *dbus,
1368                         struct l_dbus_message *msg,
1369                                 void *user_data)
1370 {
1371         struct hal_ev_mesh_authentication_request ev;
1372         char *str;
1373         uint8_t *net_uuid;
1374         const char *dbus_path;
1375         GSList *l;
1376         meshcfg_app *app;
1377
1378         dbus_path =  l_dbus_message_get_path(msg);
1379         net_uuid = __mesh_get_net_uuid_from_path(dbus_path,
1380                         true,  MESH_AGENT_IFACE);
1381
1382         INFO("Mesh: app path [%s]", dbus_path);
1383
1384         l = g_slist_find_custom(mesh_apps, net_uuid,
1385                         __mesh_compare_network_uuid);
1386         app = l->data;
1387
1388         memset(&ev, 0, sizeof(ev));
1389         memcpy(ev.net_uuid, net_uuid, 16);
1390
1391         g_free(net_uuid);
1392         if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1393                 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1394
1395                 struct hal_ev_mesh_provision_finished ev;
1396                 memset(&ev, 0, sizeof(ev));
1397                 memcpy(ev.net_uuid, app->uuid, 16);
1398                 ev.status = BT_STATUS_FAIL;
1399                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1400                 if (mesh_event_cb) {
1401                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1402                                 (void*)&ev, sizeof(ev));
1403                 }
1404                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1405         }
1406
1407         INFO("Mesh:[IN] Numeric Authentication type [%s]", str);
1408
1409         ev.auth_type = __mesh_get_authentication_type(str);
1410         if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1411                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1412         agent_msg = msg;
1413         l_dbus_message_ref(msg);
1414         if (mesh_event_cb)
1415                 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1416                         (void*)&ev, sizeof(ev));
1417
1418         return NULL;
1419 }
1420
1421 static struct l_dbus_message *__mesh_agent_prompt_static_request(
1422                 struct l_dbus *dbus,
1423                         struct l_dbus_message *msg,
1424                                 void *user_data)
1425 {
1426         struct hal_ev_mesh_authentication_request ev;
1427         char *str;
1428         uint8_t *net_uuid;
1429         const char *dbus_path;
1430         GSList *l;
1431         meshcfg_app *app;
1432
1433         dbus_path =  l_dbus_message_get_path(msg);
1434         net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
1435                         MESH_AGENT_IFACE);
1436
1437         INFO("Mesh: app path [%s]", dbus_path);
1438
1439         l = g_slist_find_custom(mesh_apps, net_uuid,
1440                         __mesh_compare_network_uuid);
1441         app = l->data;
1442
1443         memset(&ev, 0, sizeof(ev));
1444         memcpy(ev.net_uuid, net_uuid, 16);
1445
1446         g_free(net_uuid);
1447         if (!l_dbus_message_get_arguments(msg, "s", &str)) {
1448                 ERR("Mesh: Cannot parse \"PromptNumeric\" arguments");
1449
1450                 struct hal_ev_mesh_provision_finished ev;
1451                 memset(&ev, 0, sizeof(ev));
1452                 memcpy(ev.net_uuid, app->uuid, 16);
1453                 ev.status = BT_STATUS_FAIL;
1454                 ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
1455                 if (mesh_event_cb)
1456                         mesh_event_cb(HAL_EV_MESH_PROVISIONING_FINISHED,
1457                                         (void*)&ev, sizeof(ev));
1458                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1459         }
1460
1461         INFO("Mesh: [IN] AlphaNumeric Authentication type [%s]", str);
1462
1463         ev.auth_type = __mesh_get_authentication_type(str);
1464         if (ev.auth_type == BT_HAL_MESH_UNKNOWN_AUTH_METHOD)
1465                 return l_dbus_message_new_error(msg, dbus_err_fail, NULL);
1466         agent_msg = msg;
1467         l_dbus_message_ref(msg);
1468         if (mesh_event_cb)
1469                 mesh_event_cb(HAL_EV_MESH_AUTHENTICATION_REQUEST,
1470                                 (void*)&ev, sizeof(ev));
1471
1472         return NULL;
1473 }
1474
1475 static void __bt_hal_mesh_setup_agent_iface(struct l_dbus_interface *interface)
1476 {
1477         INFO("Mesh: Setup Agent interface properties & methods");
1478         l_dbus_interface_property(interface, "Capabilities", 0, "as",
1479                         __mesh_agent_capability_getter,
1480                         NULL);
1481         /* TODO: Other properties */
1482         l_dbus_interface_method(interface, "DisplayString", 0,
1483                         __mesh_agent_display_string_request,
1484                         "", "s", "value");
1485         l_dbus_interface_method(interface, "DisplayNumeric", 0,
1486                         __mesh_agent_display_numeric_request,
1487                         "", "su", "type", "number");
1488         l_dbus_interface_method(interface, "PromptNumeric", 0,
1489                         __mesh_agent_prompt_numeric_request,
1490                         "u", "s", "number", "type");
1491         l_dbus_interface_method(interface, "PromptStatic", 0,
1492                         __mesh_agent_prompt_static_request,
1493                         "ay", "s", "data", "type");
1494 }
1495
1496 static void __bt_hal_mesh_register_element_obj(gpointer data, gpointer user_data)
1497 {
1498         meshcfg_el *elem = (meshcfg_el*) data;
1499         INFO("Mesh: Register Element: Index [%d] elem path [%s]",
1500                 elem->index, elem->path);
1501         if (!l_dbus_register_object(dbus, elem->path, NULL, NULL,
1502                                 BT_HAL_MESH_ELEMENT_INTERFACE, elem, NULL)) {
1503                 ERR("Mesh: Failed to register object %s", elem->path);
1504         }
1505 }
1506
1507 bool __bt_hal_mesh_register_agent(meshcfg_app *ptr)
1508 {
1509         if (!ptr)
1510                 return false;
1511
1512         if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISION_AGENT_INTERFACE,
1513                                 __bt_hal_mesh_setup_agent_iface, NULL, false)) {
1514                 ERR("Mesh: Unable to register agent interface");
1515                 //return false;
1516         }
1517
1518         INFO("Mesh: Register Agent path [%s]",  ptr->agent_path);
1519         if (!l_dbus_register_object(dbus, ptr->agent_path, NULL, NULL,
1520                                 BT_HAL_MESH_PROVISION_AGENT_INTERFACE, ptr, NULL)) {
1521                 ERR("Mesh: Failed to register object %s", ptr->agent_path);
1522                 return false;
1523         }
1524
1525         if (!l_dbus_object_add_interface(dbus, ptr->agent_path,
1526                                 L_DBUS_INTERFACE_PROPERTIES, NULL)) {
1527                 ERR("Mesh: Failed to add interface %s",
1528                                 L_DBUS_INTERFACE_PROPERTIES);
1529                 return false;
1530         }
1531
1532         return true;
1533 }
1534
1535 bool __bt_hal_mesh_register_application(meshcfg_app *ptr)
1536 {
1537
1538         if (!ptr)
1539                 return false;
1540         if (!dbus)
1541                 return false;
1542
1543         if (!l_dbus_register_interface(dbus, BT_HAL_MESH_APPLICATION_INTERFACE,
1544                                 __bt_hal_mesh_setup_app_iface, NULL, false)) {
1545                 ERR("Mesh: Failed to register interface %s",
1546                                 BT_HAL_MESH_APPLICATION_INTERFACE);
1547                 //return false;
1548         }
1549
1550         if (!l_dbus_register_interface(dbus, BT_HAL_MESH_PROVISIONER_INTERFACE,
1551                                 __bt_hal_mesh_setup_prov_iface, NULL, false)) {
1552                 ERR("Mesh: Failed to register interface %s",
1553                                 BT_HAL_MESH_PROVISIONER_INTERFACE);
1554                 //return false;
1555         }
1556
1557         if (!l_dbus_register_object(dbus, ptr->path, NULL, NULL,
1558                                 BT_HAL_MESH_APPLICATION_INTERFACE, ptr,
1559                                 BT_HAL_MESH_PROVISIONER_INTERFACE, ptr,
1560                                 NULL)) {
1561                 ERR("Mesh: Failed to register object %s", ptr->path);
1562                 return false;
1563         }
1564
1565         if (!__bt_hal_mesh_register_agent(ptr))
1566                 return false;
1567
1568         if (!l_dbus_register_interface(dbus, BT_HAL_MESH_ELEMENT_INTERFACE,
1569                                 __bt_hal_mesh_setup_ele_iface, NULL, false)) {
1570                 ERR("Mesh: Failed to register interface %s",
1571                                 BT_HAL_MESH_ELEMENT_INTERFACE);
1572                 //return false;
1573         }
1574
1575         INFO("Mesh: Number of elements to be registsred [%d]",
1576                         g_slist_length(ptr->elements));
1577
1578         g_slist_foreach(ptr->elements, __bt_hal_mesh_register_element_obj, ptr);
1579
1580         INFO("Mesh: Add Object manager Interface: app path [%s]", ptr->path);
1581         if (!l_dbus_object_add_interface(dbus, ptr->path,
1582                                 L_DBUS_INTERFACE_OBJECT_MANAGER, NULL)) {
1583                 ERR("Mesh: Failed to add interface %s",
1584                                 L_DBUS_INTERFACE_OBJECT_MANAGER);
1585                 return false;
1586         }
1587         INFO("Mesh: Application Register completed");
1588
1589         return true;
1590 }
1591
1592 static void __bt_mesh_hal_create_element_object(gpointer data, gpointer user_data)
1593 {
1594         GSList *l;
1595         meshcfg_el *elem;
1596         meshcfg_model *model_info = (meshcfg_model*) data;
1597         meshcfg_app *app = (meshcfg_app*) user_data;
1598
1599         l = g_slist_find_custom(app->elements,
1600                 GUINT_TO_POINTER(model_info->elem_index), __compare_element_index);
1601         if (l) {
1602                 elem = l->data;
1603         } else {
1604                 elem = g_malloc0(sizeof(meshcfg_el));
1605                 elem->index = model_info->elem_index;
1606                 elem->path = g_strdup_printf("%s/elem%u", app->path, elem->index);
1607                 app->elements = g_slist_append(app->elements, elem);
1608                 INFO("Mesh: Created element index [%d] path [%s]",
1609                         elem->index, elem->path);
1610         }
1611         INFO("Mesh: This is model [0x%4.4x] for Element [0x%2.2x]",
1612                 model_info->model, elem->index);
1613         /* Add Model in the element */
1614         elem->models = g_slist_append(elem->models, model_info);
1615         INFO("Mesh: Model added in element: total Model count in elem [%d] is [%d]",
1616                         elem->index, g_slist_length(elem->models));
1617 }
1618
1619 meshcfg_app *__bt_hal_mesh_create_app(bt_hal_mesh_node_t *node,
1620                 GSList *models, bool is_prov)
1621 {
1622         uint8_t uuid[16];
1623         meshcfg_app *app = NULL;
1624         char *uuid_str = NULL;
1625
1626         uuid_str = l_util_hexstring(node->uuid.uu, sizeof(uuid));
1627
1628         app = g_malloc0(sizeof(meshcfg_app));
1629         memcpy(app->uuid, node->uuid.uu, sizeof(uuid));
1630
1631         app->cid = node->vendor_info.companyid;
1632         app->pid = node->vendor_info.vendorid;
1633         app->vid =  node->vendor_info.versionid;
1634         app->crpl = node->vendor_info.crpl;
1635
1636         if (is_prov) {
1637                 app->path = g_strdup_printf("/tizen/mesh/cfg/%s", uuid_str);
1638                 app->agent_path = g_strdup_printf("%s/agent", app->path);
1639
1640         } else {
1641                 app->path = g_strdup_printf("/tizen/mesh/node/%s", uuid_str);
1642                 app->agent_path = g_strdup_printf("%s/agent", app->path);
1643         }
1644         g_slist_foreach(models, __bt_mesh_hal_create_element_object, app);
1645
1646         g_free(uuid_str);
1647         app->is_prov = is_prov;
1648         INFO("Mesh: app created");
1649         return app;
1650 }
1651
1652 static void __bt_hal_mesh_create_net_reply(
1653                 struct l_dbus_proxy *proxy,
1654                         struct l_dbus_message *msg, void *user_data)
1655 {
1656         meshcfg_app *app;
1657         app = (meshcfg_app*) user_data;
1658
1659         INFO("Mesh: Create Network Reply from Meshd: app path [%s]", app->path);
1660         if (l_dbus_message_is_error(msg)) {
1661                 const char *name;
1662
1663                 l_dbus_message_get_error(msg, &name, NULL);
1664                 ERR("Mesh: Failed to create network: %s", name);
1665
1666                 /* Send Network creation fail event */
1667                 __send_network_attach_event(app, BT_STATUS_FAIL);
1668
1669                 /* Destroy mesh app object */
1670                 __bt_hal_mesh_destroy_app_object(app);
1671                 return;
1672         }
1673 }
1674
1675 static void __bt_hal_mesh_create_net_setup(struct l_dbus_message *msg,
1676                 void *user_data)
1677 {
1678         meshcfg_app *app;
1679         struct l_dbus_message_builder *builder;
1680         app = (meshcfg_app*) user_data;
1681
1682         builder = l_dbus_message_builder_new(msg);
1683
1684         INFO("Mesh: Create Network Setup app path [%s]", app->path);
1685         l_dbus_message_builder_append_basic(builder, 'o', app->path);
1686         __mesh_append_byte_array(builder, app->uuid, 16);
1687         l_dbus_message_builder_finalize(builder);
1688         l_dbus_message_builder_destroy(builder);
1689 }
1690
1691 static void __mesh_trigger_scan_finished_event(meshcfg_app *app)
1692 {
1693         struct hal_ev_mesh_scan_state_changed ev;
1694
1695         memset(&ev, 0, sizeof(ev));
1696         memcpy(ev.net_uuid, app->uuid, 16);
1697
1698         ev.status = BT_STATUS_SUCCESS;
1699
1700         ev.state = HAL_MESH_SCAN_STATE_STOPPED;
1701         if (mesh_event_cb)
1702                 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1703                         (void*)&ev, sizeof(ev));
1704 }
1705
1706 static gboolean __bt_mesh_scan_timer_cb(gpointer user_data)
1707 {
1708         meshcfg_app *app = (meshcfg_app*) user_data;
1709         __mesh_trigger_scan_finished_event(app);
1710         return false;
1711 }
1712
1713 void __bt_mesh_enable_scanning_timer(uint8_t *net_uuid, uint16_t secs)
1714 {
1715         GSList *l;
1716         meshcfg_app *app;
1717         l = g_slist_find_custom(mesh_apps, net_uuid,
1718                         __mesh_compare_network_uuid);
1719         app = l->data;
1720
1721         if (app->scan_timer_id > 0) {
1722                 g_source_remove(app->scan_timer_id);
1723                 app->scan_timer_id = 0;
1724         }
1725
1726         app->scan_timer_id = g_timeout_add_seconds(secs,
1727                         __bt_mesh_scan_timer_cb, app);
1728
1729         return;
1730 }
1731
1732 static void __mesh_scan_reply(struct l_dbus_proxy *proxy,
1733                 struct l_dbus_message *msg, void *user_data)
1734 {
1735         struct hal_ev_mesh_scan_state_changed ev;
1736         const char *dbus_path;
1737         uint8_t *net_uuid;
1738         dbus_path =  l_dbus_proxy_get_path(proxy);
1739         INFO("Mesh: DBUS path [%s]", dbus_path);
1740         net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1741
1742         uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1743         INFO("Mesh: Scan duration [%u]", secs);
1744
1745         memset(&ev, 0, sizeof(ev));
1746         memcpy(ev.net_uuid, net_uuid, 16);
1747
1748         if (l_dbus_message_is_error(msg)) {
1749                 const char *name;
1750                 l_dbus_message_get_error(msg, &name, NULL);
1751                 ERR("Mesh: Failed to start unprovisioned scan: [%s]", name);
1752                 ev.status = BT_STATUS_FAIL;
1753         } else {
1754                 INFO("Mesh: Unprovisioned scan started\n");
1755                 ev.status = BT_STATUS_SUCCESS;
1756                 __bt_mesh_enable_scanning_timer(net_uuid, secs);
1757         }
1758
1759         ev.state = HAL_MESH_SCAN_STATE_STARTED;
1760         if (mesh_event_cb)
1761                 mesh_event_cb(HAL_EV_MESH_SCAN_STATE_CHANGED,
1762                         (void*)&ev, sizeof(ev));
1763         l_free(net_uuid);
1764 }
1765
1766 static void append_dict_entry_basic(struct l_dbus_message_builder *builder,
1767                 const char *key, const char *signature,
1768                 const void *data)
1769 {
1770         if (!builder)
1771                 return;
1772
1773         l_dbus_message_builder_enter_dict(builder, "sv");
1774         l_dbus_message_builder_append_basic(builder, 's', key);
1775         l_dbus_message_builder_enter_variant(builder, signature);
1776         l_dbus_message_builder_append_basic(builder, signature[0], data);
1777         l_dbus_message_builder_leave_variant(builder);
1778         l_dbus_message_builder_leave_dict(builder);
1779 }
1780
1781 static void __mesh_scan_setup(struct l_dbus_message *msg, void *user_data)
1782 {
1783         struct l_dbus_message_builder *builder;
1784         uint16_t secs = (uint16_t) L_PTR_TO_UINT(user_data);
1785         INFO("Mesh: Scan duration [%u]", secs);
1786
1787         builder = l_dbus_message_builder_new(msg);
1788         l_dbus_message_builder_enter_array(builder, "{sv}");
1789         append_dict_entry_basic(builder, "Seconds", "q", &secs);
1790         l_dbus_message_builder_leave_array(builder);
1791         l_dbus_message_builder_finalize(builder);
1792         l_dbus_message_builder_destroy(builder);
1793 }
1794
1795
1796 bt_status_t _bt_hal_mesh_network_set_caps(
1797                 bt_uuid_t *net_uuid, bt_hal_mesh_prov_caps_t *caps)
1798 {
1799         GSList *l;
1800         meshcfg_app *app;
1801         l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1802         if (l) {
1803                 app = l->data;
1804                 /* Fill OOB data */
1805                 app->public_oob = caps->public_oob;
1806                 app->static_oob = caps->static_oob;
1807                 app->out_oob = caps->out_oob;
1808                 app->in_oob = caps->in_oob;
1809         } else {
1810                 ERR("Mesh: app not found!!");
1811                 return BT_STATUS_PARM_INVALID;
1812
1813         }
1814         return BT_STATUS_SUCCESS;
1815 }
1816
1817 static void __bt_hal_mesh_add_node_reply(
1818                 struct l_dbus_proxy *proxy,
1819                         struct l_dbus_message *msg,
1820                                 void *user_data)
1821 {
1822         struct hal_ev_mesh_provision_status ev;
1823         const char *dbus_path;
1824         uint8_t *net_uuid;
1825         dbus_path =  l_dbus_proxy_get_path(proxy);
1826         INFO("Mesh: DBUS path [%s]", dbus_path);
1827         net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1828
1829         bt_uuid_t *dev_uuid = (bt_uuid_t*) user_data;
1830
1831         INFO("Mesh: app path [%s]", dbus_path);
1832
1833         memset(&ev, 0, sizeof(ev));
1834         memcpy(ev.net_uuid, net_uuid, 16);
1835         memcpy(ev.dev_uuid, dev_uuid->uu, 16);
1836
1837         /* Free User data */
1838         g_free((void*)dev_uuid);
1839         l_free(net_uuid);
1840
1841         if (l_dbus_message_is_error(msg)) {
1842                 const char *name;
1843
1844                 l_dbus_message_get_error(msg, &name, NULL);
1845                 ERR("Mesh: Failed to start provisioning: %s", name);
1846                 ev.status = BT_STATUS_FAIL;
1847         } else {
1848                 INFO("Mesh: Provisioning started\n");
1849                 ev.status = BT_STATUS_SUCCESS;
1850         }
1851         if (mesh_event_cb)
1852                 mesh_event_cb(HAL_EV_MESH_PROVISIONING_STATUS,
1853                         (void*)&ev, sizeof(ev));
1854         INFO("Mesh: Provisioning status sent");
1855 }
1856
1857 static void __bt_hal_mesh_add_node_setup(struct l_dbus_message *msg,
1858                 void *user_data)
1859 {
1860         char *uuid;
1861         bt_uuid_t *dev = user_data;
1862         struct l_dbus_message_builder *builder;
1863         uuid =  l_util_hexstring(dev->uu, 16);
1864         INFO("Mesh: Add Node Setup UUID [%s]", uuid);
1865
1866         builder = l_dbus_message_builder_new(msg);
1867         __mesh_append_byte_array(builder, dev->uu, 16);
1868         l_dbus_message_builder_enter_array(builder, "{sv}");
1869         l_dbus_message_builder_leave_array(builder);
1870         l_dbus_message_builder_finalize(builder);
1871         l_dbus_message_builder_destroy(builder);
1872 }
1873
1874 bt_status_t _bt_hal_mesh_provision_device(
1875                 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
1876 {
1877         GSList *l;
1878         meshcfg_app *app;
1879         bt_uuid_t *dev;
1880         l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
1881         if (l) {
1882                 app = l->data;
1883                 dev = g_memdup((gpointer)dev_uuid, 16);
1884                 INFO("Mesh: Schedule Add Node request to meshd");
1885                 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "AddNode",
1886                                         __bt_hal_mesh_add_node_setup,
1887                                         __bt_hal_mesh_add_node_reply,
1888                                         (void*)dev, NULL))
1889                         return BT_STATUS_FAIL;
1890         } else {
1891                 ERR("Mesh: app not found!!");
1892                 return BT_STATUS_PARM_INVALID;
1893
1894         }
1895         return BT_STATUS_SUCCESS;
1896 }
1897
1898 static void __bt_hal_mesh_subnet_key_setup(
1899                 struct l_dbus_message *msg, void *user_data)
1900 {
1901         struct subnet_key_request *req = user_data;
1902         uint16_t idx = (uint16_t) req->idx;
1903
1904         l_dbus_message_set_arguments(msg, "q", idx);
1905 }
1906
1907 static void __bt_hal_mesh_subnet_key_reply(struct l_dbus_proxy *proxy,
1908                 struct l_dbus_message *msg, void *user_data)
1909 {
1910         struct hal_ev_mesh_netkey_execute_event ev;
1911         const char *dbus_path;
1912         uint8_t *net_uuid;
1913         struct subnet_key_request *req = user_data;
1914         const char *method = req->str;
1915
1916         dbus_path =  l_dbus_proxy_get_path(proxy);
1917         INFO("Mesh: DBUS path [%s]", dbus_path);
1918         net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1919
1920         memset(&ev, 0, sizeof(ev));
1921         memcpy(ev.net_uuid, net_uuid, 16);
1922         ev.key_idx = req->idx;
1923
1924         g_free(net_uuid);
1925
1926         if (l_dbus_message_is_error(msg)) {
1927                 const char *name;
1928
1929                 l_dbus_message_get_error(msg, &name, NULL);
1930                 ERR("Mesh: Subnet [%s] failed: error: [%s]", method, name);
1931                 ev.status = BT_STATUS_FAIL;
1932         }
1933
1934         ev.status = BT_STATUS_SUCCESS;
1935
1936         if (!strcmp("CreateSubnet", method)) {
1937                 INFO("Mesh: Reply for CreateSubnet");
1938                 ev.key_event = HAL_MESH_KEY_ADD;
1939         } else if (!strcmp("DeleteSubnet", method)) {
1940                 INFO("Mesh: Reply for DeleteSubnet");
1941                 ev.key_event = HAL_MESH_KEY_DELETE;
1942         } else if (!strcmp("UpdateSubnet", method)) {
1943                 INFO("Mesh: Reply for UpdateSubnet");
1944                 ev.key_event = HAL_MESH_KEY_UPDATE;
1945         }
1946
1947         if (mesh_event_cb)
1948                 mesh_event_cb(HAL_EV_MESH_NETKEY_EXECUTE_EVENT,
1949                         (void*)&ev, sizeof(ev));
1950 }
1951
1952 static bool  __mesh_subnet_netkey_command_execute(meshcfg_app *app,
1953                         uint16_t index, const char *key_execute_method)
1954 {
1955         struct subnet_key_request *req;
1956
1957         req = l_new(struct subnet_key_request, 1);
1958         req->str = key_execute_method;
1959         req->idx = index;
1960
1961         if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
1962                                 __bt_hal_mesh_subnet_key_setup,
1963                                 __bt_hal_mesh_subnet_key_reply,
1964                                 req, l_free))
1965                 return false;
1966
1967         return true;
1968 }
1969
1970 static void __bt_hal_mesh_app_key_setup(struct l_dbus_message *msg,
1971         void *user_data)
1972 {
1973         struct app_key_request *req = user_data;
1974         uint16_t net_idx = (uint16_t) req->net_idx;
1975         uint16_t app_idx = (uint16_t) req->app_idx;
1976
1977         if (g_strcmp0(req->str, "CreateAppKey") == 0)
1978                 l_dbus_message_set_arguments(msg, "qq", net_idx, app_idx);
1979         else
1980                 l_dbus_message_set_arguments(msg, "q", app_idx);
1981 }
1982
1983 static void __bt_hal_mesh_app_key_reply(struct l_dbus_proxy *proxy,
1984                 struct l_dbus_message *msg, void *user_data)
1985 {
1986         struct hal_ev_mesh_appkey_execute_event ev;
1987         const char *dbus_path;
1988         uint8_t *net_uuid;
1989         struct app_key_request *req = user_data;
1990         const char *method = req->str;
1991
1992         dbus_path =  l_dbus_proxy_get_path(proxy);
1993         INFO("Mesh: DBUS path [%s]", dbus_path);
1994         net_uuid = __mesh_get_net_uuid_from_dbus_proxy_path(dbus_path);
1995
1996         memset(&ev, 0, sizeof(ev));
1997         memcpy(ev.net_uuid, net_uuid, 16);
1998         ev.net_idx = req->net_idx;
1999         ev.app_idx = req->app_idx;
2000
2001         g_free(net_uuid);
2002
2003         if (l_dbus_message_is_error(msg)) {
2004                 const char *name;
2005
2006                 l_dbus_message_get_error(msg, &name, NULL);
2007                 ERR("Mesh: AppKey execute [%s] failed: error: [%s]", method, name);
2008                 ev.status = BT_STATUS_FAIL;
2009         } else
2010                 ev.status = BT_STATUS_SUCCESS;
2011
2012         if (!strcmp("CreateAppKey", method)) {
2013                 INFO("Mesh: AppKey Create Reply");
2014                 ev.key_event = HAL_MESH_KEY_ADD;
2015         } else if (!strcmp("DeleteAppKey", method)) {
2016                 INFO("Mesh: AppKey Delete Reply");
2017                 ev.key_event = HAL_MESH_KEY_DELETE;
2018         } else if (!strcmp("UpdateAppKey", method)) {
2019                 INFO("Mesh: AppKey Update Reply");
2020                 ev.key_event = HAL_MESH_KEY_UPDATE;
2021         }
2022
2023         if (mesh_event_cb)
2024                 mesh_event_cb(HAL_EV_MESH_APPKEY_EXECUTE_EVENT, (void*)&ev, sizeof(ev));
2025 }
2026
2027 static bool  __mesh_subnet_appkey_command_execute(meshcfg_app *app,
2028                         uint16_t net_idx, uint16_t app_idx,
2029                                 const char *key_execute_method)
2030 {
2031         struct app_key_request *req;
2032
2033         req = l_new(struct app_key_request, 1);
2034         req->str = key_execute_method;
2035         req->net_idx = net_idx;
2036         req->app_idx = app_idx;
2037
2038         if (!l_dbus_proxy_method_call(app->mgmt_proxy, key_execute_method,
2039                                 __bt_hal_mesh_app_key_setup,
2040                                 __bt_hal_mesh_app_key_reply,
2041                                 req, l_free))
2042                 return false;
2043
2044         return true;
2045 }
2046
2047 bt_status_t _bt_hal_mesh_network_subnet_execute(bt_uuid_t *net_uuid,
2048                         bt_mesh_key_op_e op, uint16_t netkey_idx)
2049 {
2050         GSList *l;
2051         meshcfg_app *app;
2052         bool status = true;
2053         l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2054         if (l) {
2055                 app = l->data;
2056
2057                 if (op == BT_MESH_KEY_CREATE)
2058                         status = __mesh_subnet_netkey_command_execute(app,
2059                                         netkey_idx, "CreateSubnet");
2060                 else if (op == BT_MESH_KEY_DELETE)
2061                         status = __mesh_subnet_netkey_command_execute(app,
2062                                         netkey_idx, "DeleteSubnet");
2063                 else if (op == BT_MESH_KEY_UPDATE)
2064                         status = __mesh_subnet_netkey_command_execute(app,
2065                                         netkey_idx, "UpdateSubnet");
2066                 if (!status)
2067                         return BT_STATUS_FAIL;
2068
2069         } else {
2070                 ERR("Mesh: app not found!!");
2071                 return BT_STATUS_PARM_INVALID;
2072
2073         }
2074         return BT_STATUS_SUCCESS;
2075 }
2076
2077 bt_status_t _bt_hal_mesh_network_appkey_execute(bt_uuid_t *net_uuid,
2078                         bt_mesh_key_op_e op, uint16_t netkey_idx, uint16_t appkey_idx)
2079 {
2080         GSList *l;
2081         meshcfg_app *app;
2082         bool status = true;
2083         l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2084         if (l) {
2085                 app = l->data;
2086
2087                 if (op == BT_MESH_KEY_CREATE)
2088                         status = __mesh_subnet_appkey_command_execute(app,
2089                                 netkey_idx, appkey_idx, "CreateAppKey");
2090                 else if (op == BT_MESH_KEY_DELETE)
2091                         status = __mesh_subnet_appkey_command_execute(app,
2092                                 netkey_idx, appkey_idx, "DeleteAppKey");
2093                 else if (op == BT_MESH_KEY_UPDATE) {
2094                         INFO("Mesh: Update ApKey command NK Idx [0x%2.2x] AK Idx [0x%2.2x]",
2095                                         netkey_idx, appkey_idx);
2096                         status = __mesh_subnet_appkey_command_execute(app,
2097                                 netkey_idx, appkey_idx, "UpdateAppKey");
2098                 }
2099                 if (!status)
2100                         return BT_STATUS_FAIL;
2101
2102         } else {
2103                 ERR("Mesh: app not found!!");
2104                 return BT_STATUS_PARM_INVALID;
2105
2106         }
2107         return BT_STATUS_SUCCESS;
2108 }
2109
2110 bt_status_t _bt_hal_mesh_send_provision_data(
2111                 bt_uuid_t *net_uuid, uint16_t netkey_idx, uint16_t unicast)
2112 {
2113         GSList *l;
2114         meshcfg_app *app;
2115         struct l_dbus_message *msg;
2116         struct l_dbus_message *reply;
2117
2118         l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2119         if (l) {
2120                 app = l->data;
2121                 msg = app->msg;
2122
2123                 reply = l_dbus_message_new_method_return(msg);
2124                 l_dbus_message_set_arguments(reply, "qq", netkey_idx,  unicast);
2125                 l_dbus_send(dbus, reply);
2126         } else {
2127                 ERR("Mesh: app not found!!");
2128                 return BT_STATUS_PARM_INVALID;
2129         }
2130         return BT_STATUS_SUCCESS;
2131 }
2132
2133 bt_status_t _bt_hal_mesh_network_scan_cancel(bt_uuid_t *net_uuid)
2134 {
2135         GSList *l;
2136         meshcfg_app *app;
2137         l = g_slist_find_custom(mesh_apps,
2138                 net_uuid->uu, __mesh_compare_network_uuid);
2139         if (l) {
2140                 app = l->data;
2141                 if (!__bt_mesh_proxy_check(app)) {
2142                         ERR("Mesh: Proxy check failed!!");
2143                         return BT_STATUS_FAIL;
2144                 }
2145                 if (!l_dbus_proxy_method_call(app->mgmt_proxy,
2146                                 "UnprovisionedScanCancel",
2147                                         NULL, NULL, NULL, NULL))
2148                         return BT_STATUS_FAIL;
2149         } else {
2150                 ERR("Mesh: app not found!!");
2151                 return BT_STATUS_PARM_INVALID;
2152         }
2153
2154         /* Stop Scan timer */
2155         if (app->scan_timer_id > 0) {
2156                 g_source_remove(app->scan_timer_id);
2157                 app->scan_timer_id = 0;
2158         }
2159
2160         /* Trigger Scan finished event */
2161         __mesh_trigger_scan_finished_event(app);
2162
2163         return BT_STATUS_SUCCESS;
2164 }
2165
2166 bt_status_t _bt_hal_mesh_auth_reply(bt_hal_mesh_auth_variant_e auth_type,
2167                         const char *auth_value)
2168 {
2169         uint32_t val_u32;
2170         struct l_dbus_message *reply = NULL;
2171         struct l_dbus_message_builder *builder;
2172         uint8_t *alpha;
2173         bt_status_t ret = BT_STATUS_SUCCESS;
2174         size_t sz = 0;
2175
2176         /* Proxy Check */
2177         if (!__bt_mesh_proxy_check(0)) {
2178                 ERR("Mesh: Proxy check failed!!");
2179                 return BT_STATUS_FAIL;
2180         }
2181         INFO("Mesh: Authentication Reply: auth type [%d]", auth_type);
2182         INFO("Mesh: Authentication Reply: auth value [%s]", auth_value);
2183         /* For Numeric Type Inputs: Numeric, Blink, Beep & Vibrate */
2184         if (auth_type >= BT_HAL_MESH_AUTH_REQ_NUMERIC_INPUT &&
2185                         auth_type <= BT_HAL_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT) {
2186                 INFO("Mesh: Authentication reply: Numeric Type");
2187                 val_u32 = atoi(auth_value);
2188                 reply = l_dbus_message_new_method_return(agent_msg);
2189                 l_dbus_message_set_arguments(reply, "u", val_u32);
2190                 if (!reply)
2191                         reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2192                 l_dbus_send(dbus, reply);
2193                 ret = BT_STATUS_SUCCESS;
2194         /* For Alpha-Numeric */
2195         } else if (auth_type == BT_HAL_MESH_AUTH_REQ_ALPHANUMERIC_INPUT ||
2196                         auth_type == BT_HAL_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT ||
2197                         auth_type == BT_HAL_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT) {
2198                 INFO("Mesh: Authentication reply: Alpha-Numeric Type");
2199                 alpha = l_util_from_hexstring(auth_value, &sz);
2200                 reply = l_dbus_message_new_method_return(agent_msg);
2201                 builder = l_dbus_message_builder_new(reply);
2202                 __mesh_append_byte_array(builder, alpha, 16);
2203                 l_dbus_message_builder_finalize(builder);
2204                 l_dbus_message_builder_destroy(builder);
2205                 l_free(alpha);
2206                 if (!reply)
2207                         reply = l_dbus_message_new_error(agent_msg, dbus_err_fail, NULL);
2208                 l_dbus_send(dbus, reply);
2209                 ret = BT_STATUS_SUCCESS;
2210         }
2211         return ret;
2212 }
2213
2214 bt_status_t _bt_hal_mesh_network_scan(bt_uuid_t *net_uuid,
2215                 bt_hal_mesh_scan_param_t *param)
2216 {
2217         GSList *l;
2218         meshcfg_app *app;
2219         l = g_slist_find_custom(mesh_apps, net_uuid->uu, __mesh_compare_network_uuid);
2220         if (l) {
2221                 app = l->data;
2222                 if (!__bt_mesh_proxy_check(app)) {
2223                         ERR("Mesh: Proxy check failed!!");
2224                         return BT_STATUS_FAIL;
2225                 }
2226                 if (!l_dbus_proxy_method_call(app->mgmt_proxy, "UnprovisionedScan",
2227                                         __mesh_scan_setup, __mesh_scan_reply,
2228                                         L_UINT_TO_PTR(param->scan_time), NULL))
2229                         return BT_STATUS_FAIL;
2230         } else {
2231                 ERR("Mesh: app not found!!");
2232                 return BT_STATUS_PARM_INVALID;
2233         }
2234         return BT_STATUS_SUCCESS;
2235 }
2236
2237 bt_status_t _bt_hal_mesh_create_network(
2238                 bt_hal_mesh_node_t *node, GSList *models, bool is_prov)
2239 {
2240         meshcfg_app *app;
2241
2242         INFO("Mesh: Create Network Request");
2243
2244         if (!__bt_mesh_proxy_check(0)) {
2245                 ERR("Mesh: Proxy check failed!!");
2246                 return BT_STATUS_FAIL;
2247         }
2248
2249         INFO("Mesh: Node Element count [%d]", node->num_elements);
2250         INFO("Mesh: Node Primary Unicast[0x%2.2x]", node->primary_unicast);
2251         INFO("Mesh: Node Vendor Info: CID[0x%2.2x]", node->vendor_info.companyid);
2252         INFO("Mesh: Node Vendor Info: VID[0x%2.2x]", node->vendor_info.vendorid);
2253         INFO("Mesh: Node Vendor Info: VSID[0x%2.2x]", node->vendor_info.versionid);
2254         INFO("Mesh: Node Vendor Info: CRPL[0x%2.2x]", node->vendor_info.crpl);
2255         INFO("Mesh: Node Total Number of Models in the node[%d]", g_slist_length(models));
2256         /* Create DBUS APP */
2257         app = __bt_hal_mesh_create_app(node, models, is_prov);
2258         if (!app)
2259                 return BT_STATUS_FAIL;
2260
2261         /* Register DBUS APP */
2262         if (!__bt_hal_mesh_register_application(app))
2263                 goto failed;
2264
2265         if (app->token.u64 == 0) {
2266                 INFO("Mesh: Create New Network");
2267                 /* Create CFG Network */
2268                 if (!l_dbus_proxy_method_call(net_proxy, "CreateNetwork",
2269                                         __bt_hal_mesh_create_net_setup,
2270                                         __bt_hal_mesh_create_net_reply, app,
2271                                         NULL)) {
2272                         ERR("Mesh: Network Create failed!!");
2273                         goto failed;
2274                 }
2275         } else {
2276                 INFO("Mesh: Attach Node to Network");
2277                 /* Attach to Network */
2278                 if (!l_dbus_proxy_method_call(net_proxy, "Attach",
2279                                         __bt_hal_mesh_attach_node_setup,
2280                                         __bt_hal_mesh_attach_node_reply,
2281                                         app,
2282                                 NULL)) {
2283                         ERR("Mesh: Node attach failed!!");
2284                         goto failed;
2285                 }
2286         }
2287
2288         INFO("Mesh: Node registration request scheudled");
2289         mesh_apps = g_slist_append(mesh_apps, app);
2290         INFO("Mesh: Total number of apps in list  [%d]",
2291                 g_slist_length(mesh_apps));
2292         return BT_STATUS_SUCCESS;
2293 failed:
2294         ERR("Mesh: network can not be created!!");
2295         __bt_hal_mesh_destroy_app_object(app);
2296         return BT_STATUS_FAIL;
2297 }
2298
2299 static void __bt_hal_mesh_config_send(
2300                 struct l_dbus_message *msg, void *user_data)
2301 {
2302         struct configuration_request *req = user_data;
2303         struct l_dbus_message_builder *builder;
2304
2305         builder = l_dbus_message_builder_new(msg);
2306
2307         l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2308         l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2309         if (req->is_dev_key)
2310                 l_dbus_message_builder_append_basic(builder, 'b', &req->rmt);
2311
2312         l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2313         __mesh_append_byte_array(builder, req->data, req->len);
2314         l_dbus_message_builder_finalize(builder);
2315         l_dbus_message_builder_destroy(builder);
2316 }
2317
2318 static void __bt_hal_mesh_key_config_send(
2319                 struct l_dbus_message *msg, void *user_data)
2320 {
2321         struct key_config_request *req = user_data;
2322         struct l_dbus_message_builder *builder;
2323
2324         builder = l_dbus_message_builder_new(msg);
2325
2326         l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2327         l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2328         l_dbus_message_builder_append_basic(builder, 'q', &req->key_req_idx);
2329         l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2330         l_dbus_message_builder_append_basic(builder, 'b', &req->update_req);
2331         l_dbus_message_builder_finalize(builder);
2332         l_dbus_message_builder_destroy(builder);
2333 }
2334
2335 static void __bt_hal_mesh_model_execute_message(
2336                 struct l_dbus_message *msg, void *user_data)
2337 {
2338         struct configuration_request *req = user_data;
2339         struct l_dbus_message_builder *builder;
2340
2341         builder = l_dbus_message_builder_new(msg);
2342
2343         l_dbus_message_builder_append_basic(builder, 'o', req->ele_path);
2344         l_dbus_message_builder_append_basic(builder, 'q', &req->dst);
2345         l_dbus_message_builder_append_basic(builder, 'q', &req->idx);
2346         __mesh_append_byte_array(builder, req->data, req->len);
2347         l_dbus_message_builder_finalize(builder);
2348         l_dbus_message_builder_destroy(builder);
2349 }
2350
2351 bt_status_t _bt_hal_mesh_send_key_config_message(
2352                 bt_uuid_t *network, uint16_t dest,
2353                         bool is_netkey, bool is_update,
2354                                 uint16_t key_idx, uint16_t netkey_idx)
2355 {
2356         GSList *l;
2357         GSList *l1;
2358         struct key_config_request *req;
2359         meshcfg_app *app;
2360         meshcfg_el *elem;
2361         const char *key_method = (!is_netkey) ? "AddAppKey" : "AddNetKey";
2362         /* Source is Config Client Local Node */
2363         int src_elem_idx = 0;
2364         l = g_slist_find_custom(mesh_apps, network->uu, __mesh_compare_network_uuid);
2365         if (l) {
2366                 app = l->data;
2367                 if (!__bt_mesh_proxy_check(app)) {
2368                         ERR("Mesh: Proxy check failed!!");
2369                         return BT_STATUS_FAIL;
2370                 }
2371                 l1 = g_slist_find_custom(app->elements,
2372                         GUINT_TO_POINTER(src_elem_idx), __compare_element_index);
2373                 if (!l1)
2374                         return BT_STATUS_FAIL;
2375                 elem = l1->data;
2376
2377                 req = l_new(struct key_config_request, 1);
2378                 req->ele_path = elem->path;
2379                 req->dst = dest;
2380                 req->key_req_idx = key_idx;
2381                 req->idx = netkey_idx; /* Encryption Key index */
2382                 req->update_req = is_update;
2383
2384                 if (!l_dbus_proxy_method_call(app->proxy, key_method,
2385                                         __bt_hal_mesh_key_config_send, NULL,
2386                                         (void*)req, l_free))
2387                         return BT_STATUS_FAIL;
2388         } else {
2389                 ERR("Mesh: app not found!!");
2390                 return BT_STATUS_PARM_INVALID;
2391
2392         }
2393         return BT_STATUS_SUCCESS;
2394 }
2395
2396 bt_status_t _bt_hal_mesh_send_configuration_message(
2397         bt_uuid_t *network, uint16_t dest,
2398                 bool is_dev_key, uint16_t netkey_idx,
2399                         uint8_t *buf, int len)
2400 {
2401         GSList *l;
2402         GSList *l1;
2403         struct configuration_request *req;
2404         meshcfg_app *app;
2405         meshcfg_el *elem;
2406         int src_elem_idx = 0;
2407         l = g_slist_find_custom(mesh_apps, network->uu,
2408                         __mesh_compare_network_uuid);
2409         if (l) {
2410                 app = l->data;
2411                 if (!__bt_mesh_proxy_check(app)) {
2412                         ERR("Mesh: Proxy check failed!!");
2413                         return BT_STATUS_FAIL;
2414                 }
2415                 l1 = g_slist_find_custom(app->elements,
2416                                 GUINT_TO_POINTER(src_elem_idx),
2417                                 __compare_element_index);
2418                 if (!l1)
2419                         return BT_STATUS_FAIL;
2420                 elem = l1->data;
2421
2422                 req = l_new(struct configuration_request, 1);
2423                 req->ele_path = elem->path;
2424                 req->dst = dest;
2425                 req->idx = netkey_idx;
2426                 req->data = buf;
2427                 req->len = len;
2428                 req->rmt = true;
2429                 req->is_dev_key = is_dev_key;
2430
2431                 if (!l_dbus_proxy_method_call(app->proxy, "DevKeySend",
2432                                         __bt_hal_mesh_config_send, NULL,
2433                                         (void*)req, l_free))
2434                         return BT_STATUS_FAIL;
2435         } else {
2436                 ERR("Mesh: app not found!!");
2437                 return BT_STATUS_PARM_INVALID;
2438
2439         }
2440         return BT_STATUS_SUCCESS;
2441 }
2442
2443 bt_status_t _bt_hal_mesh_model_execute_message(
2444         bt_uuid_t *network, uint16_t dest,
2445         uint16_t appkey_idx, uint8_t *buf, int len)
2446 {
2447         GSList *l;
2448         GSList *l1;
2449         struct configuration_request *req;
2450         meshcfg_app *app;
2451         meshcfg_el *elem;
2452         int src_elem_idx = 0;
2453         l = g_slist_find_custom(mesh_apps, network->uu,
2454                         __mesh_compare_network_uuid);
2455         if (l) {
2456                 app = l->data;
2457                 if (!__bt_mesh_proxy_check(app)) {
2458                         ERR("Mesh: Proxy check failed!!");
2459                         return BT_STATUS_FAIL;
2460                 }
2461                 l1 = g_slist_find_custom(app->elements,
2462                                 GUINT_TO_POINTER(src_elem_idx),
2463                                 __compare_element_index);
2464                 if (!l1)
2465                         return BT_STATUS_FAIL;
2466                 elem = l1->data;
2467
2468                 req = l_new(struct configuration_request, 1);
2469                 req->ele_path = elem->path;
2470                 req->dst = dest;
2471                 req->idx = appkey_idx;
2472                 req->data = buf;
2473                 req->len = len;
2474                 req->rmt = false;
2475                 req->is_dev_key = false;
2476
2477                 if (!l_dbus_proxy_method_call(app->proxy, "Send",
2478                                         __bt_hal_mesh_model_execute_message,
2479                                         NULL, (void*)req, l_free))
2480                         return BT_STATUS_FAIL;
2481         } else {
2482                 ERR("Mesh: app not found!!");
2483                 return BT_STATUS_PARM_INVALID;
2484
2485         }
2486         return BT_STATUS_SUCCESS;
2487 }