Mesh: Fix coding style issue
[platform/core/api/bluetooth.git] / src / bluetooth-mesh.c
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * @author: Anupam Roy <anupam.r@samsung.com>
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <glib.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <ctype.h>
23 #include <dlog.h>
24 #include <stdio.h>
25 #include <stdbool.h>
26 #include <arpa/inet.h>
27 #include <bluetooth-api.h>
28
29 #include "bluetooth.h"
30 #include "bluetooth_internal.h"
31 #include "bluetooth_private.h"
32 #include "bluetooth-mesh-api.h"
33
34 #define BT_MESH_MAX_ELEMENTS 32767
35 #define BT_MESH_MAX_MODELS 32767
36 #define BT_MESH_MAX_NODES 32767
37 #define BT_MESH_MAX_SUBNETS 4096
38
39 #define BT_MESH_FIXED_GROUP_LOW         0xff00
40 #define BT_MESH_FIXED_GROUP_HIGH        0xffff
41 #define BT_MESH_ALL_NODES_ADDRESS       0xffff
42 #define BT_MESH_VIRTUAL_ADDRESS_LOW     0x8000
43 #define BT_MESH_VIRTUAL_ADDRESS_HIGH    0xbfff
44 #define BT_MESH_GROUP_ADDRESS_LOW       0xc000
45 #define BT_MESH_GROUP_ADDRESS_HIGH      0xfeff
46
47 #define BT_MESH_IS_GROUP(x)             ((((x) >= BT_MESH_GROUP_ADDRESS_LOW) && \
48                                         ((x) < BT_MESH_FIXED_GROUP_HIGH)) || \
49                                         ((x) == BT_MESH_ALL_NODES_ADDRESS))
50
51 static bool is_mesh_initialized = false;
52
53 /**< List of Local handles >*/
54 static GSList *networks;
55 static GSList *node_list;
56 static GSList *element_list;
57 static GSList *model_list;
58 static GSList *appkey_list;
59 static GSList *netkey_list;
60 static GSList *group_list;
61
62
63 #define BT_CHECK_MESH_SUPPORT() \
64 { \
65         BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
66         BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \
67         BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_MESH); \
68 }
69
70 #define BT_CHECK_MESH_INIT_STATUS() \
71         if (__bt_check_mesh_init_status() == BT_ERROR_NOT_INITIALIZED) { \
72                 LOGE("[%s] NOT_INITIALIZED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_INITIALIZED); \
73                 return BT_ERROR_NOT_INITIALIZED; \
74         }
75
76
77 #define BT_CHECK_MESH_REMOTE(handle) \
78 {       if (handle->is_local) return BT_ERROR_OPERATION_FAILED; }
79
80
81 #define BT_CHECK_MESH_LOCAL(handle) \
82 {       if (!handle->is_local) return BT_ERROR_OPERATION_FAILED; }
83
84
85 #define BT_CHECK_MESH_IS_ATTACHED(handle) \
86 {       if (handle->is_attached) return BT_ERROR_OPERATION_FAILED; }
87
88 #define BT_MESH_VALIDATE_HANDLE(h1, list) \
89 { \
90         GSList *l; \
91         bool valid = FALSE; \
92         for (l = list; l; l = g_slist_next(l)) { \
93                 void *h2 = (void *)l->data; \
94                 if (h1 == h2) { \
95                         BT_INFO("Handle matched [%p]", h2); \
96                         valid = TRUE; break; \
97                 } \
98         } \
99         if (valid == FALSE) { \
100                 BT_ERR("Handle [%p] did not match with any stored handles!!", h1); \
101                 return BT_ERROR_INVALID_PARAMETER; \
102         } \
103 } \
104
105 /* forward declaration for static methods */
106 static void __bt_mesh_destroy_network_handles(bt_mesh_network_s *net);
107
108 size_t __bt_mesh_util_convert_hex_to_string(uint8_t *in,
109                 size_t in_len, char *out, size_t out_len)
110 {
111         static const char hexdigits[] = "0123456789abcdef";
112         size_t i;
113
114         if (in_len * 2 > (out_len - 1))
115                 return 0;
116
117         for (i = 0; i < in_len; i++) {
118                 out[i * 2] = hexdigits[in[i] >> 4];
119                 out[i * 2 + 1] = hexdigits[in[i] & 0xf];
120         }
121
122         out[in_len * 2] = '\0';
123         return i;
124 }
125
126 static int __compare_group_address(gconstpointer a, gconstpointer b)
127 {
128         const bt_mesh_group_s *group = a;
129         uint16_t addr = GPOINTER_TO_UINT(b);
130
131         return (group->addr - addr);
132 }
133
134 static int __compare_node_primary_unicast(gconstpointer a, gconstpointer b)
135 {
136         const bt_mesh_node_s *node = a;
137         uint16_t index = GPOINTER_TO_UINT(b);
138
139         return (node->unicast - index);
140 }
141
142 static int __compare_node_element_index(gconstpointer a, gconstpointer b)
143 {
144         const bt_mesh_element_s *element = a;
145         int index = GPOINTER_TO_UINT(b);
146
147         return (element->index - index);
148 }
149
150 static int __compare_network_group_address(gconstpointer a, gconstpointer b)
151 {
152         const bt_mesh_group_s *group = a;
153         uint16_t group_addr = GPOINTER_TO_UINT(b);
154
155         return (group->addr - group_addr);
156 }
157
158 static int __compare_model_id(gconstpointer a, gconstpointer b)
159 {
160         const bt_mesh_model_s *model_s = a;
161         uint32_t model = GPOINTER_TO_UINT(b);
162
163         return (model_s->id - model);
164 }
165
166 static int __compare_netkey_index(gconstpointer a, gconstpointer b)
167 {
168         const bt_mesh_netkey_s *nk = a;
169         uint16_t netkey_index = GPOINTER_TO_UINT(b);
170
171         return (nk->netkey_index - netkey_index);
172 }
173
174 /* LCOV_EXCL_START */
175 static int __simple_compare(gconstpointer a, gconstpointer b)
176 {
177         if (a == b)
178                 return 0;
179         else
180                 return 1;
181 }
182 /* LCOV_EXCL_STOP */
183
184 static int __compare_appkey_index(gconstpointer a, gconstpointer b)
185 {
186         const bt_mesh_appkey_s *ak = a;
187         uint16_t appkey_index = GPOINTER_TO_UINT(b);
188
189         return (ak->appkey_index - appkey_index);
190 }
191
192 static int __compare_element_index(gconstpointer a, gconstpointer b)
193 {
194         const bt_mesh_element_s *elem = a;
195         uint16_t element_index = GPOINTER_TO_UINT(b);
196
197         return (elem->index - element_index);
198 }
199
200 static bt_mesh_netkey_s * __bt_mesh_network_is_netkey_added(
201                 bt_mesh_network_s *network_s, uint16_t netkey_idx)
202 {
203         GSList *l;
204
205         l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
206                         (GCompareFunc)__compare_netkey_index);
207         if (!l)
208                 return NULL;
209
210         return (bt_mesh_netkey_s*) l->data;
211 }
212
213 bt_mesh_element_s *_bt_mesh_get_element_from_index(
214                 bt_mesh_node_s *node_s, int element_index)
215 {
216         GSList *l;
217
218         l = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(element_index),
219                         (GCompareFunc)__compare_element_index);
220         if (!l)
221                 return NULL;
222
223         return (bt_mesh_element_s*) l->data;
224 }
225
226 bt_mesh_appkey_s *_bt_mesh_network_get_appkey_from_index(
227                 bt_mesh_network_s *network_s, uint16_t appkey_idx)
228 {
229         GSList *l, *l1;
230
231         for (l = network_s->netkeys; l; l = l->next) {
232                 bt_mesh_netkey_s *netkey_s = l->data;
233
234                 l1 = g_slist_find_custom(netkey_s->appkeys, GUINT_TO_POINTER(appkey_idx),
235                                 (GCompareFunc)__compare_appkey_index);
236
237                 if (l1)
238                         return l1->data;
239         }
240         return NULL;
241 }
242
243 bt_mesh_model_s *_bt_mesh_get_model_from_modelid(
244                 bt_mesh_element_s *element_s, uint32_t modelid)
245 {
246         GSList *l;
247
248         l = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(modelid),
249                         (GCompareFunc)__compare_model_id);
250         if (!l)
251                 return NULL;
252
253         return (bt_mesh_model_s*) l->data;
254 }
255
256 bt_mesh_group_s* _bt_mesh_network_get_group(
257                 bt_mesh_network_s *network_s, uint16_t group_addr)
258 {
259         GSList *l;
260         bt_mesh_group_s *group_s = NULL;
261
262         /* Unassigned address */
263         if (group_addr == 0x0000)
264                 return NULL;
265
266         l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(group_addr),
267                         (GCompareFunc) __compare_network_group_address);
268         if (!l) {
269
270                 BT_INFO("Mesh: Group not available in Network: Addr[0x%2.2x]",
271                         group_addr);
272                 group_s = g_malloc0(sizeof(bt_mesh_group_s));
273                 group_s->addr = group_addr;
274                 if (!BT_MESH_IS_GROUP(group_addr))
275                         group_s->is_virtual = true;
276                 else
277                         group_s->is_virtual = false;
278                 group_s->parent = network_s;
279
280                 if (g_slist_append(network_s->groups, group_s))
281                         BT_INFO("Mesh: Group created");
282
283                 group_list = g_slist_append(group_list, group_s);
284         } else
285                 group_s = l->data;
286
287         return group_s;
288 }
289
290 /* LCOV_EXCL_START */
291 bt_mesh_appkey_s* _bt_mesh_node_get_appkey(
292                 bt_mesh_node_s *node_s, uint16_t appkey_idx)
293 {
294         GSList *l;
295
296         l = g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(appkey_idx),
297                         (GCompareFunc)__compare_appkey_index);
298         if (!l)
299                 return NULL;
300
301         return (bt_mesh_appkey_s*) l->data;
302 }
303 /* LCOV_EXCL_STOP */
304
305 static bt_mesh_appkey_s *__bt_mesh_network_is_appkey_added(
306                 bt_mesh_network_s *network_s,
307                         uint16_t netkey_idx,
308                                 uint16_t appkey_idx)
309 {
310         GSList *l, *l1;
311         const bt_mesh_netkey_s *netkey;
312
313         l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
314                         (GCompareFunc)__compare_netkey_index);
315         if (!l)
316                 return NULL;
317         netkey = l->data;
318
319         l1 = g_slist_find_custom(netkey->appkeys, GUINT_TO_POINTER(appkey_idx),
320                         (GCompareFunc)__compare_appkey_index);
321         if (!l1)
322                 return NULL;
323
324         return (bt_mesh_appkey_s*) l1->data;
325 }
326
327 int __bt_check_mesh_init_status(void)
328 {
329         if (is_mesh_initialized != true) {
330                 BT_ERR("NOT_INITIALIZED(0x%08x)", BT_ERROR_NOT_INITIALIZED);
331                 return BT_ERROR_NOT_INITIALIZED;
332         }
333
334         return BT_ERROR_NONE;
335 }
336
337 /* Local static */
338 static void __bt_mesh_free_models(void *data)
339 {
340         bt_mesh_model_s *model = (bt_mesh_model_s*)data;
341         model_list = g_slist_remove(model_list, model);
342         g_free(model);
343 }
344
345 static void __bt_mesh_free_elements(void *data)
346 {
347         bt_mesh_element_s *elem = (bt_mesh_element_s*)data;
348         element_list = g_slist_remove(element_list, elem);
349         g_slist_free_full(elem->models, __bt_mesh_free_models);
350         g_free(elem);
351 }
352
353 /* LCOV_EXCL_START */
354 static void __bt_mesh_free_appkeys(void *data)
355 {
356         bt_mesh_appkey_s *appkey = (bt_mesh_appkey_s*)data;
357         appkey_list = g_slist_remove(appkey_list, appkey);
358         g_free(appkey);
359 }
360 /* LCOV_EXCL_STOP */
361
362 static gint __bt_mesh_compare_net_uuid(gpointer *a, gpointer *b)
363 {
364         bt_mesh_network_s *net = (bt_mesh_network_s *)a;
365         char *net_uuid = (char *)b;
366         return g_strcmp0(net->uuid, net_uuid);
367 }
368
369
370 static void __bt_mesh_insert_elements_in_node(
371                 bt_mesh_node_s *node, uint16_t unicast,
372                         int num_elements, bool is_local)
373 {
374         bt_mesh_element_s *element_s;
375
376         for (int i = 0; i < num_elements; i++) {
377                 element_s = g_malloc0(sizeof(bt_mesh_element_s));
378                 element_s->is_local = is_local;
379                 element_s->parent = node;
380                 element_s->index = i;
381                 node->elements = g_slist_append(node->elements, element_s);
382                 element_list = g_slist_append(element_list, element_s);
383         }
384 }
385
386 bt_mesh_appkey_s *_bt_mesh_handle_node_appkey_configure(
387                 bt_mesh_network_s *network_s,
388                         bt_mesh_node_s *node_s, uint16_t netkey_idx,
389                                 uint16_t appkey_idx,
390                                         bt_mesh_node_key_configuration_e op)
391 {
392         bt_mesh_appkey_s *appkey_s;
393
394         appkey_s = __bt_mesh_network_is_appkey_added(
395                         network_s, netkey_idx, appkey_idx);
396
397         /* AppKey with index not found in network */
398         if (!appkey_s) {
399                 BT_ERR("Mesh: Exceptional case: AppKey not found in Network");
400                 return NULL;
401         }
402
403         if (op == BT_MESH_NODE_KEY_ADD) {
404                 if (!g_slist_find_custom(node_s->appkeys, (gconstpointer) appkey_s,
405                                         (GCompareFunc)__simple_compare)) {
406                         node_s->appkeys = g_slist_append(node_s->appkeys, appkey_s);
407                 } else
408                         BT_INFO("Mesh: AppKey Already added");
409                 return appkey_s;
410         } else  if (op == BT_MESH_NODE_KEY_DELETE) {
411                 node_s->appkeys = g_slist_remove(node_s->appkeys, appkey_s);
412                 return NULL;
413         } else  /* Node NetKey update */
414                 return appkey_s;
415 }
416
417 bt_mesh_netkey_s *_bt_mesh_handle_node_netkey_configure(
418                 bt_mesh_network_s *network_s,
419                         bt_mesh_node_s *node_s, uint16_t netkey_idx,
420                                 bt_mesh_node_key_configuration_e op)
421 {
422         bt_mesh_netkey_s *netkey_s;
423
424         netkey_s = __bt_mesh_network_is_netkey_added(network_s, netkey_idx);
425
426         /* Netkey with index not found in network */
427         if (!netkey_s) {
428                 BT_ERR("Mesh: Exceptional case: Netkey not found in Network");
429                 return NULL;
430         }
431
432         if (op == BT_MESH_NODE_KEY_ADD) {
433                 if (!g_slist_find_custom(node_s->netkeys, (gconstpointer) netkey_s,
434                                         (GCompareFunc)__simple_compare)) {
435                         node_s->netkeys = g_slist_append(node_s->netkeys, netkey_s);
436                 } else
437                         BT_INFO("Mesh: NetKey Already added");
438                 return netkey_s;
439         } else if (op == BT_MESH_NODE_KEY_DELETE) {
440                 node_s->netkeys = g_slist_remove(node_s->netkeys, netkey_s);
441                 return NULL;
442         } else  /* Node NetKey update */
443                 return netkey_s;
444 }
445
446 bt_mesh_group_s * _bt_mesh_get_group_from_sub(
447                 bt_mesh_network_s *network_s, bt_mesh_model_s *model_s,
448                         bt_mesh_model_subscription_op_e op, uint16_t sub_addr)
449 {
450         GSList *l;
451         bt_mesh_group_s *group_s = NULL;
452         l  = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(sub_addr),
453                         (GCompareFunc) __compare_network_group_address);
454         if (l)
455                 group_s = l->data;
456
457         if (op ==  BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
458                 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL");
459         if (op == BT_MESH_MODEL_SUBSCRIPTION_ADD)
460                 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_ADD");
461         if (op == BT_MESH_MODEL_SUBSCRIPTION_DELETE)
462                 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE");
463         if (op == BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE)
464                 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE");
465
466         return group_s;
467 }
468
469 bt_mesh_model_s *_bt_mesh_get_node_get_model_from_element(
470                 char *net_uuid, uint16_t unicast,
471                         int elem_idx, uint32_t model)
472 {
473         GSList *l, *l1, *l2, *l3;
474         bt_mesh_network_s *network_s;
475         bt_mesh_node_s *node_s;
476         bt_mesh_element_s *element_s;
477
478         l = g_slist_find_custom(networks, net_uuid,
479                 (GCompareFunc)__bt_mesh_compare_net_uuid);
480         if (!l)
481                 return NULL;
482
483         network_s = (bt_mesh_network_s*) l->data;
484
485         l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
486                         (GCompareFunc)__compare_node_primary_unicast);
487         if (!l1)
488                 return NULL;
489
490         node_s = (bt_mesh_node_s*) l1->data;
491
492         l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
493                         (GCompareFunc)__compare_node_element_index);
494         if (!l2)
495                 return NULL;
496
497         element_s =  (bt_mesh_element_s*) l2->data;
498
499
500         l3 = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(model),
501                         (GCompareFunc) __compare_model_id);
502         if (!l3)
503                 return NULL;
504
505         return (bt_mesh_model_s*) l3->data;
506 }
507
508 bt_mesh_element_s * _bt_mesh_get_node_get_element_from_index(char *net_uuid,
509                         uint16_t unicast, int elem_idx)
510 {
511         GSList *l, *l1, *l2;
512         bt_mesh_network_s *network_s;
513         bt_mesh_node_s *node_s;
514
515         l = g_slist_find_custom(networks, net_uuid,
516                         (GCompareFunc)__bt_mesh_compare_net_uuid);
517         if (!l)
518                 return NULL;
519
520         network_s = l->data;
521
522         l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
523                         (GCompareFunc)__compare_node_primary_unicast);
524         if (!l1)
525                 return NULL;
526
527         node_s = l1->data;
528
529         l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
530                         (GCompareFunc)__compare_node_element_index);
531         if (!l2)
532                 return NULL;
533
534         return (bt_mesh_element_s*) l->data;
535 }
536
537 bt_mesh_node_s *_bt_mesh_get_node_from_unicast(char *net_uuid, uint16_t unicast)
538 {
539         GSList *l, *l1;
540         bt_mesh_network_s *network_s;
541         bt_mesh_node_s *node_s;
542
543         l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
544         if (!l)
545                 return NULL;
546
547         network_s = l->data;
548
549         l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
550                         (GCompareFunc)__compare_node_primary_unicast);
551         if (!l1)
552                 return NULL;
553
554         node_s = l1->data;
555         return node_s;
556 }
557
558 bt_mesh_node_s *_bt_mesh_remote_node_browsed(char *net_uuid, char *dev_uuid,
559                         uint16_t unicast, int count)
560 {
561         GSList *l, *l1;
562         bt_mesh_network_s *network_s;
563         bt_mesh_node_s *node_s;
564
565         l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
566         if (!l)
567                 return NULL;
568
569         network_s = l->data;
570
571         l1 = g_slist_find_custom(network_s->nodes,  GUINT_TO_POINTER(unicast),
572                         (GCompareFunc)__compare_node_primary_unicast);
573         if (l1) {
574                 node_s = l1->data;
575                 g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
576         } else {
577                 node_s = g_malloc0(sizeof(bt_mesh_node_s));
578                 node_s->parent = network_s;
579                 node_s->unicast = unicast;
580                 node_s->is_attached = true;
581                 if (node_s->unicast == 0x0001) {
582                         node_s->is_local = true;
583                         node_s->is_provisioner = true;
584                 }
585                 g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
586                 __bt_mesh_insert_elements_in_node(node_s, unicast,
587                                 count, node_s->is_local ? true : false);
588                 network_s->nodes = g_slist_append(network_s->nodes, node_s);
589                 node_list = g_slist_append(node_list, node_s);
590         }
591         return node_s;
592 }
593
594 bt_mesh_network_s * _bt_mesh_get_network_handle_info(char *net_uuid)
595 {
596         GSList *l;
597
598         l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
599         if (!l)
600                 return NULL;
601
602         return (bt_mesh_network_s*)l->data;
603 }
604
605 /* LCOV_EXCL_START */
606 char * _bt_mesh_get_auth_string_from_value(int auth)
607 {
608         switch (auth) {
609         case BT_MESH_AUTH_ALPHANUMERIC_DISPLAY:
610                 BT_INFO("Mesh: ALPHANUMERIC_DISPLAY");
611                 return "ALPHANUMERIC_DISPLAY";
612         case BT_MESH_AUTH_NUMERIC_DISPLAY:
613                 BT_INFO("Mesh: NUMERIC_DISPLAY");
614                 return "NUMERIC_DISPLAY";
615         case BT_MESH_AUTH_PUSH_COUNT_DISPLAY:
616                 BT_INFO("Mesh: PUSH_COUNT_DISPLAY");
617                 return "PUSH_COUNT_DISPLAY";
618         case BT_MESH_AUTH_TWIST_COUNT_DISPLAY:
619                 BT_INFO("Mesh: TWIST_COUNT_DISPLAY");
620                 return "TWIST_COUNT_DISPLAY";
621
622                 /*< Input authentication request types */
623         case BT_MESH_AUTH_REQ_ALPHANUMERIC_INPUT:
624                 BT_INFO("Mesh: REQ_ALPHANUMERIC_INPUT");
625                 return "REQ_ALPHANUMERIC_INPUT";
626         case BT_MESH_AUTH_REQ_NUMERIC_INPUT:
627                 BT_INFO("Mesh: REQ_NUMERIC_INPUT");
628                 return "REQ_NUMERIC_INPUT";
629         case BT_MESH_AUTH_REQ_BLINK_COUNT_INPUT:
630                 BT_INFO("Mesh: REQ_BLINK_COUNT_INPUT");
631                 return "REQ_BLINK_COUNT_INPUT";
632         case BT_MESH_AUTH_REQ_BEEP_COUNT_INPUT:
633                 BT_INFO("Mesh: REQ_BEEP_COUNT_INPUT");
634                 return "REQ_BEEP_COUNT_INPUT";
635         case BT_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT:
636                 BT_INFO("Mesh: REQ_VIBRATE_COUNT_INPUT");
637                 return "REQ_VIBRATE_COUNT_INPUT";
638
639                 /**< OOB Key Inputs */
640         case BT_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT:
641                 BT_INFO("Mesh: OOB_PUBLIC_KEY_INPUT");
642                 return "OOB_PUBLIC_KEY_INPUT";
643         case BT_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT:
644                 BT_INFO("Mesh: OOB_STATIC_KEY_INPUT");
645                 return "OOB_STATIC_KEY_INPUT";
646         default:
647                 return "";
648         }
649 }
650 /* LCOV_EXCL_STOP */
651
652 /* Mesh API */
653 int bt_mesh_initialize(void)
654 {
655         FUNC_ENTRY;
656         BT_CHECK_MESH_SUPPORT();
657
658         int ret = BT_ERROR_NONE;
659
660         BT_INFO("Is Mesh initialized:[%s]",
661                 is_mesh_initialized ? "TRUE" : "FALSE");
662
663         if (is_mesh_initialized) {
664                 BT_ERR("Mesh is initialized");
665                 return BT_ERROR_NONE;
666         }
667
668         if (!is_mesh_initialized) {
669                 ret = _bt_get_error_code(bluetooth_mesh_init(
670                                 _bt_mesh_event_proxy, NULL));
671
672                 if (ret != BT_ERROR_NONE) {
673                         BT_ERR("%s(0x%08x)",
674                                         _bt_convert_error_to_string(ret), ret);
675                         return BT_ERROR_OPERATION_FAILED;
676                 }
677
678                 is_mesh_initialized = true;
679                 return BT_ERROR_NONE;
680         }
681
682         BT_INFO("Mesh is already initialized");
683
684         FUNC_EXIT;
685         return BT_ERROR_NONE;
686 }
687
688 static void __mesh_unload_network_configurations(gpointer data,
689                 gpointer user_data)
690 {
691         bt_mesh_network_s *network_s = (bt_mesh_network_s*)data;
692         bluetooth_mesh_network_t net;
693
694         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
695
696         g_strlcpy(net.uuid, network_s->uuid, 33);
697         g_strlcpy(net.token.token, network_s->token, 17);
698         g_strlcpy(net.name.name, network_s->name,
699                         BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
700
701         BT_INFO("Mesh: Send Network Unload Request: UUID [%s]", net.uuid);
702         if (BLUETOOTH_ERROR_NONE != bluetooth_mesh_network_unload(&net)) {
703                 BT_ERR("Mesh: Failed to Unload Network [%s]",
704                                 network_s->uuid);
705         } else {
706                 BT_INFO("Mesh: Unoaded Network [%s] successfully",
707                                 network_s->uuid);
708
709                 __bt_mesh_destroy_network_handles(network_s);
710                 networks = g_slist_remove(networks, network_s);
711                 g_free(network_s);
712
713                 BT_INFO("Mesh: Current number of networks after removing [%d]",
714                                 g_slist_length(networks));
715
716         }
717 }
718
719 int bt_mesh_deinitialize(void)
720 {
721         FUNC_ENTRY;
722         BT_CHECK_MESH_SUPPORT();
723         BT_CHECK_MESH_INIT_STATUS();
724         int error;
725
726         BT_INFO("Mesh: Mesh Deinitialize");
727
728         BT_INFO("Mesh: Remove All Network:  Total Nets [%d]",
729                         g_slist_length(networks));
730         /* Unload All Network Configurations */
731         g_slist_foreach(networks,
732                 __mesh_unload_network_configurations,
733                         NULL);
734
735         BT_INFO("Mesh: After removal: Remaining Networks [%d]",
736                 g_slist_length(networks));
737
738         error = bluetooth_mesh_deinit();
739         error = _bt_get_error_code(error);
740         if (BT_ERROR_NONE != error)
741                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error);
742
743         is_mesh_initialized = false;
744
745         FUNC_EXIT;
746         return BT_ERROR_NONE;
747 }
748
749 int bt_mesh_node_create(bt_mesh_node_features_s *features,
750                 bt_mesh_node_h *node_handle)
751 {
752         FUNC_ENTRY;
753         bt_mesh_node_s *node = NULL;
754
755         BT_CHECK_MESH_SUPPORT();
756         BT_CHECK_MESH_INIT_STATUS();
757         BT_CHECK_INPUT_PARAMETER(node_handle);
758         BT_CHECK_INPUT_PARAMETER(features);
759
760         node = g_malloc0(sizeof(bt_mesh_node_s));
761         if (!node) {
762                 BT_ERR("g_malloc0 failed");
763                 return BT_ERROR_OUT_OF_MEMORY;
764         }
765
766         node->is_local = true;
767         node->features = *features;
768         node->unicast = 0x0001;
769
770         node_list = g_slist_append(node_list, node);
771         *node_handle = (bt_mesh_node_h)node;
772
773         FUNC_EXIT;
774         return BT_ERROR_NONE;
775 }
776
777 int bt_mesh_node_reset(bt_mesh_node_h node_handle)
778 {
779         FUNC_ENTRY;
780
781         bt_mesh_network_s *network_s;
782         bt_mesh_node_s *node_s;
783         bluetooth_mesh_node_info_t node;
784         int error_code = BT_ERROR_NONE;
785
786         BT_CHECK_MESH_SUPPORT();
787         BT_CHECK_MESH_INIT_STATUS();
788         BT_CHECK_INPUT_PARAMETER(node_handle);
789
790         node_s = (bt_mesh_node_s*)node_handle;
791         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
792
793         network_s = node_s->parent;
794         BT_CHECK_INPUT_PARAMETER(network_s);
795         BT_MESH_VALIDATE_HANDLE(network_s, networks);
796
797         /* Resetting a local node is not allowed */
798         BT_CHECK_MESH_REMOTE(node_s);
799
800         /* Only attached remote nodes can be resetted */
801         if (!node_s->is_attached)
802                 return BT_ERROR_INVALID_PARAMETER;
803
804         BT_INFO("Mesh: Reset the node [0x%2.2x]", node_s->unicast);
805
806         /* Fill node */
807         memset(&node, 0x00, sizeof(bluetooth_mesh_node_info_t));
808         g_strlcpy(node.net_uuid, network_s->uuid, 33);
809         node.primary_unicast = node_s->unicast;
810         node.num_elements = g_slist_length(node_s->elements);
811
812         error_code = _bt_get_error_code(bluetooth_mesh_node_reset(&node));
813         if (error_code != BT_ERROR_NONE) {
814                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
815                 return error_code;
816         }
817
818         /* Cleanup the Node handles */
819         node_list = g_slist_remove(node_list, node_s);
820         g_slist_free_full(node_s->elements, __bt_mesh_free_elements);
821         g_free(node_s);
822
823         FUNC_EXIT;
824         return error_code;
825 }
826
827 int bt_mesh_node_destroy(bt_mesh_node_h node_handle)
828 {
829         FUNC_ENTRY;
830
831         BT_CHECK_MESH_SUPPORT();
832         BT_CHECK_MESH_INIT_STATUS();
833         BT_CHECK_INPUT_PARAMETER(node_handle);
834
835         bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
836         BT_MESH_VALIDATE_HANDLE(node, node_list);
837
838         /* It is NOT allowed to destroy attached node: Do Reset */
839         BT_CHECK_MESH_IS_ATTACHED(node);
840
841         node_list = g_slist_remove(node_list, node);
842         g_slist_free_full(node->elements, __bt_mesh_free_elements);
843         g_free(node);
844
845         FUNC_EXIT;
846         return BT_ERROR_NONE;
847 }
848
849 /* LCOV_EXCL_START */
850 static void __bt_mesh_destroy_network_handles(bt_mesh_network_s *net)
851 {
852         GSList *l;
853
854         if (!net)
855                 return;
856
857         BT_INFO("Mesh: Destroy handles of Network [%s] UUID [%s] Token [%s]",
858                         net->name, net->uuid, net->token);
859
860         /* Remove all Nodes of Network */
861         BT_INFO("Mesh: Total nodes present in Network [%d]",
862                 g_slist_length(net->nodes));
863         for (l = net->nodes; l != NULL;) {
864                 bt_mesh_node_s *node_s = (bt_mesh_node_s*)l->data;
865                 l = g_slist_next(l);
866
867                 net->nodes = g_slist_remove(net->nodes, node_s);
868                 node_list = g_slist_remove(node_list, node_s);
869                 BT_INFO("Mesh: Total elements present in Node [%d]",
870                         g_slist_length(node_s->elements));
871
872                 g_slist_free_full(node_s->elements, __bt_mesh_free_elements);
873                 g_free(node_s);
874         }
875
876         /* Remove all Netkeys & Appkeys of Network */
877         BT_INFO("Mesh: Total netkeys present in Network [%d]",
878                 g_slist_length(net->netkeys));
879         for (l = net->netkeys; l != NULL;) {
880                 bt_mesh_netkey_s *netkey_s = (bt_mesh_netkey_s*)l->data;
881                 l = g_slist_next(l);
882
883                 net->netkeys = g_slist_remove(net->netkeys, netkey_s);
884                 netkey_list = g_slist_remove(netkey_list, netkey_s);
885                 BT_INFO("Mesh: Total appkeys present in Netkey [%d]",
886                         g_slist_length(netkey_s->appkeys));
887                 g_slist_free_full(netkey_s->appkeys, __bt_mesh_free_appkeys);
888                 g_free(netkey_s);
889         }
890
891         /* Remove all groups of Network */
892         BT_INFO("Mesh: Total groups present in Network [%d]",
893                 g_slist_length(net->groups));
894         for (l = net->groups; l != NULL;) {
895                 bt_mesh_group_s *group_s = (bt_mesh_group_s*)l->data;
896                 l = g_slist_next(l);
897
898                 net->groups = g_slist_remove(net->groups, group_s);
899                 group_list = g_slist_remove(group_list, group_s);
900                 g_free(group_s);
901         }
902         BT_INFO("Mesh: Handle Removal Done!");
903 }
904 /* LCOV_EXCL_STOP */
905
906 static void __bt_mesh_generate_element(bt_mesh_node_s *node_s,
907                 bt_mesh_element_s *elem_s)
908 {
909         GSList *l;
910         uint16_t index = 0;
911
912         for (l = node_s->elements; l; l = l->next) {
913                 bt_mesh_element_s *el = (bt_mesh_element_s*)l->data;
914                 if (el->index != index)
915                         break;
916                 index++;
917         }
918         elem_s->index = index;
919         node_s->elements = g_slist_insert(node_s->elements, elem_s, index);
920 }
921
922 int bt_mesh_node_create_element(bt_mesh_node_h node_handle,
923                 bt_mesh_element_h *element_handle)
924 {
925         FUNC_ENTRY;
926         BT_CHECK_MESH_SUPPORT();
927         BT_CHECK_MESH_INIT_STATUS();
928         BT_CHECK_INPUT_PARAMETER(node_handle);
929         BT_CHECK_INPUT_PARAMETER(element_handle);
930
931         bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
932         bt_mesh_element_s *element = NULL;
933
934         BT_INFO("Mesh: Element creation request");
935         BT_MESH_VALIDATE_HANDLE(node, node_list);
936
937         /* It is NOT allowed to add an element to a already attached node */
938         BT_CHECK_MESH_IS_ATTACHED(node);
939
940         /* Check num elements already present in the node */
941         if (g_slist_length(node->elements) >= BT_MESH_MAX_ELEMENTS)
942                 return BT_ERROR_QUOTA_EXCEEDED;
943
944
945         element = g_malloc0(sizeof(bt_mesh_element_s));
946         if (!element) {
947                 BT_ERR("g_malloc0 failed");
948                 return BT_ERROR_OUT_OF_MEMORY;
949         }
950
951         element->is_local = true;
952         element->parent = node;
953
954         __bt_mesh_generate_element(node, element);
955         element_list = g_slist_append(element_list, element);
956         *element_handle = (bt_mesh_element_h)element;
957
958         BT_INFO("Mesh: Element created successfully: element index [%d]", element->index);
959         FUNC_EXIT;
960         return BT_ERROR_NONE;
961 }
962
963 int bt_mesh_element_destroy(bt_mesh_element_h element_handle)
964 {
965         FUNC_ENTRY;
966         BT_CHECK_MESH_SUPPORT();
967         BT_CHECK_MESH_INIT_STATUS();
968         BT_CHECK_INPUT_PARAMETER(element_handle);
969         BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
970
971         bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
972         bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
973
974         /* It is NOT allowed to destroy remote element */
975         BT_CHECK_MESH_LOCAL(node);
976
977         /* It is NOT allowed to destroy an attahced element */
978         BT_CHECK_MESH_IS_ATTACHED(node);
979
980         element_list = g_slist_remove(element_list, element);
981         node->elements = g_slist_remove(node->elements, element);
982
983         g_slist_free_full(element->models, __bt_mesh_free_models);
984         g_free(element);
985
986         FUNC_EXIT;
987         return BT_ERROR_NONE;
988 }
989
990 int bt_mesh_element_create_model(
991                 bt_mesh_element_h element_handle,
992                         bt_mesh_model_id_s *model_id,
993                                 bt_mesh_model_h *model_handle)
994 {
995         FUNC_ENTRY;
996         uint32_t mod_id;
997         bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
998         bt_mesh_model_s *model = NULL;
999
1000         BT_CHECK_MESH_SUPPORT();
1001         BT_CHECK_MESH_INIT_STATUS();
1002         BT_CHECK_INPUT_PARAMETER(element_handle);
1003         BT_CHECK_INPUT_PARAMETER(model_id);
1004         BT_CHECK_INPUT_PARAMETER(model_handle);
1005         BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
1006
1007         bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
1008
1009         /* It is NOT allowed to add model to a remote element */
1010         BT_CHECK_MESH_LOCAL(node);
1011
1012         /* It is NOT allowed to add a Model to a already attached node */
1013         BT_CHECK_MESH_IS_ATTACHED(node);
1014
1015         BT_INFO("Mesh: Model creation request: Company ID [0x%2.2x] Model ID [0x%2.2x]",
1016                         model_id->company_id, model_id->model_id);
1017
1018         mod_id = model_id->company_id;
1019         mod_id <<= 16;
1020         mod_id |= model_id->model_id;
1021         /* Allow configuration server model only in primary element */
1022         if ((model_id->model_id == BT_MESH_MODEL_ID_CFG_SRV) &&
1023                         element->index != 0)
1024                 return BT_ERROR_OPERATION_FAILED;
1025
1026         /* Check num models already present in the element */
1027         if (g_slist_length(element->models) >= BT_MESH_MAX_MODELS)
1028                 return BT_ERROR_QUOTA_EXCEEDED;
1029
1030         /* Don't allow multiple instance of same model in an element */
1031         if (g_slist_find_custom(element->models, GUINT_TO_POINTER(mod_id),
1032                 (GCompareFunc)__compare_model_id))
1033                 return BT_ERROR_ALREADY_DONE;
1034
1035         model = g_malloc0(sizeof(bt_mesh_model_s));
1036         if (!model) {
1037                 BT_ERR("g_malloc0 failed");
1038                 return BT_ERROR_OUT_OF_MEMORY;
1039         }
1040
1041         model->is_local = true;
1042         model->parent = element;
1043         model->id = mod_id;
1044
1045         BT_INFO("Mesh: Model ID [0x%2.2x]", model_id->model_id);
1046         BT_INFO("Mesh: Company ID [0x%2.2x]", model_id->company_id);
1047         BT_INFO("Mesh: MOD [0x%4.4x]", model->id);
1048
1049         model_list = g_slist_append(model_list, model);
1050         element->models = g_slist_append(element->models, model);
1051         *model_handle = (bt_mesh_model_h)model;
1052
1053         BT_INFO("Mesh: Model created successfully");
1054         FUNC_EXIT;
1055         return BT_ERROR_NONE;
1056 }
1057
1058 int bt_mesh_model_destroy(bt_mesh_model_h model_handle)
1059 {
1060         FUNC_ENTRY;
1061
1062         BT_CHECK_MESH_SUPPORT();
1063         BT_CHECK_MESH_INIT_STATUS();
1064         BT_CHECK_INPUT_PARAMETER(model_handle);
1065
1066         bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
1067         BT_MESH_VALIDATE_HANDLE(model, model_list);
1068
1069         bt_mesh_element_s *element = model->parent;
1070         BT_CHECK_INPUT_PARAMETER(element);
1071         BT_MESH_VALIDATE_HANDLE(element, element_list);
1072
1073         bt_mesh_node_s *node = element->parent;
1074         BT_CHECK_INPUT_PARAMETER(node);
1075         BT_MESH_VALIDATE_HANDLE(node, node_list);
1076
1077         /* It is NOT allowed to destroy remote model */
1078         BT_CHECK_MESH_LOCAL(node);
1079
1080         /* It is NOT allowed to destroy an attahced model */
1081         BT_CHECK_MESH_IS_ATTACHED(node);
1082
1083         model_list = g_slist_remove(model_list, model);
1084         element->models = g_slist_remove(element->models, model);
1085         g_free(model);
1086
1087         FUNC_EXIT;
1088         return BT_ERROR_NONE;
1089 }
1090
1091 int bt_mesh_model_get_id(bt_mesh_model_h model_handle,
1092                 bt_mesh_model_id_s *model_id)
1093 {
1094         FUNC_ENTRY;
1095
1096         BT_CHECK_MESH_SUPPORT();
1097         BT_CHECK_MESH_INIT_STATUS();
1098         BT_CHECK_INPUT_PARAMETER(model_handle);
1099         BT_CHECK_INPUT_PARAMETER(model_id);
1100
1101         bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
1102         BT_MESH_VALIDATE_HANDLE(model, model_list);
1103
1104         BT_INFO("Mesh: Model ID [0x%4.4x]", model->id);
1105         model_id->company_id = model->id >> 16;
1106         model_id->model_id = model->id;
1107         BT_INFO("Mesh: CID [0x%2.2x]",  model_id->company_id);
1108         BT_INFO("Mesh: MID [0x%2.2x]",  model_id->model_id);
1109
1110         FUNC_EXIT;
1111         return BT_ERROR_NONE;
1112 }
1113
1114 int bt_mesh_node_get_network(bt_mesh_node_h node_handle, bt_mesh_network_h *network)
1115 {
1116         FUNC_ENTRY;
1117
1118         BT_CHECK_MESH_SUPPORT();
1119         BT_CHECK_MESH_INIT_STATUS();
1120         BT_CHECK_INPUT_PARAMETER(node_handle);
1121         BT_CHECK_INPUT_PARAMETER(network);
1122
1123         bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
1124         BT_MESH_VALIDATE_HANDLE(node_handle, node_list);
1125
1126         *network = node->parent;
1127
1128         FUNC_EXIT;
1129         return BT_ERROR_NONE;
1130 }
1131
1132 int bt_mesh_element_get_node(bt_mesh_element_h element_handle,
1133                 bt_mesh_node_h *node)
1134 {
1135         FUNC_ENTRY;
1136
1137         BT_CHECK_MESH_SUPPORT();
1138         BT_CHECK_MESH_INIT_STATUS();
1139         BT_CHECK_INPUT_PARAMETER(element_handle);
1140         BT_CHECK_INPUT_PARAMETER(node);
1141
1142         bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
1143         BT_MESH_VALIDATE_HANDLE(element, element_list);
1144
1145         *node = element->parent;
1146
1147         FUNC_EXIT;
1148         return BT_ERROR_NONE;
1149 }
1150
1151 int bt_mesh_model_get_element(bt_mesh_model_h model_handle,
1152                 bt_mesh_element_h *element)
1153 {
1154         FUNC_ENTRY;
1155
1156         BT_CHECK_MESH_SUPPORT();
1157         BT_CHECK_MESH_INIT_STATUS();
1158         BT_CHECK_INPUT_PARAMETER(model_handle);
1159         BT_CHECK_INPUT_PARAMETER(element);
1160
1161         bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
1162         BT_MESH_VALIDATE_HANDLE(model, model_list);
1163
1164         *element = model->parent;
1165
1166         FUNC_EXIT;
1167         return BT_ERROR_NONE;
1168 }
1169
1170 int bt_mesh_appkey_get_netkey(bt_mesh_appkey_h appkey_handle,
1171                 bt_mesh_netkey_h *netkey)
1172 {
1173         FUNC_ENTRY;
1174
1175         BT_CHECK_MESH_SUPPORT();
1176         BT_CHECK_MESH_INIT_STATUS();
1177         BT_CHECK_INPUT_PARAMETER(appkey_handle);
1178         BT_CHECK_INPUT_PARAMETER(netkey);
1179
1180         bt_mesh_appkey_s *appkey = (bt_mesh_appkey_s*)appkey_handle;
1181         BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
1182
1183         *netkey = appkey->parent;
1184
1185         FUNC_EXIT;
1186         return BT_ERROR_NONE;
1187 }
1188
1189 int bt_mesh_network_destroy(bt_mesh_network_h network)
1190 {
1191         FUNC_ENTRY;
1192
1193         int error_code = BT_ERROR_NONE;
1194         bt_mesh_network_s *network_s;
1195         bluetooth_mesh_network_t net;
1196
1197         BT_CHECK_MESH_SUPPORT();
1198         BT_CHECK_MESH_INIT_STATUS();
1199         BT_CHECK_INPUT_PARAMETER(network);
1200         BT_MESH_VALIDATE_HANDLE(network, networks);
1201
1202         network_s = (bt_mesh_network_s*) network;
1203         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1204
1205         g_strlcpy(net.uuid, network_s->uuid, 33);
1206         g_strlcpy(net.token.token, network_s->token, 17);
1207         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1208
1209         BT_INFO("Mesh: Destroy Network: Name [%s]", network_s->name);
1210
1211         BT_INFO("Mesh: Send Network Destroy Request to FRWK");
1212         error_code = _bt_get_error_code(bluetooth_mesh_network_destroy(&net));
1213         if (error_code != BT_ERROR_NONE) {
1214                 BT_INFO("Mesh: Network Destroy Failed!!");
1215                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1216
1217                 FUNC_EXIT;
1218                 return error_code;
1219         }
1220
1221         BT_INFO("Mesh: Network Destroyed successfully");
1222
1223         __bt_mesh_destroy_network_handles(network_s);
1224         networks = g_slist_remove(networks, network_s);
1225         g_free(network_s);
1226
1227         BT_INFO("Mesh: Current number of networks after removing [%d]",
1228                         g_slist_length(networks));
1229         FUNC_EXIT;
1230         return error_code;
1231 }
1232
1233 /* Async API's to bt-service & stack */
1234 int bt_mesh_network_create(bt_mesh_node_h config_client,
1235                 const char *network_name,
1236                         bt_mesh_network_h *network, char **token)
1237 {
1238         FUNC_ENTRY;
1239         int error_code = BT_ERROR_NONE;
1240         GSList *l1, *l2;
1241         int i, j;
1242         int offset = 0;
1243         int num_models = 0;
1244         bluetooth_mesh_network_t net;
1245         bluetooth_mesh_node_t param_node;
1246         bluetooth_mesh_model_t **param_model;
1247         bt_mesh_network_s *network_s;
1248         bt_mesh_netkey_s *netkey_s;
1249
1250         BT_CHECK_MESH_SUPPORT();
1251         BT_CHECK_MESH_INIT_STATUS();
1252         BT_CHECK_INPUT_PARAMETER(config_client);
1253         BT_CHECK_INPUT_PARAMETER(network_name);
1254         BT_CHECK_INPUT_PARAMETER(network);
1255         BT_CHECK_INPUT_PARAMETER(token);
1256
1257         BT_INFO("Mesh: Create Network: Name [%s]", network_name);
1258         bt_mesh_node_s *node = (bt_mesh_node_s*)config_client;
1259         BT_MESH_VALIDATE_HANDLE(node, node_list);
1260
1261         /* Error if remote node*/
1262         BT_CHECK_MESH_LOCAL(node);
1263
1264         /* It is NOT allowed to create network out of a already attahced node */
1265         BT_CHECK_MESH_IS_ATTACHED(node);
1266
1267         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1268
1269         if (strlen(network_name) >= BT_MESH_NETWORK_NAME_STRING_MAX_LEN)
1270                 return BT_ERROR_INVALID_PARAMETER;
1271
1272         /* Node in network should contain at-least one element */
1273         if (!g_slist_length(node->elements)) {
1274                 BT_INFO("Mesh: No element present in Node: NOT ALLOWED!!");
1275                 return BT_ERROR_INVALID_PARAMETER;
1276         }
1277
1278         /* Element in Node should contain at-least one Model */
1279         for (l1 = node->elements; l1 != NULL; l1 = l1->next) {
1280                 bt_mesh_element_s *el = l1->data;
1281                 int models = 0;
1282                 models = g_slist_length(el->models);
1283                 BT_INFO("Mesh: Num models element [%u] has is [%d]", el->index, models);
1284                 if (!models) {
1285                         BT_INFO("Mesh: No Model present in element: NOT ALLOWED!!");
1286                         return BT_ERROR_INVALID_PARAMETER;
1287                 }
1288                 /* If Primary element does not contain CFG SRV model, create and append */
1289                 if (el->index == 0x0000) {
1290                         uint32_t mod_id = 0xFFFF0000; /* CFG SRV */
1291
1292                         if (!g_slist_find_custom(el->models, GUINT_TO_POINTER(mod_id),
1293                                                 (GCompareFunc)__compare_model_id)) {
1294                                 bt_mesh_model_s *model_s;
1295                                 BT_ERR("Mesh: Primary element does not contain CFG SRV Model:Add it!");
1296                                 model_s = g_malloc0(sizeof(bt_mesh_model_s));
1297
1298                                 model_s->is_local = true;
1299                                 model_s->parent = el;
1300                                 model_s->id = mod_id;
1301
1302                                 model_list = g_slist_append(model_list, model_s);
1303                                 el->models = g_slist_append(el->models, model_s);
1304                                 num_models++;
1305                         } else
1306                                 BT_INFO("Mesh: CFG SRV model is already added in primary element");
1307                 }
1308                 num_models += models;
1309         }
1310
1311         memset(&param_node, 0x00, sizeof(bluetooth_mesh_node_t));
1312         param_node.vendor_info.companyid = node->features.cid;
1313         param_node.vendor_info.vendorid = node->features.pid;
1314         param_node.vendor_info.versionid = node->features.vid;
1315         param_node.vendor_info.crpl = node->features.crpl;
1316
1317         if (node->features.features & BT_MESH_FEATURE_RELAY)
1318                 param_node.vendor_info.relay = 1;
1319         if (node->features.features & BT_MESH_FEATURE_PROXY)
1320                 param_node.vendor_info.proxy = 1;
1321         if (node->features.features & BT_MESH_FEATURE_FRIEND)
1322                 param_node.vendor_info.frnd = 1;
1323         if (node->features.features & BT_MESH_FEATURE_LOWPOWER)
1324                 param_node.vendor_info.lpn = 1;
1325
1326         param_node.num_elements =  g_slist_length(node->elements);
1327         param_node.primary_unicast = 0x0001;
1328         _bt_get_random_bytes(param_node.uuid, 16);
1329
1330         BT_INFO("Mesh: Total Models [%d]", num_models);
1331         param_model = (bluetooth_mesh_model_t**)g_malloc0(num_models * sizeof(bluetooth_mesh_model_t*));
1332
1333         for (l1 = node->elements, i = 0; l1 != NULL; l1 = l1->next, i++) {
1334                 bt_mesh_element_s *e = l1->data;
1335
1336                 for (l2 = e->models, j = 0; l2 != NULL; l2 = l2->next, j++) {
1337                         bt_mesh_model_s *m = l2->data;
1338                         param_model[j+offset] = g_malloc0(sizeof(bluetooth_mesh_model_t));
1339                         param_model[j+offset]->elem_index = i;
1340                         param_model[j+offset]->model_id = m->id;
1341
1342                 }
1343                 offset += g_slist_length(e->models);
1344         }
1345
1346         BT_INFO("Mesh: Send Network create Request to FRWK");
1347         error_code = _bt_get_error_code(bluetooth_mesh_network_create(network_name, &param_node,
1348                                 num_models, param_model, &net));
1349         if (error_code != BT_ERROR_NONE) {
1350                 BT_INFO("Mesh: Network could not be created!!");
1351                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1352
1353                 /* Cleanup */
1354                 for (int i = 0; i < num_models; i++)
1355                         g_free(param_model[i]);
1356
1357                 return error_code;
1358         }
1359
1360         BT_INFO("Mesh: Network created successfully");
1361
1362         /* Create Network object & fill data in network */
1363         network_s = g_malloc0(sizeof(bt_mesh_network_s));
1364         network_s->num_nodes = 1;
1365         network_s->is_local = true;
1366         network_s->is_discovered = true;
1367
1368         /* Fill network name, token & UUID */
1369         __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid, 16,
1370                         network_s->uuid, sizeof(network_s->uuid));
1371         g_strlcpy(network_s->token, net.token.token, 17);
1372         g_strlcpy(network_s->name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1373         network_s->nodes = g_slist_append(network_s->nodes, node);
1374         BT_INFO("Mesh: Network Name [%s]", network_s->name);
1375         BT_INFO("Mesh: Network Token[%s]", network_s->token);
1376         BT_INFO("Mesh: Network UUID [%s]", network_s->uuid);
1377
1378         /* Create primary Netkey object */
1379         netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
1380         netkey_s->parent = network_s;
1381         netkey_s->netkey_index = 0x0000; /* Primary index */
1382         network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
1383         netkey_list = g_slist_append(netkey_list, netkey_s);
1384
1385         /* Fill Config Client Node Data */
1386         node->is_attached = true;
1387         node->is_provisioner = true;
1388         __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid,
1389                 16, node->uuid, sizeof(node->uuid));
1390         node->unicast = 0x0001;
1391         node->parent = network_s;
1392
1393         /* Prepare Out parameters */
1394         *token = network_s->token;
1395         *network = (bt_mesh_network_h)network_s;
1396
1397         /* Save network in list */
1398         BT_INFO("Mesh: Total networks present in app [%d]",
1399                 g_slist_length(networks));
1400
1401         networks = g_slist_append(networks, network_s);
1402
1403         BT_INFO("Mesh: Total networks present in app: After update [%d]",
1404                 g_slist_length(networks));
1405
1406         /* Clean up memory */
1407         for (int i = 0; i < num_models; i++)
1408                 g_free(param_model[i]);
1409
1410         FUNC_EXIT;
1411         return error_code;
1412 }
1413
1414 int bt_mesh_network_load(const char *token, bt_mesh_network_h *network)
1415 {
1416         int error_code = BT_ERROR_NONE;
1417         bluetooth_mesh_network_t net;
1418         bt_mesh_network_s *network_s;
1419
1420         BT_CHECK_MESH_SUPPORT();
1421         BT_CHECK_MESH_INIT_STATUS();
1422         BT_CHECK_INPUT_PARAMETER(token);
1423         BT_CHECK_INPUT_PARAMETER(network);
1424
1425         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1426         error_code = _bt_get_error_code(bluetooth_mesh_network_load(token, &net));
1427         if (error_code != BT_ERROR_NONE) {
1428                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1429                 return error_code;
1430         }
1431
1432         /* Create Network object */
1433         network_s = g_malloc0(sizeof(bt_mesh_network_s));
1434         network_s->is_local = true;
1435         g_strlcpy(network_s->uuid, net.uuid, 33);
1436         g_strlcpy(network_s->token, token, 17);
1437         g_strlcpy(network_s->name, net.name.name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1438         networks = g_slist_append(networks, network_s);
1439
1440         *network = (bt_mesh_network_h)network_s;
1441         FUNC_EXIT;
1442         return error_code;
1443 }
1444
1445 int bt_mesh_network_get_name(bt_mesh_network_h network, char **network_name)
1446 {
1447         bt_mesh_network_s *network_s;
1448
1449         FUNC_ENTRY;
1450         BT_CHECK_MESH_SUPPORT();
1451         BT_CHECK_MESH_INIT_STATUS();
1452         BT_CHECK_INPUT_PARAMETER(network);
1453         BT_CHECK_INPUT_PARAMETER(network_name);
1454
1455         BT_MESH_VALIDATE_HANDLE(network, networks);
1456
1457         network_s = (bt_mesh_network_s*)network;
1458         *network_name = strdup(network_s->name);
1459         if (*network_name == NULL) {
1460                 BT_ERR("OUT_OF_MEMORY(0x%08x)",
1461                                 BT_ERROR_OUT_OF_MEMORY);
1462                 return BT_ERROR_OUT_OF_MEMORY;
1463         }
1464
1465         FUNC_EXIT;
1466         return BT_ERROR_NONE;
1467 }
1468
1469 int bt_mesh_network_set_name(bt_mesh_network_h network, const char *network_name)
1470 {
1471         int error_code = BT_ERROR_NONE;
1472         bluetooth_mesh_network_t net;
1473         bt_mesh_network_s* network_s;
1474         FUNC_ENTRY;
1475
1476         BT_CHECK_MESH_SUPPORT();
1477         BT_CHECK_MESH_INIT_STATUS();
1478         BT_CHECK_INPUT_PARAMETER(network);
1479         BT_CHECK_INPUT_PARAMETER(network_name);
1480
1481         network_s = (bt_mesh_network_s*)network;
1482         BT_MESH_VALIDATE_HANDLE(network_s, networks);
1483
1484         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1485         g_strlcpy(net.uuid, network_s->uuid, 33);
1486         g_strlcpy(net.token.token, network_s->token, 17);
1487         g_strlcpy(net.name.name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1488
1489         BT_INFO("Mesh: Set Network Name [%s]", network_name);
1490         error_code = _bt_get_error_code(bluetooth_mesh_network_set_name(&net));
1491         if (error_code != BT_ERROR_NONE) {
1492                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1493                 return error_code;
1494         }
1495
1496         BT_INFO("Mesh: Network Name set successfully [%s]", network_name);
1497         g_strlcpy(network_s->name, network_name, sizeof(network_s->name));
1498
1499         FUNC_EXIT;
1500         return BT_ERROR_NONE;
1501 }
1502
1503 int bt_mesh_network_add_netkey(bt_mesh_network_h network,
1504                 bt_mesh_netkey_h *netkey)
1505 {
1506         int error_code = BT_ERROR_NONE;
1507         bt_mesh_network_s *network_s;
1508         bt_mesh_netkey_s *netkey_s;
1509         bluetooth_mesh_network_t net;
1510         uint16_t netkey_idx;
1511
1512         FUNC_ENTRY;
1513         BT_CHECK_MESH_SUPPORT();
1514         BT_CHECK_MESH_INIT_STATUS();
1515         BT_CHECK_INPUT_PARAMETER(network);
1516         BT_CHECK_INPUT_PARAMETER(netkey);
1517
1518         BT_MESH_VALIDATE_HANDLE(network, networks);
1519
1520         network_s = (bt_mesh_network_s*)network;
1521         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1522
1523         g_strlcpy(net.uuid, network_s->uuid, 33);
1524         g_strlcpy(net.token.token, network_s->token, 17);
1525         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1526
1527         error_code = _bt_get_error_code(bluetooth_mesh_network_add_netkey(&net, &netkey_idx));
1528         if (error_code != BT_ERROR_NONE) {
1529                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1530                 return error_code;
1531         }
1532
1533         BT_INFO("Mesh: Subnet Key created: Index [%d]", netkey_idx);
1534         /* Create Netkey object */
1535         netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
1536         netkey_s->parent = network_s;
1537         netkey_s->netkey_index = netkey_idx;
1538         network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
1539         netkey_list = g_slist_append(netkey_list, netkey_s);
1540         *netkey = (bt_mesh_netkey_h)netkey_s;
1541
1542         FUNC_EXIT;
1543         return BT_ERROR_NONE;
1544 }
1545
1546 int bt_mesh_network_foreach_netkeys(bt_mesh_network_h network,
1547                 bt_mesh_network_netkey_info_cb callback, void *user_data)
1548 {
1549         bluetooth_mesh_network_t net;
1550         GPtrArray *netkeys = NULL;
1551         GSList *l;
1552         int error_code = BT_ERROR_NONE;
1553         uint16_t *netkey_idx = NULL;
1554         int i;
1555         int total;
1556         bt_mesh_network_s *network_s;
1557
1558         FUNC_ENTRY;
1559         BT_CHECK_MESH_SUPPORT();
1560         BT_CHECK_MESH_INIT_STATUS();
1561         BT_CHECK_INPUT_PARAMETER(network);
1562         BT_CHECK_INPUT_PARAMETER(callback);
1563
1564         BT_MESH_VALIDATE_HANDLE(network, networks);
1565
1566         netkeys = g_ptr_array_new();
1567         if (netkeys == NULL) {
1568                 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1569                 return BT_ERROR_OUT_OF_MEMORY;
1570         }
1571
1572         network_s = (bt_mesh_network_s*)network;
1573         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1574
1575         g_strlcpy(net.uuid, network_s->uuid, 33);
1576         g_strlcpy(net.token.token, network_s->token, 17);
1577         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1578
1579         error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_netkey(&net, &netkeys));
1580         if (error_code != BT_ERROR_NONE) {
1581                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1582                 g_ptr_array_free(netkeys, TRUE);
1583                 return error_code;
1584         }
1585
1586         for (i = 0; i < netkeys->len; i++) {
1587                 netkey_idx = g_ptr_array_index(netkeys, i);
1588                 if (netkey_idx) {
1589                         /* Create and insert netkey object in list */
1590                         if (!__bt_mesh_network_is_netkey_added(network_s, *netkey_idx)) {
1591                                 bt_mesh_netkey_s *nk;
1592                                 nk = g_malloc0(sizeof(bt_mesh_netkey_s));
1593                                 nk->parent = network_s;
1594                                 nk->netkey_index = *netkey_idx;
1595                                 network_s->netkeys = g_slist_append(network_s->netkeys, nk);
1596                                 netkey_list = g_slist_append(netkey_list, nk);
1597                         }
1598
1599                 } else {
1600                         BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1601                                         BT_ERROR_OPERATION_FAILED);
1602                         error_code = BT_ERROR_OPERATION_FAILED;
1603                         break;
1604                 }
1605         }
1606
1607         total = g_slist_length(network_s->netkeys);
1608         if (total == 0) {
1609                 BT_INFO("Mesh: No netkey added in network");
1610                 callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
1611                                 NULL, 0xFFFF, user_data);
1612         }
1613         for (l = network_s->netkeys; l != NULL; l = g_slist_next(l)) {
1614                 bt_mesh_netkey_s *netkey;
1615                 netkey = l->data;
1616
1617                 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
1618                                         (bt_mesh_netkey_h) netkey,
1619                                         netkey->netkey_index, user_data)) {
1620                         break;
1621                 }
1622         }
1623
1624         g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
1625         g_ptr_array_free(netkeys, TRUE);
1626
1627         FUNC_EXIT;
1628         return error_code;
1629 }
1630
1631 int bt_mesh_netkey_get_index(bt_mesh_netkey_h netkey, uint16_t *index)
1632 {
1633         bt_mesh_netkey_s *netkey_s;
1634
1635         FUNC_ENTRY;
1636         BT_CHECK_MESH_SUPPORT();
1637         BT_CHECK_MESH_INIT_STATUS();
1638         BT_CHECK_INPUT_PARAMETER(netkey);
1639         BT_CHECK_INPUT_PARAMETER(index);
1640
1641         BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
1642
1643         netkey_s = (bt_mesh_netkey_s*)netkey;
1644         *index = netkey_s->netkey_index;
1645
1646         FUNC_EXIT;
1647         return BT_ERROR_NONE;
1648 }
1649
1650 int bt_mesh_netkey_update(bt_mesh_netkey_h netkey)
1651 {
1652         int error_code = BT_ERROR_NONE;
1653         bt_mesh_network_s *network_s;
1654         bt_mesh_netkey_s *netkey_s;
1655         bluetooth_mesh_network_t net;
1656
1657         FUNC_ENTRY;
1658         BT_CHECK_MESH_SUPPORT();
1659         BT_CHECK_MESH_INIT_STATUS();
1660         BT_CHECK_INPUT_PARAMETER(netkey);
1661
1662         netkey_s = (bt_mesh_netkey_s*)netkey;
1663         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1664         network_s = netkey_s->parent;
1665         BT_CHECK_INPUT_PARAMETER(network_s);
1666         BT_MESH_VALIDATE_HANDLE(network_s, networks);
1667
1668         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1669
1670         g_strlcpy(net.uuid, network_s->uuid, 33);
1671         g_strlcpy(net.token.token, network_s->token, 17);
1672         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1673
1674         error_code = _bt_get_error_code(bluetooth_mesh_network_update_netkey(
1675                                 &net, netkey_s->netkey_index));
1676         if (error_code != BT_ERROR_NONE) {
1677                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1678                 return error_code;
1679         }
1680
1681         FUNC_EXIT;
1682         return BT_ERROR_NONE;
1683 }
1684
1685 int bt_mesh_netkey_delete(bt_mesh_netkey_h netkey)
1686 {
1687         int error_code = BT_ERROR_NONE;
1688         bt_mesh_network_s *network_s;
1689         bt_mesh_netkey_s *netkey_s;
1690         bluetooth_mesh_network_t net;
1691
1692         FUNC_ENTRY;
1693         BT_CHECK_MESH_SUPPORT();
1694         BT_CHECK_MESH_INIT_STATUS();
1695
1696         BT_CHECK_INPUT_PARAMETER(netkey);
1697
1698         netkey_s = (bt_mesh_netkey_s*)netkey;
1699         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1700
1701         network_s = netkey_s->parent;
1702         BT_CHECK_INPUT_PARAMETER(network_s);
1703         BT_MESH_VALIDATE_HANDLE(network_s, networks);
1704
1705         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1706
1707         g_strlcpy(net.uuid, network_s->uuid, 33);
1708         g_strlcpy(net.token.token, network_s->token, 17);
1709         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1710
1711         error_code = _bt_get_error_code(bluetooth_mesh_network_delete_netkey(&net, netkey_s->netkey_index));
1712         if (error_code != BT_ERROR_NONE) {
1713                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1714                 return error_code;
1715         }
1716
1717         network_s->netkeys = g_slist_remove(network_s->netkeys, netkey_s);
1718         netkey_list = g_slist_remove(netkey_list, netkey_s);
1719         g_slist_free_full(netkey_s->appkeys, __bt_mesh_free_appkeys);
1720         g_free(netkey_s);
1721
1722         FUNC_EXIT;
1723         return BT_ERROR_NONE;
1724 }
1725
1726 int bt_mesh_netkey_add_appkey(bt_mesh_netkey_h netkey,
1727                 bt_mesh_appkey_h *appkey)
1728 {
1729         int error_code = BT_ERROR_NONE;
1730         uint16_t appkey_idx;
1731         bt_mesh_network_s *network_s;
1732         bt_mesh_netkey_s *netkey_s;
1733         bt_mesh_appkey_s *appkey_s;
1734         bluetooth_mesh_network_t net;
1735
1736         FUNC_ENTRY;
1737         BT_CHECK_MESH_SUPPORT();
1738         BT_CHECK_MESH_INIT_STATUS();
1739
1740         BT_CHECK_INPUT_PARAMETER(netkey);
1741         BT_CHECK_INPUT_PARAMETER(appkey);
1742
1743         netkey_s = (bt_mesh_netkey_s*)netkey;
1744         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1745
1746         network_s = netkey_s->parent;
1747         BT_CHECK_INPUT_PARAMETER(network_s);
1748         BT_MESH_VALIDATE_HANDLE(network_s, networks);
1749
1750         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1751
1752         g_strlcpy(net.uuid, network_s->uuid, 33);
1753         g_strlcpy(net.token.token, network_s->token, 17);
1754         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1755
1756         error_code = _bt_get_error_code(bluetooth_mesh_network_add_appkey(
1757                                 &net, netkey_s->netkey_index, &appkey_idx));
1758         if (error_code != BT_ERROR_NONE) {
1759                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1760                 return error_code;
1761         }
1762
1763         /* Create Appkey object */
1764         appkey_s = g_malloc0(sizeof(bt_mesh_appkey_s));
1765         appkey_s->parent = netkey_s;
1766         appkey_s->appkey_index = appkey_idx;
1767         netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_s);
1768         appkey_list = g_slist_append(appkey_list, appkey_s);
1769         *appkey = (bt_mesh_appkey_h)appkey_s;
1770
1771         FUNC_EXIT;
1772         return BT_ERROR_NONE;
1773 }
1774
1775 int bt_mesh_appkey_update(bt_mesh_appkey_h appkey)
1776 {
1777         int error_code = BT_ERROR_NONE;
1778         bt_mesh_network_s *network_s;
1779         bt_mesh_netkey_s *netkey_s;
1780         bt_mesh_appkey_s *appkey_s;
1781         bluetooth_mesh_network_t net;
1782
1783         FUNC_ENTRY;
1784         BT_CHECK_MESH_SUPPORT();
1785         BT_CHECK_MESH_INIT_STATUS();
1786         BT_CHECK_INPUT_PARAMETER(appkey);
1787
1788         appkey_s = (bt_mesh_appkey_s*)appkey;
1789         BT_CHECK_INPUT_PARAMETER(appkey_s);
1790         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
1791
1792         netkey_s = appkey_s->parent;
1793         BT_CHECK_INPUT_PARAMETER(netkey_s);
1794         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1795
1796         network_s = netkey_s->parent;
1797         BT_CHECK_INPUT_PARAMETER(network_s);
1798         BT_MESH_VALIDATE_HANDLE(network_s, networks);
1799
1800         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1801
1802         g_strlcpy(net.uuid, network_s->uuid, 33);
1803         g_strlcpy(net.token.token, network_s->token, 17);
1804         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1805
1806         error_code = _bt_get_error_code(bluetooth_mesh_network_update_appkey(
1807                                 &net, netkey_s->netkey_index, appkey_s->appkey_index));
1808         if (error_code != BT_ERROR_NONE) {
1809                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1810                 return error_code;
1811         }
1812
1813         FUNC_EXIT;
1814         return BT_ERROR_NONE;
1815 }
1816
1817 int bt_mesh_appkey_delete(bt_mesh_appkey_h appkey)
1818 {
1819         int error_code = BT_ERROR_NONE;
1820         bt_mesh_network_s *network_s;
1821         bt_mesh_netkey_s *netkey_s;
1822         bt_mesh_appkey_s *appkey_s;
1823         bluetooth_mesh_network_t net;
1824
1825         FUNC_ENTRY;
1826         BT_CHECK_MESH_SUPPORT();
1827         BT_CHECK_MESH_INIT_STATUS();
1828         BT_CHECK_INPUT_PARAMETER(appkey);
1829
1830         appkey_s = (bt_mesh_appkey_s*)appkey;
1831         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
1832
1833         netkey_s = appkey_s->parent;
1834         BT_CHECK_INPUT_PARAMETER(netkey_s);
1835         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1836
1837         network_s = netkey_s->parent;
1838         BT_CHECK_INPUT_PARAMETER(network_s);
1839         BT_MESH_VALIDATE_HANDLE(network_s, networks);
1840
1841         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1842
1843         g_strlcpy(net.uuid, network_s->uuid, 33);
1844         g_strlcpy(net.token.token, network_s->token, 17);
1845         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1846
1847         error_code = _bt_get_error_code(bluetooth_mesh_network_delete_appkey(
1848                         &net, netkey_s->netkey_index, appkey_s->appkey_index));
1849         if (error_code != BT_ERROR_NONE) {
1850                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1851                 return error_code;
1852         }
1853
1854         /* Delete Appkey Object */
1855         netkey_s->appkeys = g_slist_remove(netkey_s->appkeys, appkey_s);
1856         appkey_list = g_slist_remove(appkey_list, appkey_s);
1857         g_free(appkey_s);
1858
1859         FUNC_EXIT;
1860         return BT_ERROR_NONE;
1861 }
1862
1863 int bt_mesh_netkey_foreach_appkeys(bt_mesh_netkey_h netkey,
1864                 bt_mesh_appkey_info_cb callback, void *user_data)
1865 {
1866         int error_code = BT_ERROR_NONE;
1867         bt_mesh_netkey_s *netkey_s;
1868         bt_mesh_network_s *network_s;
1869         bluetooth_mesh_network_t net;
1870         int total;
1871         int i;
1872         GSList *l;
1873         GPtrArray *appkeys = NULL;
1874         uint16_t *appkey_idx = NULL;
1875
1876         FUNC_ENTRY;
1877         BT_CHECK_MESH_SUPPORT();
1878         BT_CHECK_MESH_INIT_STATUS();
1879         BT_CHECK_INPUT_PARAMETER(netkey);
1880         BT_CHECK_INPUT_PARAMETER(callback);
1881
1882         BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
1883
1884         netkey_s = (bt_mesh_netkey_s*)netkey;
1885
1886         network_s = netkey_s->parent;
1887         BT_CHECK_INPUT_PARAMETER(network_s);
1888         BT_MESH_VALIDATE_HANDLE(network_s, networks);
1889
1890         appkeys = g_ptr_array_new();
1891         if (appkeys == NULL) {
1892                 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1893                 return BT_ERROR_OUT_OF_MEMORY;
1894         }
1895
1896         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1897
1898         g_strlcpy(net.uuid, network_s->uuid, 33);
1899         g_strlcpy(net.token.token, network_s->token, 17);
1900         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1901
1902         BT_INFO("Mesh: Find all Appkeys for Netkey : index [%d]", netkey_s->netkey_index);
1903         error_code = _bt_get_error_code(bluetooth_mesh_netkey_get_all_appkey(
1904                         &net, netkey_s->netkey_index, &appkeys));
1905         if (error_code != BT_ERROR_NONE) {
1906                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1907                 g_ptr_array_free(appkeys, TRUE);
1908                 return error_code;
1909         }
1910         for (i = 0; i < appkeys->len; i++) {
1911                 appkey_idx = g_ptr_array_index(appkeys, i);
1912                 if (appkey_idx) {
1913                         /* Create and insert netkey object in list */
1914                         if (!__bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx)) {
1915                                 bt_mesh_appkey_s *key;
1916                                 key = g_malloc0(sizeof(bt_mesh_appkey_s));
1917                                 key->parent = netkey_s;
1918                                 key->appkey_index = *appkey_idx;
1919                                 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, key);
1920                                 appkey_list = g_slist_append(appkey_list, key);
1921                         }
1922
1923                 } else {
1924                         BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1925                                         BT_ERROR_OPERATION_FAILED);
1926                         error_code = BT_ERROR_OPERATION_FAILED;
1927                         break;
1928                 }
1929         }
1930
1931         total = g_slist_length(netkey_s->appkeys);
1932         BT_INFO("Mesh: Total appkeys [%d]", total);
1933
1934         if (!total) {
1935                 BT_INFO("Mesh: No AppKey added in NetKey yet!");
1936                 callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
1937                                 (bt_mesh_netkey_h) netkey_s, NULL,
1938                                 0xFFFF, user_data);
1939                 return BT_ERROR_NONE;
1940         }
1941
1942
1943         for (l = netkey_s->appkeys; l; l = g_slist_next(l)) {
1944                 bt_mesh_appkey_s *appkey_s;
1945                 appkey_s = l->data;
1946                 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
1947                                         (bt_mesh_netkey_h) netkey_s, (bt_mesh_appkey_h) appkey_s,
1948                                         appkey_s->appkey_index, user_data))
1949                         break;
1950         }
1951
1952         g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
1953         g_ptr_array_free(appkeys, TRUE);
1954
1955         FUNC_EXIT;
1956         return BT_ERROR_NONE;
1957 }
1958
1959 int bt_mesh_appkey_get_index(bt_mesh_appkey_h appkey, uint16_t *index)
1960 {
1961         bt_mesh_appkey_s *appkey_s;
1962
1963         FUNC_ENTRY;
1964         BT_CHECK_MESH_SUPPORT();
1965         BT_CHECK_MESH_INIT_STATUS();
1966         BT_CHECK_INPUT_PARAMETER(appkey);
1967         BT_CHECK_INPUT_PARAMETER(index);
1968
1969         BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
1970
1971         appkey_s = (bt_mesh_appkey_s*)appkey;
1972         *index = appkey_s->appkey_index;
1973
1974         FUNC_EXIT;
1975         return BT_ERROR_NONE;
1976 }
1977
1978 /* Sync API's to bt-service: Discovery API's */
1979 int bt_mesh_network_foreach_devices(bt_mesh_network_h network,
1980                 bt_mesh_network_device_info_cb callback, void *user_data)
1981 {
1982         bluetooth_mesh_network_t net;
1983         bluetooth_mesh_node_info_t *node_info;
1984         GPtrArray *nodes = NULL;
1985         int error_code = BT_ERROR_NONE;
1986         int i;
1987         bt_mesh_network_s *network_s;
1988
1989         FUNC_ENTRY;
1990         BT_CHECK_MESH_SUPPORT();
1991         BT_CHECK_MESH_INIT_STATUS();
1992         BT_CHECK_INPUT_PARAMETER(network);
1993         BT_CHECK_INPUT_PARAMETER(callback);
1994
1995         BT_MESH_VALIDATE_HANDLE(network, networks);
1996
1997         nodes = g_ptr_array_new();
1998         if (nodes == NULL) {
1999                 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2000                 return BT_ERROR_OUT_OF_MEMORY;
2001         }
2002
2003         network_s = (bt_mesh_network_s*)network;
2004         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2005
2006         g_strlcpy(net.uuid, network_s->uuid, 33);
2007         g_strlcpy(net.token.token, network_s->token, 17);
2008         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2009
2010         error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_nodes(&net, &nodes));
2011         if (error_code != BT_ERROR_NONE) {
2012                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2013                 g_ptr_array_free(nodes, TRUE);
2014                 return error_code;
2015         }
2016
2017         BT_INFO("Mesh: Total number of Devices found [%d]", nodes->len);
2018         for (i = 0; i < nodes->len; i++) {
2019                 node_info = g_ptr_array_index(nodes, i);
2020                 if (node_info) {
2021                         if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, nodes->len,
2022                                         node_info->dev_uuid, node_info->primary_unicast, user_data)) {
2023                                 break;
2024                         }
2025                 } else {
2026                         BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2027                                         BT_ERROR_OPERATION_FAILED);
2028                         error_code = BT_ERROR_OPERATION_FAILED;
2029                         break;
2030                 }
2031         }
2032
2033         g_ptr_array_foreach(nodes, (GFunc)g_free, NULL);
2034         g_ptr_array_free(nodes, TRUE);
2035
2036         FUNC_EXIT;
2037         return error_code;
2038 }
2039
2040 int bt_mesh_node_get_primary_address(bt_mesh_node_h node,
2041                 uint16_t *primary_address)
2042 {
2043         bt_mesh_node_s *node_s;
2044
2045         FUNC_ENTRY;
2046         BT_CHECK_MESH_SUPPORT();
2047         BT_CHECK_MESH_INIT_STATUS();
2048         BT_CHECK_INPUT_PARAMETER(node);
2049         BT_CHECK_INPUT_PARAMETER(primary_address);
2050
2051         BT_MESH_VALIDATE_HANDLE(node, node_list);
2052
2053         node_s = (bt_mesh_node_s*) node;
2054         *primary_address = node_s->unicast;
2055
2056         FUNC_EXIT;
2057         return BT_ERROR_NONE;
2058 }
2059
2060 int bt_mesh_node_foreach_element(bt_mesh_node_h node,
2061         bt_mesh_node_element_info_cb callback, void *user_data)
2062 {
2063         bt_mesh_node_s *node_s;
2064         int total = 0;
2065         GSList *l;
2066
2067         FUNC_ENTRY;
2068         BT_CHECK_MESH_SUPPORT();
2069         BT_CHECK_MESH_INIT_STATUS();
2070         BT_CHECK_INPUT_PARAMETER(node);
2071         BT_CHECK_INPUT_PARAMETER(callback);
2072
2073         BT_MESH_VALIDATE_HANDLE(node, node_list);
2074         node_s = (bt_mesh_node_s*) node;
2075
2076         total = g_slist_length(node_s->elements);
2077         if (!total) {
2078                 callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
2079                         (bt_mesh_element_h) NULL, -1, 0xFFFF,  user_data);
2080
2081         }
2082
2083         for (l = node_s->elements; l; l = g_slist_next(l)) {
2084                 bt_mesh_element_s *element_s;
2085                 element_s = l->data;
2086                 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
2087                                         (bt_mesh_element_h)element_s, element_s->index,
2088                                         (node_s->unicast + element_s->index), user_data))
2089                         break;
2090         }
2091
2092         FUNC_EXIT;
2093         return BT_ERROR_NONE;
2094 }
2095
2096 int bt_mesh_element_foreach_models(bt_mesh_element_h element,
2097         bt_mesh_element_model_info_cb callback, void *user_data)
2098 {
2099         bluetooth_mesh_network_t net;
2100         bt_mesh_network_s *network_s;
2101         bt_mesh_node_s *node_s;
2102         bt_mesh_element_s *element_s;
2103
2104         GPtrArray *models = NULL;
2105         GSList *l = NULL;
2106         uint32_t *model_info;
2107         int error_code = BT_ERROR_NONE;
2108         int i;
2109         int total;
2110
2111         FUNC_ENTRY;
2112         BT_CHECK_MESH_SUPPORT();
2113         BT_CHECK_MESH_INIT_STATUS();
2114         BT_CHECK_INPUT_PARAMETER(element);
2115         BT_CHECK_INPUT_PARAMETER(callback);
2116
2117         element_s = (bt_mesh_element_s*) element;
2118         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2119
2120         node_s = (bt_mesh_node_s*) element_s->parent;
2121         BT_CHECK_INPUT_PARAMETER(node_s);
2122         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2123
2124         network_s = (bt_mesh_network_s*) node_s->parent;
2125
2126         /* Only for local Node */
2127         if (node_s->is_local) {
2128                 GSList *l;
2129                 BT_INFO("Mesh: Local element");
2130
2131                 total = g_slist_length(element_s->models);
2132                 if (!total)
2133                         callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, 0,
2134                                         (bt_mesh_model_h) NULL, NULL, user_data);
2135
2136                 for (l = element_s->models; l; l = l->next) {
2137                         bt_mesh_model_s *model_s = l->data;
2138                         bt_mesh_model_id_s modid;
2139
2140                         modid.company_id = model_s->id >> 16;
2141                         modid.model_id = model_s->id;
2142
2143                         if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
2144                                                 (bt_mesh_model_h) model_s,
2145                                                 &modid, user_data)) {
2146                                 break;
2147                         }
2148                 }
2149                 FUNC_EXIT;
2150                 return BT_ERROR_NONE;
2151         }
2152
2153         models = g_ptr_array_new();
2154         if (models == NULL) {
2155                 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2156                 return BT_ERROR_OUT_OF_MEMORY;
2157         }
2158         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2159
2160         g_strlcpy(net.uuid, network_s->uuid, 33);
2161         g_strlcpy(net.token.token, network_s->token, 17);
2162         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2163
2164         BT_INFO("Mesh: Get Models for element of Remote Node");
2165         error_code = _bt_get_error_code(bluetooth_mesh_element_get_all_models(&net,
2166                                 /* Node identity */node_s->unicast,
2167                                 /* eleement identity */element_s->index,
2168                                 /*Output*/ &models));
2169         if (error_code != BT_ERROR_NONE) {
2170                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2171                 g_ptr_array_free(models, TRUE);
2172                 return error_code;
2173         }
2174
2175         total = models->len;
2176         BT_INFO("Mesh: Total models in element [%d]", total);
2177         for (i = 0; i < models->len; i++) {
2178                 model_info = g_ptr_array_index(models, i);
2179                 if (model_info) {
2180                         BT_INFO("Mesh: Model ID [0x%4.4x]", *model_info);
2181
2182                         /* Skip if Model is already added in the element */
2183                         l = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(*model_info),
2184                                                 (GCompareFunc)__compare_model_id);
2185                         if (l) {
2186                                 bt_mesh_model_id_s modid;
2187                                 bt_mesh_model_s *mod = (bt_mesh_model_s*)l->data;
2188                                 modid.company_id = mod->id >> 16;
2189                                 modid.model_id = mod->id;
2190
2191                                 BT_INFO("Mesh: Model ID [0x%4.4x] is already present in element", *model_info);
2192                                 if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
2193                                                         (bt_mesh_model_h) mod,
2194                                                         &modid, user_data)) {
2195                                         break;
2196                                 }
2197                                 continue;
2198                         }
2199
2200                         /* Create and insert model object in list */
2201                         bt_mesh_model_s *mod;
2202                         bt_mesh_model_id_s modid;
2203                         mod = g_malloc0(sizeof(bt_mesh_model_s));
2204                         mod->parent = element_s;
2205
2206                         if (node_s->unicast == 0x0001)
2207
2208                                 mod->is_local = true;
2209                         mod->id = *model_info;
2210                         element_s->models = g_slist_append(element_s->models, mod);
2211                         model_list = g_slist_append(model_list, mod);
2212
2213                         modid.company_id = *model_info >> 16;
2214                         modid.model_id = *model_info;
2215                         BT_INFO("Mesh: Model was not present in Element, created & inserted");
2216                         BT_INFO("Mesh: Total Models present in Element [%d]",
2217                                         g_slist_length(element_s->models));
2218
2219                         /* Send Callback */
2220                         if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
2221                                                 (bt_mesh_model_h) mod,
2222                                                 &modid, user_data)) {
2223                                 break;
2224                         }
2225                 } else {
2226                         BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2227                                         BT_ERROR_OPERATION_FAILED);
2228                         error_code = BT_ERROR_OPERATION_FAILED;
2229                         break;
2230                 }
2231         }
2232
2233         g_ptr_array_foreach(models, (GFunc)g_free, NULL);
2234         g_ptr_array_free(models, TRUE);
2235
2236         FUNC_EXIT;
2237         return error_code;
2238 }
2239
2240 /* Provisioning & capabilities related*/
2241 int bt_mesh_network_unprovisioned_device_scan(bt_mesh_network_h network,
2242                 bt_mesh_scan_params_s *scan_params,
2243                         bt_mesh_network_scan_unprovisioned_device_result_cb callback,
2244                                 void *user_data)
2245 {
2246         bt_mesh_network_s *network_s;
2247         bluetooth_mesh_network_t net;
2248         int error_code = BT_ERROR_NONE;
2249
2250         FUNC_ENTRY;
2251         BT_CHECK_MESH_SUPPORT();
2252         BT_CHECK_MESH_INIT_STATUS();
2253         BT_CHECK_INPUT_PARAMETER(network);
2254         BT_CHECK_INPUT_PARAMETER(scan_params);
2255         BT_CHECK_INPUT_PARAMETER(callback);
2256
2257         BT_MESH_VALIDATE_HANDLE(network, networks);
2258
2259         network_s = (bt_mesh_network_s*)network;
2260         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2261
2262         g_strlcpy(net.uuid, network_s->uuid, 33);
2263         g_strlcpy(net.token.token, network_s->token, 17);
2264         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2265
2266         error_code = _bt_get_error_code(bluetooth_mesh_network_scan(
2267                         &net, (bluetooth_mesh_scan_param_t*) scan_params));
2268
2269         if (error_code != BT_ERROR_NONE) {
2270                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2271                 return error_code;
2272         }
2273
2274         _bt_set_cb(BT_EVENT_MESH_NETWORK_SCAN_STATE_CHANGED, callback, user_data);
2275         FUNC_EXIT;
2276         return BT_ERROR_NONE;
2277 }
2278
2279 int bt_mesh_stop_unprovisioned_device_scan(bt_mesh_network_h network)
2280 {
2281         bt_mesh_network_s *network_s;
2282         bluetooth_mesh_network_t net;
2283         int error_code = BT_ERROR_NONE;
2284
2285         FUNC_ENTRY;
2286         BT_CHECK_MESH_SUPPORT();
2287         BT_CHECK_MESH_INIT_STATUS();
2288         BT_CHECK_INPUT_PARAMETER(network);
2289
2290         BT_MESH_VALIDATE_HANDLE(network, networks);
2291
2292         network_s = (bt_mesh_network_s*)network;
2293         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2294
2295         g_strlcpy(net.uuid, network_s->uuid, 33);
2296         g_strlcpy(net.token.token, network_s->token, 17);
2297         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2298
2299         error_code = _bt_get_error_code(bluetooth_mesh_network_cancel_scan(&net));
2300
2301         if (error_code != BT_ERROR_NONE) {
2302                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2303                 return error_code;
2304         }
2305
2306         FUNC_EXIT;
2307         return BT_ERROR_NONE;
2308 }
2309
2310 int bt_mesh_network_set_provisioning_capabilities(bt_mesh_network_h network,
2311                 bt_mesh_provisioner_capabilities_s *capabilities)
2312 {
2313         bt_mesh_network_s *network_s;
2314         bluetooth_mesh_network_t net;
2315         bluetooth_mesh_provisioner_caps_t caps;
2316         int error_code = BT_ERROR_NONE;
2317
2318         FUNC_ENTRY;
2319         BT_CHECK_MESH_SUPPORT();
2320         BT_CHECK_MESH_INIT_STATUS();
2321         BT_CHECK_INPUT_PARAMETER(network);
2322         BT_CHECK_INPUT_PARAMETER(capabilities);
2323
2324         BT_MESH_VALIDATE_HANDLE(network, networks);
2325
2326         network_s = (bt_mesh_network_s*)network;
2327         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2328         memset(&caps, 0x00, sizeof(bluetooth_mesh_provisioner_caps_t));
2329
2330         g_strlcpy(net.uuid, network_s->uuid, 33);
2331         g_strlcpy(net.token.token, network_s->token, 17);
2332         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2333
2334         caps.public_oob = capabilities->public_oob;
2335         caps.static_oob = capabilities->static_oob;
2336         caps.out_oob = capabilities->out_oob;
2337         caps.in_oob = capabilities->in_oob;
2338
2339         error_code = _bt_get_error_code(bluetooth_mesh_network_set_capabilities(
2340                                         &net, (bluetooth_mesh_provisioner_caps_t*) &caps));
2341
2342         if (error_code != BT_ERROR_NONE) {
2343                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2344                 return error_code;
2345         }
2346
2347         FUNC_EXIT;
2348         return BT_ERROR_NONE;
2349 }
2350
2351 int bt_mesh_network_provision_device(bt_mesh_network_h network,
2352                 const char *dev_uuid,
2353                         bt_mesh_network_device_provision_cb callback,
2354                                 void *user_data)
2355 {
2356         bt_mesh_network_s *network_s;
2357         bluetooth_mesh_provisioning_request_t req;
2358         int error_code = BT_ERROR_NONE;
2359
2360         FUNC_ENTRY;
2361         BT_CHECK_MESH_SUPPORT();
2362         BT_CHECK_MESH_INIT_STATUS();
2363         BT_CHECK_INPUT_PARAMETER(network);
2364         BT_CHECK_INPUT_PARAMETER(dev_uuid);
2365         BT_CHECK_INPUT_PARAMETER(callback);
2366
2367         BT_MESH_VALIDATE_HANDLE(network, networks);
2368
2369         network_s = (bt_mesh_network_s*)network;
2370         memset(&req, 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
2371
2372         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2373         g_strlcpy(req.dev_uuid, dev_uuid, 33);
2374
2375         BT_INFO("Mesh: Provision Device [%s]", dev_uuid);
2376         error_code = _bt_get_error_code(bluetooth_mesh_network_provision_device(&req));
2377
2378         if (error_code != BT_ERROR_NONE) {
2379                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2380                 return error_code;
2381         }
2382
2383         _bt_set_cb(BT_EVENT_MESH_NETWORK_PROVISIONING_RESULT, callback, user_data);
2384         FUNC_EXIT;
2385         return BT_ERROR_NONE;
2386 }
2387
2388 int bt_mesh_authentication_set_request_cb(bt_mesh_authentication_request_cb callback, void *user_data)
2389 {
2390         FUNC_ENTRY;
2391         BT_CHECK_MESH_SUPPORT();
2392         BT_CHECK_MESH_INIT_STATUS();
2393         BT_CHECK_INPUT_PARAMETER(callback);
2394
2395         _bt_set_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST, callback, user_data);
2396
2397         FUNC_EXIT;
2398         return BT_ERROR_NONE;
2399 }
2400
2401 int bt_mesh_authentication_unset_request_cb(bt_mesh_authentication_request_cb callback)
2402 {
2403         FUNC_ENTRY;
2404
2405         BT_CHECK_MESH_SUPPORT();
2406         BT_CHECK_MESH_INIT_STATUS();
2407         BT_CHECK_INPUT_PARAMETER(callback);
2408
2409         _bt_unset_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST);
2410
2411         FUNC_EXIT;
2412         return BT_ERROR_NONE;
2413 }
2414
2415 int bt_mesh_authentication_reply(bt_mesh_authentication_type_e auth_type, const char *value,  bool auth_reply)
2416 {
2417         int error_code = BT_ERROR_NONE;
2418
2419         FUNC_ENTRY;
2420         BT_CHECK_MESH_SUPPORT();
2421         BT_CHECK_MESH_INIT_STATUS();
2422         BT_CHECK_INPUT_PARAMETER(value);
2423
2424         error_code = _bt_get_error_code(bluetooth_mesh_authentication_reply(auth_type, value, auth_reply));
2425         if (error_code != BT_ERROR_NONE)
2426                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2427
2428         FUNC_EXIT;
2429         return error_code;
2430 }
2431
2432 int bt_mesh_network_discover_node(bt_mesh_network_h network,
2433                 const char *dev_uuid, bt_mesh_node_discover_status_cb callback, void *user_data)
2434 {
2435         int error_code = BT_ERROR_NONE;
2436         bt_mesh_network_s *network_s;
2437         bluetooth_mesh_node_discover_t req;
2438
2439         FUNC_ENTRY;
2440         BT_CHECK_MESH_SUPPORT();
2441         BT_CHECK_MESH_INIT_STATUS();
2442         BT_CHECK_INPUT_PARAMETER(network);
2443         BT_CHECK_INPUT_PARAMETER(dev_uuid);
2444         BT_CHECK_INPUT_PARAMETER(callback);
2445
2446         BT_MESH_VALIDATE_HANDLE(network, networks);
2447
2448         BT_INFO("Mesh: Discover Node with UUID[%s]", dev_uuid);
2449
2450         /* Check if node with dev_uuid is already created */
2451         network_s = (bt_mesh_network_s*)network;
2452         memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2453
2454         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2455         g_strlcpy(req.dev_uuid, dev_uuid, 33);
2456
2457         error_code = _bt_get_error_code(bluetooth_mesh_browse_remote_node(&req));
2458         if (error_code != BT_ERROR_NONE) {
2459                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2460                 return error_code;
2461         }
2462
2463         FUNC_EXIT;
2464         _bt_set_cb(BT_EVENT_MESH_NODE_BROWSING_COMPLETED, callback, user_data);
2465         return BT_ERROR_NONE;
2466 }
2467
2468 int bt_mesh_node_configure_netkey(bt_mesh_node_h node,
2469                 bt_mesh_node_key_configuration_e netkey_op,
2470                         bt_mesh_netkey_h netkey,
2471                                 bt_mesh_netkey_status_cb callback,
2472                                         void *user_data)
2473 {
2474         int error_code = BT_ERROR_NONE;
2475         bt_mesh_network_s *network_s;
2476         bt_mesh_node_s *node_s;
2477         bt_mesh_netkey_s *netkey_s;
2478         bluetooth_mesh_key_configure_t req;
2479
2480         FUNC_ENTRY;
2481         BT_CHECK_MESH_SUPPORT();
2482         BT_CHECK_MESH_INIT_STATUS();
2483         BT_CHECK_INPUT_PARAMETER(node);
2484         BT_CHECK_INPUT_PARAMETER(netkey);
2485         BT_CHECK_INPUT_PARAMETER(callback);
2486
2487         node_s = (bt_mesh_node_s*) node;
2488         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2489
2490         network_s = node_s->parent;
2491         BT_CHECK_INPUT_PARAMETER(network_s);
2492         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2493
2494         netkey_s = (bt_mesh_netkey_s*) netkey;
2495         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2496
2497         /* Return error, if node is not attached */
2498         if (!node_s->is_attached)
2499                 return BT_ERROR_INVALID_PARAMETER;
2500
2501         /* Return error, if netkey is not present in the specific network */
2502         if (netkey_s->parent != network_s)
2503                 return BT_ERROR_INVALID_PARAMETER;
2504
2505         memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
2506
2507         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2508         req.primary_unicast = node_s->unicast;
2509         req.netkey_idx = netkey_s->netkey_index;
2510         req.is_netkey = true;
2511         req.op = (bluetooth_mesh_node_key_conf_e) netkey_op;
2512
2513         BT_INFO("Mesh: Add NetKey Idx [%d] to node", req.netkey_idx);
2514         error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
2515         if (error_code != BT_ERROR_NONE) {
2516                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2517                 return error_code;
2518         }
2519
2520         FUNC_EXIT;
2521         _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
2522         return BT_ERROR_NONE;
2523 }
2524
2525 int bt_mesh_node_configure_appkey(bt_mesh_node_h node,
2526                 bt_mesh_node_key_configuration_e appkey_op,
2527                         bt_mesh_appkey_h appkey,
2528                                 bt_mesh_appkey_status_cb callback,
2529                                         void *user_data)
2530 {
2531         int error_code = BT_ERROR_NONE;
2532         bt_mesh_network_s *network_s;
2533         bt_mesh_node_s *node_s;
2534         bt_mesh_netkey_s *netkey_s;
2535         bt_mesh_appkey_s *appkey_s;
2536         bluetooth_mesh_key_configure_t req;
2537
2538         FUNC_ENTRY;
2539         BT_CHECK_MESH_SUPPORT();
2540         BT_CHECK_MESH_INIT_STATUS();
2541         BT_CHECK_INPUT_PARAMETER(node);
2542         BT_CHECK_INPUT_PARAMETER(appkey);
2543         BT_CHECK_INPUT_PARAMETER(callback);
2544
2545         node_s = (bt_mesh_node_s*) node;
2546         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2547
2548         network_s = node_s->parent;
2549         BT_CHECK_INPUT_PARAMETER(network_s);
2550         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2551
2552         appkey_s = (bt_mesh_appkey_s*) appkey;
2553         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2554
2555         netkey_s = (bt_mesh_netkey_s*) appkey_s->parent;
2556         BT_CHECK_INPUT_PARAMETER(netkey_s);
2557         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2558
2559         /* Return error, if node is not attached */
2560         if (!node_s->is_attached)
2561                 return BT_ERROR_INVALID_PARAMETER;
2562
2563         /* Return error, if netkey is not present in the specific network */
2564         if (netkey_s->parent != network_s)
2565                 return BT_ERROR_INVALID_PARAMETER;
2566
2567         memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
2568
2569         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2570         req.primary_unicast = node_s->unicast;
2571         req.netkey_idx = netkey_s->netkey_index;
2572         req.appkey_idx = appkey_s->appkey_index;
2573         req.is_netkey = false;
2574         req.op = (bluetooth_mesh_node_key_conf_e) appkey_op;
2575
2576         error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
2577         if (error_code != BT_ERROR_NONE) {
2578                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2579                 return error_code;
2580         }
2581
2582         FUNC_EXIT;
2583         _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
2584         return BT_ERROR_NONE;
2585 }
2586
2587 /* Remote Node Operations: CONFIG: Non Key */
2588 int bt_mesh_node_get_features(bt_mesh_node_h node,
2589                 bt_mesh_node_features_cb callback, void *user_data)
2590 {
2591         int error_code = BT_ERROR_NONE;
2592         bt_mesh_network_s *network_s;
2593         bt_mesh_node_s *node_s;
2594         bluetooth_mesh_node_features_t req;
2595
2596         FUNC_ENTRY;
2597         BT_CHECK_MESH_SUPPORT();
2598         BT_CHECK_MESH_INIT_STATUS();
2599         BT_CHECK_INPUT_PARAMETER(node);
2600         BT_CHECK_INPUT_PARAMETER(callback);
2601
2602         node_s = (bt_mesh_node_s*) node;
2603         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2604
2605         /* Return error, if node is not attached */
2606         if (!node_s->is_attached)
2607                 return BT_ERROR_INVALID_PARAMETER;
2608
2609         network_s = (bt_mesh_network_s*) node_s->parent;
2610         BT_CHECK_INPUT_PARAMETER(network_s);
2611         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2612
2613         memset(&req, 0x00, sizeof(bluetooth_mesh_node_features_t));
2614
2615         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2616         req.unicast = node_s->unicast;
2617         req.elem_count = node_s->unicast;
2618
2619         error_code = _bt_get_error_code(bluetooth_mesh_node_browse_vendor_features(&req));
2620         if (error_code != BT_ERROR_NONE) {
2621                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2622                 return error_code;
2623         }
2624
2625         FUNC_EXIT;
2626         _bt_set_cb(BT_EVENT_MESH_NODE_VENDOR_FEATURES, callback, user_data);
2627         return BT_ERROR_NONE;
2628 }
2629
2630 int bt_mesh_node_get_ttl(bt_mesh_node_h node, bt_mesh_node_ttl_cb callback, void *user_data)
2631 {
2632         int error_code = BT_ERROR_NONE;
2633         bt_mesh_network_s *network_s;
2634         bt_mesh_node_s *node_s;
2635         bluetooth_mesh_node_ttl_info_t req;
2636
2637         FUNC_ENTRY;
2638         BT_CHECK_MESH_SUPPORT();
2639         BT_CHECK_MESH_INIT_STATUS();
2640         BT_CHECK_INPUT_PARAMETER(node);
2641         BT_CHECK_INPUT_PARAMETER(callback);
2642
2643         node_s = (bt_mesh_node_s*) node;
2644         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2645
2646         network_s = node_s->parent;
2647         BT_CHECK_INPUT_PARAMETER(network_s);
2648         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2649
2650         /* Return error, if node is not attached */
2651         if (!node_s->is_attached)
2652                 return BT_ERROR_INVALID_PARAMETER;
2653
2654         memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
2655
2656         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2657         req.unicast = node_s->unicast;
2658         req.is_set = false;
2659
2660         error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
2661         if (error_code != BT_ERROR_NONE) {
2662                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2663                 return error_code;
2664         }
2665
2666         FUNC_EXIT;
2667         _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
2668         return BT_ERROR_NONE;
2669 }
2670
2671 int bt_mesh_node_set_ttl(bt_mesh_node_h node, uint8_t ttl, bt_mesh_node_ttl_cb callback, void *user_data)
2672 {
2673         int error_code = BT_ERROR_NONE;
2674         bt_mesh_network_s *network_s;
2675         bt_mesh_node_s *node_s;
2676         bluetooth_mesh_node_ttl_info_t req;
2677
2678         FUNC_ENTRY;
2679         BT_CHECK_MESH_SUPPORT();
2680         BT_CHECK_MESH_INIT_STATUS();
2681         BT_CHECK_INPUT_PARAMETER(node);
2682         BT_CHECK_INPUT_PARAMETER(callback);
2683
2684         node_s = (bt_mesh_node_s*) node;
2685         network_s = node_s->parent;
2686         BT_CHECK_INPUT_PARAMETER(network_s);
2687         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2688         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2689
2690         /* Return error, if node is not attached */
2691         if (!node_s->is_attached)
2692                 return BT_ERROR_INVALID_PARAMETER;
2693
2694         memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
2695
2696         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2697         req.unicast = node_s->unicast;
2698         req.is_set = true;
2699         req.ttl = ttl;
2700
2701         error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
2702         if (error_code != BT_ERROR_NONE) {
2703                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2704                 return error_code;
2705         }
2706
2707         FUNC_EXIT;
2708         _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
2709         return BT_ERROR_NONE;
2710 }
2711
2712 int bt_mesh_node_foreach_netkeys(bt_mesh_node_h node, bt_mesh_node_netkey_info_cb callback, void *user_data)
2713 {
2714         GPtrArray *netkeys = NULL;
2715         GSList *l;
2716         int error_code = BT_ERROR_NONE;
2717         uint16_t *netkey_idx = NULL;
2718         int i;
2719         int total;
2720         bluetooth_mesh_node_discover_t req;
2721         bt_mesh_network_s *network_s;
2722         bt_mesh_node_s *node_s;
2723
2724         FUNC_ENTRY;
2725         BT_CHECK_MESH_SUPPORT();
2726         BT_CHECK_MESH_INIT_STATUS();
2727         BT_CHECK_INPUT_PARAMETER(node);
2728         BT_CHECK_INPUT_PARAMETER(callback);
2729
2730         node_s = (bt_mesh_node_s*) node;
2731         network_s = node_s->parent;
2732
2733         BT_CHECK_INPUT_PARAMETER(network_s);
2734         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2735         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2736
2737         /* Return error, if node is not attached */
2738         if (!node_s->is_attached)
2739                 return BT_ERROR_INVALID_PARAMETER;
2740
2741         netkeys = g_ptr_array_new();
2742         if (netkeys == NULL) {
2743                 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2744                 return BT_ERROR_OUT_OF_MEMORY;
2745         }
2746
2747         memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2748
2749         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2750         req.unicast = node_s->unicast;
2751
2752         error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_netkeys(&req, &netkeys));
2753         if (error_code != BT_ERROR_NONE) {
2754                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2755                 g_ptr_array_free(netkeys, TRUE);
2756                 return error_code;
2757         }
2758
2759         BT_INFO("Mesh: Total netkeys added in node is [%d]", netkeys->len);
2760         for (i = 0; i < netkeys->len; i++) {
2761                 bt_mesh_netkey_s *netkey_local;
2762                 netkey_idx = g_ptr_array_index(netkeys, i);
2763                 if (netkey_idx) {
2764                         /* Check if netkey index is present in network or not */
2765                         BT_INFO("Mesh: NetKey IDX [%d]", *netkey_idx);
2766                         netkey_local = __bt_mesh_network_is_netkey_added(network_s, *netkey_idx);
2767                         if (!netkey_local) {
2768                                 BT_ERR("Mesh: Network does not contain the netKey index, possibly reloaded");
2769                                 /* Create Netkey object */
2770                                 netkey_local = g_malloc0(sizeof(bt_mesh_netkey_s));
2771                                 netkey_local->parent = network_s;
2772                                 netkey_local->netkey_index = *netkey_idx;
2773                                 network_s->netkeys = g_slist_append(network_s->netkeys, netkey_local);
2774                                 netkey_list = g_slist_append(netkey_list, netkey_local);
2775
2776                                 if (!g_slist_find_custom(node_s->netkeys, GUINT_TO_POINTER(*netkey_idx),
2777                                                         (GCompareFunc)__compare_netkey_index))
2778                                         node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
2779                         } else {
2780                                 /* Check if netkey index is present in target node or not */
2781                                 if (!g_slist_find_custom(node_s->netkeys, (gconstpointer) netkey_local,
2782                                                         (GCompareFunc)__simple_compare)) {
2783                                         node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
2784                                 } else {
2785                                         /* DO NOTHING*/
2786                                         BT_INFO("Mesh: Netkey is already added in node");
2787                                 }
2788                         }
2789                 } else {
2790                         BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2791                                         BT_ERROR_OPERATION_FAILED);
2792                         error_code = BT_ERROR_OPERATION_FAILED;
2793                         break;
2794                 }
2795         }
2796
2797         total = g_slist_length(node_s->netkeys);
2798         if (total == 0) {
2799                 BT_ERR("Mesh: Unexpcted: No netkey added in node!!");
2800                 callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
2801                                 NULL, 0xFFFF, user_data);
2802         }
2803         for (l = node_s->netkeys; l != NULL; l = g_slist_next(l)) {
2804                 bt_mesh_netkey_s *netkey;
2805                 netkey = l->data;
2806
2807                 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
2808                                         (bt_mesh_netkey_h) netkey,
2809                                         netkey->netkey_index, user_data)) {
2810                         break;
2811                 }
2812         }
2813
2814         if (netkeys) {
2815                 g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
2816                 g_ptr_array_free(netkeys, TRUE);
2817         }
2818
2819         FUNC_EXIT;
2820         return error_code;
2821 }
2822
2823 int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node, bt_mesh_netkey_h netkey,
2824                 bt_mesh_node_appkey_info_cb callback, void *user_data)
2825 {
2826         GPtrArray *appkeys = NULL;
2827         int error_code = BT_ERROR_NONE;
2828         int i;
2829         bluetooth_mesh_node_discover_t req;
2830         uint16_t *appkey_idx = NULL;
2831         bt_mesh_network_s *network_s;
2832         bt_mesh_node_s *node_s;
2833         bt_mesh_netkey_s *netkey_s;
2834
2835         FUNC_ENTRY;
2836         BT_CHECK_MESH_SUPPORT();
2837         BT_CHECK_MESH_INIT_STATUS();
2838         BT_CHECK_INPUT_PARAMETER(node);
2839         BT_CHECK_INPUT_PARAMETER(netkey);
2840         BT_CHECK_INPUT_PARAMETER(callback);
2841
2842         node_s = (bt_mesh_node_s*) node;
2843         network_s = node_s->parent;
2844         netkey_s = (bt_mesh_netkey_s*) netkey;
2845
2846         BT_CHECK_INPUT_PARAMETER(network_s);
2847         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2848         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2849         BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2850
2851         /* Return error, if node is not attached */
2852         if (!node_s->is_attached)
2853                 return BT_ERROR_INVALID_PARAMETER;
2854
2855         appkeys = g_ptr_array_new();
2856         if (appkeys == NULL) {
2857                 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2858                 return BT_ERROR_OUT_OF_MEMORY;
2859         }
2860
2861         memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2862
2863         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2864         req.unicast = node_s->unicast;
2865         req.netkey_idx = netkey_s->netkey_index;
2866
2867         error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_appkeys(&req, &appkeys));
2868         if (error_code != BT_ERROR_NONE) {
2869                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2870                 g_ptr_array_free(appkeys, TRUE);
2871                 return error_code;
2872         }
2873
2874         BT_INFO("Mesh: Total appkeys found in Node [%d]", appkeys->len);
2875         for (i = 0; i < appkeys->len; i++) {
2876                 bt_mesh_appkey_s *appkey_local;
2877                 appkey_idx = g_ptr_array_index(appkeys, i);
2878                 if (appkey_idx) {
2879                         /* Check if appkey index is present in network or not */
2880                         BT_INFO("Mesh: AppKey index [%d]", *appkey_idx);
2881                         appkey_local = __bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx);
2882
2883                         if (!appkey_local) {
2884                                 BT_ERR("Mesh: Network does not AppKey index, possibly Network reloaded!!");
2885                                 /* Create Appkey object */
2886                                 appkey_local = g_malloc0(sizeof(bt_mesh_appkey_s));
2887                                 appkey_local->parent = netkey_s;
2888                                 appkey_local->appkey_index = *appkey_idx;
2889                                 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_local);
2890                                 appkey_list = g_slist_append(appkey_list, appkey_local);
2891
2892                                 if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
2893                                                         (GCompareFunc)__compare_appkey_index))
2894                                         node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
2895                         } else {
2896                                 /* Check if netkey index is present in target node or not */
2897                                 if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
2898                                                         (GCompareFunc)__compare_appkey_index)) {
2899                                         node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
2900                                 } else {
2901                                         /* DO NOTHING*/
2902                                         BT_INFO("Mesh: AppKey is already added in node");
2903                                 }
2904                         }
2905                         /* Send CallBack */
2906                         if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, appkeys->len,
2907                                                 (bt_mesh_netkey_h) netkey, (bt_mesh_appkey_h) appkey_local,
2908                                                 appkey_local->appkey_index, user_data)) {
2909                                 break;
2910                         }
2911                 } else {
2912                         BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2913                                         BT_ERROR_OPERATION_FAILED);
2914                         error_code = BT_ERROR_OPERATION_FAILED;
2915                         break;
2916                 }
2917         }
2918
2919         if (appkeys->len == 0) {
2920                 BT_ERR("Mesh: No appkey configured for the bound netkey Idx [%d]",
2921                         req.netkey_idx);
2922                 callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, 0,
2923                                 (bt_mesh_netkey_h) netkey_s, NULL, 0xFFFF, user_data);
2924         }
2925         if (appkeys) {
2926                 g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
2927                 g_ptr_array_free(appkeys, TRUE);
2928         }
2929         FUNC_EXIT;
2930         return error_code;
2931 }
2932
2933 int bt_mesh_model_bind_appkey(bt_mesh_model_h model,
2934         bt_mesh_appkey_h appkey, bt_mesh_model_bind_cb callback,
2935                 void *user_data)
2936 {
2937         int error_code = BT_ERROR_NONE;
2938         bt_mesh_model_s *model_s;
2939         bt_mesh_element_s *element_s;
2940         bt_mesh_node_s *node_s;
2941         bt_mesh_network_s *network_s;
2942         bt_mesh_appkey_s *appkey_s;
2943         bluetooth_mesh_model_configure_t req;
2944
2945         FUNC_ENTRY;
2946         BT_CHECK_MESH_SUPPORT();
2947         BT_CHECK_MESH_INIT_STATUS();
2948         BT_CHECK_INPUT_PARAMETER(model);
2949         BT_CHECK_INPUT_PARAMETER(appkey);
2950         BT_CHECK_INPUT_PARAMETER(callback);
2951
2952         model_s = (bt_mesh_model_s*) model;
2953         element_s = (bt_mesh_element_s*) model_s->parent;
2954         node_s = (bt_mesh_node_s*) element_s->parent;
2955         appkey_s = (bt_mesh_appkey_s*) appkey;
2956         network_s = (bt_mesh_network_s*) node_s->parent;
2957
2958         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2959         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2960         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2961         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2962         BT_MESH_VALIDATE_HANDLE(network_s, networks);
2963
2964         /* Return error, if node is not attached */
2965         if (!node_s->is_attached)
2966                 return BT_ERROR_INVALID_PARAMETER;
2967
2968         memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
2969
2970         g_strlcpy(req.net_uuid, network_s->uuid, 33);
2971         req.primary_unicast = node_s->unicast;
2972         req.elem_index = element_s->index;
2973         req.model = model_s->id;
2974         req.appkey_idx = appkey_s->appkey_index;
2975         req.is_bind = true;
2976
2977         error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
2978         if (error_code != BT_ERROR_NONE) {
2979                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2980                 return error_code;
2981         }
2982
2983         FUNC_EXIT;
2984         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
2985         return BT_ERROR_NONE;
2986 }
2987
2988 int bt_mesh_model_unbind_appkey(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
2989                 bt_mesh_model_unbind_cb callback, void *user_data)
2990 {
2991         int error_code = BT_ERROR_NONE;
2992         bt_mesh_model_s *model_s;
2993         bt_mesh_element_s *element_s;
2994         bt_mesh_node_s *node_s;
2995         bt_mesh_appkey_s *appkey_s;
2996         bt_mesh_network_s *network_s;
2997         bluetooth_mesh_model_configure_t req;
2998
2999         FUNC_ENTRY;
3000         BT_CHECK_MESH_SUPPORT();
3001         BT_CHECK_MESH_INIT_STATUS();
3002         BT_CHECK_INPUT_PARAMETER(model);
3003         BT_CHECK_INPUT_PARAMETER(appkey);
3004         BT_CHECK_INPUT_PARAMETER(callback);
3005
3006         model_s = (bt_mesh_model_s*) model;
3007         element_s = (bt_mesh_element_s*) model_s->parent;
3008         node_s = (bt_mesh_node_s*) element_s->parent;
3009         appkey_s = (bt_mesh_appkey_s*) appkey;
3010         network_s = (bt_mesh_network_s*) node_s->parent;
3011
3012         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3013         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3014         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3015         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3016         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3017
3018         /* Return error, if node is not attached */
3019         if (!node_s->is_attached)
3020                 return BT_ERROR_INVALID_PARAMETER;
3021
3022         memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3023
3024         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3025         req.primary_unicast = node_s->unicast;
3026         req.elem_index = element_s->index;
3027         req.model = model_s->id;
3028         req.appkey_idx = appkey_s->appkey_index;
3029         req.is_bind = false;
3030
3031         error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
3032         if (error_code != BT_ERROR_NONE) {
3033                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3034                 return error_code;
3035         }
3036
3037         FUNC_EXIT;
3038         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
3039         return BT_ERROR_NONE;
3040 }
3041
3042 int bt_mesh_model_get_appkey_list(bt_mesh_model_h model,
3043                 bt_mesh_model_appkey_list_cb callback, void *user_data)
3044 {
3045         int error_code = BT_ERROR_NONE;
3046         bt_mesh_model_s *model_s;
3047         bt_mesh_element_s *element_s;
3048         bt_mesh_node_s *node_s;
3049         bt_mesh_network_s *network_s;
3050         bluetooth_mesh_model_configure_t req;
3051
3052         FUNC_ENTRY;
3053         BT_CHECK_MESH_SUPPORT();
3054         BT_CHECK_MESH_INIT_STATUS();
3055         BT_CHECK_INPUT_PARAMETER(model);
3056         BT_CHECK_INPUT_PARAMETER(callback);
3057
3058         model_s = (bt_mesh_model_s*) model;
3059         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3060
3061         element_s = (bt_mesh_element_s*) model_s->parent;
3062         BT_CHECK_INPUT_PARAMETER(element_s);
3063         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3064
3065         node_s = (bt_mesh_node_s*) element_s->parent;
3066         BT_CHECK_INPUT_PARAMETER(node_s);
3067         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3068
3069         network_s = (bt_mesh_network_s*) node_s->parent;
3070         BT_CHECK_INPUT_PARAMETER(network_s);
3071         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3072
3073         /* Return error, if node is not attached */
3074         if (!node_s->is_attached)
3075                 return BT_ERROR_INVALID_PARAMETER;
3076
3077         memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3078
3079         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3080         req.primary_unicast = node_s->unicast;
3081         req.elem_index = element_s->index;
3082         req.model = model_s->id;
3083
3084         error_code = _bt_get_error_code(bluetooth_mesh_model_get_all_appkeys(&req));
3085         if (error_code != BT_ERROR_NONE) {
3086                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3087                 return error_code;
3088         }
3089
3090         FUNC_EXIT;
3091         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_APPKEY_LIST, callback, user_data);
3092         return error_code;
3093 }
3094
3095 int bt_mesh_model_send_msg(bt_mesh_model_h model,
3096         bt_mesh_appkey_h appkey, bt_mesh_model_msg_params_s *msg_params,
3097         bt_mesh_model_msg_cb callback, void *user_data)
3098 {
3099         int error_code = BT_ERROR_NONE;
3100         bt_mesh_model_s *model_s;
3101         bt_mesh_element_s *element_s;
3102         bt_mesh_node_s *node_s;
3103         bt_mesh_network_s *network_s;
3104         bt_mesh_appkey_s *appkey_s;
3105         bluetooth_mesh_model_msg_t req;
3106
3107         FUNC_ENTRY;
3108         BT_CHECK_MESH_SUPPORT();
3109         BT_CHECK_MESH_INIT_STATUS();
3110         BT_CHECK_INPUT_PARAMETER(model);
3111         BT_CHECK_INPUT_PARAMETER(appkey);
3112         BT_CHECK_INPUT_PARAMETER(msg_params);
3113         BT_CHECK_INPUT_PARAMETER(callback);
3114
3115         model_s = (bt_mesh_model_s*) model;
3116         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3117
3118         element_s = (bt_mesh_element_s*) model_s->parent;
3119         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3120
3121         node_s = (bt_mesh_node_s*) element_s->parent;
3122         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3123
3124         appkey_s = (bt_mesh_appkey_s*) appkey;
3125         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3126
3127         network_s = (bt_mesh_network_s*) node_s->parent;
3128         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3129
3130         /* Return error, if node is not attached */
3131         if (!node_s->is_attached)
3132                 return BT_ERROR_INVALID_PARAMETER;
3133
3134         BT_INFO("Mesh: Model msg opcode: 0x%2.2X", msg_params->opcode);
3135
3136         memset(&req, 0x00, sizeof(bluetooth_mesh_model_msg_t));
3137
3138         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3139         req.primary_unicast = node_s->unicast;
3140         req.elem_index = element_s->index;
3141         req.model = model_s->id;
3142         req.appkey_idx = appkey_s->appkey_index;
3143         req.opcode = msg_params->opcode;
3144         if (msg_params->data) {
3145                 BT_INFO("Mesh: model msg strlen %zd message: %s",
3146                 strlen(msg_params->data), msg_params->data);
3147
3148                 req.msg_len = strlen(msg_params->data);
3149                 g_strlcpy(req.msg, msg_params->data, req.msg_len + 1);
3150         } else {
3151                 req.msg_len = 0;
3152         }
3153
3154         error_code = _bt_get_error_code(bluetooth_mesh_model_send_msg(&req));
3155         if (error_code != BT_ERROR_NONE) {
3156                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3157                 return error_code;
3158         }
3159
3160         FUNC_EXIT;
3161         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_EXECUTE_MSG_COMPLETED, callback, user_data);
3162         return BT_ERROR_NONE;
3163 }
3164
3165 int bt_mesh_group_send_msg(bt_mesh_group_h group,
3166         bt_mesh_appkey_h appkey, bt_mesh_model_msg_params_s *msg_params,
3167         bt_mesh_model_msg_cb callback, void *user_data)
3168 {
3169         int error_code = BT_ERROR_NONE;
3170         bt_mesh_group_s *group_s;
3171         bt_mesh_network_s *network_s;
3172         bt_mesh_appkey_s *appkey_s;
3173         bluetooth_mesh_model_msg_t req;
3174
3175         FUNC_ENTRY;
3176         BT_CHECK_MESH_SUPPORT();
3177         BT_CHECK_MESH_INIT_STATUS();
3178         BT_CHECK_INPUT_PARAMETER(group);
3179         BT_CHECK_INPUT_PARAMETER(appkey);
3180         BT_CHECK_INPUT_PARAMETER(msg_params);
3181         BT_CHECK_INPUT_PARAMETER(callback);
3182
3183         group_s = (bt_mesh_group_s*) group;
3184         BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3185
3186         appkey_s = (bt_mesh_appkey_s*) appkey;
3187         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3188
3189         network_s = (bt_mesh_network_s*) group_s->parent;
3190         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3191
3192         BT_INFO("Mesh: Model msg opcode: 0x%2.2X", msg_params->opcode);
3193
3194         memset(&req, 0x00, sizeof(bluetooth_mesh_model_msg_t));
3195         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3196         req.primary_unicast = group_s->addr;
3197         req.appkey_idx = appkey_s->appkey_index;
3198         req.opcode = msg_params->opcode;
3199
3200         if (msg_params->data) {
3201                 BT_INFO("Mesh: Group msg strlen %zd message: %s",
3202                 strlen(msg_params->data), msg_params->data);
3203
3204                 req.msg_len = strlen(msg_params->data);
3205                 g_strlcpy(req.msg, msg_params->data, req.msg_len + 1);
3206         } else {
3207                 req.msg_len = 0;
3208         }
3209
3210         error_code = _bt_get_error_code(bluetooth_mesh_model_send_msg(&req));
3211         if (error_code != BT_ERROR_NONE) {
3212                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3213                 return error_code;
3214         }
3215
3216         FUNC_EXIT;
3217         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_EXECUTE_MSG_COMPLETED, callback, user_data);
3218         return BT_ERROR_NONE;
3219 }
3220
3221 int bt_mesh_network_foreach_groups(bt_mesh_network_h network,
3222                 bt_mesh_network_group_info_cb callback, void *user_data)
3223 {
3224         int error_code = BT_ERROR_NONE;
3225         bluetooth_mesh_network_t net;
3226         bt_mesh_network_s *network_s;
3227         GPtrArray *groups = NULL;
3228         GSList *l = NULL;
3229         bluetooth_mesh_network_group_info_t *group_info = NULL;
3230         int i;
3231         int total;
3232
3233         FUNC_ENTRY;
3234         BT_CHECK_MESH_SUPPORT();
3235         BT_CHECK_MESH_INIT_STATUS();
3236         BT_CHECK_INPUT_PARAMETER(network);
3237         BT_CHECK_INPUT_PARAMETER(callback);
3238
3239         BT_MESH_VALIDATE_HANDLE(network, networks);
3240
3241         groups = g_ptr_array_new();
3242         if (groups == NULL) {
3243                 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
3244                 return BT_ERROR_OUT_OF_MEMORY;
3245         }
3246
3247         network_s = (bt_mesh_network_s*)network;
3248         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3249
3250         g_strlcpy(net.uuid, network_s->uuid, 33);
3251         g_strlcpy(net.token.token, network_s->token, 17);
3252         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3253
3254         error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_groups(&net, &groups));
3255         if (error_code != BT_ERROR_NONE) {
3256                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3257                 g_ptr_array_free(groups, TRUE);
3258                 return error_code;
3259         }
3260
3261         BT_INFO("Mesh: Total number of Groups in network [%d]", groups->len);
3262         for (i = 0; i < groups->len; i++) {
3263                 group_info = g_ptr_array_index(groups, i);
3264                 if (group_info) {
3265                         BT_INFO("Mesh: Group Is Virtual [%s] Group Addr [0x%2.2x]",
3266                                         group_info->is_virtual ? "YES" : "NO", group_info->group_addr);
3267
3268                         if (group_info->is_virtual)
3269                                 BT_INFO("Mesh: Virtual label UUID [%s]", group_info->label_uuid);
3270
3271                         BT_INFO("Mesh: Total groups already present in Network [%d]",
3272                                         g_slist_length(network_s->groups));
3273                         /* Find or create group in network list */
3274                         if (!g_slist_find_custom(network_s->groups,
3275                                                 GUINT_TO_POINTER(group_info->group_addr),
3276                                                 (GCompareFunc)__compare_network_group_address)) {
3277                                 BT_INFO("Mesh: Its a new Group, add in network");
3278                                 bt_mesh_group_s *group_s;
3279                                 group_s = g_malloc0(sizeof(bt_mesh_group_s));
3280                                 group_s->addr = group_info->group_addr;
3281                                 group_s->parent = network_s;
3282                                 group_s->is_virtual = group_info->is_virtual;
3283                                 if (group_s->is_virtual)
3284                                         g_strlcpy(group_s->label_uuid, group_info->label_uuid,
3285                                                         sizeof(group_s->label_uuid));
3286                                 BT_INFO("Mesh: Group [0x%2.2x] added in network", group_s->addr);
3287
3288                                 network_s->groups = g_slist_append(network_s->groups, group_s);
3289                                 group_list = g_slist_append(group_list, group_s);
3290                         } else
3291                                 BT_INFO("Mesh: Group [0x%2.2x] Already Added in network",
3292                                                 group_info->group_addr);
3293                 } else {
3294                         BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
3295                                         BT_ERROR_OPERATION_FAILED);
3296                         error_code = BT_ERROR_OPERATION_FAILED;
3297                         break;
3298                 }
3299         }
3300
3301         total = g_slist_length(network_s->groups);
3302         BT_INFO("Mesh: Total number of groups [%d]", total);
3303         if (total == 0) {
3304                 BT_INFO("Mesh: No Groups added in network");
3305                 callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
3306                                 NULL, user_data);
3307         }
3308         for (l = network_s->groups; l != NULL; l = g_slist_next(l)) {
3309                 bt_mesh_group_s *group_s;
3310                 group_s = l->data;
3311
3312                 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
3313                                         (bt_mesh_group_h) group_s,
3314                                         user_data))
3315                         break;
3316         }
3317
3318         g_ptr_array_foreach(groups, (GFunc)g_free, NULL);
3319         g_ptr_array_free(groups, TRUE);
3320
3321         FUNC_EXIT;
3322         return error_code;
3323 }
3324
3325 int bt_mesh_network_create_virtual_group(bt_mesh_network_h network,
3326          bt_mesh_group_h *group)
3327 {
3328         int error_code = BT_ERROR_NONE;
3329         bt_mesh_network_s *network_s;
3330         bt_mesh_group_s *group_s;
3331         bluetooth_mesh_network_group_info_t req;
3332         bluetooth_mesh_network_t net;
3333
3334         FUNC_ENTRY;
3335         BT_CHECK_MESH_SUPPORT();
3336         BT_CHECK_MESH_INIT_STATUS();
3337         BT_CHECK_INPUT_PARAMETER(network);
3338
3339         network_s = (bt_mesh_network_s*) network;
3340
3341         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3342
3343         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3344         memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3345
3346         g_strlcpy(net.uuid, network_s->uuid, 33);
3347         g_strlcpy(net.token.token, network_s->token, 17);
3348         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3349
3350         error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, true, 0x0000, &req));
3351         if (error_code != BT_ERROR_NONE) {
3352                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3353                 return error_code;
3354         }
3355
3356         group_s = g_malloc0(sizeof(bt_mesh_group_s));
3357         group_s->addr = req.group_addr;
3358         group_s->is_virtual = true;
3359         group_s->parent = network_s;
3360         g_strlcpy(group_s->label_uuid, req.label_uuid, BT_MESH_UUID_STRING_LEN + 1);
3361         BT_INFO("Mesh: Virtual Group created : Addr [0x%2.2x]", req.group_addr);
3362         BT_INFO("Mesh: Virtual Group label UUID [%s]", group_s->label_uuid);
3363
3364         network_s->groups = g_slist_append(network_s->groups, group_s);
3365         group_list = g_slist_append(group_list, group_s);
3366
3367         *group = (bt_mesh_group_h) group_s;
3368         FUNC_EXIT;
3369         return error_code;
3370 }
3371
3372 int bt_mesh_network_remove_group(bt_mesh_group_h group)
3373 {
3374         int error_code = BT_ERROR_NONE;
3375         bt_mesh_network_s *network_s;
3376         bt_mesh_group_s *group_s;
3377         bluetooth_mesh_network_group_info_t req;
3378         bluetooth_mesh_network_t net;
3379
3380         FUNC_ENTRY;
3381         BT_CHECK_MESH_SUPPORT();
3382         BT_CHECK_INPUT_PARAMETER(group);
3383
3384         group_s = (bt_mesh_group_s*) group;
3385         BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3386         network_s = group_s->parent;
3387
3388         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3389         memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3390
3391         BT_INFO("Mesh: Remove Group [0x%2.2x] from network", group_s->addr);
3392         BT_INFO("Mesh: Is Group Virtual [%s]", group_s->is_virtual ? "YES" : "NO");
3393         if (group_s->is_virtual)
3394                 BT_INFO("Mesh: Group Label UUID [%s]", group_s->label_uuid);
3395
3396         /* Fill Network Info */
3397         g_strlcpy(net.uuid, network_s->uuid, 33);
3398         g_strlcpy(net.token.token, network_s->token, 17);
3399         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3400
3401         /* Fill Group Info */
3402         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3403         req.is_virtual = group_s->is_virtual;
3404         req.group_addr = group_s->addr;
3405         if (req.is_virtual)
3406                  g_strlcpy(req.label_uuid, group_s->label_uuid, sizeof(req.label_uuid));
3407
3408         error_code = _bt_get_error_code(bluetooth_mesh_network_remove_group(&net, &req));
3409         if (error_code != BT_ERROR_NONE) {
3410                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3411                 FUNC_EXIT;
3412                 return error_code;
3413         }
3414
3415         network_s->groups = g_slist_remove(network_s->groups, group_s);
3416         group_list = g_slist_remove(group_list, group_s);
3417
3418         g_free(group_s);
3419         FUNC_EXIT;
3420         return BT_ERROR_NONE;
3421 }
3422
3423 int bt_mesh_network_create_group(bt_mesh_network_h network,
3424                 uint16_t grp_addr, bt_mesh_group_h *group)
3425 {
3426         int error_code = BT_ERROR_NONE;
3427         bt_mesh_network_s *network_s;
3428         bt_mesh_group_s *group_s;
3429         bluetooth_mesh_network_t net;
3430         bluetooth_mesh_network_group_info_t req;
3431         GSList *l;
3432
3433         FUNC_ENTRY;
3434         BT_CHECK_MESH_SUPPORT();
3435         BT_CHECK_MESH_INIT_STATUS();
3436         BT_CHECK_INPUT_PARAMETER(network);
3437         BT_CHECK_INPUT_PARAMETER(group);
3438
3439         network_s = (bt_mesh_network_s*) network;
3440
3441         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3442
3443         /* Check for valid Group Address */
3444         if (!BT_MESH_IS_GROUP(grp_addr)) {
3445                 BT_INFO("Mesh: group Address [0x%2.2x] is not valid Group Address",
3446                         grp_addr);
3447                 return BT_ERROR_INVALID_PARAMETER;
3448         }
3449
3450         l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(grp_addr),
3451                         (GCompareFunc)__compare_group_address);
3452
3453         if (l) {
3454                 BT_INFO("Mesh: Group [0x%2.2x]Already exist", grp_addr);
3455                 group_s = l->data;
3456                 *group = (bt_mesh_group_h) group_s;
3457                 FUNC_EXIT;
3458                 return error_code;
3459         }
3460         memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3461         memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3462
3463         /* Fill Network Info */
3464         g_strlcpy(net.uuid, network_s->uuid, 33);
3465         g_strlcpy(net.token.token, network_s->token, 17);
3466         g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3467
3468         error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, false, grp_addr, &req));
3469         if (error_code != BT_ERROR_NONE) {
3470                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3471                 return error_code;
3472         }
3473
3474         BT_INFO("Mesh: Group created [0x%2.2x]", grp_addr);
3475         group_s = g_malloc0(sizeof(bt_mesh_group_s));
3476         group_s->addr = grp_addr;
3477         group_s->is_virtual = false;
3478         group_s->parent = network_s;
3479
3480         network_s->groups = g_slist_append(network_s->groups, group_s);
3481         group_list = g_slist_append(group_list, group_s);
3482
3483         *group = (bt_mesh_group_h) group_s;
3484         FUNC_EXIT;
3485         return error_code;
3486 }
3487
3488 int bt_mesh_model_configure_group_subscription(bt_mesh_model_subscription_op_e model_op,
3489                 bt_mesh_model_h model, bt_mesh_group_h group,
3490                         bt_mesh_model_subscription_op_cb callback, void *user_data)
3491 {
3492         int error_code = BT_ERROR_NONE;
3493         bt_mesh_model_s *model_s;
3494         bt_mesh_element_s *element_s;
3495         bt_mesh_node_s *node_s;
3496         bt_mesh_network_s *network_s;
3497         bt_mesh_group_s *group_s;
3498         bluetooth_mesh_model_configure_t req;
3499
3500         FUNC_ENTRY;
3501         BT_CHECK_MESH_SUPPORT();
3502         BT_CHECK_MESH_INIT_STATUS();
3503         BT_CHECK_INPUT_PARAMETER(model);
3504         BT_CHECK_INPUT_PARAMETER(group);
3505         BT_CHECK_INPUT_PARAMETER(callback);
3506
3507         model_s = (bt_mesh_model_s*) model;
3508         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3509
3510         group_s = (bt_mesh_group_s*) group;
3511         BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3512
3513         element_s = (bt_mesh_element_s*) model_s->parent;
3514         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3515
3516         node_s = (bt_mesh_node_s*) element_s->parent;
3517         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3518
3519         network_s = (bt_mesh_network_s*) node_s->parent;
3520         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3521
3522         BT_INFO("Mesh: Configure Group Request [%d]", model_op);
3523         BT_INFO("Mesh: Group Addr [0x%2.2x] Is Virtual [%s]",
3524                         group_s->addr, group_s->is_virtual ? "YES" : "NO");
3525
3526         /* Check group belongs to the same network */
3527         if (network_s != group_s->parent)
3528                 return BT_ERROR_INVALID_PARAMETER;
3529
3530         /* Check group is non virtual */
3531         if (group_s->is_virtual)
3532                 return BT_ERROR_INVALID_PARAMETER;
3533
3534         /* Return error, if node is not attached */
3535         if (!node_s->is_attached)
3536                 return BT_ERROR_INVALID_PARAMETER;
3537
3538         if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
3539                 req.sub_addr = group_s->addr;
3540         req.is_virtual_sub = false;
3541         req.op = model_op;
3542         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3543         req.primary_unicast = node_s->unicast;
3544         req.elem_index = element_s->index;
3545         req.model = model_s->id;
3546
3547         error_code = _bt_get_error_code(bluetooth_mesh_model_configure_group_sub(&req));
3548         if (error_code != BT_ERROR_NONE) {
3549                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3550                 return error_code;
3551         }
3552
3553         FUNC_EXIT;
3554         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_SUB, callback, user_data);
3555         return error_code;
3556 }
3557
3558 int bt_mesh_model_configure_virtual_group_subscription(bt_mesh_model_subscription_op_e model_op,
3559                 bt_mesh_model_h model, bt_mesh_group_h group,
3560                         bt_mesh_model_subscription_op_cb callback,
3561                                 void *user_data)
3562 {
3563         int error_code = BT_ERROR_NONE;
3564         bt_mesh_model_s *model_s;
3565         bt_mesh_element_s *element_s;
3566         bt_mesh_node_s *node_s;
3567         bt_mesh_network_s *network_s;
3568         bt_mesh_group_s *group_s;
3569         bluetooth_mesh_model_configure_t req;
3570
3571         FUNC_ENTRY;
3572         BT_CHECK_MESH_SUPPORT();
3573         BT_CHECK_MESH_INIT_STATUS();
3574         BT_CHECK_INPUT_PARAMETER(model);
3575         BT_CHECK_INPUT_PARAMETER(group);
3576         BT_CHECK_INPUT_PARAMETER(callback);
3577
3578         model_s = (bt_mesh_model_s*) model;
3579         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3580
3581         group_s = (bt_mesh_group_s*) group;
3582         BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3583
3584         element_s = (bt_mesh_element_s*) model_s->parent;
3585         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3586
3587         node_s = (bt_mesh_node_s*) element_s->parent;
3588         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3589
3590         network_s = (bt_mesh_network_s*) node_s->parent;
3591         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3592
3593         BT_INFO("Mesh: Configure Virtual Group Request [%d]", model_op);
3594         BT_INFO("Mesh: Group Addr [0x%2.2x] Is Virtual [%s]",
3595                         group_s->addr, group_s->is_virtual ? "YES" : "NO");
3596
3597         /* Check group belongs to the same network */
3598         if (network_s != group_s->parent)
3599                 return BT_ERROR_INVALID_PARAMETER;
3600
3601         /* Check group is non virtual */
3602         if (!group_s->is_virtual)
3603                 return BT_ERROR_INVALID_PARAMETER;
3604
3605         /* Return error, if node is not attached */
3606         if (!node_s->is_attached)
3607                 return BT_ERROR_INVALID_PARAMETER;
3608
3609         if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
3610                 req.sub_addr = group_s->addr;
3611         req.is_virtual_sub = true;
3612         req.op = model_op;
3613         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3614         req.primary_unicast = node_s->unicast;
3615         req.elem_index = element_s->index;
3616         req.model = model_s->id;
3617
3618         error_code = _bt_get_error_code(bluetooth_mesh_model_configure_virtual_group_sub(&req));
3619         if (error_code != BT_ERROR_NONE) {
3620                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3621                 return error_code;
3622         }
3623
3624         FUNC_EXIT;
3625         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_VIR_SUB, callback, user_data);
3626         return error_code;
3627 }
3628
3629 int bt_mesh_model_get_subscription_list(bt_mesh_model_h model,
3630                  bt_mesh_model_subscription_list_cb callback, void *user_data)
3631 {
3632         int error_code = BT_ERROR_NONE;
3633         bt_mesh_model_s *model_s;
3634         bt_mesh_element_s *element_s;
3635         bt_mesh_node_s *node_s;
3636         bt_mesh_network_s *network_s;
3637         bluetooth_mesh_model_configure_t req;
3638
3639         FUNC_ENTRY;
3640         BT_CHECK_MESH_SUPPORT();
3641         BT_CHECK_MESH_INIT_STATUS();
3642         BT_CHECK_INPUT_PARAMETER(model);
3643         BT_CHECK_INPUT_PARAMETER(callback);
3644
3645         model_s = (bt_mesh_model_s*) model;
3646         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3647
3648         element_s = (bt_mesh_element_s*) model_s->parent;
3649         BT_CHECK_INPUT_PARAMETER(element_s);
3650         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3651
3652         node_s = (bt_mesh_node_s*) element_s->parent;
3653         BT_CHECK_INPUT_PARAMETER(node_s);
3654         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3655
3656         network_s = (bt_mesh_network_s*) node_s->parent;
3657         BT_CHECK_INPUT_PARAMETER(network_s);
3658         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3659
3660         /* Return error, if node is not attached */
3661         if (!node_s->is_attached)
3662                 return BT_ERROR_INVALID_PARAMETER;
3663
3664         memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3665
3666         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3667         req.primary_unicast = node_s->unicast;
3668         req.elem_index = element_s->index;
3669         req.model = model_s->id;
3670
3671         error_code = _bt_get_error_code(bluetooth_mesh_model_get_subscriptopn_list(&req));
3672         if (error_code != BT_ERROR_NONE) {
3673                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3674                 return error_code;
3675         }
3676
3677         FUNC_EXIT;
3678         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_SUB_LIST, callback, user_data);
3679         return error_code;
3680 }
3681
3682 int bt_mesh_model_set_publication(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
3683                 bt_mesh_group_h group,
3684                          bt_mesh_model_pub_params_s *params,
3685                                 bt_mesh_model_publication_status_cb callback,
3686                                         void *user_data)
3687 {
3688         int error_code = BT_ERROR_NONE;
3689         bt_mesh_model_s *model_s;
3690         bt_mesh_element_s *element_s;
3691         bt_mesh_node_s *node_s;
3692         bt_mesh_appkey_s *appkey_s;
3693         bt_mesh_network_s *network_s;
3694         bt_mesh_group_s *group_s;
3695         bluetooth_mesh_model_configure_t req;
3696
3697         FUNC_ENTRY;
3698         BT_CHECK_MESH_SUPPORT();
3699         BT_CHECK_MESH_INIT_STATUS();
3700         BT_CHECK_INPUT_PARAMETER(model);
3701         BT_CHECK_INPUT_PARAMETER(appkey);
3702         BT_CHECK_INPUT_PARAMETER(group);
3703         BT_CHECK_INPUT_PARAMETER(params);
3704         BT_CHECK_INPUT_PARAMETER(callback);
3705
3706         model_s = (bt_mesh_model_s*) model;
3707         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3708
3709         appkey_s = (bt_mesh_appkey_s*) appkey;
3710         BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3711
3712         group_s = (bt_mesh_group_s*) group;
3713         BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3714
3715         element_s = (bt_mesh_element_s*) model_s->parent;
3716         BT_CHECK_INPUT_PARAMETER(element_s);
3717         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3718
3719         node_s = (bt_mesh_node_s*) element_s->parent;
3720         BT_CHECK_INPUT_PARAMETER(node_s);
3721         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3722
3723         network_s = (bt_mesh_network_s*) node_s->parent;
3724         BT_CHECK_INPUT_PARAMETER(network_s);
3725         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3726
3727         if (group_s->parent != network_s)
3728                 return BT_ERROR_INVALID_PARAMETER;
3729
3730         if (params->num_steps > BT_MESH_MAX_PUBISH_PERIOD_STEPS)
3731                 return BT_ERROR_INVALID_PARAMETER;
3732         if (params->retrans_cnt > BT_MESH_MAX_PUBISH_RETRANSMIT_COUNT)
3733                 return BT_ERROR_INVALID_PARAMETER;
3734         if (params->retrans_step > BT_MESH_MAX_PUBISH_RETRANSMIT_INTERVAL_STEPS)
3735                 return BT_ERROR_INVALID_PARAMETER;
3736
3737         /* Return error, if node is not attached */
3738         if (!node_s->is_attached)
3739                 return BT_ERROR_INVALID_PARAMETER;
3740
3741         memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3742
3743         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3744         req.primary_unicast = node_s->unicast;
3745         req.elem_index = element_s->index;
3746         req.model = model_s->id;
3747         req.appkey_idx = appkey_s->appkey_index;
3748         req.pub_addr = group_s->addr;
3749
3750         req.ttl = params->ttl;
3751         req.period = params->num_steps;
3752         req.period = req.period << 2;
3753         req.period |= params->per_res;
3754         req.retransmit = params->retrans_cnt;
3755         req.retransmit = req.retransmit << 5;
3756         req.retransmit |= params->retrans_step;
3757
3758         error_code = _bt_get_error_code(bluetooth_mesh_model_set_publication(&req));
3759         if (error_code != BT_ERROR_NONE) {
3760                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3761                 return error_code;
3762         }
3763
3764         FUNC_EXIT;
3765         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);
3766         return error_code;
3767 }
3768
3769 int bt_mesh_model_get_publication(bt_mesh_model_h model,
3770                 bt_mesh_model_publication_status_cb callback, void *user_data)
3771 {
3772         int error_code = BT_ERROR_NONE;
3773         bt_mesh_model_s *model_s;
3774         bt_mesh_element_s *element_s;
3775         bt_mesh_node_s *node_s;
3776         bt_mesh_network_s *network_s;
3777         bluetooth_mesh_model_configure_t req;
3778
3779         FUNC_ENTRY;
3780         BT_CHECK_MESH_SUPPORT();
3781         BT_CHECK_MESH_INIT_STATUS();
3782         BT_CHECK_INPUT_PARAMETER(model);
3783         BT_CHECK_INPUT_PARAMETER(callback);
3784
3785         model_s = (bt_mesh_model_s*) model;
3786         BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3787
3788         element_s = (bt_mesh_element_s*) model_s->parent;
3789         BT_CHECK_INPUT_PARAMETER(element_s);
3790         BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3791
3792         node_s = (bt_mesh_node_s*) element_s->parent;
3793         BT_CHECK_INPUT_PARAMETER(node_s);
3794         BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3795
3796         network_s = (bt_mesh_network_s*) node_s->parent;
3797         BT_CHECK_INPUT_PARAMETER(network_s);
3798         BT_MESH_VALIDATE_HANDLE(network_s, networks);
3799
3800         /* Return error, if node is not attached */
3801         if (!node_s->is_attached)
3802                 return BT_ERROR_INVALID_PARAMETER;
3803
3804         memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3805
3806         g_strlcpy(req.net_uuid, network_s->uuid, 33);
3807         req.primary_unicast = node_s->unicast;
3808         req.elem_index = element_s->index;
3809         req.model = model_s->id;
3810
3811         error_code = _bt_get_error_code(bluetooth_mesh_model_get_publication(&req));
3812         if (error_code != BT_ERROR_NONE) {
3813                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3814                 return error_code;
3815         }
3816
3817         FUNC_EXIT;
3818         _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);
3819         return error_code;
3820 }