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