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