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