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