2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
4 * @author: Anupam Roy <anupam.r@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include <arpa/inet.h>
27 #include <bluetooth-api.h>
29 #include "bluetooth.h"
30 #include "bluetooth_internal.h"
31 #include "bluetooth_private.h"
32 #include "bluetooth-mesh-api.h"
34 #define BT_MESH_MAX_ELEMENTS 32767
35 #define BT_MESH_MAX_MODELS 32767
36 #define BT_MESH_MAX_NODES 32767
37 #define BT_MESH_MAX_SUBNETS 4096
39 #define BT_MESH_FIXED_GROUP_LOW 0xff00
40 #define BT_MESH_FIXED_GROUP_HIGH 0xffff
41 #define BT_MESH_ALL_NODES_ADDRESS 0xffff
42 #define BT_MESH_VIRTUAL_ADDRESS_LOW 0x8000
43 #define BT_MESH_VIRTUAL_ADDRESS_HIGH 0xbfff
44 #define BT_MESH_GROUP_ADDRESS_LOW 0xc000
45 #define BT_MESH_GROUP_ADDRESS_HIGH 0xfeff
47 #define BT_MESH_IS_GROUP(x) ((((x) >= BT_MESH_GROUP_ADDRESS_LOW) && \
48 ((x) < BT_MESH_FIXED_GROUP_HIGH)) || \
49 ((x) == BT_MESH_ALL_NODES_ADDRESS))
51 static bool is_mesh_initialized = false;
53 /**< List of Local handles >*/
63 #define BT_CHECK_MESH_SUPPORT() \
65 BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
66 BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \
67 BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_MESH); \
70 #define BT_CHECK_MESH_INIT_STATUS() \
71 if (__bt_check_mesh_init_status() == BT_ERROR_NOT_INITIALIZED) { \
72 LOGE("[%s] NOT_INITIALIZED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_INITIALIZED); \
73 return BT_ERROR_NOT_INITIALIZED; \
77 #define BT_CHECK_MESH_REMOTE(handle) \
78 { if (handle->is_local) return BT_ERROR_OPERATION_FAILED; }
81 #define BT_CHECK_MESH_LOCAL(handle) \
82 { if (!handle->is_local) return BT_ERROR_OPERATION_FAILED; }
85 #define BT_CHECK_MESH_IS_ATTACHED(handle) \
86 { if (handle->is_attached) return BT_ERROR_OPERATION_FAILED; }
88 #define BT_MESH_VALIDATE_HANDLE(h1, list) \
92 for (l = list; l; l = g_slist_next(l)) { \
93 void *h2 = (void *)l->data; \
95 BT_INFO("Handle matched [%p]", h2); \
96 valid = TRUE; break; \
99 if (valid == FALSE) { \
100 BT_ERR("Handle [%p] did not match with any stored handles!!", h1); \
101 return BT_ERROR_INVALID_PARAMETER; \
105 size_t __bt_mesh_util_convert_hex_to_string(uint8_t *in,
106 size_t in_len, char *out, size_t out_len)
108 static const char hexdigits[] = "0123456789abcdef";
111 if (in_len * 2 > (out_len - 1))
114 for (i = 0; i < in_len; i++) {
115 out[i * 2] = hexdigits[in[i] >> 4];
116 out[i * 2 + 1] = hexdigits[in[i] & 0xf];
119 out[in_len * 2] = '\0';
123 static int __compare_group_address(gconstpointer a, gconstpointer b)
125 const bt_mesh_group_s *group = a;
126 uint16_t addr = GPOINTER_TO_UINT(b);
128 return (group->addr - addr);
131 static int __compare_node_primary_unicast(gconstpointer a, gconstpointer b)
133 const bt_mesh_node_s *node = a;
134 uint16_t index = GPOINTER_TO_UINT(b);
136 return (node->unicast - index);
139 static int __compare_node_element_index(gconstpointer a, gconstpointer b)
141 const bt_mesh_element_s *element = a;
142 int index = GPOINTER_TO_UINT(b);
144 return (element->index - index);
147 static int __compare_network_group_address(gconstpointer a, gconstpointer b)
149 const bt_mesh_group_s *group = a;
150 uint16_t group_addr = GPOINTER_TO_UINT(b);
152 return (group->addr - group_addr);
155 static int __compare_model_id(gconstpointer a, gconstpointer b)
157 const bt_mesh_model_s *model_s = a;
158 uint32_t model = GPOINTER_TO_UINT(b);
160 return (model_s->id - model);
163 static int __compare_netkey_index(gconstpointer a, gconstpointer b)
165 const bt_mesh_netkey_s *nk = a;
166 uint16_t netkey_index = GPOINTER_TO_UINT(b);
168 return (nk->netkey_index - netkey_index);
171 static int __simple_compare(gconstpointer a, gconstpointer b)
179 static int __compare_appkey_index(gconstpointer a, gconstpointer b)
181 const bt_mesh_appkey_s *ak = a;
182 uint16_t appkey_index = GPOINTER_TO_UINT(b);
184 return (ak->appkey_index - appkey_index);
187 static int __compare_element_index(gconstpointer a, gconstpointer b)
189 const bt_mesh_element_s *elem = a;
190 uint16_t element_index = GPOINTER_TO_UINT(b);
192 return (elem->index - element_index);
195 static bt_mesh_netkey_s * __bt_mesh_network_is_netkey_added(
196 bt_mesh_network_s *network_s, uint16_t netkey_idx)
200 l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
201 (GCompareFunc)__compare_netkey_index);
205 return (bt_mesh_netkey_s*) l->data;
208 bt_mesh_element_s *_bt_mesh_get_element_from_index(
209 bt_mesh_node_s *node_s, int element_index)
213 l = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(element_index),
214 (GCompareFunc)__compare_element_index);
218 return (bt_mesh_element_s*) l->data;
221 bt_mesh_appkey_s *_bt_mesh_network_get_appkey_from_index(
222 bt_mesh_network_s *network_s, uint16_t appkey_idx)
226 for (l = network_s->netkeys; l; l = l->next) {
227 bt_mesh_netkey_s *netkey_s = l->data;
229 l1 = g_slist_find_custom(netkey_s->appkeys, GUINT_TO_POINTER(appkey_idx),
230 (GCompareFunc)__compare_appkey_index);
238 bt_mesh_model_s *_bt_mesh_get_model_from_modelid(
239 bt_mesh_element_s *element_s, uint32_t modelid)
243 l = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(modelid),
244 (GCompareFunc)__compare_model_id);
248 return (bt_mesh_model_s*) l->data;
251 bt_mesh_group_s* _bt_mesh_network_get_group(
252 bt_mesh_network_s *network_s, uint16_t group_addr)
255 bt_mesh_group_s *group_s = NULL;
257 /* Unassigned address */
258 if (group_addr == 0x0000)
261 l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(group_addr),
262 (GCompareFunc) __compare_network_group_address);
265 BT_INFO("Mesh: Group not available in Network: Addr[0x%2.2x]",
267 group_s = g_malloc0(sizeof(bt_mesh_group_s));
268 group_s->addr = group_addr;
269 if (!BT_MESH_IS_GROUP(group_addr))
270 group_s->is_virtual = true;
272 group_s->is_virtual = false;
273 group_s->parent = network_s;
275 if (g_slist_append(network_s->groups, group_s))
276 BT_INFO("Mesh: Group created");
278 group_list = g_slist_append(group_list, group_s);
285 bt_mesh_appkey_s* _bt_mesh_node_get_appkey(
286 bt_mesh_node_s *node_s, uint16_t appkey_idx)
290 l = g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(appkey_idx),
291 (GCompareFunc)__compare_appkey_index);
295 return (bt_mesh_appkey_s*) l->data;
298 static bt_mesh_appkey_s *__bt_mesh_network_is_appkey_added(
299 bt_mesh_network_s *network_s,
304 const bt_mesh_netkey_s *netkey;
306 l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
307 (GCompareFunc)__compare_netkey_index);
312 l1 = g_slist_find_custom(netkey->appkeys, GUINT_TO_POINTER(appkey_idx),
313 (GCompareFunc)__compare_appkey_index);
317 return (bt_mesh_appkey_s*) l1->data;
320 int __bt_check_mesh_init_status(void)
322 if (is_mesh_initialized != true) {
323 BT_ERR("NOT_INITIALIZED(0x%08x)", BT_ERROR_NOT_INITIALIZED);
324 return BT_ERROR_NOT_INITIALIZED;
327 return BT_ERROR_NONE;
331 static void __bt_mesh_free_models(void *data)
333 bt_mesh_model_s *model = (bt_mesh_model_s*)data;
334 model_list = g_slist_remove(model_list, model);
338 static void __bt_mesh_free_elements(void *data)
340 bt_mesh_element_s *elem = (bt_mesh_element_s*)data;
341 element_list = g_slist_remove(element_list, elem);
342 g_slist_free_full(elem->models, __bt_mesh_free_models);
346 static void __bt_mesh_free_appkeys(void *data)
348 bt_mesh_appkey_s *appkey = (bt_mesh_appkey_s*)data;
349 appkey_list = g_slist_remove(appkey_list, appkey);
353 static gint __bt_mesh_compare_net_uuid(gpointer *a, gpointer *b)
355 bt_mesh_network_s *net = (bt_mesh_network_s *)a;
356 char *net_uuid = (char *)b;
357 return g_strcmp0(net->uuid, net_uuid);
361 static void __bt_mesh_insert_elements_in_node(
362 bt_mesh_node_s *node, uint16_t unicast,
363 int num_elements, bool is_local)
365 bt_mesh_element_s *element_s;
367 for (int i = 0; i < num_elements; i++) {
368 element_s = g_malloc0(sizeof(bt_mesh_element_s));
369 element_s->is_local = is_local;
370 element_s->parent = node;
371 element_s->index = i;
372 node->elements = g_slist_append(node->elements, element_s);
373 element_list = g_slist_append(element_list, element_s);
377 bt_mesh_appkey_s *_bt_mesh_handle_node_appkey_configure(
378 bt_mesh_network_s *network_s,
379 bt_mesh_node_s *node_s, uint16_t netkey_idx,
381 bt_mesh_node_key_configuration_e op)
383 bt_mesh_appkey_s *appkey_s;
385 appkey_s = __bt_mesh_network_is_appkey_added(
386 network_s, netkey_idx, appkey_idx);
388 /* AppKey with index not found in network */
390 BT_ERR("Mesh: Exceptional case: AppKey not found in Network");
394 if (op == BT_MESH_NODE_KEY_ADD) {
395 if (!g_slist_find_custom(node_s->appkeys,(gconstpointer) appkey_s,
396 (GCompareFunc)__simple_compare)) {
397 node_s->appkeys = g_slist_append(node_s->appkeys, appkey_s);
399 BT_INFO("Mesh: AppKey Already added");
401 } else if (op == BT_MESH_NODE_KEY_DELETE) {
402 node_s->appkeys = g_slist_remove(node_s->appkeys, appkey_s);
404 } else /* Node NetKey update */
408 bt_mesh_netkey_s *_bt_mesh_handle_node_netkey_configure(
409 bt_mesh_network_s *network_s,
410 bt_mesh_node_s *node_s, uint16_t netkey_idx,
411 bt_mesh_node_key_configuration_e op)
413 bt_mesh_netkey_s *netkey_s;
415 netkey_s = __bt_mesh_network_is_netkey_added(network_s, netkey_idx);
417 /* Netkey with index not found in network */
419 BT_ERR("Mesh: Exceptional case: Netkey not found in Network");
423 if (op == BT_MESH_NODE_KEY_ADD) {
424 if (!g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_s,
425 (GCompareFunc)__simple_compare)) {
426 node_s->netkeys = g_slist_append(node_s->netkeys, netkey_s);
428 BT_INFO("Mesh: NetKey Already added");
430 } else if (op == BT_MESH_NODE_KEY_DELETE) {
431 node_s->netkeys = g_slist_remove(node_s->netkeys, netkey_s);
433 } else /* Node NetKey update */
437 bt_mesh_group_s * _bt_mesh_get_group_from_sub(
438 bt_mesh_network_s *network_s, bt_mesh_model_s *model_s,
439 bt_mesh_model_subscription_op_e op, uint16_t sub_addr)
442 bt_mesh_group_s *group_s = NULL;
443 l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(sub_addr),
444 (GCompareFunc) __compare_network_group_address);
448 if (op == BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
449 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL");
450 if (op == BT_MESH_MODEL_SUBSCRIPTION_ADD)
451 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_ADD");
452 if (op == BT_MESH_MODEL_SUBSCRIPTION_DELETE)
453 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE");
454 if (op == BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE)
455 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE");
460 bt_mesh_model_s *_bt_mesh_get_node_get_model_from_element(
461 char *net_uuid, uint16_t unicast,
462 int elem_idx, uint32_t model)
464 GSList *l, *l1, *l2, *l3;
465 bt_mesh_network_s *network_s;
466 bt_mesh_node_s *node_s;
467 bt_mesh_element_s *element_s;
469 l = g_slist_find_custom(networks, net_uuid,
470 (GCompareFunc)__bt_mesh_compare_net_uuid);
474 network_s = (bt_mesh_network_s*) l->data;
476 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
477 (GCompareFunc)__compare_node_primary_unicast);
481 node_s = (bt_mesh_node_s*) l1->data;
483 l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
484 (GCompareFunc)__compare_node_element_index);
488 element_s = (bt_mesh_element_s*) l2->data;
491 l3 = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(model),
492 (GCompareFunc) __compare_model_id);
496 return (bt_mesh_model_s*) l3->data;
499 bt_mesh_element_s * _bt_mesh_get_node_get_element_from_index(char *net_uuid,
500 uint16_t unicast, int elem_idx)
503 bt_mesh_network_s *network_s;
504 bt_mesh_node_s *node_s;
506 l = g_slist_find_custom(networks, net_uuid,
507 (GCompareFunc)__bt_mesh_compare_net_uuid);
513 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
514 (GCompareFunc)__compare_node_primary_unicast);
520 l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
521 (GCompareFunc)__compare_node_element_index);
525 return (bt_mesh_element_s*) l->data;
528 bt_mesh_node_s *_bt_mesh_get_node_from_unicast(char *net_uuid, uint16_t unicast)
531 bt_mesh_network_s *network_s;
532 bt_mesh_node_s *node_s;
534 l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
540 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
541 (GCompareFunc)__compare_node_primary_unicast);
549 bt_mesh_node_s *_bt_mesh_remote_node_browsed(char *net_uuid, char *dev_uuid,
550 uint16_t unicast, int count)
553 bt_mesh_network_s *network_s;
554 bt_mesh_node_s *node_s;
556 l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
562 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
563 (GCompareFunc)__compare_node_primary_unicast);
566 g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
568 node_s = g_malloc0(sizeof(bt_mesh_node_s));
569 node_s->parent = network_s;
570 node_s->unicast = unicast;
571 node_s->is_attached = true;
572 if (node_s->unicast == 0x0001) {
573 node_s->is_local = true;
574 node_s->is_provisioner = true;
576 g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
577 __bt_mesh_insert_elements_in_node(node_s, unicast,
578 count, node_s->is_local? true : false);
579 network_s->nodes = g_slist_append(network_s->nodes, node_s);
580 node_list = g_slist_append(node_list, node_s);
585 bt_mesh_network_s * _bt_mesh_get_network_handle_info(char *net_uuid)
589 l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
593 return (bt_mesh_network_s*)l->data;
596 char * _bt_mesh_get_auth_string_from_value(int auth)
599 case BT_MESH_AUTH_ALPHANUMERIC_DISPLAY:
600 BT_INFO("Mesh: ALPHANUMERIC_DISPLAY");
601 return "ALPHANUMERIC_DISPLAY";
602 case BT_MESH_AUTH_NUMERIC_DISPLAY:
603 BT_INFO("Mesh: NUMERIC_DISPLAY");
604 return "NUMERIC_DISPLAY";
605 case BT_MESH_AUTH_PUSH_COUNT_DISPLAY:
606 BT_INFO("Mesh: PUSH_COUNT_DISPLAY");
607 return "PUSH_COUNT_DISPLAY";
608 case BT_MESH_AUTH_TWIST_COUNT_DISPLAY:
609 BT_INFO("Mesh: TWIST_COUNT_DISPLAY");
610 return "TWIST_COUNT_DISPLAY";
612 /*< Input authentication request types */
613 case BT_MESH_AUTH_REQ_ALPHANUMERIC_INPUT:
614 BT_INFO("Mesh: REQ_ALPHANUMERIC_INPUT");
615 return "REQ_ALPHANUMERIC_INPUT";
616 case BT_MESH_AUTH_REQ_NUMERIC_INPUT:
617 BT_INFO("Mesh: REQ_NUMERIC_INPUT");
618 return "REQ_NUMERIC_INPUT";
619 case BT_MESH_AUTH_REQ_BLINK_COUNT_INPUT:
620 BT_INFO("Mesh: REQ_BLINK_COUNT_INPUT");
621 return "REQ_BLINK_COUNT_INPUT";
622 case BT_MESH_AUTH_REQ_BEEP_COUNT_INPUT:
623 BT_INFO("Mesh: REQ_BEEP_COUNT_INPUT");
624 return "REQ_BEEP_COUNT_INPUT";
625 case BT_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT:
626 BT_INFO("Mesh: REQ_VIBRATE_COUNT_INPUT");
627 return "REQ_VIBRATE_COUNT_INPUT";
629 /**< OOB Key Inputs */
630 case BT_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT:
631 BT_INFO("Mesh: OOB_PUBLIC_KEY_INPUT");
632 return "OOB_PUBLIC_KEY_INPUT";
633 case BT_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT:
634 BT_INFO("Mesh: OOB_STATIC_KEY_INPUT");
635 return "OOB_STATIC_KEY_INPUT";
642 int bt_mesh_initialize(void)
645 BT_CHECK_MESH_SUPPORT();
647 int ret = BT_ERROR_NONE;
649 BT_INFO("Is Mesh initialized:[%s]",
650 is_mesh_initialized ? "TRUE": "FALSE");
652 if (is_mesh_initialized) {
653 BT_ERR("Mesh is initialized");
654 return BT_ERROR_NONE;
657 if (!is_mesh_initialized) {
658 ret = _bt_get_error_code(bluetooth_mesh_init(
659 _bt_mesh_event_proxy, NULL));
661 if (ret != BT_ERROR_NONE) {
663 _bt_convert_error_to_string(ret), ret);
664 return BT_ERROR_OPERATION_FAILED;
667 is_mesh_initialized = true;
668 return BT_ERROR_NONE;
671 BT_INFO("Mesh is already initialized");
674 return BT_ERROR_NONE;
677 int bt_mesh_deinitialize(void)
680 BT_CHECK_MESH_SUPPORT();
681 BT_CHECK_MESH_INIT_STATUS();
684 error = bluetooth_mesh_deinit();
685 error = _bt_get_error_code(error);
686 if (BT_ERROR_NONE != error)
687 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error);
689 is_mesh_initialized = false;
692 return BT_ERROR_NONE;
695 int bt_mesh_node_create(bt_mesh_node_features_s *features,
696 bt_mesh_node_h *node_handle)
699 bt_mesh_node_s *node = NULL;
701 BT_CHECK_MESH_SUPPORT();
702 BT_CHECK_MESH_INIT_STATUS();
703 BT_CHECK_INPUT_PARAMETER(node_handle);
704 BT_CHECK_INPUT_PARAMETER(features);
706 node = g_malloc0(sizeof(bt_mesh_node_s));
708 BT_ERR("g_malloc0 failed");
709 return BT_ERROR_OUT_OF_MEMORY;
712 node->is_local = true;
713 node->features = *features;
714 node->unicast = 0x0001;
716 node_list = g_slist_append(node_list, node);
717 *node_handle = (bt_mesh_node_h)node;
720 return BT_ERROR_NONE;
723 int bt_mesh_node_reset(bt_mesh_node_h node_handle)
727 bt_mesh_network_s *network_s;
728 bt_mesh_node_s *node_s;
729 bluetooth_mesh_node_info_t node;
730 int error_code = BT_ERROR_NONE;
732 BT_CHECK_MESH_SUPPORT();
733 BT_CHECK_MESH_INIT_STATUS();
734 BT_CHECK_INPUT_PARAMETER(node_handle);
736 node_s = (bt_mesh_node_s*)node_handle;
737 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
739 network_s = node_s->parent;
740 BT_CHECK_INPUT_PARAMETER(network_s);
741 BT_MESH_VALIDATE_HANDLE(network_s, networks);
743 /* Resetting a local node is not allowed */
744 BT_CHECK_MESH_REMOTE(node_s);
746 /* Only attached remote nodes can be resetted */
747 if (!node_s->is_attached)
748 return BT_ERROR_INVALID_PARAMETER;
750 BT_INFO("Mesh: Reset the node [0x%2.2x]", node_s->unicast);
753 memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
754 g_strlcpy(node.net_uuid, network_s->uuid, 33);
755 node.primary_unicast = node_s->unicast;
756 node.num_elements = g_slist_length(node_s->elements);
758 error_code = _bt_get_error_code(bluetooth_mesh_node_reset(&node));
759 if (error_code != BT_ERROR_NONE) {
760 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
764 /* Cleanup the Node handles */
765 node_list = g_slist_remove(node_list, node_s);
766 g_slist_free_full(node_s->elements, __bt_mesh_free_elements);
773 int bt_mesh_node_destroy(bt_mesh_node_h node_handle)
777 BT_CHECK_MESH_SUPPORT();
778 BT_CHECK_MESH_INIT_STATUS();
779 BT_CHECK_INPUT_PARAMETER(node_handle);
781 bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
782 BT_MESH_VALIDATE_HANDLE(node, node_list);
784 /* It is NOT allowed to destroy attached node: Do Reset */
785 BT_CHECK_MESH_IS_ATTACHED(node);
787 node_list = g_slist_remove(node_list, node);
788 g_slist_free_full(node->elements, __bt_mesh_free_elements);
792 return BT_ERROR_NONE;
795 static void __bt_mesh_destroy_network_handles(bt_mesh_network_s *net)
802 BT_INFO("Mesh: Destroy handles of Network [%s] UUID [%s] Token [%s]",
803 net->name, net->uuid, net->token);
805 /* Remove all Nodes of Network */
806 BT_INFO("Mesh: Total nodes present in Network [%d]",
807 g_slist_length(net->nodes));
808 for (l = net->nodes; l != NULL; l = l->next) {
809 bt_mesh_node_s *node_s = (bt_mesh_node_s*)l->data;
811 net->nodes = g_slist_remove(net->nodes, node_s);
812 node_list = g_slist_remove(node_list, node_s);
813 BT_INFO("Mesh: Total elements present in Node [%d]",
814 g_slist_length(node_s->elements));
816 g_slist_free_full(node_s->elements, __bt_mesh_free_elements);
820 /* Remove all Netkeys & Appkeys of Network */
821 BT_INFO("Mesh: Total netkeys present in Network [%d]",
822 g_slist_length(net->netkeys));
823 for (l = net->netkeys; l != NULL; l = l->next) {
824 bt_mesh_netkey_s *netkey_s = (bt_mesh_netkey_s*)l->data;
826 net->netkeys = g_slist_remove(net->netkeys, netkey_s);
827 netkey_list = g_slist_remove(netkey_list, netkey_s);
828 BT_INFO("Mesh: Total appkeys present in Netkey [%d]",
829 g_slist_length(netkey_s->appkeys));
830 g_slist_free_full(netkey_s->appkeys, __bt_mesh_free_appkeys);
834 /* Remove all groups of Network */
835 BT_INFO("Mesh: Total groups present in Network [%d]",
836 g_slist_length(net->groups));
837 for (l = net->groups; l != NULL; l = l->next) {
838 bt_mesh_group_s *group_s = (bt_mesh_group_s*)l->data;
840 net->groups = g_slist_remove(net->groups, group_s);
841 group_list = g_slist_remove(group_list, group_s);
844 BT_INFO("Mesh: Handle Removal Done!");
847 static void __bt_mesh_generate_element(bt_mesh_node_s *node_s,
848 bt_mesh_element_s *elem_s)
853 for (l = node_s->elements; l; l = l->next) {
854 bt_mesh_element_s *el = (bt_mesh_element_s*)l->data;
855 if (el->index != index)
859 elem_s->index = index;
860 node_s->elements = g_slist_insert(node_s->elements, elem_s, index);
863 int bt_mesh_node_create_element(bt_mesh_node_h node_handle,
864 bt_mesh_element_h *element_handle)
867 BT_CHECK_MESH_SUPPORT();
868 BT_CHECK_MESH_INIT_STATUS();
869 BT_CHECK_INPUT_PARAMETER(node_handle);
870 BT_CHECK_INPUT_PARAMETER(element_handle);
872 bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
873 bt_mesh_element_s *element = NULL;
875 BT_INFO("Mesh: Element creation request");
876 BT_MESH_VALIDATE_HANDLE(node, node_list);
878 /* It is NOT allowed to add an element to a already attached node */
879 BT_CHECK_MESH_IS_ATTACHED(node);
881 /* Check num elements already present in the node */
882 if (g_slist_length(node->elements) >= BT_MESH_MAX_ELEMENTS)
883 return BT_ERROR_QUOTA_EXCEEDED;
886 element = g_malloc0(sizeof(bt_mesh_element_s));
888 BT_ERR("g_malloc0 failed");
889 return BT_ERROR_OUT_OF_MEMORY;
892 element->is_local = true;
893 element->parent = node;
895 __bt_mesh_generate_element(node, element);
896 element_list = g_slist_append(element_list, element);
897 *element_handle = (bt_mesh_element_h)element;
899 BT_INFO("Mesh: Element created successfully: element index [%d]", element->index);
901 return BT_ERROR_NONE;
904 int bt_mesh_element_destroy(bt_mesh_element_h element_handle)
907 BT_CHECK_MESH_SUPPORT();
908 BT_CHECK_MESH_INIT_STATUS();
909 BT_CHECK_INPUT_PARAMETER(element_handle);
910 BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
912 bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
913 bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
915 /* It is NOT allowed to destroy remote element */
916 BT_CHECK_MESH_LOCAL(node);
918 /* It is NOT allowed to destroy an attahced element */
919 BT_CHECK_MESH_IS_ATTACHED(node);
921 element_list = g_slist_remove(element_list, element);
922 node->elements = g_slist_remove(node->elements, element);
924 g_slist_free_full(element->models, __bt_mesh_free_models);
928 return BT_ERROR_NONE;
931 int bt_mesh_element_create_model(
932 bt_mesh_element_h element_handle,
933 bt_mesh_model_id_s *model_id,
934 bt_mesh_model_h *model_handle)
938 bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
939 bt_mesh_model_s *model = NULL;
941 BT_CHECK_MESH_SUPPORT();
942 BT_CHECK_MESH_INIT_STATUS();
943 BT_CHECK_INPUT_PARAMETER(element_handle);
944 BT_CHECK_INPUT_PARAMETER(model_id);
945 BT_CHECK_INPUT_PARAMETER(model_handle);
946 BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
948 bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
950 /* It is NOT allowed to add model to a remote element */
951 BT_CHECK_MESH_LOCAL(node);
953 /* It is NOT allowed to add a Model to a already attached node */
954 BT_CHECK_MESH_IS_ATTACHED(node);
956 BT_INFO("Mesh: Model creation request: Company ID [0x%2.2x] Model ID [0x%2.2x]",
957 model_id->company_id, model_id->model_id);
959 mod_id = model_id->company_id;
961 mod_id |= model_id->model_id;
962 /* Allow configuration server model only in primary element */
963 if ((model_id->model_id == BT_MESH_MODEL_ID_CFG_SRV) &&
965 return BT_ERROR_OPERATION_FAILED;
967 /* Check num models already present in the element */
968 if (g_slist_length(element->models) >= BT_MESH_MAX_MODELS)
969 return BT_ERROR_QUOTA_EXCEEDED;
971 /* Don't allow multiple instance of same model in an element */
972 if (g_slist_find_custom(element->models, GUINT_TO_POINTER(mod_id),
973 (GCompareFunc)__compare_model_id))
974 return BT_ERROR_ALREADY_DONE;
976 model = g_malloc0(sizeof(bt_mesh_model_s));
978 BT_ERR("g_malloc0 failed");
979 return BT_ERROR_OUT_OF_MEMORY;
982 model->is_local = true;
983 model->parent = element;
986 BT_INFO("Mesh: Model ID [0x%2.2x]", model_id->model_id);
987 BT_INFO("Mesh: Company ID [0x%2.2x]", model_id->company_id);
988 BT_INFO("Mesh: MOD [0x%4.4x]", model->id);
990 model_list = g_slist_append(model_list, model);
991 element->models = g_slist_append(element->models, model);
992 *model_handle = (bt_mesh_model_h)model;
994 BT_INFO("Mesh: Model created successfully");
996 return BT_ERROR_NONE;
999 int bt_mesh_model_destroy(bt_mesh_model_h model_handle)
1003 BT_CHECK_MESH_SUPPORT();
1004 BT_CHECK_MESH_INIT_STATUS();
1005 BT_CHECK_INPUT_PARAMETER(model_handle);
1007 bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
1008 BT_MESH_VALIDATE_HANDLE(model, model_list);
1010 bt_mesh_element_s *element = model->parent;
1011 BT_CHECK_INPUT_PARAMETER(element);
1012 BT_MESH_VALIDATE_HANDLE(element, element_list);
1014 bt_mesh_node_s *node = element->parent;
1015 BT_CHECK_INPUT_PARAMETER(node);
1016 BT_MESH_VALIDATE_HANDLE(node, node_list);
1018 /* It is NOT allowed to destroy remote model */
1019 BT_CHECK_MESH_LOCAL(node);
1021 /* It is NOT allowed to destroy an attahced model */
1022 BT_CHECK_MESH_IS_ATTACHED(node);
1024 model_list = g_slist_remove(model_list, model);
1025 element->models = g_slist_remove(element->models, model);
1029 return BT_ERROR_NONE;
1032 int bt_mesh_model_get_id(bt_mesh_model_h model_handle,
1033 bt_mesh_model_id_s *model_id)
1037 BT_CHECK_MESH_SUPPORT();
1038 BT_CHECK_MESH_INIT_STATUS();
1039 BT_CHECK_INPUT_PARAMETER(model_handle);
1040 BT_CHECK_INPUT_PARAMETER(model_id);
1042 bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
1043 BT_MESH_VALIDATE_HANDLE(model, model_list);
1045 BT_INFO("Mesh: Model ID [0x%4.4x]", model->id);
1046 model_id->company_id = model->id >> 16;
1047 model_id->model_id = model->id;
1048 BT_INFO("Mesh: CID [0x%2.2x]", model_id->company_id);
1049 BT_INFO("Mesh: MID [0x%2.2x]", model_id->model_id);
1052 return BT_ERROR_NONE;
1055 int bt_mesh_node_get_network(bt_mesh_node_h node_handle, bt_mesh_network_h *network)
1059 BT_CHECK_MESH_SUPPORT();
1060 BT_CHECK_MESH_INIT_STATUS();
1061 BT_CHECK_INPUT_PARAMETER(node_handle);
1062 BT_CHECK_INPUT_PARAMETER(network);
1064 bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
1065 BT_MESH_VALIDATE_HANDLE(node_handle, node_list);
1067 *network = node->parent;
1070 return BT_ERROR_NONE;
1073 int bt_mesh_element_get_node(bt_mesh_element_h element_handle,
1074 bt_mesh_node_h *node)
1078 BT_CHECK_MESH_SUPPORT();
1079 BT_CHECK_MESH_INIT_STATUS();
1080 BT_CHECK_INPUT_PARAMETER(element_handle);
1081 BT_CHECK_INPUT_PARAMETER(node);
1083 bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
1084 BT_MESH_VALIDATE_HANDLE(element, element_list);
1086 *node = element->parent;
1089 return BT_ERROR_NONE;
1092 int bt_mesh_model_get_element(bt_mesh_model_h model_handle,
1093 bt_mesh_element_h *element)
1097 BT_CHECK_MESH_SUPPORT();
1098 BT_CHECK_MESH_INIT_STATUS();
1099 BT_CHECK_INPUT_PARAMETER(model_handle);
1100 BT_CHECK_INPUT_PARAMETER(element);
1102 bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
1103 BT_MESH_VALIDATE_HANDLE(model, model_list);
1105 *element = model->parent;
1108 return BT_ERROR_NONE;
1111 int bt_mesh_appkey_get_netkey(bt_mesh_appkey_h appkey_handle,
1112 bt_mesh_netkey_h *netkey)
1116 BT_CHECK_MESH_SUPPORT();
1117 BT_CHECK_MESH_INIT_STATUS();
1118 BT_CHECK_INPUT_PARAMETER(appkey_handle);
1119 BT_CHECK_INPUT_PARAMETER(netkey);
1121 bt_mesh_appkey_s *appkey = (bt_mesh_appkey_s*)appkey_handle;
1122 BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
1124 *netkey = appkey->parent;
1127 return BT_ERROR_NONE;
1130 int bt_mesh_network_destroy(bt_mesh_network_h network)
1134 int error_code = BT_ERROR_NONE;
1135 bt_mesh_network_s *network_s;
1136 bluetooth_mesh_network_t net;
1138 BT_CHECK_MESH_SUPPORT();
1139 BT_CHECK_MESH_INIT_STATUS();
1140 BT_CHECK_INPUT_PARAMETER(network);
1141 BT_MESH_VALIDATE_HANDLE(network, networks);
1143 network_s = (bt_mesh_network_s*) network;
1144 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1146 g_strlcpy(net.uuid, network_s->uuid, 33);
1147 g_strlcpy(net.token.token, network_s->token, 17);
1148 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1150 BT_INFO("Mesh: Destroy Network: Name [%s]", network_s->name);
1152 BT_INFO("Mesh: Send Network Destroy Request to FRWK");
1153 error_code = _bt_get_error_code(bluetooth_mesh_network_destroy(&net));
1154 if (error_code != BT_ERROR_NONE) {
1155 BT_INFO("Mesh: Network Destroy Failed!!");
1156 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1162 BT_INFO("Mesh: Network Destroyed successfully");
1164 __bt_mesh_destroy_network_handles(network_s);
1165 networks = g_slist_remove(networks, network_s);
1168 BT_INFO("Mesh: Current number of networks after removing [%d]",
1169 g_slist_length(networks));
1174 /* Async API's to bt-service & stack */
1175 int bt_mesh_network_create(bt_mesh_node_h config_client,
1176 const char *network_name,
1177 bt_mesh_network_h *network, char **token)
1180 int error_code = BT_ERROR_NONE;
1185 bluetooth_mesh_network_t net;
1186 bluetooth_mesh_node_t param_node;
1187 bluetooth_mesh_model_t **param_model;
1188 bt_mesh_network_s *network_s;
1189 bt_mesh_netkey_s *netkey_s;
1191 BT_CHECK_MESH_SUPPORT();
1192 BT_CHECK_MESH_INIT_STATUS();
1193 BT_CHECK_INPUT_PARAMETER(config_client);
1194 BT_CHECK_INPUT_PARAMETER(network_name);
1195 BT_CHECK_INPUT_PARAMETER(network);
1196 BT_CHECK_INPUT_PARAMETER(token);
1198 BT_INFO("Mesh: Create Network: Name [%s]", network_name);
1199 bt_mesh_node_s *node = (bt_mesh_node_s*)config_client;
1200 BT_MESH_VALIDATE_HANDLE(node, node_list);
1202 /* Error if remote node*/
1203 BT_CHECK_MESH_LOCAL(node);
1205 /* It is NOT allowed to create network out of a already attahced node */
1206 BT_CHECK_MESH_IS_ATTACHED(node);
1208 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1210 if (strlen(network_name) >= BT_MESH_NETWORK_NAME_STRING_MAX_LEN)
1211 return BT_ERROR_INVALID_PARAMETER;
1213 /* Node in network should contain at-least one element */
1214 if (!g_slist_length(node->elements)) {
1215 BT_INFO("Mesh: No element present in Node: NOT ALLOWED!!");
1216 return BT_ERROR_INVALID_PARAMETER;
1219 /* Element in Node should contain at-least one Model */
1220 for (l1 = node->elements; l1 != NULL; l1 = l1->next) {
1221 bt_mesh_element_s *el = l1->data;
1223 models = g_slist_length(el->models);
1224 BT_INFO("Mesh: Num models element [%u] has is [%d]", el->index, models);
1226 BT_INFO("Mesh: No Model present in element: NOT ALLOWED!!");
1227 return BT_ERROR_INVALID_PARAMETER;
1229 /* If Primary element does not contain CFG SRV model, create and append */
1230 if (el->index == 0x0000) {
1231 uint32_t mod_id = 0xFFFF0000; /* CFG SRV */
1233 if (!g_slist_find_custom(el->models, GUINT_TO_POINTER(mod_id),
1234 (GCompareFunc)__compare_model_id)) {
1235 bt_mesh_model_s *model_s;
1236 BT_ERR("Mesh: Primary element does not contain CFG SRV Model:Add it!");
1237 model_s = g_malloc0(sizeof(bt_mesh_model_s));
1239 model_s->is_local = true;
1240 model_s->parent = el;
1241 model_s->id = mod_id;
1243 model_list = g_slist_append(model_list, model_s);
1244 el->models = g_slist_append(el->models, model_s);
1247 BT_INFO("Mesh: CFG SRV model is already added in primary element");
1249 num_models += models;
1252 memset(¶m_node, 0x00, sizeof(bluetooth_mesh_node_t));
1253 memcpy(¶m_node.vendor_info, &(node->features), sizeof(node->features));
1254 param_node.num_elements = g_slist_length(node->elements);
1255 param_node.primary_unicast = 0x0001;
1256 _bt_get_random_bytes(param_node.uuid, 16);
1258 BT_INFO("Mesh: Total Models [%d]", num_models);
1259 param_model = (bluetooth_mesh_model_t**)g_malloc0(num_models * sizeof(bluetooth_mesh_model_t*));
1261 for (l1 = node->elements, i = 0; l1 != NULL; l1 = l1->next, i++) {
1262 bt_mesh_element_s *e = l1->data;
1264 for (l2 = e->models, j = 0; l2 != NULL; l2 = l2->next, j++) {
1265 bt_mesh_model_s *m = l2->data;
1266 param_model[j+offset] = g_malloc0(sizeof(bluetooth_mesh_model_t));
1267 param_model[j+offset]->elem_index = i;
1268 param_model[j+offset]->model_id = m->id;
1271 offset += g_slist_length(e->models);
1274 BT_INFO("Mesh: Send Network create Request to FRWK");
1275 error_code = _bt_get_error_code(bluetooth_mesh_network_create(network_name, ¶m_node,
1276 num_models, param_model, &net));
1277 if (error_code != BT_ERROR_NONE) {
1278 BT_INFO("Mesh: Network could not be created!!");
1279 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1282 for (int i = 0; i < num_models; i++)
1283 g_free(param_model[i]);
1288 BT_INFO("Mesh: Network created successfully");
1290 /* Create Network object & fill data in network */
1291 network_s = g_malloc0(sizeof(bt_mesh_network_s));
1292 network_s->num_nodes = 1;
1293 network_s->is_local = true;
1294 network_s->is_discovered = true;
1296 /* Fill network name, token & UUID */
1297 __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid, 16,
1298 network_s->uuid, sizeof(network_s->uuid));
1299 g_strlcpy(network_s->token, net.token.token, 17);
1300 g_strlcpy(network_s->name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1301 network_s->nodes = g_slist_append(network_s->nodes, node);
1302 BT_INFO("Mesh: Network Name [%s]", network_s->name);
1303 BT_INFO("Mesh: Network Token[%s]", network_s->token);
1304 BT_INFO("Mesh: Network UUID [%s]", network_s->uuid);
1306 /* Create primary Netkey object */
1307 netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
1308 netkey_s->parent = network_s;
1309 netkey_s->netkey_index = 0x0000; /* Primary index */
1310 network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
1311 netkey_list = g_slist_append(netkey_list, netkey_s);
1313 /* Fill Config Client Node Data */
1314 node->is_attached = true;
1315 node->is_provisioner = true;
1316 __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid,
1317 16, node->uuid, sizeof(node->uuid));
1318 node->unicast = 0x0001;
1319 node->parent = network_s;
1321 /* Prepare Out parameters */
1322 *token = network_s->token;
1323 *network = (bt_mesh_network_h)network_s;
1325 /* Save network in list */
1326 networks = g_slist_append(networks, network_s);
1328 /* Clean up memory */
1329 for (int i = 0; i < num_models; i++)
1330 g_free(param_model[i]);
1336 int bt_mesh_network_load(const char *token, bt_mesh_network_h *network)
1338 int error_code = BT_ERROR_NONE;
1339 bluetooth_mesh_network_t net;
1340 bt_mesh_network_s *network_s;
1342 BT_CHECK_MESH_SUPPORT();
1343 BT_CHECK_MESH_INIT_STATUS();
1344 BT_CHECK_INPUT_PARAMETER(token);
1345 BT_CHECK_INPUT_PARAMETER(network);
1347 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1348 error_code = _bt_get_error_code(bluetooth_mesh_network_load(token, &net));
1349 if (error_code != BT_ERROR_NONE) {
1350 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1354 /* Create Network object */
1355 network_s = g_malloc0(sizeof(bt_mesh_network_s));
1356 network_s->is_local = true;
1357 g_strlcpy(network_s->uuid, net.uuid, 33);
1358 g_strlcpy(network_s->token, token, 17);
1359 g_strlcpy(network_s->name, net.name.name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1360 networks = g_slist_append(networks, network_s);
1366 int bt_mesh_network_get_name(bt_mesh_network_h network, char **network_name)
1368 bt_mesh_network_s *network_s;
1371 BT_CHECK_MESH_SUPPORT();
1372 BT_CHECK_MESH_INIT_STATUS();
1373 BT_CHECK_INPUT_PARAMETER(network);
1374 BT_CHECK_INPUT_PARAMETER(network_name);
1376 BT_MESH_VALIDATE_HANDLE(network, networks);
1378 network_s = (bt_mesh_network_s*)network;
1379 *network_name = strdup(network_s->name);
1380 if (*network_name == NULL) {
1381 BT_ERR("OUT_OF_MEMORY(0x%08x)",
1382 BT_ERROR_OUT_OF_MEMORY);
1383 return BT_ERROR_OUT_OF_MEMORY;
1387 return BT_ERROR_NONE;
1390 int bt_mesh_network_set_name(bt_mesh_network_h network, const char *network_name)
1392 int error_code = BT_ERROR_NONE;
1393 bluetooth_mesh_network_t net;
1394 bt_mesh_network_s* network_s;
1397 BT_CHECK_MESH_SUPPORT();
1398 BT_CHECK_MESH_INIT_STATUS();
1399 BT_CHECK_INPUT_PARAMETER(network);
1400 BT_CHECK_INPUT_PARAMETER(network_name);
1402 network_s = (bt_mesh_network_s*)network;
1403 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1405 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1406 g_strlcpy(net.uuid, network_s->uuid, 33);
1407 g_strlcpy(net.token.token, network_s->token, 17);
1408 g_strlcpy(net.name.name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1410 BT_INFO("Mesh: Set Network Name [%s]", network_name);
1411 error_code = _bt_get_error_code(bluetooth_mesh_network_set_name(&net));
1412 if (error_code != BT_ERROR_NONE) {
1413 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1417 BT_INFO("Mesh: Network Name set successfully [%s]", network_name);
1418 g_strlcpy(network_s->name, network_name, sizeof(network_s->name));
1421 return BT_ERROR_NONE;
1424 int bt_mesh_network_add_netkey(bt_mesh_network_h network,
1425 bt_mesh_netkey_h *netkey)
1427 int error_code = BT_ERROR_NONE;
1428 bt_mesh_network_s *network_s;
1429 bt_mesh_netkey_s *netkey_s;
1430 bluetooth_mesh_network_t net;
1431 uint16_t netkey_idx;
1434 BT_CHECK_MESH_SUPPORT();
1435 BT_CHECK_MESH_INIT_STATUS();
1436 BT_CHECK_INPUT_PARAMETER(network);
1437 BT_CHECK_INPUT_PARAMETER(netkey);
1439 BT_MESH_VALIDATE_HANDLE(network, networks);
1441 network_s = (bt_mesh_network_s*)network;
1442 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1444 g_strlcpy(net.uuid, network_s->uuid, 33);
1445 g_strlcpy(net.token.token, network_s->token, 17);
1446 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1448 error_code = _bt_get_error_code(bluetooth_mesh_network_add_netkey(&net, &netkey_idx));
1449 if (error_code != BT_ERROR_NONE) {
1450 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1454 BT_INFO("Mesh: Subnet Key created: Index [%d]", netkey_idx);
1455 /* Create Netkey object */
1456 netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
1457 netkey_s->parent = network_s;
1458 netkey_s->netkey_index = netkey_idx;
1459 network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
1460 netkey_list = g_slist_append(netkey_list, netkey_s);
1461 *netkey = (bt_mesh_netkey_h)netkey_s;
1464 return BT_ERROR_NONE;
1467 int bt_mesh_network_foreach_netkeys(bt_mesh_network_h network,
1468 bt_mesh_network_netkey_info_cb callback, void *user_data)
1470 bluetooth_mesh_network_t net;
1471 GPtrArray *netkeys = NULL;
1473 int error_code = BT_ERROR_NONE;
1474 uint16_t *netkey_idx = NULL;
1477 bt_mesh_network_s *network_s;
1480 BT_CHECK_MESH_SUPPORT();
1481 BT_CHECK_MESH_INIT_STATUS();
1482 BT_CHECK_INPUT_PARAMETER(network);
1483 BT_CHECK_INPUT_PARAMETER(callback);
1485 BT_MESH_VALIDATE_HANDLE(network, networks);
1487 netkeys = g_ptr_array_new();
1488 if (netkeys == NULL) {
1489 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1490 return BT_ERROR_OUT_OF_MEMORY;
1493 network_s = (bt_mesh_network_s*)network;
1494 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1496 g_strlcpy(net.uuid, network_s->uuid, 33);
1497 g_strlcpy(net.token.token, network_s->token, 17);
1498 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1500 error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_netkey(&net, &netkeys));
1501 if (error_code != BT_ERROR_NONE) {
1502 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1503 g_ptr_array_free(netkeys, TRUE);
1507 for (i = 0; i < netkeys->len; i++) {
1508 netkey_idx = g_ptr_array_index(netkeys, i);
1510 /* Create and insert netkey object in list */
1511 if (!__bt_mesh_network_is_netkey_added(network_s, *netkey_idx)) {
1512 bt_mesh_netkey_s *nk;
1513 nk = g_malloc0(sizeof(bt_mesh_netkey_s));
1514 nk->parent = network_s;
1515 nk->netkey_index = *netkey_idx;
1516 network_s->netkeys = g_slist_append(network_s->netkeys, nk);
1517 netkey_list = g_slist_append(netkey_list, nk);
1521 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1522 BT_ERROR_OPERATION_FAILED);
1523 error_code = BT_ERROR_OPERATION_FAILED;
1528 total = g_slist_length(network_s->netkeys);
1530 BT_INFO("Mesh: No netkey added in network");
1531 callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
1532 NULL, 0xFFFF, user_data);
1534 for (l = network_s->netkeys; l != NULL; l = g_slist_next(l)) {
1535 bt_mesh_netkey_s *netkey;
1538 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
1539 (bt_mesh_netkey_h) netkey,
1540 netkey->netkey_index, user_data)) {
1545 g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
1546 g_ptr_array_free(netkeys, TRUE);
1552 int bt_mesh_netkey_get_index(bt_mesh_netkey_h netkey, uint16_t *index)
1554 bt_mesh_netkey_s *netkey_s;
1557 BT_CHECK_MESH_SUPPORT();
1558 BT_CHECK_MESH_INIT_STATUS();
1559 BT_CHECK_INPUT_PARAMETER(netkey);
1560 BT_CHECK_INPUT_PARAMETER(index);
1562 BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
1564 netkey_s = (bt_mesh_netkey_s*)netkey;
1565 *index = netkey_s->netkey_index;
1568 return BT_ERROR_NONE;
1571 int bt_mesh_netkey_update(bt_mesh_netkey_h netkey)
1573 int error_code = BT_ERROR_NONE;
1574 bt_mesh_network_s *network_s;
1575 bt_mesh_netkey_s *netkey_s;
1576 bluetooth_mesh_network_t net;
1579 BT_CHECK_MESH_SUPPORT();
1580 BT_CHECK_MESH_INIT_STATUS();
1581 BT_CHECK_INPUT_PARAMETER(netkey);
1583 netkey_s = (bt_mesh_netkey_s*)netkey;
1584 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1585 network_s = netkey_s->parent;
1586 BT_CHECK_INPUT_PARAMETER(network_s);
1587 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1589 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1591 g_strlcpy(net.uuid, network_s->uuid, 33);
1592 g_strlcpy(net.token.token, network_s->token, 17);
1593 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1595 error_code = _bt_get_error_code(bluetooth_mesh_network_update_netkey(
1596 &net, netkey_s->netkey_index));
1597 if (error_code != BT_ERROR_NONE) {
1598 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1603 return BT_ERROR_NONE;
1606 int bt_mesh_netkey_delete(bt_mesh_netkey_h netkey)
1608 int error_code = BT_ERROR_NONE;
1609 bt_mesh_network_s *network_s;
1610 bt_mesh_netkey_s *netkey_s;
1611 bluetooth_mesh_network_t net;
1614 BT_CHECK_MESH_SUPPORT();
1615 BT_CHECK_MESH_INIT_STATUS();
1617 BT_CHECK_INPUT_PARAMETER(netkey);
1619 netkey_s = (bt_mesh_netkey_s*)netkey;
1620 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1622 network_s = netkey_s->parent;
1623 BT_CHECK_INPUT_PARAMETER(network_s);
1624 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1626 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1628 g_strlcpy(net.uuid, network_s->uuid, 33);
1629 g_strlcpy(net.token.token, network_s->token, 17);
1630 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1632 error_code = _bt_get_error_code(bluetooth_mesh_network_delete_netkey(&net, netkey_s->netkey_index));
1633 if (error_code != BT_ERROR_NONE) {
1634 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1638 network_s->netkeys = g_slist_remove(network_s->netkeys, netkey_s);
1639 netkey_list = g_slist_remove(netkey_list, netkey_s);
1640 g_slist_free_full(netkey_s->appkeys, __bt_mesh_free_appkeys);
1644 return BT_ERROR_NONE;
1647 int bt_mesh_netkey_add_appkey(bt_mesh_netkey_h netkey,
1648 bt_mesh_appkey_h *appkey)
1650 int error_code = BT_ERROR_NONE;
1651 uint16_t appkey_idx;
1652 bt_mesh_network_s *network_s;
1653 bt_mesh_netkey_s *netkey_s;
1654 bt_mesh_appkey_s *appkey_s;
1655 bluetooth_mesh_network_t net;
1658 BT_CHECK_MESH_SUPPORT();
1659 BT_CHECK_MESH_INIT_STATUS();
1661 BT_CHECK_INPUT_PARAMETER(netkey);
1662 BT_CHECK_INPUT_PARAMETER(appkey);
1664 netkey_s = (bt_mesh_netkey_s*)netkey;
1665 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1667 network_s = netkey_s->parent;
1668 BT_CHECK_INPUT_PARAMETER(network_s);
1669 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1671 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1673 g_strlcpy(net.uuid, network_s->uuid, 33);
1674 g_strlcpy(net.token.token, network_s->token, 17);
1675 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1677 error_code = _bt_get_error_code(bluetooth_mesh_network_add_appkey(
1678 &net, netkey_s->netkey_index, &appkey_idx));
1679 if (error_code != BT_ERROR_NONE) {
1680 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1684 /* Create Appkey object */
1685 appkey_s = g_malloc0(sizeof(bt_mesh_appkey_s));
1686 appkey_s->parent = netkey_s;
1687 appkey_s->appkey_index = appkey_idx;
1688 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_s);
1689 appkey_list = g_slist_append(appkey_list, appkey_s);
1690 *appkey = (bt_mesh_appkey_h)appkey_s;
1693 return BT_ERROR_NONE;
1696 int bt_mesh_appkey_update(bt_mesh_appkey_h appkey)
1698 int error_code = BT_ERROR_NONE;
1699 bt_mesh_network_s *network_s;
1700 bt_mesh_netkey_s *netkey_s;
1701 bt_mesh_appkey_s *appkey_s;
1702 bluetooth_mesh_network_t net;
1705 BT_CHECK_MESH_SUPPORT();
1706 BT_CHECK_MESH_INIT_STATUS();
1707 BT_CHECK_INPUT_PARAMETER(appkey);
1709 appkey_s = (bt_mesh_appkey_s*)appkey;
1710 BT_CHECK_INPUT_PARAMETER(appkey_s);
1711 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
1713 netkey_s = appkey_s->parent;
1714 BT_CHECK_INPUT_PARAMETER(netkey_s);
1715 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1717 network_s = netkey_s->parent;
1718 BT_CHECK_INPUT_PARAMETER(network_s);
1719 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1721 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1723 g_strlcpy(net.uuid, network_s->uuid, 33);
1724 g_strlcpy(net.token.token, network_s->token, 17);
1725 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1727 error_code = _bt_get_error_code(bluetooth_mesh_network_update_appkey(
1728 &net, netkey_s->netkey_index, appkey_s->appkey_index));
1729 if (error_code != BT_ERROR_NONE) {
1730 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1735 return BT_ERROR_NONE;
1738 int bt_mesh_appkey_delete(bt_mesh_appkey_h appkey)
1740 int error_code = BT_ERROR_NONE;
1741 bt_mesh_network_s *network_s;
1742 bt_mesh_netkey_s *netkey_s;
1743 bt_mesh_appkey_s *appkey_s;
1744 bluetooth_mesh_network_t net;
1747 BT_CHECK_MESH_SUPPORT();
1748 BT_CHECK_MESH_INIT_STATUS();
1749 BT_CHECK_INPUT_PARAMETER(appkey);
1751 appkey_s = (bt_mesh_appkey_s*)appkey;
1752 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
1754 netkey_s = appkey_s->parent;
1755 BT_CHECK_INPUT_PARAMETER(netkey_s);
1756 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1758 network_s = netkey_s->parent;
1759 BT_CHECK_INPUT_PARAMETER(network_s);
1760 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1762 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1764 g_strlcpy(net.uuid, network_s->uuid, 33);
1765 g_strlcpy(net.token.token, network_s->token, 17);
1766 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1768 error_code = _bt_get_error_code(bluetooth_mesh_network_delete_appkey(
1769 &net, netkey_s->netkey_index, appkey_s->appkey_index));
1770 if (error_code != BT_ERROR_NONE) {
1771 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1775 /* Delete Appkey Object */
1776 netkey_s->appkeys = g_slist_remove(netkey_s->appkeys, appkey_s);
1777 appkey_list = g_slist_remove(appkey_list, appkey_s);
1781 return BT_ERROR_NONE;
1784 int bt_mesh_netkey_foreach_appkeys(bt_mesh_netkey_h netkey,
1785 bt_mesh_appkey_info_cb callback, void *user_data)
1787 int error_code = BT_ERROR_NONE;
1788 bt_mesh_netkey_s *netkey_s;
1789 bt_mesh_network_s *network_s;
1790 bluetooth_mesh_network_t net;
1794 GPtrArray *appkeys = NULL;
1795 uint16_t *appkey_idx = NULL;
1798 BT_CHECK_MESH_SUPPORT();
1799 BT_CHECK_MESH_INIT_STATUS();
1800 BT_CHECK_INPUT_PARAMETER(netkey);
1801 BT_CHECK_INPUT_PARAMETER(callback);
1803 BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
1805 netkey_s = (bt_mesh_netkey_s*)netkey;
1807 network_s = netkey_s->parent;
1808 BT_CHECK_INPUT_PARAMETER(network_s);
1809 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1811 appkeys = g_ptr_array_new();
1812 if (appkeys == NULL) {
1813 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1814 return BT_ERROR_OUT_OF_MEMORY;
1817 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1819 g_strlcpy(net.uuid, network_s->uuid, 33);
1820 g_strlcpy(net.token.token, network_s->token, 17);
1821 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1823 BT_INFO("Mesh: Find all Appkeys for Netkey : index [%d]", netkey_s->netkey_index);
1824 error_code = _bt_get_error_code(bluetooth_mesh_netkey_get_all_appkey(
1825 &net, netkey_s->netkey_index, &appkeys));
1826 if (error_code != BT_ERROR_NONE) {
1827 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1828 g_ptr_array_free(appkeys, TRUE);
1831 for (i = 0; i < appkeys->len; i++) {
1832 appkey_idx = g_ptr_array_index(appkeys, i);
1834 /* Create and insert netkey object in list */
1835 if (!__bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx)) {
1836 bt_mesh_appkey_s *key;
1837 key = g_malloc0(sizeof(bt_mesh_appkey_s));
1838 key->parent = netkey_s;
1839 key->appkey_index = *appkey_idx;
1840 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, key);
1841 appkey_list = g_slist_append(appkey_list, key);
1845 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1846 BT_ERROR_OPERATION_FAILED);
1847 error_code = BT_ERROR_OPERATION_FAILED;
1852 total = g_slist_length(netkey_s->appkeys);
1853 BT_INFO("Mesh: Total appkeys [%d]", total);
1856 BT_INFO("Mesh: No AppKey added in NetKey yet!");
1857 callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
1858 (bt_mesh_netkey_h) netkey_s, NULL,
1860 return BT_ERROR_NONE;
1864 for (l = netkey_s->appkeys; l; l = g_slist_next(l)) {
1865 bt_mesh_appkey_s *appkey_s;
1867 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
1868 (bt_mesh_netkey_h) netkey_s, (bt_mesh_appkey_h) appkey_s,
1869 appkey_s->appkey_index, user_data))
1873 g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
1874 g_ptr_array_free(appkeys, TRUE);
1877 return BT_ERROR_NONE;
1880 int bt_mesh_appkey_get_index(bt_mesh_appkey_h appkey, uint16_t *index)
1882 bt_mesh_appkey_s *appkey_s;
1885 BT_CHECK_MESH_SUPPORT();
1886 BT_CHECK_MESH_INIT_STATUS();
1887 BT_CHECK_INPUT_PARAMETER(appkey);
1888 BT_CHECK_INPUT_PARAMETER(index);
1890 BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
1892 appkey_s = (bt_mesh_appkey_s*)appkey;
1893 *index = appkey_s->appkey_index;
1896 return BT_ERROR_NONE;
1899 /* Sync API's to bt-service: Discovery API's */
1900 int bt_mesh_network_foreach_devices(bt_mesh_network_h network,
1901 bt_mesh_network_device_info_cb callback, void *user_data)
1903 bluetooth_mesh_network_t net;
1904 bluetooth_mesh_node_info_t *node_info;
1905 GPtrArray *nodes = NULL;
1906 int error_code = BT_ERROR_NONE;
1908 bt_mesh_network_s *network_s;
1911 BT_CHECK_MESH_SUPPORT();
1912 BT_CHECK_MESH_INIT_STATUS();
1913 BT_CHECK_INPUT_PARAMETER(network);
1914 BT_CHECK_INPUT_PARAMETER(callback);
1916 BT_MESH_VALIDATE_HANDLE(network, networks);
1918 nodes = g_ptr_array_new();
1919 if (nodes == NULL) {
1920 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1921 return BT_ERROR_OUT_OF_MEMORY;
1924 network_s = (bt_mesh_network_s*)network;
1925 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1927 g_strlcpy(net.uuid, network_s->uuid, 33);
1928 g_strlcpy(net.token.token, network_s->token, 17);
1929 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1931 error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_nodes(&net, &nodes));
1932 if (error_code != BT_ERROR_NONE) {
1933 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1934 g_ptr_array_free(nodes, TRUE);
1938 BT_INFO("Mesh: Total number of Devices found [%d]", nodes->len);
1939 for (i = 0; i < nodes->len; i++) {
1940 node_info = g_ptr_array_index(nodes, i);
1942 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, nodes->len,
1943 node_info->dev_uuid, node_info->primary_unicast, user_data)) {
1947 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1948 BT_ERROR_OPERATION_FAILED);
1949 error_code = BT_ERROR_OPERATION_FAILED;
1954 g_ptr_array_foreach(nodes, (GFunc)g_free, NULL);
1955 g_ptr_array_free(nodes, TRUE);
1961 int bt_mesh_node_get_primary_address(bt_mesh_node_h node,
1962 uint16_t *primary_address)
1964 bt_mesh_node_s *node_s;
1967 BT_CHECK_MESH_SUPPORT();
1968 BT_CHECK_MESH_INIT_STATUS();
1969 BT_CHECK_INPUT_PARAMETER(node);
1970 BT_CHECK_INPUT_PARAMETER(primary_address);
1972 BT_MESH_VALIDATE_HANDLE(node, node_list);
1974 node_s = (bt_mesh_node_s*) node;
1975 *primary_address = node_s->unicast;
1978 return BT_ERROR_NONE;
1981 int bt_mesh_node_foreach_element(bt_mesh_node_h node,
1982 bt_mesh_node_element_info_cb callback, void *user_data)
1984 bt_mesh_node_s *node_s;
1989 BT_CHECK_MESH_SUPPORT();
1990 BT_CHECK_MESH_INIT_STATUS();
1991 BT_CHECK_INPUT_PARAMETER(node);
1992 BT_CHECK_INPUT_PARAMETER(callback);
1994 BT_MESH_VALIDATE_HANDLE(node, node_list);
1995 node_s = (bt_mesh_node_s*) node;
1997 total = g_slist_length(node_s->elements);
1999 callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
2000 (bt_mesh_element_h) NULL, -1, 0xFFFF, user_data);
2004 for (l = node_s->elements; l; l = g_slist_next(l)) {
2005 bt_mesh_element_s *element_s;
2006 element_s = l->data;
2007 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
2008 (bt_mesh_element_h)element_s, element_s->index,
2009 (node_s->unicast + element_s->index), user_data))
2014 return BT_ERROR_NONE;
2017 int bt_mesh_element_foreach_models(bt_mesh_element_h element,
2018 bt_mesh_element_model_info_cb callback, void *user_data)
2020 bluetooth_mesh_network_t net;
2021 bt_mesh_network_s *network_s;
2022 bt_mesh_node_s *node_s;
2023 bt_mesh_element_s *element_s;
2025 GPtrArray *models = NULL;
2027 uint32_t *model_info;
2028 int error_code = BT_ERROR_NONE;
2033 BT_CHECK_MESH_SUPPORT();
2034 BT_CHECK_MESH_INIT_STATUS();
2035 BT_CHECK_INPUT_PARAMETER(element);
2036 BT_CHECK_INPUT_PARAMETER(callback);
2038 element_s = (bt_mesh_element_s*) element;
2039 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2041 node_s = (bt_mesh_node_s*) element_s->parent;
2042 BT_CHECK_INPUT_PARAMETER(node_s);
2043 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2045 network_s = (bt_mesh_network_s*) node_s->parent;
2047 /* Only for local Node */
2048 if (node_s->is_local) {
2050 BT_INFO("Mesh: Local element");
2052 total = g_slist_length(element_s->models);
2054 callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, 0,
2055 (bt_mesh_model_h) NULL, NULL, user_data);
2057 for (l = element_s->models; l; l = l->next) {
2058 bt_mesh_model_s *model_s = l->data;
2059 bt_mesh_model_id_s modid;
2061 modid.company_id = model_s->id >> 16;
2062 modid.model_id = model_s->id;
2064 if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
2065 (bt_mesh_model_h) model_s,
2066 &modid, user_data)) {
2071 return BT_ERROR_NONE;
2074 models = g_ptr_array_new();
2075 if (models == NULL) {
2076 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2077 return BT_ERROR_OUT_OF_MEMORY;
2079 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
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);
2085 BT_INFO("Mesh: Get Models for element of Remote Node");
2086 error_code = _bt_get_error_code(bluetooth_mesh_element_get_all_models(&net,
2087 /* Node identity */node_s->unicast,
2088 /* eleement identity */element_s->index,
2089 /*Output*/ &models));
2090 if (error_code != BT_ERROR_NONE) {
2091 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2092 g_ptr_array_free(models, TRUE);
2096 total = models->len;
2097 BT_INFO("Mesh: Total models in element [%d]", total);
2098 for (i = 0; i < models->len; i++) {
2099 model_info = g_ptr_array_index(models, i);
2101 BT_INFO("Mesh: Model ID [0x%4.4x]", *model_info);
2102 /* Skip if Model is already added in the element */
2103 l = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(*model_info),
2104 (GCompareFunc)__compare_model_id);
2106 bt_mesh_model_id_s modid;
2107 bt_mesh_model_s *mod = (bt_mesh_model_s*)l->data;
2108 modid.company_id = mod->id >> 16;
2109 modid.model_id = mod->id;
2111 BT_INFO("Mesh: Model ID [0x%4.4x] is already present in element", *model_info);
2112 if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
2113 (bt_mesh_model_h) mod,
2114 &modid, user_data)) {
2119 /* Create and insert model object in list */
2120 bt_mesh_model_s *mod;
2121 bt_mesh_model_id_s modid;
2122 mod = g_malloc0(sizeof(bt_mesh_model_s));
2123 mod->parent = element_s;
2124 if (node_s->unicast == 0x0001) {
2125 mod->is_local = true;
2127 mod->id = *model_info;
2128 element_s->models = g_slist_append(element_s->models, mod);
2129 model_list = g_slist_append(model_list, mod);
2131 modid.company_id = *model_info >> 16;
2132 modid.model_id = *model_info;
2133 BT_INFO("Mesh: Model was not present in Element, created & inserted");
2134 BT_INFO("Mesh: Total Models present in Element [%d]",
2135 g_slist_length(element_s->models));
2137 if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
2138 (bt_mesh_model_h) mod,
2139 &modid, user_data)) {
2143 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2144 BT_ERROR_OPERATION_FAILED);
2145 error_code = BT_ERROR_OPERATION_FAILED;
2150 g_ptr_array_foreach(models, (GFunc)g_free, NULL);
2151 g_ptr_array_free(models, TRUE);
2157 /* Provisioning & capabilities related*/
2158 int bt_mesh_network_unprovisioned_device_scan(bt_mesh_network_h network,
2159 bt_mesh_scan_params_s *scan_params,
2160 bt_mesh_network_scan_unprovisioned_device_result_cb callback,
2163 bt_mesh_network_s *network_s;
2164 bluetooth_mesh_network_t net;
2165 int error_code = BT_ERROR_NONE;
2168 BT_CHECK_MESH_SUPPORT();
2169 BT_CHECK_MESH_INIT_STATUS();
2170 BT_CHECK_INPUT_PARAMETER(network);
2171 BT_CHECK_INPUT_PARAMETER(scan_params);
2172 BT_CHECK_INPUT_PARAMETER(callback);
2174 BT_MESH_VALIDATE_HANDLE(network, networks);
2176 network_s = (bt_mesh_network_s*)network;
2177 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2179 g_strlcpy(net.uuid, network_s->uuid, 33);
2180 g_strlcpy(net.token.token, network_s->token, 17);
2181 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2183 error_code = _bt_get_error_code(bluetooth_mesh_network_scan(
2184 &net, (bluetooth_mesh_scan_param_t*) scan_params));
2186 if (error_code != BT_ERROR_NONE) {
2187 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2191 _bt_set_cb(BT_EVENT_MESH_NETWORK_SCAN_STATE_CHANGED, callback, user_data);
2193 return BT_ERROR_NONE;
2196 int bt_mesh_stop_unprovisioned_device_scan(bt_mesh_network_h network)
2198 bt_mesh_network_s *network_s;
2199 bluetooth_mesh_network_t net;
2200 int error_code = BT_ERROR_NONE;
2203 BT_CHECK_MESH_SUPPORT();
2204 BT_CHECK_MESH_INIT_STATUS();
2205 BT_CHECK_INPUT_PARAMETER(network);
2207 BT_MESH_VALIDATE_HANDLE(network, networks);
2209 network_s = (bt_mesh_network_s*)network;
2210 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2212 g_strlcpy(net.uuid, network_s->uuid, 33);
2213 g_strlcpy(net.token.token, network_s->token, 17);
2214 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2216 error_code = _bt_get_error_code(bluetooth_mesh_network_cancel_scan(&net));
2218 if (error_code != BT_ERROR_NONE) {
2219 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2224 return BT_ERROR_NONE;
2227 int bt_mesh_network_set_provisioning_capabilities(bt_mesh_network_h network,
2228 bt_mesh_provisioner_capabilities_s *capabilities)
2230 bt_mesh_network_s *network_s;
2231 bluetooth_mesh_network_t net;
2232 bluetooth_mesh_provisioner_caps_t caps;
2233 int error_code = BT_ERROR_NONE;
2236 BT_CHECK_MESH_SUPPORT();
2237 BT_CHECK_MESH_INIT_STATUS();
2238 BT_CHECK_INPUT_PARAMETER(network);
2239 BT_CHECK_INPUT_PARAMETER(capabilities);
2241 BT_MESH_VALIDATE_HANDLE(network, networks);
2243 network_s = (bt_mesh_network_s*)network;
2244 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2245 memset(&caps, 0x00, sizeof(bluetooth_mesh_provisioner_caps_t));
2247 g_strlcpy(net.uuid, network_s->uuid, 33);
2248 g_strlcpy(net.token.token, network_s->token, 17);
2249 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2251 caps.public_oob = capabilities->public_oob;
2252 caps.static_oob = capabilities->static_oob;
2253 caps.out_oob = capabilities->out_oob;
2254 caps.in_oob = capabilities->in_oob;
2256 error_code = _bt_get_error_code(bluetooth_mesh_network_set_capabilities(
2257 &net,(bluetooth_mesh_provisioner_caps_t*) &caps));
2259 if (error_code != BT_ERROR_NONE) {
2260 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2265 return BT_ERROR_NONE;
2268 int bt_mesh_network_provision_device(bt_mesh_network_h network,
2269 const char *dev_uuid,
2270 bt_mesh_network_device_provision_cb callback,
2273 bt_mesh_network_s *network_s;
2274 bluetooth_mesh_provisioning_request_t req;
2275 int error_code = BT_ERROR_NONE;
2278 BT_CHECK_MESH_SUPPORT();
2279 BT_CHECK_MESH_INIT_STATUS();
2280 BT_CHECK_INPUT_PARAMETER(network);
2281 BT_CHECK_INPUT_PARAMETER(dev_uuid);
2282 BT_CHECK_INPUT_PARAMETER(callback);
2284 BT_MESH_VALIDATE_HANDLE(network, networks);
2286 network_s = (bt_mesh_network_s*)network;
2287 memset(&req, 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
2289 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2290 g_strlcpy(req.dev_uuid, dev_uuid, 33);
2292 BT_INFO("Mesh: Provision Device [%s]", dev_uuid);
2293 error_code = _bt_get_error_code(bluetooth_mesh_network_provision_device(&req));
2295 if (error_code != BT_ERROR_NONE) {
2296 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2300 _bt_set_cb(BT_EVENT_MESH_NETWORK_PROVISIONING_RESULT, callback, user_data);
2302 return BT_ERROR_NONE;
2305 int bt_mesh_authentication_set_request_cb(bt_mesh_authentication_request_cb callback, void *user_data)
2308 BT_CHECK_MESH_SUPPORT();
2309 BT_CHECK_MESH_INIT_STATUS();
2310 BT_CHECK_INPUT_PARAMETER(callback);
2312 _bt_set_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST, callback, user_data);
2315 return BT_ERROR_NONE;
2318 int bt_mesh_authentication_unset_request_cb(bt_mesh_authentication_request_cb callback)
2322 BT_CHECK_MESH_SUPPORT();
2323 BT_CHECK_MESH_INIT_STATUS();
2324 BT_CHECK_INPUT_PARAMETER(callback);
2326 _bt_unset_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST);
2329 return BT_ERROR_NONE;
2332 int bt_mesh_authentication_reply(bt_mesh_authentication_type_e auth_type, const char *value, bool auth_reply)
2334 int error_code = BT_ERROR_NONE;
2337 BT_CHECK_MESH_SUPPORT();
2338 BT_CHECK_MESH_INIT_STATUS();
2339 BT_CHECK_INPUT_PARAMETER(value);
2341 error_code = _bt_get_error_code(bluetooth_mesh_authentication_reply(auth_type, value, auth_reply));
2342 if (error_code != BT_ERROR_NONE)
2343 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2349 int bt_mesh_network_discover_node(bt_mesh_network_h network,
2350 const char *dev_uuid, bt_mesh_node_discover_status_cb callback, void *user_data)
2352 int error_code = BT_ERROR_NONE;
2353 bt_mesh_network_s *network_s;
2354 bluetooth_mesh_node_discover_t req;
2357 BT_CHECK_MESH_SUPPORT();
2358 BT_CHECK_MESH_INIT_STATUS();
2359 BT_CHECK_INPUT_PARAMETER(network);
2360 BT_CHECK_INPUT_PARAMETER(dev_uuid);
2361 BT_CHECK_INPUT_PARAMETER(callback);
2363 BT_MESH_VALIDATE_HANDLE(network, networks);
2365 BT_INFO("Mesh: Discover Node with UUID[%s]", dev_uuid);
2367 /* Check if node with dev_uuid is already created */
2368 network_s = (bt_mesh_network_s*)network;
2369 memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2371 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2372 g_strlcpy(req.dev_uuid, dev_uuid, 33);
2374 error_code = _bt_get_error_code(bluetooth_mesh_browse_remote_node(&req));
2375 if (error_code != BT_ERROR_NONE) {
2376 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2381 _bt_set_cb(BT_EVENT_MESH_NODE_BROWSING_COMPLETED, callback, user_data);
2382 return BT_ERROR_NONE;
2385 int bt_mesh_node_configure_netkey(bt_mesh_node_h node,
2386 bt_mesh_node_key_configuration_e netkey_op,
2387 bt_mesh_netkey_h netkey,
2388 bt_mesh_netkey_status_cb callback,
2391 int error_code = BT_ERROR_NONE;
2392 bt_mesh_network_s *network_s;
2393 bt_mesh_node_s *node_s;
2394 bt_mesh_netkey_s *netkey_s;
2395 bluetooth_mesh_key_configure_t req;
2398 BT_CHECK_MESH_SUPPORT();
2399 BT_CHECK_MESH_INIT_STATUS();
2400 BT_CHECK_INPUT_PARAMETER(node);
2401 BT_CHECK_INPUT_PARAMETER(netkey);
2402 BT_CHECK_INPUT_PARAMETER(callback);
2404 node_s = (bt_mesh_node_s*) node;
2405 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2407 network_s = node_s->parent;
2408 BT_CHECK_INPUT_PARAMETER(network_s);
2409 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2411 netkey_s = (bt_mesh_netkey_s*) netkey;
2412 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2414 /* Return error, if node is not attached */
2415 if (!node_s->is_attached)
2416 return BT_ERROR_INVALID_PARAMETER;
2418 /* Return error, if netkey is not present in the specific network */
2419 if (netkey_s->parent != network_s)
2420 return BT_ERROR_INVALID_PARAMETER;
2423 /* Return Already done, if netkey is present in the node */
2424 if (g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_s,
2425 (GCompareFunc)__simple_compare))
2426 return BT_ERROR_ALREADY_DONE;
2428 memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
2430 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2431 req.primary_unicast = node_s->unicast;
2432 req.netkey_idx = netkey_s->netkey_index;
2433 req.is_netkey = true;
2434 req.op = (bluetooth_mesh_node_key_conf_e) netkey_op;
2436 BT_INFO("Mesh: Add NetKey Idx [%d] to node", req.netkey_idx);
2437 error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
2438 if (error_code != BT_ERROR_NONE) {
2439 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2444 _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
2445 return BT_ERROR_NONE;
2448 int bt_mesh_node_configure_appkey(bt_mesh_node_h node,
2449 bt_mesh_node_key_configuration_e appkey_op,
2450 bt_mesh_appkey_h appkey,
2451 bt_mesh_appkey_status_cb callback,
2454 int error_code = BT_ERROR_NONE;
2455 bt_mesh_network_s *network_s;
2456 bt_mesh_node_s *node_s;
2457 bt_mesh_netkey_s *netkey_s;
2458 bt_mesh_appkey_s *appkey_s;
2459 bluetooth_mesh_key_configure_t req;
2462 BT_CHECK_MESH_SUPPORT();
2463 BT_CHECK_MESH_INIT_STATUS();
2464 BT_CHECK_INPUT_PARAMETER(node);
2465 BT_CHECK_INPUT_PARAMETER(appkey);
2466 BT_CHECK_INPUT_PARAMETER(callback);
2468 node_s = (bt_mesh_node_s*) node;
2469 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2471 network_s = node_s->parent;
2472 BT_CHECK_INPUT_PARAMETER(network_s);
2473 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2475 appkey_s = (bt_mesh_appkey_s*) appkey;
2476 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2478 netkey_s = (bt_mesh_netkey_s*) appkey_s->parent;
2479 BT_CHECK_INPUT_PARAMETER(netkey_s);
2480 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2482 /* Return error, if node is not attached */
2483 if (!node_s->is_attached)
2484 return BT_ERROR_INVALID_PARAMETER;
2486 /* Return error, if netkey is not present in the specific network */
2487 if (netkey_s->parent != network_s)
2488 return BT_ERROR_INVALID_PARAMETER;
2490 memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
2492 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2493 req.primary_unicast = node_s->unicast;
2494 req.netkey_idx = netkey_s->netkey_index;
2495 req.appkey_idx = appkey_s->appkey_index;
2496 req.is_netkey = false;
2497 req.op = (bluetooth_mesh_node_key_conf_e) appkey_op;
2499 error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
2500 if (error_code != BT_ERROR_NONE) {
2501 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2506 _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
2507 return BT_ERROR_NONE;
2510 /* Remote Node Operations: CONFIG: Non Key */
2511 int bt_mesh_node_get_features(bt_mesh_node_h node,
2512 bt_mesh_node_features_cb callback, void *user_data)
2514 int error_code = BT_ERROR_NONE;
2515 bt_mesh_network_s *network_s;
2516 bt_mesh_node_s *node_s;
2517 bluetooth_mesh_node_features_t req;
2520 BT_CHECK_MESH_SUPPORT();
2521 BT_CHECK_MESH_INIT_STATUS();
2522 BT_CHECK_INPUT_PARAMETER(node);
2523 BT_CHECK_INPUT_PARAMETER(callback);
2525 node_s = (bt_mesh_node_s*) node;
2526 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2528 /* Return error, if node is not attached */
2529 if (!node_s->is_attached)
2530 return BT_ERROR_INVALID_PARAMETER;
2532 network_s = (bt_mesh_network_s*) node_s->parent;
2533 BT_CHECK_INPUT_PARAMETER(network_s);
2534 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2536 memset(&req, 0x00, sizeof(bluetooth_mesh_node_features_t));
2538 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2539 req.unicast = node_s->unicast;
2540 req.elem_count = node_s->unicast;
2542 error_code = _bt_get_error_code(bluetooth_mesh_node_browse_vendor_features(&req));
2543 if (error_code != BT_ERROR_NONE) {
2544 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2549 _bt_set_cb(BT_EVENT_MESH_NODE_VENDOR_FEATURES, callback, user_data);
2550 return BT_ERROR_NONE;
2553 int bt_mesh_node_get_ttl(bt_mesh_node_h node, bt_mesh_node_ttl_cb callback, void *user_data)
2555 int error_code = BT_ERROR_NONE;
2556 bt_mesh_network_s *network_s;
2557 bt_mesh_node_s *node_s;
2558 bluetooth_mesh_node_ttl_info_t req;
2561 BT_CHECK_MESH_SUPPORT();
2562 BT_CHECK_MESH_INIT_STATUS();
2563 BT_CHECK_INPUT_PARAMETER(node);
2564 BT_CHECK_INPUT_PARAMETER(callback);
2566 node_s = (bt_mesh_node_s*) node;
2567 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2569 network_s = node_s->parent;
2570 BT_CHECK_INPUT_PARAMETER(network_s);
2571 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2573 /* Return error, if node is not attached */
2574 if (!node_s->is_attached)
2575 return BT_ERROR_INVALID_PARAMETER;
2577 memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
2579 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2580 req.unicast = node_s->unicast;
2583 error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
2584 if (error_code != BT_ERROR_NONE) {
2585 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2590 _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
2591 return BT_ERROR_NONE;
2594 int bt_mesh_node_set_ttl(bt_mesh_node_h node, uint8_t ttl, bt_mesh_node_ttl_cb callback, void *user_data)
2596 int error_code = BT_ERROR_NONE;
2597 bt_mesh_network_s *network_s;
2598 bt_mesh_node_s *node_s;
2599 bluetooth_mesh_node_ttl_info_t req;
2602 BT_CHECK_MESH_SUPPORT();
2603 BT_CHECK_MESH_INIT_STATUS();
2604 BT_CHECK_INPUT_PARAMETER(node);
2605 BT_CHECK_INPUT_PARAMETER(callback);
2607 node_s = (bt_mesh_node_s*) node;
2608 network_s = node_s->parent;
2609 BT_CHECK_INPUT_PARAMETER(network_s);
2610 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2611 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2613 /* Return error, if node is not attached */
2614 if (!node_s->is_attached)
2615 return BT_ERROR_INVALID_PARAMETER;
2617 memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
2619 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2620 req.unicast = node_s->unicast;
2624 error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
2625 if (error_code != BT_ERROR_NONE) {
2626 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2631 _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
2632 return BT_ERROR_NONE;
2635 int bt_mesh_node_foreach_netkeys(bt_mesh_node_h node, bt_mesh_node_netkey_info_cb callback, void *user_data)
2637 GPtrArray *netkeys = NULL;
2639 int error_code = BT_ERROR_NONE;
2640 uint16_t *netkey_idx = NULL;
2643 bluetooth_mesh_node_discover_t req;
2644 bt_mesh_network_s *network_s;
2645 bt_mesh_node_s *node_s;
2648 BT_CHECK_MESH_SUPPORT();
2649 BT_CHECK_MESH_INIT_STATUS();
2650 BT_CHECK_INPUT_PARAMETER(node);
2651 BT_CHECK_INPUT_PARAMETER(callback);
2653 node_s = (bt_mesh_node_s*) node;
2654 network_s = node_s->parent;
2656 BT_CHECK_INPUT_PARAMETER(network_s);
2657 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2658 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2660 /* Return error, if node is not attached */
2661 if (!node_s->is_attached)
2662 return BT_ERROR_INVALID_PARAMETER;
2664 netkeys = g_ptr_array_new();
2665 if (netkeys == NULL) {
2666 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2667 return BT_ERROR_OUT_OF_MEMORY;
2670 memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2672 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2673 req.unicast = node_s->unicast;
2675 error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_netkeys(&req, &netkeys));
2676 if (error_code != BT_ERROR_NONE) {
2677 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2678 g_ptr_array_free(netkeys, TRUE);
2682 BT_INFO("Mesh: Total netkeys added in node is [%d]", netkeys->len);
2683 for (i = 0; i < netkeys->len; i++) {
2684 bt_mesh_netkey_s *netkey_local;
2685 netkey_idx = g_ptr_array_index(netkeys, i);
2687 /* Check if netkey index is present in network or not */
2688 BT_INFO("Mesh: NetKey IDX [%d]", *netkey_idx);
2689 netkey_local = __bt_mesh_network_is_netkey_added(network_s, *netkey_idx);
2690 if (!netkey_local) {
2691 BT_ERR("Mesh: Network does not contain the netKey index, possibly reloaded");
2692 /* Create Netkey object */
2693 netkey_local = g_malloc0(sizeof(bt_mesh_netkey_s));
2694 netkey_local->parent = network_s;
2695 netkey_local->netkey_index = *netkey_idx;
2696 network_s->netkeys = g_slist_append(network_s->netkeys, netkey_local);
2697 netkey_list = g_slist_append(netkey_list, netkey_local);
2699 if (!g_slist_find_custom(node_s->netkeys, GUINT_TO_POINTER(*netkey_idx),
2700 (GCompareFunc)__compare_netkey_index))
2701 node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
2703 /* Check if netkey index is present in target node or not */
2704 if (!g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_local,
2705 (GCompareFunc)__simple_compare)) {
2706 node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
2709 BT_INFO("Mesh: Netkey is already added in node");
2713 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2714 BT_ERROR_OPERATION_FAILED);
2715 error_code = BT_ERROR_OPERATION_FAILED;
2720 total = g_slist_length(node_s->netkeys);
2722 BT_ERR("Mesh: Unexpcted: No netkey added in node!!");
2723 callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
2724 NULL, 0xFFFF, user_data);
2726 for (l = node_s->netkeys; l != NULL; l = g_slist_next(l)) {
2727 bt_mesh_netkey_s *netkey;
2730 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
2731 (bt_mesh_netkey_h) netkey,
2732 netkey->netkey_index, user_data)) {
2738 g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
2739 g_ptr_array_free(netkeys, TRUE);
2746 int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node, bt_mesh_netkey_h netkey,
2747 bt_mesh_node_appkey_info_cb callback, void *user_data)
2749 GPtrArray *appkeys = NULL;
2750 int error_code = BT_ERROR_NONE;
2752 bluetooth_mesh_node_discover_t req;
2753 uint16_t *appkey_idx = NULL;
2754 bt_mesh_network_s *network_s;
2755 bt_mesh_node_s *node_s;
2756 bt_mesh_netkey_s *netkey_s;
2759 BT_CHECK_MESH_SUPPORT();
2760 BT_CHECK_MESH_INIT_STATUS();
2761 BT_CHECK_INPUT_PARAMETER(node);
2762 BT_CHECK_INPUT_PARAMETER(netkey);
2763 BT_CHECK_INPUT_PARAMETER(callback);
2765 node_s = (bt_mesh_node_s*) node;
2766 network_s = node_s->parent;
2767 netkey_s = (bt_mesh_netkey_s*) netkey;
2769 BT_CHECK_INPUT_PARAMETER(network_s);
2770 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2771 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2772 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2774 /* Return error, if node is not attached */
2775 if (!node_s->is_attached)
2776 return BT_ERROR_INVALID_PARAMETER;
2778 appkeys = g_ptr_array_new();
2779 if (appkeys == NULL) {
2780 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2781 return BT_ERROR_OUT_OF_MEMORY;
2784 memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2786 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2787 req.unicast = node_s->unicast;
2788 req.netkey_idx = netkey_s->netkey_index;
2790 error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_appkeys(&req, &appkeys));
2791 if (error_code != BT_ERROR_NONE) {
2792 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2793 g_ptr_array_free(appkeys, TRUE);
2797 BT_INFO("Mesh: Total appkeys found in Node [%d]", appkeys->len);
2798 for (i = 0; i < appkeys->len; i++) {
2799 bt_mesh_appkey_s *appkey_local;
2800 appkey_idx = g_ptr_array_index(appkeys, i);
2802 /* Check if appkey index is present in network or not */
2803 BT_INFO("Mesh: AppKey index [%d]", *appkey_idx);
2804 appkey_local = __bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx);
2806 if (!appkey_local) {
2807 BT_ERR("Mesh: Network does not AppKey index, possibly Network reloaded!!");
2808 /* Create Appkey object */
2809 appkey_local = g_malloc0(sizeof(bt_mesh_appkey_s));
2810 appkey_local->parent = netkey_s;
2811 appkey_local->appkey_index = *appkey_idx;
2812 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_local);
2813 appkey_list = g_slist_append(appkey_list, appkey_local);
2815 if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
2816 (GCompareFunc)__compare_appkey_index))
2817 node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
2819 /* Check if netkey index is present in target node or not */
2820 if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
2821 (GCompareFunc)__compare_appkey_index)) {
2822 node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
2825 BT_INFO("Mesh: AppKey is already added in node");
2829 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, appkeys->len,
2830 (bt_mesh_netkey_h) netkey, (bt_mesh_appkey_h) appkey_local,
2831 appkey_local->appkey_index, user_data)) {
2835 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2836 BT_ERROR_OPERATION_FAILED);
2837 error_code = BT_ERROR_OPERATION_FAILED;
2842 if (appkeys->len == 0) {
2843 BT_ERR("Mesh: No appkey configured for the bound netkey Idx [%d]",
2845 callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, 0,
2846 (bt_mesh_netkey_h) netkey_s, NULL, 0xFFFF, user_data);
2849 g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
2850 g_ptr_array_free(appkeys, TRUE);
2856 int bt_mesh_model_bind_appkey(bt_mesh_model_h model,
2857 bt_mesh_appkey_h appkey, bt_mesh_model_bind_cb callback,
2860 int error_code = BT_ERROR_NONE;
2861 bt_mesh_model_s *model_s;
2862 bt_mesh_element_s *element_s;
2863 bt_mesh_node_s *node_s;
2864 bt_mesh_network_s *network_s;
2865 bt_mesh_appkey_s *appkey_s;
2866 bluetooth_mesh_model_configure_t req;
2869 BT_CHECK_MESH_SUPPORT();
2870 BT_CHECK_MESH_INIT_STATUS();
2871 BT_CHECK_INPUT_PARAMETER(model);
2872 BT_CHECK_INPUT_PARAMETER(appkey);
2873 BT_CHECK_INPUT_PARAMETER(callback);
2875 model_s = (bt_mesh_model_s*) model;
2876 element_s = (bt_mesh_element_s*) model_s->parent;
2877 node_s = (bt_mesh_node_s*) element_s->parent;
2878 appkey_s = (bt_mesh_appkey_s*) appkey;
2879 network_s = (bt_mesh_network_s*) node_s->parent;
2881 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2882 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2883 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2884 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2885 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2887 /* Return error, if node is not attached */
2888 if (!node_s->is_attached)
2889 return BT_ERROR_INVALID_PARAMETER;
2891 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
2893 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2894 req.primary_unicast = node_s->unicast;
2895 req.elem_index = element_s->index;
2896 req.model = model_s->id;
2897 req.appkey_idx = appkey_s->appkey_index;
2900 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
2901 if (error_code != BT_ERROR_NONE) {
2902 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2907 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
2908 return BT_ERROR_NONE;
2911 int bt_mesh_model_unbind_appkey(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
2912 bt_mesh_model_unbind_cb callback, void *user_data)
2914 int error_code = BT_ERROR_NONE;
2915 bt_mesh_model_s *model_s;
2916 bt_mesh_element_s *element_s;
2917 bt_mesh_node_s *node_s;
2918 bt_mesh_appkey_s *appkey_s;
2919 bt_mesh_network_s *network_s;
2920 bluetooth_mesh_model_configure_t req;
2923 BT_CHECK_MESH_SUPPORT();
2924 BT_CHECK_MESH_INIT_STATUS();
2925 BT_CHECK_INPUT_PARAMETER(model);
2926 BT_CHECK_INPUT_PARAMETER(appkey);
2927 BT_CHECK_INPUT_PARAMETER(callback);
2929 model_s = (bt_mesh_model_s*) model;
2930 element_s = (bt_mesh_element_s*) model_s->parent;
2931 node_s = (bt_mesh_node_s*) element_s->parent;
2932 appkey_s = (bt_mesh_appkey_s*) appkey;
2933 network_s = (bt_mesh_network_s*) node_s->parent;
2935 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2936 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2937 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2938 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2939 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2941 /* Return error, if node is not attached */
2942 if (!node_s->is_attached)
2943 return BT_ERROR_INVALID_PARAMETER;
2945 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
2947 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2948 req.primary_unicast = node_s->unicast;
2949 req.elem_index = element_s->index;
2950 req.model = model_s->id;
2951 req.appkey_idx = appkey_s->appkey_index;
2952 req.is_bind = false;
2954 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
2955 if (error_code != BT_ERROR_NONE) {
2956 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2961 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
2962 return BT_ERROR_NONE;
2965 int bt_mesh_model_get_appkey_list(bt_mesh_model_h model,
2966 bt_mesh_model_appkey_list_cb callback, void *user_data)
2968 int error_code = BT_ERROR_NONE;
2969 bt_mesh_model_s *model_s;
2970 bt_mesh_element_s *element_s;
2971 bt_mesh_node_s *node_s;
2972 bt_mesh_network_s *network_s;
2973 bluetooth_mesh_model_configure_t req;
2976 BT_CHECK_MESH_SUPPORT();
2977 BT_CHECK_MESH_INIT_STATUS();
2978 BT_CHECK_INPUT_PARAMETER(model);
2979 BT_CHECK_INPUT_PARAMETER(callback);
2981 model_s = (bt_mesh_model_s*) model;
2982 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2984 element_s = (bt_mesh_element_s*) model_s->parent;
2985 BT_CHECK_INPUT_PARAMETER(element_s);
2986 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2988 node_s = (bt_mesh_node_s*) element_s->parent;
2989 BT_CHECK_INPUT_PARAMETER(node_s);
2990 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2992 network_s = (bt_mesh_network_s*) node_s->parent;
2993 BT_CHECK_INPUT_PARAMETER(network_s);
2994 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2996 /* Return error, if node is not attached */
2997 if (!node_s->is_attached)
2998 return BT_ERROR_INVALID_PARAMETER;
3000 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3002 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3003 req.primary_unicast = node_s->unicast;
3004 req.elem_index = element_s->index;
3005 req.model = model_s->id;
3007 error_code = _bt_get_error_code(bluetooth_mesh_model_get_all_appkeys(&req));
3008 if (error_code != BT_ERROR_NONE) {
3009 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3014 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_APPKEY_LIST, callback, user_data);
3018 int bt_mesh_model_send_msg(bt_mesh_model_h model,
3019 bt_mesh_appkey_h appkey, bt_mesh_model_msg_params_s *msg_params,
3020 bt_mesh_model_msg_cb callback, void *user_data)
3022 int error_code = BT_ERROR_NONE;
3023 bt_mesh_model_s *model_s;
3024 bt_mesh_element_s *element_s;
3025 bt_mesh_node_s *node_s;
3026 bt_mesh_network_s *network_s;
3027 bt_mesh_appkey_s *appkey_s;
3028 bluetooth_mesh_model_msg_t req;
3031 BT_CHECK_MESH_SUPPORT();
3032 BT_CHECK_MESH_INIT_STATUS();
3033 BT_CHECK_INPUT_PARAMETER(model);
3034 BT_CHECK_INPUT_PARAMETER(appkey);
3035 BT_CHECK_INPUT_PARAMETER(msg_params);
3036 BT_CHECK_INPUT_PARAMETER(callback);
3038 model_s = (bt_mesh_model_s*) model;
3039 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3041 element_s = (bt_mesh_element_s*) model_s->parent;
3042 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3044 node_s = (bt_mesh_node_s*) element_s->parent;
3045 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3047 appkey_s = (bt_mesh_appkey_s*) appkey;
3048 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3050 network_s = (bt_mesh_network_s*) node_s->parent;
3051 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3053 /* Return error, if node is not attached */
3054 if (!node_s->is_attached)
3055 return BT_ERROR_INVALID_PARAMETER;
3057 BT_INFO("Mesh: Model msg opcode: 0x%2.2X",msg_params->opcode);
3059 memset(&req, 0x00, sizeof(bluetooth_mesh_model_msg_t));
3061 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3062 req.primary_unicast = node_s->unicast;
3063 req.elem_index = element_s->index;
3064 req.model = model_s->id;
3065 req.appkey_idx = appkey_s->appkey_index;
3066 req.opcode = msg_params->opcode;
3067 if (msg_params->data) {
3068 BT_INFO("Mesh: model msg strlen %zd message: %s",
3069 strlen(msg_params->data), msg_params->data);
3071 req.msg_len = strlen(msg_params->data);
3072 g_strlcpy(req.msg, msg_params->data, sizeof(msg_params->data) + 1);
3077 error_code = _bt_get_error_code(bluetooth_mesh_model_send_msg(&req));
3078 if (error_code != BT_ERROR_NONE) {
3079 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3084 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_EXECUTE_MSG_COMPLETED, callback, user_data);
3085 return BT_ERROR_NONE;
3088 int bt_mesh_group_send_msg(bt_mesh_group_h group,
3089 bt_mesh_appkey_h appkey, bt_mesh_model_msg_params_s *msg_params,
3090 bt_mesh_model_msg_cb callback, void *user_data)
3092 int error_code = BT_ERROR_NONE;
3093 bt_mesh_group_s *group_s;
3094 bt_mesh_network_s *network_s;
3095 bt_mesh_appkey_s *appkey_s;
3096 bluetooth_mesh_model_msg_t req;
3099 BT_CHECK_MESH_SUPPORT();
3100 BT_CHECK_MESH_INIT_STATUS();
3101 BT_CHECK_INPUT_PARAMETER(group);
3102 BT_CHECK_INPUT_PARAMETER(appkey);
3103 BT_CHECK_INPUT_PARAMETER(msg_params);
3104 BT_CHECK_INPUT_PARAMETER(callback);
3106 group_s = (bt_mesh_group_s*) group;
3107 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3109 appkey_s = (bt_mesh_appkey_s*) appkey;
3110 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3112 network_s = (bt_mesh_network_s*) group_s->parent;
3113 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3115 BT_INFO("Mesh: Model msg opcode: 0x%2.2X",msg_params->opcode);
3117 memset(&req, 0x00, sizeof(bluetooth_mesh_model_msg_t));
3118 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3119 req.primary_unicast = group_s->addr;
3120 req.appkey_idx = appkey_s->appkey_index;
3121 req.opcode = msg_params->opcode;
3123 if (msg_params->data) {
3124 BT_INFO("Mesh: Group msg strlen %zd message: %s",
3125 strlen(msg_params->data), msg_params->data);
3127 req.msg_len = strlen(msg_params->data);
3128 g_strlcpy(req.msg, msg_params->data, sizeof(msg_params->data) + 1);
3133 error_code = _bt_get_error_code(bluetooth_mesh_model_send_msg(&req));
3134 if (error_code != BT_ERROR_NONE) {
3135 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3140 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_EXECUTE_MSG_COMPLETED, callback, user_data);
3141 return BT_ERROR_NONE;
3144 int bt_mesh_network_foreach_groups(bt_mesh_network_h network,
3145 bt_mesh_network_group_info_cb callback, void *user_data)
3147 int error_code = BT_ERROR_NONE;
3148 bluetooth_mesh_network_t net;
3149 bt_mesh_network_s *network_s;
3150 GPtrArray *groups = NULL;
3152 bluetooth_mesh_network_group_info_t *group_info = NULL;
3157 BT_CHECK_MESH_SUPPORT();
3158 BT_CHECK_MESH_INIT_STATUS();
3159 BT_CHECK_INPUT_PARAMETER(network);
3160 BT_CHECK_INPUT_PARAMETER(callback);
3162 BT_MESH_VALIDATE_HANDLE(network, networks);
3164 groups = g_ptr_array_new();
3165 if (groups == NULL) {
3166 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
3167 return BT_ERROR_OUT_OF_MEMORY;
3170 network_s = (bt_mesh_network_s*)network;
3171 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3173 g_strlcpy(net.uuid, network_s->uuid, 33);
3174 g_strlcpy(net.token.token, network_s->token, 17);
3175 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3177 error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_groups(&net, &groups));
3178 if (error_code != BT_ERROR_NONE) {
3179 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3180 g_ptr_array_free(groups, TRUE);
3184 BT_INFO("Mesh: Total number of Groups in network [%d]", groups->len);
3185 for (i = 0; i < groups->len; i++) {
3186 group_info = g_ptr_array_index(groups, i);
3188 BT_INFO("Mesh: Group Is Virtual [%s] Group Addr [0x%2.2x]",
3189 group_info->is_virtual ? "YES" : "NO", group_info->group_addr);
3191 if (group_info->is_virtual)
3192 BT_INFO("Mesh: Virtual label UUID [%s]", group_info->label_uuid);
3194 BT_INFO("Mesh: Total groups already present in Network [%d]",
3195 g_slist_length(network_s->groups));
3196 /* Find or create group in network list */
3197 if (!g_slist_find_custom(network_s->groups,
3198 GUINT_TO_POINTER(group_info->group_addr),
3199 (GCompareFunc)__compare_network_group_address)) {
3200 BT_INFO("Mesh: Its a new Group, add in network");
3201 bt_mesh_group_s *group_s;
3202 group_s = g_malloc0(sizeof(bt_mesh_group_s));
3203 group_s->addr = group_info->group_addr;
3204 group_s->parent = network_s;
3205 group_s->is_virtual = group_info->is_virtual;
3206 if (group_s->is_virtual)
3207 g_strlcpy(group_s->label_uuid, group_info->label_uuid,
3208 sizeof(group_s->label_uuid));
3209 BT_INFO("Mesh: Group [0x%2.2x] added in network", group_s->addr);
3211 network_s->groups = g_slist_append(network_s->groups, group_s);
3212 group_list = g_slist_append(group_list, group_s);
3214 BT_INFO("Mesh: Group [0x%2.2x] Already Added in network",
3215 group_info->group_addr);
3217 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
3218 BT_ERROR_OPERATION_FAILED);
3219 error_code = BT_ERROR_OPERATION_FAILED;
3224 total = g_slist_length(network_s->groups);
3225 BT_INFO("Mesh: Total number of groups [%d]", total);
3227 BT_INFO("Mesh: No Groups added in network");
3228 callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
3231 for (l = network_s->groups; l != NULL; l = g_slist_next(l)) {
3232 bt_mesh_group_s *group_s;
3235 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
3236 (bt_mesh_group_h) group_s,
3241 g_ptr_array_foreach(groups, (GFunc)g_free, NULL);
3242 g_ptr_array_free(groups, TRUE);
3248 int bt_mesh_network_create_virtual_group(bt_mesh_network_h network,
3249 bt_mesh_group_h *group)
3251 int error_code = BT_ERROR_NONE;
3252 bt_mesh_network_s *network_s;
3253 bt_mesh_group_s *group_s;
3254 bluetooth_mesh_network_group_info_t req;
3255 bluetooth_mesh_network_t net;
3258 BT_CHECK_MESH_SUPPORT();
3259 BT_CHECK_MESH_INIT_STATUS();
3260 BT_CHECK_INPUT_PARAMETER(network);
3262 network_s = (bt_mesh_network_s*) network;
3264 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3266 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3267 memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3269 g_strlcpy(net.uuid, network_s->uuid, 33);
3270 g_strlcpy(net.token.token, network_s->token, 17);
3271 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3273 error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, true, 0x0000, &req));
3274 if (error_code != BT_ERROR_NONE) {
3275 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3279 group_s = g_malloc0(sizeof(bt_mesh_group_s));
3280 group_s->addr = req.group_addr;
3281 group_s->is_virtual = true;
3282 group_s->parent = network_s;
3283 g_strlcpy(group_s->label_uuid, req.label_uuid, BT_MESH_UUID_STRING_LEN + 1);
3284 BT_INFO("Mesh: Virtual Group created : Addr [0x%2.2x]", req.group_addr);
3285 BT_INFO("Mesh: Virtual Group label UUID [%s]", group_s->label_uuid);
3287 network_s->groups = g_slist_append(network_s->groups, group_s);
3288 group_list = g_slist_append(group_list, group_s);
3290 *group = (bt_mesh_group_h) group_s;
3295 int bt_mesh_network_remove_group(bt_mesh_group_h group)
3297 int error_code = BT_ERROR_NONE;
3298 bt_mesh_network_s *network_s;
3299 bt_mesh_group_s *group_s;
3300 bluetooth_mesh_network_group_info_t req;
3301 bluetooth_mesh_network_t net;
3304 BT_CHECK_MESH_SUPPORT();
3305 BT_CHECK_INPUT_PARAMETER(group);
3307 group_s = (bt_mesh_group_s*) group;
3308 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3309 network_s = group_s->parent;
3311 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3312 memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3314 BT_INFO("Mesh: Remove Group [0x%2.2x] from network", group_s->addr);
3315 BT_INFO("Mesh: Is Group Virtual [%s]", group_s->is_virtual? "YES": "NO");
3316 if (group_s->is_virtual)
3317 BT_INFO("Mesh: Group Label UUID [%s]", group_s->label_uuid);
3319 /* Fill Network Info */
3320 g_strlcpy(net.uuid, network_s->uuid, 33);
3321 g_strlcpy(net.token.token, network_s->token, 17);
3322 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3324 /* Fill Group Info */
3325 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3326 req.is_virtual = group_s->is_virtual;
3327 req.group_addr = group_s->addr;
3329 g_strlcpy(req.label_uuid, group_s->label_uuid, sizeof(req.label_uuid));
3331 error_code = _bt_get_error_code(bluetooth_mesh_network_remove_group(&net, &req));
3332 if (error_code != BT_ERROR_NONE) {
3333 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3338 network_s->groups = g_slist_remove(network_s->groups, group_s);
3339 group_list = g_slist_remove(group_list, group_s);
3343 return BT_ERROR_NONE;
3346 int bt_mesh_network_create_group(bt_mesh_network_h network,
3347 uint16_t grp_addr, bt_mesh_group_h *group)
3349 int error_code = BT_ERROR_NONE;
3350 bt_mesh_network_s *network_s;
3351 bt_mesh_group_s *group_s;
3352 bluetooth_mesh_network_t net;
3353 bluetooth_mesh_network_group_info_t req;
3357 BT_CHECK_MESH_SUPPORT();
3358 BT_CHECK_MESH_INIT_STATUS();
3359 BT_CHECK_INPUT_PARAMETER(network);
3360 BT_CHECK_INPUT_PARAMETER(group);
3362 network_s = (bt_mesh_network_s*) network;
3364 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3366 /* Check for valid Group Address */
3367 if (!BT_MESH_IS_GROUP(grp_addr)) {
3368 BT_INFO("Mesh: group Address [0x%2.2x] is not valid Group Address",
3370 return BT_ERROR_INVALID_PARAMETER;
3373 l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(grp_addr),
3374 (GCompareFunc)__compare_group_address);
3377 BT_INFO("Mesh: Group [0x%2.2x]Already exist", grp_addr);
3379 *group = (bt_mesh_group_h) group_s;
3383 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3384 memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3386 /* Fill Network Info */
3387 g_strlcpy(net.uuid, network_s->uuid, 33);
3388 g_strlcpy(net.token.token, network_s->token, 17);
3389 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3391 error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, false, grp_addr, &req));
3392 if (error_code != BT_ERROR_NONE) {
3393 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3397 BT_INFO("Mesh: Group created [0x%2.2x]", grp_addr);
3398 group_s = g_malloc0(sizeof(bt_mesh_group_s));
3399 group_s->addr = grp_addr;
3400 group_s->is_virtual = false;
3401 group_s->parent = network_s;
3403 network_s->groups = g_slist_append(network_s->groups, group_s);
3404 group_list = g_slist_append(group_list, group_s);
3406 *group = (bt_mesh_group_h) group_s;
3411 int bt_mesh_model_configure_group_subscription(bt_mesh_model_subscription_op_e model_op,
3412 bt_mesh_model_h model, bt_mesh_group_h group,
3413 bt_mesh_model_subscription_op_cb callback, void *user_data)
3415 int error_code = BT_ERROR_NONE;
3416 bt_mesh_model_s *model_s;
3417 bt_mesh_element_s *element_s;
3418 bt_mesh_node_s *node_s;
3419 bt_mesh_network_s *network_s;
3420 bt_mesh_group_s *group_s;
3421 bluetooth_mesh_model_configure_t req;
3424 BT_CHECK_MESH_SUPPORT();
3425 BT_CHECK_MESH_INIT_STATUS();
3426 BT_CHECK_INPUT_PARAMETER(model);
3427 BT_CHECK_INPUT_PARAMETER(group);
3428 BT_CHECK_INPUT_PARAMETER(callback);
3430 model_s = (bt_mesh_model_s*) model;
3431 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3433 group_s = (bt_mesh_group_s*) group;
3434 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3436 element_s = (bt_mesh_element_s*) model_s->parent;
3437 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3439 node_s = (bt_mesh_node_s*) element_s->parent;
3440 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3442 network_s = (bt_mesh_network_s*) node_s->parent;
3443 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3445 BT_INFO("Mesh: Configure Group Request [%d]", model_op);
3446 BT_INFO("Mesh: Group Addr [0x%2.2x] Is Virtual [%s]",
3447 group_s->addr, group_s->is_virtual? "YES" : "NO");
3449 /* Check group belongs to the same network */
3450 if (network_s != group_s->parent)
3451 return BT_ERROR_INVALID_PARAMETER;
3453 /* Check group is non virtual */
3454 if (group_s->is_virtual)
3455 return BT_ERROR_INVALID_PARAMETER;
3457 /* Return error, if node is not attached */
3458 if (!node_s->is_attached)
3459 return BT_ERROR_INVALID_PARAMETER;
3461 if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
3462 req.sub_addr = group_s->addr;
3463 req.is_virtual_sub = false;
3465 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3466 req.primary_unicast = node_s->unicast;
3467 req.elem_index = element_s->index;
3468 req.model = model_s->id;
3470 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_group_sub(&req));
3471 if (error_code != BT_ERROR_NONE) {
3472 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3477 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_SUB, callback, user_data);
3481 int bt_mesh_model_configure_virtual_group_subscription(bt_mesh_model_subscription_op_e model_op,
3482 bt_mesh_model_h model, bt_mesh_group_h group,
3483 bt_mesh_model_subscription_op_cb callback,
3486 int error_code = BT_ERROR_NONE;
3487 bt_mesh_model_s *model_s;
3488 bt_mesh_element_s *element_s;
3489 bt_mesh_node_s *node_s;
3490 bt_mesh_network_s *network_s;
3491 bt_mesh_group_s *group_s;
3492 bluetooth_mesh_model_configure_t req;
3495 BT_CHECK_MESH_SUPPORT();
3496 BT_CHECK_MESH_INIT_STATUS();
3497 BT_CHECK_INPUT_PARAMETER(model);
3498 BT_CHECK_INPUT_PARAMETER(group);
3499 BT_CHECK_INPUT_PARAMETER(callback);
3501 model_s = (bt_mesh_model_s*) model;
3502 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3504 group_s = (bt_mesh_group_s*) group;
3505 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3507 element_s = (bt_mesh_element_s*) model_s->parent;
3508 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3510 node_s = (bt_mesh_node_s*) element_s->parent;
3511 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3513 network_s = (bt_mesh_network_s*) node_s->parent;
3514 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3516 BT_INFO("Mesh: Configure Virtual Group Request [%d]", model_op);
3517 BT_INFO("Mesh: Group Addr [0x%2.2x] Is Virtual [%s]",
3518 group_s->addr, group_s->is_virtual? "YES" : "NO");
3520 /* Check group belongs to the same network */
3521 if (network_s != group_s->parent)
3522 return BT_ERROR_INVALID_PARAMETER;
3524 /* Check group is non virtual */
3525 if (!group_s->is_virtual)
3526 return BT_ERROR_INVALID_PARAMETER;
3528 /* Return error, if node is not attached */
3529 if (!node_s->is_attached)
3530 return BT_ERROR_INVALID_PARAMETER;
3532 if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
3533 req.sub_addr = group_s->addr;
3534 req.is_virtual_sub = true;
3536 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3537 req.primary_unicast = node_s->unicast;
3538 req.elem_index = element_s->index;
3539 req.model = model_s->id;
3541 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_virtual_group_sub(&req));
3542 if (error_code != BT_ERROR_NONE) {
3543 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3548 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_VIR_SUB, callback, user_data);
3552 int bt_mesh_model_get_subscription_list(bt_mesh_model_h model,
3553 bt_mesh_model_subscription_list_cb callback, void *user_data)
3555 int error_code = BT_ERROR_NONE;
3556 bt_mesh_model_s *model_s;
3557 bt_mesh_element_s *element_s;
3558 bt_mesh_node_s *node_s;
3559 bt_mesh_network_s *network_s;
3560 bluetooth_mesh_model_configure_t req;
3563 BT_CHECK_MESH_SUPPORT();
3564 BT_CHECK_MESH_INIT_STATUS();
3565 BT_CHECK_INPUT_PARAMETER(model);
3566 BT_CHECK_INPUT_PARAMETER(callback);
3568 model_s = (bt_mesh_model_s*) model;
3569 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3571 element_s = (bt_mesh_element_s*) model_s->parent;
3572 BT_CHECK_INPUT_PARAMETER(element_s);
3573 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3575 node_s = (bt_mesh_node_s*) element_s->parent;
3576 BT_CHECK_INPUT_PARAMETER(node_s);
3577 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3579 network_s = (bt_mesh_network_s*) node_s->parent;
3580 BT_CHECK_INPUT_PARAMETER(network_s);
3581 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3583 /* Return error, if node is not attached */
3584 if (!node_s->is_attached)
3585 return BT_ERROR_INVALID_PARAMETER;
3587 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3589 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3590 req.primary_unicast = node_s->unicast;
3591 req.elem_index = element_s->index;
3592 req.model = model_s->id;
3594 error_code = _bt_get_error_code(bluetooth_mesh_model_get_subscriptopn_list(&req));
3595 if (error_code != BT_ERROR_NONE) {
3596 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3601 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_SUB_LIST, callback, user_data);
3605 int bt_mesh_model_set_publication(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
3606 bt_mesh_group_h group,
3607 bt_mesh_model_pub_params_s *params,
3608 bt_mesh_model_publication_status_cb callback,
3611 int error_code = BT_ERROR_NONE;
3612 bt_mesh_model_s *model_s;
3613 bt_mesh_element_s *element_s;
3614 bt_mesh_node_s *node_s;
3615 bt_mesh_appkey_s *appkey_s;
3616 bt_mesh_network_s *network_s;
3617 bt_mesh_group_s *group_s;
3618 bluetooth_mesh_model_configure_t req;
3621 BT_CHECK_MESH_SUPPORT();
3622 BT_CHECK_MESH_INIT_STATUS();
3623 BT_CHECK_INPUT_PARAMETER(model);
3624 BT_CHECK_INPUT_PARAMETER(appkey);
3625 BT_CHECK_INPUT_PARAMETER(group);
3626 BT_CHECK_INPUT_PARAMETER(params);
3627 BT_CHECK_INPUT_PARAMETER(callback);
3629 model_s = (bt_mesh_model_s*) model;
3630 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3632 appkey_s = (bt_mesh_appkey_s*) appkey;
3633 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3635 group_s = (bt_mesh_group_s*) group;
3636 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3638 element_s = (bt_mesh_element_s*) model_s->parent;
3639 BT_CHECK_INPUT_PARAMETER(element_s);
3640 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3642 node_s = (bt_mesh_node_s*) element_s->parent;
3643 BT_CHECK_INPUT_PARAMETER(node_s);
3644 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3646 network_s = (bt_mesh_network_s*) node_s->parent;
3647 BT_CHECK_INPUT_PARAMETER(network_s);
3648 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3650 if (group_s->parent != network_s)
3651 return BT_ERROR_INVALID_PARAMETER;
3653 if (params->num_steps > BT_MESH_MAX_PUBISH_PERIOD_STEPS)
3654 return BT_ERROR_INVALID_PARAMETER;
3655 if (params->retrans_cnt > BT_MESH_MAX_PUBISH_RETRANSMIT_COUNT)
3656 return BT_ERROR_INVALID_PARAMETER;
3657 if (params->retrans_step > BT_MESH_MAX_PUBISH_RETRANSMIT_INTERVAL_STEPS)
3658 return BT_ERROR_INVALID_PARAMETER;
3660 /* Return error, if node is not attached */
3661 if (!node_s->is_attached)
3662 return BT_ERROR_INVALID_PARAMETER;
3664 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3666 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3667 req.primary_unicast = node_s->unicast;
3668 req.elem_index = element_s->index;
3669 req.model = model_s->id;
3670 req.appkey_idx = appkey_s->appkey_index;
3671 req.pub_addr = group_s->addr;
3673 req.ttl = params->ttl;
3674 req.period = params->num_steps;
3675 req.period = req.period << 2;
3676 req.period |= params->per_res;
3677 req.retransmit = params->retrans_cnt;
3678 req.retransmit = req.retransmit << 5;
3679 req.retransmit |= params->retrans_step;
3681 error_code = _bt_get_error_code(bluetooth_mesh_model_set_publication(&req));
3682 if (error_code != BT_ERROR_NONE) {
3683 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3688 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);
3692 int bt_mesh_model_get_publication(bt_mesh_model_h model,
3693 bt_mesh_model_publication_status_cb callback, void *user_data)
3695 int error_code = BT_ERROR_NONE;
3696 bt_mesh_model_s *model_s;
3697 bt_mesh_element_s *element_s;
3698 bt_mesh_node_s *node_s;
3699 bt_mesh_network_s *network_s;
3700 bluetooth_mesh_model_configure_t req;
3703 BT_CHECK_MESH_SUPPORT();
3704 BT_CHECK_MESH_INIT_STATUS();
3705 BT_CHECK_INPUT_PARAMETER(model);
3706 BT_CHECK_INPUT_PARAMETER(callback);
3708 model_s = (bt_mesh_model_s*) model;
3709 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3711 element_s = (bt_mesh_element_s*) model_s->parent;
3712 BT_CHECK_INPUT_PARAMETER(element_s);
3713 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3715 node_s = (bt_mesh_node_s*) element_s->parent;
3716 BT_CHECK_INPUT_PARAMETER(node_s);
3717 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3719 network_s = (bt_mesh_network_s*) node_s->parent;
3720 BT_CHECK_INPUT_PARAMETER(network_s);
3721 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3723 /* Return error, if node is not attached */
3724 if (!node_s->is_attached)
3725 return BT_ERROR_INVALID_PARAMETER;
3727 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3729 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3730 req.primary_unicast = node_s->unicast;
3731 req.elem_index = element_s->index;
3732 req.model = model_s->id;
3734 error_code = _bt_get_error_code(bluetooth_mesh_model_get_publication(&req));
3735 if (error_code != BT_ERROR_NONE) {
3736 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3741 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);