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_NETWORKS 5
35 #define BT_MESH_MAX_ELEMENTS 32767
36 #define BT_MESH_MAX_MODELS 32767
37 #define BT_MESH_MAX_NODES 32767
38 #define BT_MESH_MAX_SUBNETS 4096
40 #define BT_MESH_FIXED_GROUP_LOW 0xff00
41 #define BT_MESH_FIXED_GROUP_HIGH 0xffff
42 #define BT_MESH_ALL_NODES_ADDRESS 0xffff
43 #define BT_MESH_VIRTUAL_ADDRESS_LOW 0x8000
44 #define BT_MESH_VIRTUAL_ADDRESS_HIGH 0xbfff
45 #define BT_MESH_GROUP_ADDRESS_LOW 0xc000
46 #define BT_MESH_GROUP_ADDRESS_HIGH 0xfeff
48 #define BT_MESH_IS_GROUP(x) ((((x) >= BT_MESH_GROUP_ADDRESS_LOW) && \
49 ((x) < BT_MESH_FIXED_GROUP_HIGH)) || \
50 ((x) == BT_MESH_ALL_NODES_ADDRESS))
52 static bool is_mesh_initialized = false;
54 /**< List of Local handles >*/
64 #define BT_CHECK_MESH_SUPPORT() \
66 BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
67 BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \
68 BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_MESH); \
71 #define BT_CHECK_MESH_INIT_STATUS() \
72 if (__bt_check_mesh_init_status() == BT_ERROR_NOT_INITIALIZED) { \
73 LOGE("[%s] NOT_INITIALIZED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_INITIALIZED); \
74 return BT_ERROR_NOT_INITIALIZED; \
78 #define BT_CHECK_MESH_REMOTE(handle) \
79 { if (handle->is_local) return BT_ERROR_OPERATION_FAILED; }
82 #define BT_CHECK_MESH_LOCAL(handle) \
83 { if (!handle->is_local) return BT_ERROR_OPERATION_FAILED; }
86 #define BT_CHECK_MESH_IS_ATTACHED(handle) \
87 { if (handle->is_attached) return BT_ERROR_OPERATION_FAILED; }
89 #define BT_MESH_VALIDATE_HANDLE(h1, list) \
93 for (l = list; l; l = g_slist_next(l)) { \
94 void *h2 = (void *)l->data; \
96 BT_INFO("Handle matched [%p]", h2); \
97 valid = TRUE; break; \
100 if (valid == FALSE) { \
101 BT_ERR("Handle [%p] did not match with any stored handles!!", h1); \
102 return BT_ERROR_INVALID_PARAMETER; \
106 size_t __bt_mesh_util_convert_hex_to_string(uint8_t *in,
107 size_t in_len, char *out, size_t out_len)
109 static const char hexdigits[] = "0123456789abcdef";
112 if (in_len * 2 > (out_len - 1))
115 for (i = 0; i < in_len; i++) {
116 out[i * 2] = hexdigits[in[i] >> 4];
117 out[i * 2 + 1] = hexdigits[in[i] & 0xf];
120 out[in_len * 2] = '\0';
124 static int __compare_group_address(gconstpointer a, gconstpointer b)
126 const bt_mesh_group_s *group = a;
127 uint16_t addr = GPOINTER_TO_UINT(b);
129 return (group->addr - addr);
132 static int __compare_node_primary_unicast(gconstpointer a, gconstpointer b)
134 const bt_mesh_node_s *node = a;
135 uint16_t index = GPOINTER_TO_UINT(b);
137 return (node->unicast - index);
140 static int __compare_node_element_index(gconstpointer a, gconstpointer b)
142 const bt_mesh_element_s *element = a;
143 int index = GPOINTER_TO_UINT(b);
145 return (element->index - index);
148 static int __compare_network_group_address(gconstpointer a, gconstpointer b)
150 const bt_mesh_group_s *group = a;
151 uint16_t group_addr = GPOINTER_TO_UINT(b);
153 return (group->addr - group_addr);
156 static int __compare_model_id(gconstpointer a, gconstpointer b)
158 const bt_mesh_model_s *model_s = a;
159 uint32_t model = GPOINTER_TO_UINT(b);
161 return (model_s->id - model);
164 static int __compare_netkey_index(gconstpointer a, gconstpointer b)
166 const bt_mesh_netkey_s *nk = a;
167 uint16_t netkey_index = GPOINTER_TO_UINT(b);
169 return (nk->netkey_index - netkey_index);
172 static int __simple_compare(gconstpointer a, gconstpointer b)
180 static int __compare_appkey_index(gconstpointer a, gconstpointer b)
182 const bt_mesh_appkey_s *ak = a;
183 uint16_t appkey_index = GPOINTER_TO_UINT(b);
185 return (ak->appkey_index - appkey_index);
188 static int __compare_element_index(gconstpointer a, gconstpointer b)
190 const bt_mesh_element_s *elem = a;
191 uint16_t element_index = GPOINTER_TO_UINT(b);
193 return (elem->index - element_index);
196 static bt_mesh_netkey_s * __bt_mesh_network_is_netkey_added(
197 bt_mesh_network_s *network_s, uint16_t netkey_idx)
201 l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
202 (GCompareFunc)__compare_netkey_index);
206 return (bt_mesh_netkey_s*) l->data;
209 bt_mesh_element_s *_bt_mesh_get_element_from_index(
210 bt_mesh_node_s *node_s, int element_index)
214 l = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(element_index),
215 (GCompareFunc)__compare_element_index);
219 return (bt_mesh_element_s*) l->data;
222 bt_mesh_appkey_s *_bt_mesh_network_get_appkey_from_index(
223 bt_mesh_network_s *network_s, uint16_t appkey_idx)
227 for (l = network_s->netkeys; l; l = l->next) {
228 bt_mesh_netkey_s *netkey_s = l->data;
230 l1 = g_slist_find_custom(netkey_s->appkeys, GUINT_TO_POINTER(appkey_idx),
231 (GCompareFunc)__compare_appkey_index);
239 bt_mesh_model_s *_bt_mesh_get_model_from_modelid(
240 bt_mesh_element_s *element_s, uint32_t modelid)
244 l = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(modelid),
245 (GCompareFunc)__compare_model_id);
249 return (bt_mesh_model_s*) l->data;
252 bt_mesh_group_s* _bt_mesh_network_get_group(
253 bt_mesh_network_s *network_s, uint16_t group_addr)
256 bt_mesh_group_s *group_s = NULL;
258 /* Unassigned address */
259 if (group_addr == 0x0000)
262 l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(group_addr),
263 (GCompareFunc) __compare_network_group_address);
266 BT_INFO("Mesh: Group not available in Network: Addr[0x%2.2x]",
268 group_s = g_malloc0(sizeof(bt_mesh_group_s));
269 group_s->addr = group_addr;
270 if (!BT_MESH_IS_GROUP(group_addr))
271 group_s->is_virtual = true;
273 group_s->is_virtual = false;
274 group_s->parent = network_s;
276 if (g_slist_append(network_s->groups, group_s))
277 BT_INFO("Mesh: Group created");
279 group_list = g_slist_append(group_list, group_s);
286 bt_mesh_appkey_s* _bt_mesh_node_get_appkey(
287 bt_mesh_node_s *node_s, uint16_t appkey_idx)
291 l = g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(appkey_idx),
292 (GCompareFunc)__compare_appkey_index);
296 return (bt_mesh_appkey_s*) l->data;
299 static bt_mesh_appkey_s *__bt_mesh_network_is_appkey_added(
300 bt_mesh_network_s *network_s,
305 const bt_mesh_netkey_s *netkey;
307 l = g_slist_find_custom(network_s->netkeys, GUINT_TO_POINTER(netkey_idx),
308 (GCompareFunc)__compare_netkey_index);
313 l1 = g_slist_find_custom(netkey->appkeys, GUINT_TO_POINTER(appkey_idx),
314 (GCompareFunc)__compare_appkey_index);
318 return (bt_mesh_appkey_s*) l1->data;
321 int __bt_check_mesh_init_status(void)
323 if (is_mesh_initialized != true) {
324 BT_ERR("NOT_INITIALIZED(0x%08x)", BT_ERROR_NOT_INITIALIZED);
325 return BT_ERROR_NOT_INITIALIZED;
328 return BT_ERROR_NONE;
332 static void __bt_mesh_free_models(void *data)
334 bt_mesh_model_s *model = (bt_mesh_model_s*)data;
335 model_list = g_slist_remove(model_list, model);
339 static void __bt_mesh_free_elements(void *data)
341 bt_mesh_element_s *elem = (bt_mesh_element_s*)data;
342 element_list = g_slist_remove(element_list, elem);
343 g_slist_free_full(elem->models, __bt_mesh_free_models);
347 static gint __bt_mesh_compare_net_uuid(gpointer *a, gpointer *b)
349 bt_mesh_network_s *net = (bt_mesh_network_s *)a;
350 char *net_uuid = (char *)b;
351 return g_strcmp0(net->uuid, net_uuid);
355 static void __bt_mesh_insert_elements_in_node(
356 bt_mesh_node_s *node, uint16_t unicast,
357 int num_elements, bool is_local)
359 bt_mesh_element_s *element_s;
361 for (int i = 0; i < num_elements; i++) {
362 element_s = g_malloc0(sizeof(bt_mesh_element_s));
363 element_s->is_local = is_local;
364 element_s->parent = node;
365 element_s->index = i;
366 node->elements = g_slist_append(node->elements, element_s);
367 element_list = g_slist_append(element_list, element_s);
371 bt_mesh_appkey_s *_bt_mesh_handle_node_appkey_configure(
372 bt_mesh_network_s *network_s,
373 bt_mesh_node_s *node_s, uint16_t netkey_idx,
375 bt_mesh_node_key_configuration_e op)
377 bt_mesh_appkey_s *appkey_s;
379 appkey_s = __bt_mesh_network_is_appkey_added(
380 network_s, netkey_idx, appkey_idx);
382 /* AppKey with index not found in network */
384 BT_ERR("Mesh: Exceptional case: AppKey not found in Network");
388 if (op == BT_MESH_NODE_KEY_ADD) {
389 if (!g_slist_find_custom(node_s->appkeys,(gconstpointer) appkey_s,
390 (GCompareFunc)__simple_compare)) {
391 node_s->appkeys = g_slist_append(node_s->appkeys, appkey_s);
393 BT_INFO("Mesh: AppKey Already added");
395 } else if (op == BT_MESH_NODE_KEY_DELETE) {
396 node_s->appkeys = g_slist_remove(node_s->appkeys, appkey_s);
398 } else /* Node NetKey update */
402 bt_mesh_netkey_s *_bt_mesh_handle_node_netkey_configure(
403 bt_mesh_network_s *network_s,
404 bt_mesh_node_s *node_s, uint16_t netkey_idx,
405 bt_mesh_node_key_configuration_e op)
407 bt_mesh_netkey_s *netkey_s;
409 netkey_s = __bt_mesh_network_is_netkey_added(network_s, netkey_idx);
411 /* Netkey with index not found in network */
413 BT_ERR("Mesh: Exceptional case: Netkey not found in Network");
417 if (op == BT_MESH_NODE_KEY_ADD) {
418 if (!g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_s,
419 (GCompareFunc)__simple_compare)) {
420 node_s->netkeys = g_slist_append(node_s->netkeys, netkey_s);
422 BT_INFO("Mesh: NetKey Already added");
424 } else if (op == BT_MESH_NODE_KEY_DELETE) {
425 node_s->netkeys = g_slist_remove(node_s->netkeys, netkey_s);
427 } else /* Node NetKey update */
431 bt_mesh_group_s * _bt_mesh_get_group_from_sub(
432 bt_mesh_network_s *network_s, bt_mesh_model_s *model_s,
433 bt_mesh_model_subscription_op_e op, uint16_t sub_addr)
436 bt_mesh_group_s *group_s = NULL;
437 l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(sub_addr),
438 (GCompareFunc) __compare_network_group_address);
442 if (op == BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
443 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL");
444 if (op == BT_MESH_MODEL_SUBSCRIPTION_ADD)
445 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_ADD");
446 if (op == BT_MESH_MODEL_SUBSCRIPTION_DELETE)
447 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_DELETE");
448 if (op == BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE)
449 BT_INFO("Mesh: Event for BT_MESH_MODEL_SUBSCRIPTION_OVERWRITE");
454 bt_mesh_model_s *_bt_mesh_get_node_get_model_from_element(
455 char *net_uuid, uint16_t unicast,
456 int elem_idx, uint32_t model)
458 GSList *l, *l1, *l2, *l3;
459 bt_mesh_network_s *network_s;
460 bt_mesh_node_s *node_s;
461 bt_mesh_element_s *element_s;
463 l = g_slist_find_custom(networks, net_uuid,
464 (GCompareFunc)__bt_mesh_compare_net_uuid);
468 network_s = (bt_mesh_network_s*) l->data;
470 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
471 (GCompareFunc)__compare_node_primary_unicast);
475 node_s = (bt_mesh_node_s*) l1->data;
477 l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
478 (GCompareFunc)__compare_node_element_index);
482 element_s = (bt_mesh_element_s*) l2->data;
485 l3 = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(model),
486 (GCompareFunc) __compare_model_id);
490 return (bt_mesh_model_s*) l3->data;
493 bt_mesh_element_s * _bt_mesh_get_node_get_element_from_index(char *net_uuid,
494 uint16_t unicast, int elem_idx)
497 bt_mesh_network_s *network_s;
498 bt_mesh_node_s *node_s;
500 l = g_slist_find_custom(networks, net_uuid,
501 (GCompareFunc)__bt_mesh_compare_net_uuid);
507 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
508 (GCompareFunc)__compare_node_primary_unicast);
514 l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
515 (GCompareFunc)__compare_node_element_index);
519 return (bt_mesh_element_s*) l->data;
522 bt_mesh_node_s *_bt_mesh_get_node_from_unicast(char *net_uuid, uint16_t unicast)
525 bt_mesh_network_s *network_s;
526 bt_mesh_node_s *node_s;
528 l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
534 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
535 (GCompareFunc)__compare_node_primary_unicast);
543 bt_mesh_node_s *_bt_mesh_remote_node_browsed(char *net_uuid, char *dev_uuid,
544 uint16_t unicast, int count)
547 bt_mesh_network_s *network_s;
548 bt_mesh_node_s *node_s;
550 l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
556 l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
557 (GCompareFunc)__compare_node_primary_unicast);
560 g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
562 node_s = g_malloc0(sizeof(bt_mesh_node_s));
563 node_s->parent = network_s;
564 node_s->unicast = unicast;
565 node_s->is_attached = true;
566 if (node_s->unicast == 0x0001) {
567 node_s->is_local = true;
568 node_s->is_provisioner = true;
570 g_strlcpy(node_s->uuid, dev_uuid, sizeof(node_s->uuid));
571 __bt_mesh_insert_elements_in_node(node_s, unicast,
572 count, node_s->is_local? true : false);
573 network_s->nodes = g_slist_append(network_s->nodes, node_s);
574 node_list = g_slist_append(node_list, node_s);
579 bt_mesh_network_s * _bt_mesh_get_network_handle_info(char *net_uuid)
583 l = g_slist_find_custom(networks, net_uuid, (GCompareFunc)__bt_mesh_compare_net_uuid);
587 return (bt_mesh_network_s*)l->data;
590 char * _bt_mesh_get_auth_string_from_value(int auth)
593 case BT_MESH_AUTH_ALPHANUMERIC_DISPLAY:
594 BT_INFO("Mesh: ALPHANUMERIC_DISPLAY");
595 return "ALPHANUMERIC_DISPLAY";
596 case BT_MESH_AUTH_NUMERIC_DISPLAY:
597 BT_INFO("Mesh: NUMERIC_DISPLAY");
598 return "NUMERIC_DISPLAY";
599 case BT_MESH_AUTH_PUSH_COUNT_DISPLAY:
600 BT_INFO("Mesh: PUSH_COUNT_DISPLAY");
601 return "PUSH_COUNT_DISPLAY";
602 case BT_MESH_AUTH_TWIST_COUNT_DISPLAY:
603 BT_INFO("Mesh: TWIST_COUNT_DISPLAY");
604 return "TWIST_COUNT_DISPLAY";
606 /*< Input authentication request types */
607 case BT_MESH_AUTH_REQ_ALPHANUMERIC_INPUT:
608 BT_INFO("Mesh: REQ_ALPHANUMERIC_INPUT");
609 return "REQ_ALPHANUMERIC_INPUT";
610 case BT_MESH_AUTH_REQ_NUMERIC_INPUT:
611 BT_INFO("Mesh: REQ_NUMERIC_INPUT");
612 return "REQ_NUMERIC_INPUT";
613 case BT_MESH_AUTH_REQ_BLINK_COUNT_INPUT:
614 BT_INFO("Mesh: REQ_BLINK_COUNT_INPUT");
615 return "REQ_BLINK_COUNT_INPUT";
616 case BT_MESH_AUTH_REQ_BEEP_COUNT_INPUT:
617 BT_INFO("Mesh: REQ_BEEP_COUNT_INPUT");
618 return "REQ_BEEP_COUNT_INPUT";
619 case BT_MESH_AUTH_REQ_VIBRATE_COUNT_INPUT:
620 BT_INFO("Mesh: REQ_VIBRATE_COUNT_INPUT");
621 return "REQ_VIBRATE_COUNT_INPUT";
623 /**< OOB Key Inputs */
624 case BT_MESH_AUTH_REQ_OOB_PUBLIC_KEY_INPUT:
625 BT_INFO("Mesh: OOB_PUBLIC_KEY_INPUT");
626 return "OOB_PUBLIC_KEY_INPUT";
627 case BT_MESH_AUTH_REQ_OOB_STATIC_KEY_INPUT:
628 BT_INFO("Mesh: OOB_STATIC_KEY_INPUT");
629 return "OOB_STATIC_KEY_INPUT";
636 int bt_mesh_initialize(void)
639 BT_CHECK_MESH_SUPPORT();
641 int ret = BT_ERROR_NONE;
643 BT_INFO("Is Mesh initialized:[%s]",
644 is_mesh_initialized ? "TRUE": "FALSE");
646 if (is_mesh_initialized) {
647 BT_ERR("Mesh is initialized");
648 return BT_ERROR_NONE;
651 if (!is_mesh_initialized) {
652 ret = _bt_get_error_code(bluetooth_mesh_init(
653 _bt_mesh_event_proxy, NULL));
655 if (ret != BT_ERROR_NONE) {
657 _bt_convert_error_to_string(ret), ret);
658 return BT_ERROR_OPERATION_FAILED;
661 is_mesh_initialized = true;
662 return BT_ERROR_NONE;
665 BT_INFO("Mesh is already initialized");
668 return BT_ERROR_NONE;
671 int bt_mesh_deinitialize(void)
674 BT_CHECK_MESH_SUPPORT();
675 BT_CHECK_MESH_INIT_STATUS();
678 error = bluetooth_mesh_deinit();
679 error = _bt_get_error_code(error);
680 if (BT_ERROR_NONE != error)
681 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error);
683 is_mesh_initialized = false;
686 return BT_ERROR_NONE;
689 int bt_mesh_node_create(bt_mesh_node_features_s *features,
690 bt_mesh_node_h *node_handle)
693 bt_mesh_node_s *node = NULL;
695 BT_CHECK_MESH_SUPPORT();
696 BT_CHECK_MESH_INIT_STATUS();
697 BT_CHECK_INPUT_PARAMETER(node_handle);
698 BT_CHECK_INPUT_PARAMETER(features);
700 node = g_malloc0(sizeof(bt_mesh_node_s));
702 BT_ERR("g_malloc0 failed");
703 return BT_ERROR_OUT_OF_MEMORY;
706 node->is_local = true;
707 node->features = *features;
708 node->unicast = 0x0001;
710 node_list = g_slist_append(node_list, node);
711 *node_handle = (bt_mesh_node_h)node;
714 return BT_ERROR_NONE;
717 int bt_mesh_node_destroy(bt_mesh_node_h node_handle)
721 BT_CHECK_MESH_SUPPORT();
722 BT_CHECK_MESH_INIT_STATUS();
723 BT_CHECK_INPUT_PARAMETER(node_handle);
725 bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
727 BT_MESH_VALIDATE_HANDLE(node, node_list);
729 /* It is NOT allowed to destroy attached node: Do Reset */
730 BT_CHECK_MESH_IS_ATTACHED(node);
732 node_list = g_slist_remove(node_list, node);
733 g_slist_free_full(node->elements, __bt_mesh_free_elements);
737 return BT_ERROR_NONE;
740 static void __bt_mesh_generate_element(bt_mesh_node_s *node_s,
741 bt_mesh_element_s *elem_s)
746 for (l = node_s->elements; l; l = l->next) {
747 bt_mesh_element_s *el = (bt_mesh_element_s*)l->data;
748 if (el->index != index)
752 elem_s->index = index;
753 node_s->elements = g_slist_insert(node_s->elements, elem_s, index);
756 int bt_mesh_node_create_element(bt_mesh_node_h node_handle,
757 bt_mesh_element_h *element_handle)
760 BT_CHECK_MESH_SUPPORT();
761 BT_CHECK_MESH_INIT_STATUS();
762 BT_CHECK_INPUT_PARAMETER(node_handle);
763 BT_CHECK_INPUT_PARAMETER(element_handle);
765 bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
766 bt_mesh_element_s *element = NULL;
768 BT_INFO("Mesh: Element creation request");
769 BT_MESH_VALIDATE_HANDLE(node, node_list);
771 /* It is NOT allowed to add an element to a already attached node */
772 BT_CHECK_MESH_IS_ATTACHED(node);
774 /* Check num elements already present in the node */
775 if (g_slist_length(node->elements) >= BT_MESH_MAX_ELEMENTS)
776 return BT_ERROR_QUOTA_EXCEEDED;
779 element = g_malloc0(sizeof(bt_mesh_element_s));
781 BT_ERR("g_malloc0 failed");
782 return BT_ERROR_OUT_OF_MEMORY;
785 element->is_local = true;
786 element->parent = node;
788 __bt_mesh_generate_element(node, element);
789 element_list = g_slist_append(element_list, element);
790 *element_handle = (bt_mesh_element_h)element;
792 BT_INFO("Mesh: Element created successfully: element index [%d]", element->index);
794 return BT_ERROR_NONE;
797 int bt_mesh_element_destroy(bt_mesh_element_h element_handle)
800 BT_CHECK_MESH_SUPPORT();
801 BT_CHECK_MESH_INIT_STATUS();
802 BT_CHECK_INPUT_PARAMETER(element_handle);
803 BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
805 bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
806 bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
808 /* It is NOT allowed to destroy remote element */
809 BT_CHECK_MESH_LOCAL(node);
811 /* It is NOT allowed to destroy an attahced element */
812 BT_CHECK_MESH_IS_ATTACHED(node);
814 element_list = g_slist_remove(element_list, element);
815 node->elements = g_slist_remove(node->elements, element);
817 g_slist_free_full(element->models, __bt_mesh_free_models);
821 return BT_ERROR_NONE;
824 int bt_mesh_element_create_model(
825 bt_mesh_element_h element_handle,
826 bt_mesh_model_id_s *model_id,
827 bt_mesh_model_h *model_handle)
831 bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
832 bt_mesh_model_s *model = NULL;
834 BT_CHECK_MESH_SUPPORT();
835 BT_CHECK_MESH_INIT_STATUS();
836 BT_CHECK_INPUT_PARAMETER(element_handle);
837 BT_CHECK_INPUT_PARAMETER(model_id);
838 BT_CHECK_INPUT_PARAMETER(model_handle);
839 BT_MESH_VALIDATE_HANDLE(element_handle, element_list);
841 bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)element_handle)->parent;
843 /* It is NOT allowed to add model to a remote element */
844 BT_CHECK_MESH_LOCAL(node);
846 /* It is NOT allowed to add a Model to a already attached node */
847 BT_CHECK_MESH_IS_ATTACHED(node);
849 BT_INFO("Mesh: Model creation request: Company ID [0x%2.2x] Model ID [0x%2.2x]",
850 model_id->company_id, model_id->model_id);
852 mod_id = model_id->company_id;
854 mod_id |= model_id->model_id;
855 /* Allow configuration server model only in primary element */
856 if ((model_id->model_id == BT_MESH_MODEL_ID_CFG_SRV) &&
858 return BT_ERROR_OPERATION_FAILED;
860 /* Check num models already present in the element */
861 if (g_slist_length(element->models) >= BT_MESH_MAX_MODELS)
862 return BT_ERROR_QUOTA_EXCEEDED;
864 /* Don't allow multiple instance of same model in an element */
865 if (g_slist_find_custom(element->models, GUINT_TO_POINTER(mod_id),
866 (GCompareFunc)__compare_model_id))
867 return BT_ERROR_ALREADY_DONE;
869 model = g_malloc0(sizeof(bt_mesh_model_s));
871 BT_ERR("g_malloc0 failed");
872 return BT_ERROR_OUT_OF_MEMORY;
875 model->is_local = true;
876 model->parent = element;
879 BT_INFO("Mesh: Model ID [0x%2.2x]", model_id->model_id);
880 BT_INFO("Mesh: Company ID [0x%2.2x]", model_id->company_id);
881 BT_INFO("Mesh: MOD [0x%4.4x]", model->id);
883 model_list = g_slist_append(model_list, model);
884 element->models = g_slist_append(element->models, model);
885 *model_handle = (bt_mesh_model_h)model;
887 BT_INFO("Mesh: Model created successfully");
889 return BT_ERROR_NONE;
892 int bt_mesh_model_destroy(bt_mesh_model_h model_handle)
896 BT_CHECK_MESH_SUPPORT();
897 BT_CHECK_MESH_INIT_STATUS();
898 BT_CHECK_INPUT_PARAMETER(model_handle);
900 bt_mesh_node_s *node = (bt_mesh_node_s*)((bt_mesh_element_s*)((bt_mesh_model_s*)model_handle)->parent)->parent;
901 bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
902 bt_mesh_element_s *element = model->parent;
904 BT_MESH_VALIDATE_HANDLE(model, model_list);
905 BT_MESH_VALIDATE_HANDLE(element, element_list);
907 /* It is NOT allowed to destroy remote model */
908 BT_CHECK_MESH_LOCAL(node);
910 /* It is NOT allowed to destroy an attahced model */
911 BT_CHECK_MESH_IS_ATTACHED(node);
913 model_list = g_slist_remove(model_list, model);
914 element->models = g_slist_remove(element->models, model);
918 return BT_ERROR_NONE;
921 int bt_mesh_model_get_id(bt_mesh_model_h model_handle,
922 bt_mesh_model_id_s *model_id)
926 BT_CHECK_MESH_SUPPORT();
927 BT_CHECK_MESH_INIT_STATUS();
928 BT_CHECK_INPUT_PARAMETER(model_handle);
929 BT_CHECK_INPUT_PARAMETER(model_id);
931 bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
932 BT_MESH_VALIDATE_HANDLE(model, model_list);
934 BT_INFO("Mesh: Model ID [0x%4.4x]", model->id);
935 model_id->company_id = model->id >> 16;
936 model_id->model_id = model->id;
937 BT_INFO("Mesh: CID [0x%2.2x]", model_id->company_id);
938 BT_INFO("Mesh: MID [0x%2.2x]", model_id->model_id);
941 return BT_ERROR_NONE;
944 int bt_mesh_node_get_network(bt_mesh_node_h node_handle, bt_mesh_network_h *network)
948 BT_CHECK_MESH_SUPPORT();
949 BT_CHECK_MESH_INIT_STATUS();
950 BT_CHECK_INPUT_PARAMETER(node_handle);
951 BT_CHECK_INPUT_PARAMETER(network);
953 bt_mesh_node_s *node = (bt_mesh_node_s*)node_handle;
954 BT_MESH_VALIDATE_HANDLE(node_handle, node_list);
956 *network = node->parent;
959 return BT_ERROR_NONE;
962 int bt_mesh_element_get_node(bt_mesh_element_h element_handle,
963 bt_mesh_node_h *node)
967 BT_CHECK_MESH_SUPPORT();
968 BT_CHECK_MESH_INIT_STATUS();
969 BT_CHECK_INPUT_PARAMETER(element_handle);
970 BT_CHECK_INPUT_PARAMETER(node);
972 bt_mesh_element_s *element = (bt_mesh_element_s*)element_handle;
973 BT_MESH_VALIDATE_HANDLE(element, element_list);
975 *node = element->parent;
978 return BT_ERROR_NONE;
981 int bt_mesh_model_get_element(bt_mesh_model_h model_handle,
982 bt_mesh_element_h *element)
986 BT_CHECK_MESH_SUPPORT();
987 BT_CHECK_MESH_INIT_STATUS();
988 BT_CHECK_INPUT_PARAMETER(model_handle);
989 BT_CHECK_INPUT_PARAMETER(element);
991 bt_mesh_model_s *model = (bt_mesh_model_s*)model_handle;
992 BT_MESH_VALIDATE_HANDLE(model, model_list);
994 *element = model->parent;
997 return BT_ERROR_NONE;
1000 int bt_mesh_appkey_get_netkey(bt_mesh_appkey_h appkey_handle,
1001 bt_mesh_netkey_h *netkey)
1005 BT_CHECK_MESH_SUPPORT();
1006 BT_CHECK_MESH_INIT_STATUS();
1007 BT_CHECK_INPUT_PARAMETER(appkey_handle);
1008 BT_CHECK_INPUT_PARAMETER(netkey);
1010 bt_mesh_appkey_s *appkey = (bt_mesh_appkey_s*)appkey_handle;
1011 BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
1013 *netkey = appkey->parent;
1016 return BT_ERROR_NONE;
1019 /* Async API's to bt-service & stack */
1020 int bt_mesh_network_create(bt_mesh_node_h config_client,
1021 const char *network_name,
1022 bt_mesh_network_h *network, char **token)
1025 int error_code = BT_ERROR_NONE;
1030 bluetooth_mesh_network_t net;
1031 bluetooth_mesh_node_t param_node;
1032 bluetooth_mesh_model_t **param_model;
1033 bt_mesh_network_s *network_s;
1034 bt_mesh_netkey_s *netkey_s;
1036 BT_CHECK_MESH_SUPPORT();
1037 BT_CHECK_MESH_INIT_STATUS();
1038 BT_CHECK_INPUT_PARAMETER(config_client);
1039 BT_CHECK_INPUT_PARAMETER(network_name);
1040 BT_CHECK_INPUT_PARAMETER(network);
1041 BT_CHECK_INPUT_PARAMETER(token);
1043 BT_INFO("Mesh: Create Network: Name [%s]", network_name);
1044 bt_mesh_node_s *node = (bt_mesh_node_s*)config_client;
1046 BT_MESH_VALIDATE_HANDLE(node, node_list);
1048 /* Error if remote node*/
1049 BT_CHECK_MESH_LOCAL(node);
1051 /* It is NOT allowed to create network out of a already attahced node */
1052 BT_CHECK_MESH_IS_ATTACHED(node);
1054 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1056 if (strlen(network_name) >= BT_MESH_NETWORK_NAME_STRING_MAX_LEN)
1057 return BT_ERROR_INVALID_PARAMETER;
1059 /* Node in network should contain at-least one element */
1060 if (!g_slist_length(node->elements)) {
1061 BT_INFO("Mesh: No element present in Node: NOT ALLOWED!!");
1062 return BT_ERROR_INVALID_PARAMETER;
1065 /* Element in Node should contain at-least one Model */
1066 for (l1 = node->elements; l1 != NULL; l1 = l1->next) {
1067 bt_mesh_element_s *el = l1->data;
1069 models = g_slist_length(el->models);
1070 BT_INFO("Mesh: Num models element [%u] has is [%d]", el->index, models);
1072 BT_INFO("Mesh: No Model present in element: NOT ALLOWED!!");
1073 return BT_ERROR_INVALID_PARAMETER;
1075 /* If Primary element does not contain CFG SRV model, create and append */
1076 if (el->index == 0x0000) {
1077 uint32_t mod_id = 0xFFFF0000; /* CFG SRV */
1079 if (!g_slist_find_custom(el->models, GUINT_TO_POINTER(mod_id),
1080 (GCompareFunc)__compare_model_id)) {
1081 bt_mesh_model_s *model_s;
1082 BT_ERR("Mesh: Primary element does not contain CFG SRV Model:Add it!");
1083 model_s = g_malloc0(sizeof(bt_mesh_model_s));
1085 model_s->is_local = true;
1086 model_s->parent = el;
1087 model_s->id = mod_id;
1089 model_list = g_slist_append(model_list, model_s);
1090 el->models = g_slist_append(el->models, model_s);
1093 BT_INFO("Mesh: CFG SRV model is already added in primary element");
1095 num_models += models;
1098 /* Check currently created network */
1099 if (g_slist_length(networks) >= BT_MESH_MAX_NETWORKS)
1100 return BT_ERROR_QUOTA_EXCEEDED;
1102 memset(¶m_node, 0x00, sizeof(bluetooth_mesh_node_t));
1103 memcpy(¶m_node.vendor_info, &(node->features), sizeof(node->features));
1104 param_node.num_elements = g_slist_length(node->elements);
1105 param_node.primary_unicast = 0x0001;
1106 _bt_get_random_bytes(param_node.uuid, 16);
1108 BT_INFO("Mesh: Total Models [%d]", num_models);
1109 param_model = (bluetooth_mesh_model_t**)g_malloc0(num_models * sizeof(bluetooth_mesh_model_t*));
1111 for (l1 = node->elements, i = 0; l1 != NULL; l1 = l1->next, i++) {
1112 bt_mesh_element_s *e = l1->data;
1114 for (l2 = e->models, j = 0; l2 != NULL; l2 = l2->next, j++) {
1115 bt_mesh_model_s *m = l2->data;
1116 param_model[j+offset] = g_malloc0(sizeof(bluetooth_mesh_model_t));
1117 param_model[j+offset]->elem_index = i;
1118 param_model[j+offset]->model_id = m->id;
1121 offset += g_slist_length(e->models);
1124 BT_INFO("Mesh: Send Network create Request to FRWK");
1125 error_code = _bt_get_error_code(bluetooth_mesh_network_create(network_name, ¶m_node,
1126 num_models, param_model, &net));
1127 if (error_code != BT_ERROR_NONE) {
1128 BT_INFO("Mesh: Network could not be created!!");
1129 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1132 for (int i = 0; i < num_models; i++)
1133 g_free(param_model[i]);
1138 BT_INFO("Mesh: Network created successfully");
1140 /* Create Network object & fill data in network */
1141 network_s = g_malloc0(sizeof(bt_mesh_network_s));
1142 network_s->num_nodes = 1;
1143 network_s->is_local = true;
1144 network_s->is_discovered = true;
1146 /* Fill network name, token & UUID */
1147 __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid, 16,
1148 network_s->uuid, sizeof(network_s->uuid));
1149 g_strlcpy(network_s->token, net.token.token, 17);
1150 g_strlcpy(network_s->name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1151 network_s->nodes = g_slist_append(network_s->nodes, node);
1152 BT_INFO("Mesh: Network Name [%s]", network_s->name);
1153 BT_INFO("Mesh: Network Token[%s]", network_s->token);
1154 BT_INFO("Mesh: Network UUID [%s]", network_s->uuid);
1156 /* Create primary Netkey object */
1157 netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
1158 netkey_s->parent = network_s;
1159 netkey_s->netkey_index = 0x0000; /* Primary index */
1160 network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
1161 netkey_list = g_slist_append(netkey_list, netkey_s);
1163 /* Fill Config Client Node Data */
1164 node->is_attached = true;
1165 node->is_provisioner = true;
1166 __bt_mesh_util_convert_hex_to_string((uint8_t *)param_node.uuid,
1167 16, node->uuid, sizeof(node->uuid));
1168 node->unicast = 0x0001;
1169 node->parent = network_s;
1171 /* Prepare Out parameters */
1172 *token = network_s->token;
1173 *network = (bt_mesh_network_h)network_s;
1175 /* Save network in list */
1176 networks = g_slist_append(networks, network_s);
1178 /* Clean up memory */
1179 for (int i = 0; i < num_models; i++)
1180 g_free(param_model[i]);
1186 int bt_mesh_network_load(const char *token, bt_mesh_network_h *network)
1188 int error_code = BT_ERROR_NONE;
1189 bluetooth_mesh_network_t net;
1190 bt_mesh_network_s *network_s;
1192 BT_CHECK_MESH_SUPPORT();
1193 BT_CHECK_MESH_INIT_STATUS();
1194 BT_CHECK_INPUT_PARAMETER(token);
1195 BT_CHECK_INPUT_PARAMETER(network);
1197 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1198 error_code = _bt_get_error_code(bluetooth_mesh_network_load(token, &net));
1199 if (error_code != BT_ERROR_NONE) {
1200 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1204 /* Create Network object */
1205 network_s = g_malloc0(sizeof(bt_mesh_network_s));
1206 network_s->is_local = true;
1207 g_strlcpy(network_s->uuid, net.uuid, 33);
1208 g_strlcpy(network_s->token, token, 17);
1209 g_strlcpy(network_s->name, net.name.name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1210 networks = g_slist_append(networks, network_s);
1216 int bt_mesh_network_get_name(bt_mesh_network_h network, char **network_name)
1218 bt_mesh_network_s *network_s;
1221 BT_CHECK_MESH_SUPPORT();
1222 BT_CHECK_MESH_INIT_STATUS();
1223 BT_CHECK_INPUT_PARAMETER(network);
1224 BT_CHECK_INPUT_PARAMETER(network_name);
1226 BT_MESH_VALIDATE_HANDLE(network, networks);
1228 network_s = (bt_mesh_network_s*)network;
1229 *network_name = strdup(network_s->name);
1230 if (*network_name == NULL) {
1231 BT_ERR("OUT_OF_MEMORY(0x%08x)",
1232 BT_ERROR_OUT_OF_MEMORY);
1233 return BT_ERROR_OUT_OF_MEMORY;
1237 return BT_ERROR_NONE;
1240 int bt_mesh_network_set_name(bt_mesh_network_h network, const char *network_name)
1242 int error_code = BT_ERROR_NONE;
1243 bluetooth_mesh_network_t net;
1244 bt_mesh_network_s* network_s;
1247 BT_CHECK_MESH_SUPPORT();
1248 BT_CHECK_MESH_INIT_STATUS();
1249 BT_CHECK_INPUT_PARAMETER(network);
1250 BT_CHECK_INPUT_PARAMETER(network_name);
1252 network_s = (bt_mesh_network_s*)network;
1253 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1255 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1256 g_strlcpy(net.uuid, network_s->uuid, 33);
1257 g_strlcpy(net.token.token, network_s->token, 17);
1258 g_strlcpy(net.name.name, network_name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1260 BT_INFO("Mesh: Set Network Name [%s]", network_name);
1261 error_code = _bt_get_error_code(bluetooth_mesh_network_set_name(&net));
1262 if (error_code != BT_ERROR_NONE) {
1263 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1267 BT_INFO("Mesh: Network Name set successfully [%s]", network_name);
1268 g_strlcpy(network_s->name, network_name, sizeof(network_s->name));
1271 return BT_ERROR_NONE;
1274 int bt_mesh_network_add_netkey(bt_mesh_network_h network,
1275 bt_mesh_netkey_h *netkey)
1277 int error_code = BT_ERROR_NONE;
1278 bt_mesh_network_s *network_s;
1279 bt_mesh_netkey_s *netkey_s;
1280 bluetooth_mesh_network_t net;
1281 uint16_t netkey_idx;
1284 BT_CHECK_MESH_SUPPORT();
1285 BT_CHECK_MESH_INIT_STATUS();
1286 BT_CHECK_INPUT_PARAMETER(network);
1287 BT_CHECK_INPUT_PARAMETER(netkey);
1289 BT_MESH_VALIDATE_HANDLE(network, networks);
1291 network_s = (bt_mesh_network_s*)network;
1292 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1294 g_strlcpy(net.uuid, network_s->uuid, 33);
1295 g_strlcpy(net.token.token, network_s->token, 17);
1296 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1298 error_code = _bt_get_error_code(bluetooth_mesh_network_add_netkey(&net, &netkey_idx));
1299 if (error_code != BT_ERROR_NONE) {
1300 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1304 BT_INFO("Mesh: Subnet Key created: Index [%d]", netkey_idx);
1305 /* Create Netkey object */
1306 netkey_s = g_malloc0(sizeof(bt_mesh_netkey_s));
1307 netkey_s->parent = network_s;
1308 netkey_s->netkey_index = netkey_idx;
1309 network_s->netkeys = g_slist_append(network_s->netkeys, netkey_s);
1310 netkey_list = g_slist_append(netkey_list, netkey_s);
1311 *netkey = (bt_mesh_netkey_h)netkey_s;
1314 return BT_ERROR_NONE;
1317 int bt_mesh_network_foreach_netkeys(bt_mesh_network_h network,
1318 bt_mesh_network_netkey_info_cb callback, void *user_data)
1320 bluetooth_mesh_network_t net;
1321 GPtrArray *netkeys = NULL;
1323 int error_code = BT_ERROR_NONE;
1324 uint16_t *netkey_idx = NULL;
1327 bt_mesh_network_s *network_s;
1330 BT_CHECK_MESH_SUPPORT();
1331 BT_CHECK_MESH_INIT_STATUS();
1332 BT_CHECK_INPUT_PARAMETER(network);
1333 BT_CHECK_INPUT_PARAMETER(callback);
1335 BT_MESH_VALIDATE_HANDLE(network, networks);
1337 netkeys = g_ptr_array_new();
1338 if (netkeys == NULL) {
1339 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1340 return BT_ERROR_OUT_OF_MEMORY;
1343 network_s = (bt_mesh_network_s*)network;
1344 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1346 g_strlcpy(net.uuid, network_s->uuid, 33);
1347 g_strlcpy(net.token.token, network_s->token, 17);
1348 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1350 error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_netkey(&net, &netkeys));
1351 if (error_code != BT_ERROR_NONE) {
1352 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1353 g_ptr_array_free(netkeys, TRUE);
1357 for (i = 0; i < netkeys->len; i++) {
1358 netkey_idx = g_ptr_array_index(netkeys, i);
1360 /* Create and insert netkey object in list */
1361 if (!__bt_mesh_network_is_netkey_added(network_s, *netkey_idx)) {
1362 bt_mesh_netkey_s *nk;
1363 nk = g_malloc0(sizeof(bt_mesh_netkey_s));
1364 nk->parent = network_s;
1365 nk->netkey_index = *netkey_idx;
1366 network_s->netkeys = g_slist_append(network_s->netkeys, nk);
1367 netkey_list = g_slist_append(netkey_list, nk);
1371 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1372 BT_ERROR_OPERATION_FAILED);
1373 error_code = BT_ERROR_OPERATION_FAILED;
1378 total = g_slist_length(network_s->netkeys);
1380 BT_INFO("Mesh: No netkey added in network");
1381 callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
1382 NULL, 0xFFFF, user_data);
1384 for (l = network_s->netkeys; l != NULL; l = g_slist_next(l)) {
1385 bt_mesh_netkey_s *netkey;
1388 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
1389 (bt_mesh_netkey_h) netkey,
1390 netkey->netkey_index, user_data)) {
1395 g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
1396 g_ptr_array_free(netkeys, TRUE);
1402 int bt_mesh_netkey_get_index(bt_mesh_netkey_h netkey, uint16_t *index)
1404 bt_mesh_netkey_s *netkey_s;
1407 BT_CHECK_MESH_SUPPORT();
1408 BT_CHECK_MESH_INIT_STATUS();
1409 BT_CHECK_INPUT_PARAMETER(netkey);
1410 BT_CHECK_INPUT_PARAMETER(index);
1412 BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
1414 netkey_s = (bt_mesh_netkey_s*)netkey;
1415 *index = netkey_s->netkey_index;
1418 return BT_ERROR_NONE;
1421 int bt_mesh_netkey_update(bt_mesh_netkey_h netkey)
1423 int error_code = BT_ERROR_NONE;
1424 bt_mesh_network_s *network_s;
1425 bt_mesh_netkey_s *netkey_s;
1426 bluetooth_mesh_network_t net;
1429 BT_CHECK_MESH_SUPPORT();
1430 BT_CHECK_MESH_INIT_STATUS();
1431 BT_CHECK_INPUT_PARAMETER(netkey);
1433 netkey_s = (bt_mesh_netkey_s*)netkey;
1434 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1435 network_s = netkey_s->parent;
1436 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1438 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1440 g_strlcpy(net.uuid, network_s->uuid, 33);
1441 g_strlcpy(net.token.token, network_s->token, 17);
1442 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1444 error_code = _bt_get_error_code(bluetooth_mesh_network_update_netkey(
1445 &net, netkey_s->netkey_index));
1446 if (error_code != BT_ERROR_NONE) {
1447 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1452 return BT_ERROR_NONE;
1455 int bt_mesh_netkey_delete(bt_mesh_netkey_h netkey)
1457 int error_code = BT_ERROR_NONE;
1458 bt_mesh_network_s *network_s;
1459 bt_mesh_netkey_s *netkey_s;
1460 bluetooth_mesh_network_t net;
1463 BT_CHECK_MESH_SUPPORT();
1464 BT_CHECK_MESH_INIT_STATUS();
1466 BT_CHECK_INPUT_PARAMETER(netkey);
1468 netkey_s = (bt_mesh_netkey_s*)netkey;
1469 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1470 network_s = netkey_s->parent;
1471 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1473 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1475 g_strlcpy(net.uuid, network_s->uuid, 33);
1476 g_strlcpy(net.token.token, network_s->token, 17);
1477 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1479 error_code = _bt_get_error_code(bluetooth_mesh_network_delete_netkey(&net, netkey_s->netkey_index));
1480 if (error_code != BT_ERROR_NONE) {
1481 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1485 network_s->netkeys = g_slist_remove(network_s->netkeys, netkey_s);
1486 netkey_list = g_slist_remove(netkey_list, netkey_s);
1487 g_slist_free_full(netkey_s->appkeys, g_free);
1490 return BT_ERROR_NONE;
1493 int bt_mesh_netkey_add_appkey(bt_mesh_netkey_h netkey,
1494 bt_mesh_appkey_h *appkey)
1496 int error_code = BT_ERROR_NONE;
1497 uint16_t appkey_idx;
1498 bt_mesh_network_s *network_s;
1499 bt_mesh_netkey_s *netkey_s;
1500 bt_mesh_appkey_s *appkey_s;
1501 bluetooth_mesh_network_t net;
1504 BT_CHECK_MESH_SUPPORT();
1505 BT_CHECK_MESH_INIT_STATUS();
1507 BT_CHECK_INPUT_PARAMETER(netkey);
1508 BT_CHECK_INPUT_PARAMETER(appkey);
1510 netkey_s = (bt_mesh_netkey_s*)netkey;
1511 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1512 network_s = netkey_s->parent;
1513 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1515 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1517 g_strlcpy(net.uuid, network_s->uuid, 33);
1518 g_strlcpy(net.token.token, network_s->token, 17);
1519 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1521 error_code = _bt_get_error_code(bluetooth_mesh_network_add_appkey(
1522 &net, netkey_s->netkey_index, &appkey_idx));
1523 if (error_code != BT_ERROR_NONE) {
1524 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1528 /* Create Appkey object */
1529 appkey_s = g_malloc0(sizeof(bt_mesh_appkey_s));
1530 appkey_s->parent = netkey_s;
1531 appkey_s->appkey_index = appkey_idx;
1532 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_s);
1533 appkey_list = g_slist_append(appkey_list, appkey_s);
1534 *appkey = (bt_mesh_appkey_h)appkey_s;
1537 return BT_ERROR_NONE;
1540 int bt_mesh_appkey_update(bt_mesh_appkey_h appkey)
1542 int error_code = BT_ERROR_NONE;
1543 bt_mesh_network_s *network_s;
1544 bt_mesh_netkey_s *netkey_s;
1545 bt_mesh_appkey_s *appkey_s;
1546 bluetooth_mesh_network_t net;
1549 BT_CHECK_MESH_SUPPORT();
1550 BT_CHECK_MESH_INIT_STATUS();
1551 BT_CHECK_INPUT_PARAMETER(appkey);
1553 appkey_s = (bt_mesh_appkey_s*)appkey;
1554 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
1555 netkey_s = appkey_s->parent;
1556 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1557 network_s = netkey_s->parent;
1558 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1560 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1562 g_strlcpy(net.uuid, network_s->uuid, 33);
1563 g_strlcpy(net.token.token, network_s->token, 17);
1564 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1566 error_code = _bt_get_error_code(bluetooth_mesh_network_update_appkey(
1567 &net, netkey_s->netkey_index, appkey_s->appkey_index));
1568 if (error_code != BT_ERROR_NONE) {
1569 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1574 return BT_ERROR_NONE;
1577 int bt_mesh_appkey_delete(bt_mesh_appkey_h appkey)
1579 int error_code = BT_ERROR_NONE;
1580 bt_mesh_network_s *network_s;
1581 bt_mesh_netkey_s *netkey_s;
1582 bt_mesh_appkey_s *appkey_s;
1583 bluetooth_mesh_network_t net;
1586 BT_CHECK_MESH_SUPPORT();
1587 BT_CHECK_MESH_INIT_STATUS();
1588 BT_CHECK_INPUT_PARAMETER(appkey);
1590 appkey_s = (bt_mesh_appkey_s*)appkey;
1591 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
1592 netkey_s = appkey_s->parent;
1593 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
1594 network_s = netkey_s->parent;
1595 BT_MESH_VALIDATE_HANDLE(network_s, networks);
1597 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1599 g_strlcpy(net.uuid, network_s->uuid, 33);
1600 g_strlcpy(net.token.token, network_s->token, 17);
1601 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1603 error_code = _bt_get_error_code(bluetooth_mesh_network_delete_appkey(
1604 &net, netkey_s->netkey_index, appkey_s->appkey_index));
1605 if (error_code != BT_ERROR_NONE) {
1606 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1610 /* Delete Appkey Object */
1611 netkey_s->appkeys = g_slist_remove(netkey_s->appkeys, appkey_s);
1612 appkey_list = g_slist_remove(appkey_list, appkey_s);
1616 return BT_ERROR_NONE;
1619 int bt_mesh_netkey_foreach_appkeys(bt_mesh_netkey_h netkey,
1620 bt_mesh_appkey_info_cb callback, void *user_data)
1622 int error_code = BT_ERROR_NONE;
1623 bt_mesh_netkey_s *netkey_s;
1624 bt_mesh_network_s *network_s;
1625 bluetooth_mesh_network_t net;
1629 GPtrArray *appkeys = NULL;
1630 uint16_t *appkey_idx = NULL;
1633 BT_CHECK_MESH_SUPPORT();
1634 BT_CHECK_MESH_INIT_STATUS();
1635 BT_CHECK_INPUT_PARAMETER(netkey);
1636 BT_CHECK_INPUT_PARAMETER(callback);
1638 BT_MESH_VALIDATE_HANDLE(netkey, netkey_list);
1640 netkey_s = (bt_mesh_netkey_s*)netkey;
1641 network_s = netkey_s->parent;
1643 appkeys = g_ptr_array_new();
1644 if (appkeys == NULL) {
1645 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1646 return BT_ERROR_OUT_OF_MEMORY;
1649 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1651 g_strlcpy(net.uuid, network_s->uuid, 33);
1652 g_strlcpy(net.token.token, network_s->token, 17);
1653 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1655 BT_INFO("Mesh: Find all Appkeys for Netkey : index [%d]", netkey_s->netkey_index);
1656 error_code = _bt_get_error_code(bluetooth_mesh_netkey_get_all_appkey(
1657 &net, netkey_s->netkey_index, &appkeys));
1658 if (error_code != BT_ERROR_NONE) {
1659 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1660 g_ptr_array_free(appkeys, TRUE);
1663 for (i = 0; i < appkeys->len; i++) {
1664 appkey_idx = g_ptr_array_index(appkeys, i);
1666 /* Create and insert netkey object in list */
1667 if (!__bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx)) {
1668 bt_mesh_appkey_s *key;
1669 key = g_malloc0(sizeof(bt_mesh_appkey_s));
1670 key->parent = netkey_s;
1671 key->appkey_index = *appkey_idx;
1672 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, key);
1673 appkey_list = g_slist_append(appkey_list, key);
1677 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1678 BT_ERROR_OPERATION_FAILED);
1679 error_code = BT_ERROR_OPERATION_FAILED;
1684 total = g_slist_length(netkey_s->appkeys);
1685 BT_INFO("Mesh: Total appkeys [%d]", total);
1688 BT_INFO("Mesh: No AppKey added in NetKey yet!");
1689 callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
1690 (bt_mesh_netkey_h) netkey_s, NULL,
1692 return BT_ERROR_NONE;
1696 for (l = netkey_s->appkeys; l; l = g_slist_next(l)) {
1697 bt_mesh_appkey_s *appkey_s;
1699 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h) network_s, total,
1700 (bt_mesh_netkey_h) netkey_s, (bt_mesh_appkey_h) appkey_s,
1701 appkey_s->appkey_index, user_data))
1705 g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
1706 g_ptr_array_free(appkeys, TRUE);
1709 return BT_ERROR_NONE;
1712 int bt_mesh_appkey_get_index(bt_mesh_appkey_h appkey, uint16_t *index)
1714 bt_mesh_appkey_s *appkey_s;
1717 BT_CHECK_MESH_SUPPORT();
1718 BT_CHECK_MESH_INIT_STATUS();
1719 BT_CHECK_INPUT_PARAMETER(appkey);
1720 BT_CHECK_INPUT_PARAMETER(index);
1722 BT_MESH_VALIDATE_HANDLE(appkey, appkey_list);
1724 appkey_s = (bt_mesh_appkey_s*)appkey;
1725 *index = appkey_s->appkey_index;
1728 return BT_ERROR_NONE;
1731 /* Sync API's to bt-service: Discovery API's */
1732 int bt_mesh_network_foreach_devices(bt_mesh_network_h network,
1733 bt_mesh_network_device_info_cb callback, void *user_data)
1735 bluetooth_mesh_network_t net;
1736 bluetooth_mesh_node_info_t *node_info;
1737 GPtrArray *nodes = NULL;
1738 int error_code = BT_ERROR_NONE;
1740 bt_mesh_network_s *network_s;
1743 BT_CHECK_MESH_SUPPORT();
1744 BT_CHECK_MESH_INIT_STATUS();
1745 BT_CHECK_INPUT_PARAMETER(network);
1746 BT_CHECK_INPUT_PARAMETER(callback);
1748 BT_MESH_VALIDATE_HANDLE(network, networks);
1750 nodes = g_ptr_array_new();
1751 if (nodes == NULL) {
1752 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1753 return BT_ERROR_OUT_OF_MEMORY;
1756 network_s = (bt_mesh_network_s*)network;
1757 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1759 g_strlcpy(net.uuid, network_s->uuid, 33);
1760 g_strlcpy(net.token.token, network_s->token, 17);
1761 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1763 error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_nodes(&net, &nodes));
1764 if (error_code != BT_ERROR_NONE) {
1765 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1766 g_ptr_array_free(nodes, TRUE);
1770 BT_INFO("Mesh: Total number of Devices found [%d]", nodes->len);
1771 for (i = 0; i < nodes->len; i++) {
1772 node_info = g_ptr_array_index(nodes, i);
1774 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, nodes->len,
1775 node_info->dev_uuid, node_info->primary_unicast, user_data)) {
1779 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1780 BT_ERROR_OPERATION_FAILED);
1781 error_code = BT_ERROR_OPERATION_FAILED;
1786 g_ptr_array_foreach(nodes, (GFunc)g_free, NULL);
1787 g_ptr_array_free(nodes, TRUE);
1793 int bt_mesh_node_get_primary_address(bt_mesh_node_h node,
1794 uint16_t *primary_address)
1796 bt_mesh_node_s *node_s;
1799 BT_CHECK_MESH_SUPPORT();
1800 BT_CHECK_MESH_INIT_STATUS();
1801 BT_CHECK_INPUT_PARAMETER(node);
1802 BT_CHECK_INPUT_PARAMETER(primary_address);
1804 BT_MESH_VALIDATE_HANDLE(node, node_list);
1806 node_s = (bt_mesh_node_s*) node;
1807 *primary_address = node_s->unicast;
1810 return BT_ERROR_NONE;
1813 int bt_mesh_node_foreach_element(bt_mesh_node_h node,
1814 bt_mesh_node_element_info_cb callback, void *user_data)
1816 bt_mesh_node_s *node_s;
1821 BT_CHECK_MESH_SUPPORT();
1822 BT_CHECK_MESH_INIT_STATUS();
1823 BT_CHECK_INPUT_PARAMETER(node);
1824 BT_CHECK_INPUT_PARAMETER(callback);
1826 BT_MESH_VALIDATE_HANDLE(node, node_list);
1827 node_s = (bt_mesh_node_s*) node;
1829 /* Only for Node which is attached to the Network */
1831 if (!node_s->is_attached)
1832 return BT_ERROR_INVALID_PARAMETER;
1834 total = g_slist_length(node_s->elements);
1836 callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
1837 (bt_mesh_element_h) NULL, -1, 0xFFFF, user_data);
1841 for (l = node_s->elements; l; l = g_slist_next(l)) {
1842 bt_mesh_element_s *element_s;
1843 element_s = l->data;
1844 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h) node, total,
1845 (bt_mesh_element_h)element_s, element_s->index,
1846 (node_s->unicast + element_s->index), user_data))
1851 return BT_ERROR_NONE;
1854 int bt_mesh_element_foreach_models(bt_mesh_element_h element,
1855 bt_mesh_element_model_info_cb callback, void *user_data)
1857 bluetooth_mesh_network_t net;
1858 bt_mesh_network_s *network_s;
1859 bt_mesh_node_s *node_s;
1860 bt_mesh_element_s *element_s;
1862 GPtrArray *models = NULL;
1864 uint32_t *model_info;
1865 int error_code = BT_ERROR_NONE;
1870 BT_CHECK_MESH_SUPPORT();
1871 BT_CHECK_MESH_INIT_STATUS();
1872 BT_CHECK_INPUT_PARAMETER(element);
1873 BT_CHECK_INPUT_PARAMETER(callback);
1875 BT_MESH_VALIDATE_HANDLE(element, element_list);
1877 element_s = (bt_mesh_element_s*) element;
1878 node_s = (bt_mesh_node_s*) element_s->parent;
1879 network_s = (bt_mesh_network_s*) node_s->parent;
1881 /* Only for local Node */
1882 if (node_s->is_local) {
1884 BT_INFO("Mesh: Local element");
1886 total = g_slist_length(element_s->models);
1888 callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, 0,
1889 (bt_mesh_model_h) NULL, NULL, user_data);
1891 for (l = element_s->models; l; l = l->next) {
1892 bt_mesh_model_s *model_s = l->data;
1893 bt_mesh_model_id_s modid;
1895 modid.company_id = model_s->id >> 16;
1896 modid.model_id = model_s->id;
1898 if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
1899 (bt_mesh_model_h) model_s,
1900 &modid, user_data)) {
1905 return BT_ERROR_NONE;
1908 models = g_ptr_array_new();
1909 if (models == NULL) {
1910 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
1911 return BT_ERROR_OUT_OF_MEMORY;
1913 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
1915 g_strlcpy(net.uuid, network_s->uuid, 33);
1916 g_strlcpy(net.token.token, network_s->token, 17);
1917 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
1919 BT_INFO("Mesh: Get Models for element of Remote Node");
1920 error_code = _bt_get_error_code(bluetooth_mesh_element_get_all_models(&net,
1921 /* Node identity */node_s->unicast,
1922 /* eleement identity */element_s->index,
1923 /*Output*/ &models));
1924 if (error_code != BT_ERROR_NONE) {
1925 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
1926 g_ptr_array_free(models, TRUE);
1930 total = models->len;
1931 BT_INFO("Mesh: Total models in element [%d]", total);
1932 for (i = 0; i < models->len; i++) {
1933 model_info = g_ptr_array_index(models, i);
1935 BT_INFO("Mesh: Model ID [0x%4.4x]", *model_info);
1936 /* Skip if Model is already added in the element */
1937 l = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(*model_info),
1938 (GCompareFunc)__compare_model_id);
1940 bt_mesh_model_id_s modid;
1941 bt_mesh_model_s *mod = (bt_mesh_model_s*)l->data;
1942 modid.company_id = mod->id >> 16;
1943 modid.model_id = mod->id;
1945 BT_INFO("Mesh: Model ID [0x%4.4x] is already present in element", *model_info);
1946 if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
1947 (bt_mesh_model_h) mod,
1948 &modid, user_data)) {
1953 /* Create and insert model object in list */
1954 bt_mesh_model_s *mod;
1955 bt_mesh_model_id_s modid;
1956 mod = g_malloc0(sizeof(bt_mesh_model_s));
1957 mod->parent = element_s;
1958 if (node_s->unicast == 0x0001) {
1959 mod->is_local = true;
1961 mod->id = *model_info;
1962 element_s->models = g_slist_append(element_s->models, mod);
1963 model_list = g_slist_append(model_list, mod);
1965 modid.company_id = *model_info >> 16;
1966 modid.model_id = *model_info;
1967 BT_INFO("Mesh: Model was not present in Element, created & inserted");
1968 BT_INFO("Mesh: Total Models present in Element [%d]",
1969 g_slist_length(element_s->models));
1971 if (!callback(BT_ERROR_NONE, (bt_mesh_element_h)element_s, total,
1972 (bt_mesh_model_h) mod,
1973 &modid, user_data)) {
1977 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
1978 BT_ERROR_OPERATION_FAILED);
1979 error_code = BT_ERROR_OPERATION_FAILED;
1984 g_ptr_array_foreach(models, (GFunc)g_free, NULL);
1985 g_ptr_array_free(models, TRUE);
1991 /* Provisioning & capabilities related*/
1992 int bt_mesh_network_unprovisioned_device_scan(bt_mesh_network_h network,
1993 bt_mesh_scan_params_s *scan_params,
1994 bt_mesh_network_scan_unprovisioned_device_result_cb callback,
1997 bt_mesh_network_s *network_s;
1998 bluetooth_mesh_network_t net;
1999 int error_code = BT_ERROR_NONE;
2002 BT_CHECK_MESH_SUPPORT();
2003 BT_CHECK_MESH_INIT_STATUS();
2004 BT_CHECK_INPUT_PARAMETER(network);
2005 BT_CHECK_INPUT_PARAMETER(scan_params);
2006 BT_CHECK_INPUT_PARAMETER(callback);
2008 BT_MESH_VALIDATE_HANDLE(network, networks);
2010 network_s = (bt_mesh_network_s*)network;
2011 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2013 g_strlcpy(net.uuid, network_s->uuid, 33);
2014 g_strlcpy(net.token.token, network_s->token, 17);
2015 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2017 error_code = _bt_get_error_code(bluetooth_mesh_network_scan(
2018 &net, (bluetooth_mesh_scan_param_t*) scan_params));
2020 if (error_code != BT_ERROR_NONE) {
2021 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2025 _bt_set_cb(BT_EVENT_MESH_NETWORK_SCAN_STATE_CHANGED, callback, user_data);
2027 return BT_ERROR_NONE;
2030 int bt_mesh_stop_unprovisioned_device_scan(bt_mesh_network_h network)
2032 bt_mesh_network_s *network_s;
2033 bluetooth_mesh_network_t net;
2034 int error_code = BT_ERROR_NONE;
2037 BT_CHECK_MESH_SUPPORT();
2038 BT_CHECK_MESH_INIT_STATUS();
2039 BT_CHECK_INPUT_PARAMETER(network);
2041 BT_MESH_VALIDATE_HANDLE(network, networks);
2043 network_s = (bt_mesh_network_s*)network;
2044 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2046 g_strlcpy(net.uuid, network_s->uuid, 33);
2047 g_strlcpy(net.token.token, network_s->token, 17);
2048 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2050 error_code = _bt_get_error_code(bluetooth_mesh_network_cancel_scan(&net));
2052 if (error_code != BT_ERROR_NONE) {
2053 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2058 return BT_ERROR_NONE;
2061 int bt_mesh_network_set_provisioning_capabilities(bt_mesh_network_h network,
2062 bt_mesh_provisioner_capabilities_s *capabilities)
2064 bt_mesh_network_s *network_s;
2065 bluetooth_mesh_network_t net;
2066 bluetooth_mesh_provisioner_caps_t caps;
2067 int error_code = BT_ERROR_NONE;
2070 BT_CHECK_MESH_SUPPORT();
2071 BT_CHECK_MESH_INIT_STATUS();
2072 BT_CHECK_INPUT_PARAMETER(network);
2073 BT_CHECK_INPUT_PARAMETER(capabilities);
2075 BT_MESH_VALIDATE_HANDLE(network, networks);
2077 network_s = (bt_mesh_network_s*)network;
2078 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2079 memset(&caps, 0x00, sizeof(bluetooth_mesh_provisioner_caps_t));
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 caps.public_oob = capabilities->public_oob;
2086 caps.static_oob = capabilities->static_oob;
2087 caps.out_oob = capabilities->out_oob;
2088 caps.in_oob = capabilities->in_oob;
2090 error_code = _bt_get_error_code(bluetooth_mesh_network_set_capabilities(
2091 &net,(bluetooth_mesh_provisioner_caps_t*) &caps));
2093 if (error_code != BT_ERROR_NONE) {
2094 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2099 return BT_ERROR_NONE;
2102 int bt_mesh_network_provision_device(bt_mesh_network_h network,
2103 const char *dev_uuid,
2104 bt_mesh_network_device_provision_cb callback,
2107 bt_mesh_network_s *network_s;
2108 bluetooth_mesh_provisioning_request_t req;
2109 int error_code = BT_ERROR_NONE;
2112 BT_CHECK_MESH_SUPPORT();
2113 BT_CHECK_MESH_INIT_STATUS();
2114 BT_CHECK_INPUT_PARAMETER(network);
2115 BT_CHECK_INPUT_PARAMETER(dev_uuid);
2116 BT_CHECK_INPUT_PARAMETER(callback);
2118 BT_MESH_VALIDATE_HANDLE(network, networks);
2120 network_s = (bt_mesh_network_s*)network;
2121 memset(&req, 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
2123 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2124 g_strlcpy(req.dev_uuid, dev_uuid, 33);
2126 BT_INFO("Mesh: Provision Device [%s]", dev_uuid);
2127 error_code = _bt_get_error_code(bluetooth_mesh_network_provision_device(&req));
2129 if (error_code != BT_ERROR_NONE) {
2130 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2134 _bt_set_cb(BT_EVENT_MESH_NETWORK_PROVISIONING_RESULT, callback, user_data);
2136 return BT_ERROR_NONE;
2139 int bt_mesh_authentication_set_request_cb(bt_mesh_authentication_request_cb callback, void *user_data)
2142 BT_CHECK_MESH_SUPPORT();
2143 BT_CHECK_MESH_INIT_STATUS();
2144 BT_CHECK_INPUT_PARAMETER(callback);
2146 _bt_set_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST, callback, user_data);
2149 return BT_ERROR_NONE;
2152 int bt_mesh_authentication_unset_request_cb(bt_mesh_authentication_request_cb callback)
2156 BT_CHECK_MESH_SUPPORT();
2157 BT_CHECK_MESH_INIT_STATUS();
2158 BT_CHECK_INPUT_PARAMETER(callback);
2160 _bt_unset_cb(BT_EVENT_MESH_AUTHENTICATION_REQUEST);
2163 return BT_ERROR_NONE;
2166 int bt_mesh_authentication_reply(bt_mesh_authentication_type_e auth_type, const char *value, bool auth_reply)
2168 int error_code = BT_ERROR_NONE;
2171 BT_CHECK_MESH_SUPPORT();
2172 BT_CHECK_MESH_INIT_STATUS();
2173 BT_CHECK_INPUT_PARAMETER(value);
2175 error_code = _bt_get_error_code(bluetooth_mesh_authentication_reply(auth_type, value, auth_reply));
2176 if (error_code != BT_ERROR_NONE)
2177 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2183 int bt_mesh_network_discover_node(bt_mesh_network_h network,
2184 const char *dev_uuid, bt_mesh_node_discover_status_cb callback, void *user_data)
2186 int error_code = BT_ERROR_NONE;
2187 bt_mesh_network_s *network_s;
2188 bluetooth_mesh_node_discover_t req;
2191 BT_CHECK_MESH_SUPPORT();
2192 BT_CHECK_MESH_INIT_STATUS();
2193 BT_CHECK_INPUT_PARAMETER(network);
2194 BT_CHECK_INPUT_PARAMETER(dev_uuid);
2195 BT_CHECK_INPUT_PARAMETER(callback);
2197 BT_MESH_VALIDATE_HANDLE(network, networks);
2199 BT_INFO("Mesh: Discover Node with UUID[%s]", dev_uuid);
2201 /* Check if node with dev_uuid is already created */
2202 network_s = (bt_mesh_network_s*)network;
2203 memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2205 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2206 g_strlcpy(req.dev_uuid, dev_uuid, 33);
2208 error_code = _bt_get_error_code(bluetooth_mesh_browse_remote_node(&req));
2209 if (error_code != BT_ERROR_NONE) {
2210 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2215 _bt_set_cb(BT_EVENT_MESH_NODE_BROWSING_COMPLETED, callback, user_data);
2216 return BT_ERROR_NONE;
2219 int bt_mesh_node_configure_netkey(bt_mesh_node_h node, bt_mesh_node_key_configuration_e netkey_op,
2220 bt_mesh_netkey_h netkey, bt_mesh_netkey_status_cb callback, void *user_data)
2222 int error_code = BT_ERROR_NONE;
2223 bt_mesh_network_s *network_s;
2224 bt_mesh_node_s *node_s;
2225 bt_mesh_netkey_s *netkey_s;
2226 bluetooth_mesh_key_configure_t req;
2229 BT_CHECK_MESH_SUPPORT();
2230 BT_CHECK_MESH_INIT_STATUS();
2231 BT_CHECK_INPUT_PARAMETER(node);
2232 BT_CHECK_INPUT_PARAMETER(netkey);
2233 BT_CHECK_INPUT_PARAMETER(callback);
2235 node_s = (bt_mesh_node_s*) node;
2236 network_s = node_s->parent;
2237 netkey_s = (bt_mesh_netkey_s*) netkey;
2239 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2240 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2241 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2243 /* Return error, if node is not attached */
2244 if (!node_s->is_attached)
2245 return BT_ERROR_INVALID_PARAMETER;
2247 /* Return error, if netkey is not present in the specific network */
2248 if (netkey_s->parent != network_s)
2249 return BT_ERROR_INVALID_PARAMETER;
2252 /* Return Already done, if netkey is present in the node */
2253 if (g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_s,
2254 (GCompareFunc)__simple_compare))
2255 return BT_ERROR_ALREADY_DONE;
2257 memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
2259 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2260 req.primary_unicast = node_s->unicast;
2261 req.netkey_idx = netkey_s->netkey_index;
2262 req.is_netkey = true;
2263 req.op = (bluetooth_mesh_node_key_conf_e) netkey_op;
2265 BT_INFO("Mesh: Add NetKey Idx [%d] to node", req.netkey_idx);
2266 error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
2267 if (error_code != BT_ERROR_NONE) {
2268 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2273 _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
2274 return BT_ERROR_NONE;
2277 int bt_mesh_node_configure_appkey(bt_mesh_node_h node, bt_mesh_node_key_configuration_e appkey_op,
2278 bt_mesh_appkey_h appkey, bt_mesh_appkey_status_cb callback, void *user_data)
2280 int error_code = BT_ERROR_NONE;
2281 bt_mesh_network_s *network_s;
2282 bt_mesh_node_s *node_s;
2283 bt_mesh_netkey_s *netkey_s;
2284 bt_mesh_appkey_s *appkey_s;
2285 bluetooth_mesh_key_configure_t req;
2288 BT_CHECK_MESH_SUPPORT();
2289 BT_CHECK_MESH_INIT_STATUS();
2290 BT_CHECK_INPUT_PARAMETER(node);
2291 BT_CHECK_INPUT_PARAMETER(appkey);
2292 BT_CHECK_INPUT_PARAMETER(callback);
2294 node_s = (bt_mesh_node_s*) node;
2295 network_s = node_s->parent;
2296 appkey_s = (bt_mesh_appkey_s*) appkey;
2297 netkey_s = (bt_mesh_netkey_s*) appkey_s->parent;
2299 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2300 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2301 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2302 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2304 /* Return error, if node is not attached */
2305 if (!node_s->is_attached)
2306 return BT_ERROR_INVALID_PARAMETER;
2308 /* Return error, if netkey is not present in the specific network */
2309 if (netkey_s->parent != network_s)
2310 return BT_ERROR_INVALID_PARAMETER;
2312 memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
2314 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2315 req.primary_unicast = node_s->unicast;
2316 req.netkey_idx = netkey_s->netkey_index;
2317 req.appkey_idx = appkey_s->appkey_index;
2318 req.is_netkey = false;
2319 req.op = (bluetooth_mesh_node_key_conf_e) appkey_op;
2321 error_code = _bt_get_error_code(bluetooth_mesh_node_configure_key(&req));
2322 if (error_code != BT_ERROR_NONE) {
2323 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2328 _bt_set_cb(BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED, callback, user_data);
2329 return BT_ERROR_NONE;
2333 /* Remote Node Operations: CONFIG: Non Key */
2334 int bt_mesh_node_get_features(bt_mesh_node_h node, bt_mesh_node_features_cb callback, void *user_data)
2336 int error_code = BT_ERROR_NONE;
2337 bt_mesh_network_s *network_s;
2338 bt_mesh_node_s *node_s;
2339 bluetooth_mesh_node_features_t req;
2342 BT_CHECK_MESH_SUPPORT();
2343 BT_CHECK_MESH_INIT_STATUS();
2344 BT_CHECK_INPUT_PARAMETER(node);
2345 BT_CHECK_INPUT_PARAMETER(callback);
2347 node_s = (bt_mesh_node_s*) node;
2349 /* Return error, if node is not attached */
2350 if (!node_s->is_attached)
2351 return BT_ERROR_INVALID_PARAMETER;
2353 network_s = (bt_mesh_network_s*) node_s->parent;
2355 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2356 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2358 memset(&req, 0x00, sizeof(bluetooth_mesh_node_features_t));
2360 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2361 req.unicast = node_s->unicast;
2362 req.elem_count = node_s->unicast;
2364 error_code = _bt_get_error_code(bluetooth_mesh_node_browse_vendor_features(&req));
2365 if (error_code != BT_ERROR_NONE) {
2366 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2371 _bt_set_cb(BT_EVENT_MESH_NODE_VENDOR_FEATURES, callback, user_data);
2372 return BT_ERROR_NONE;
2375 int bt_mesh_node_get_ttl(bt_mesh_node_h node, bt_mesh_node_ttl_cb callback, void *user_data)
2377 int error_code = BT_ERROR_NONE;
2378 bt_mesh_network_s *network_s;
2379 bt_mesh_node_s *node_s;
2380 bluetooth_mesh_node_ttl_info_t req;
2383 BT_CHECK_MESH_SUPPORT();
2384 BT_CHECK_MESH_INIT_STATUS();
2385 BT_CHECK_INPUT_PARAMETER(node);
2386 BT_CHECK_INPUT_PARAMETER(callback);
2388 node_s = (bt_mesh_node_s*) node;
2389 network_s = node_s->parent;
2391 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2392 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2394 /* Return error, if node is not attached */
2395 if (!node_s->is_attached)
2396 return BT_ERROR_INVALID_PARAMETER;
2398 memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
2400 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2401 req.unicast = node_s->unicast;
2404 error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
2405 if (error_code != BT_ERROR_NONE) {
2406 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2411 _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
2412 return BT_ERROR_NONE;
2415 int bt_mesh_node_set_ttl(bt_mesh_node_h node, uint8_t ttl, bt_mesh_node_ttl_cb callback, void *user_data)
2417 int error_code = BT_ERROR_NONE;
2418 bt_mesh_network_s *network_s;
2419 bt_mesh_node_s *node_s;
2420 bluetooth_mesh_node_ttl_info_t req;
2423 BT_CHECK_MESH_SUPPORT();
2424 BT_CHECK_MESH_INIT_STATUS();
2425 BT_CHECK_INPUT_PARAMETER(node);
2426 BT_CHECK_INPUT_PARAMETER(callback);
2428 node_s = (bt_mesh_node_s*) node;
2429 network_s = node_s->parent;
2430 BT_CHECK_INPUT_PARAMETER(network_s);
2431 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2432 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2434 /* Return error, if node is not attached */
2435 if (!node_s->is_attached)
2436 return BT_ERROR_INVALID_PARAMETER;
2438 memset(&req, 0x00, sizeof(bluetooth_mesh_node_ttl_info_t));
2440 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2441 req.unicast = node_s->unicast;
2445 error_code = _bt_get_error_code(bluetooth_mesh_node_ttl_execute(&req));
2446 if (error_code != BT_ERROR_NONE) {
2447 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2452 _bt_set_cb(BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED, callback, user_data);
2453 return BT_ERROR_NONE;
2456 int bt_mesh_node_foreach_netkeys(bt_mesh_node_h node, bt_mesh_node_netkey_info_cb callback, void *user_data)
2458 GPtrArray *netkeys = NULL;
2460 int error_code = BT_ERROR_NONE;
2461 uint16_t *netkey_idx = NULL;
2464 bluetooth_mesh_node_discover_t req;
2465 bt_mesh_network_s *network_s;
2466 bt_mesh_node_s *node_s;
2469 BT_CHECK_MESH_SUPPORT();
2470 BT_CHECK_MESH_INIT_STATUS();
2471 BT_CHECK_INPUT_PARAMETER(node);
2472 BT_CHECK_INPUT_PARAMETER(callback);
2474 node_s = (bt_mesh_node_s*) node;
2475 network_s = node_s->parent;
2477 BT_CHECK_INPUT_PARAMETER(network_s);
2478 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2479 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2481 /* Return error, if node is not attached */
2482 if (!node_s->is_attached)
2483 return BT_ERROR_INVALID_PARAMETER;
2485 netkeys = g_ptr_array_new();
2486 if (netkeys == NULL) {
2487 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2488 return BT_ERROR_OUT_OF_MEMORY;
2491 memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2493 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2494 req.unicast = node_s->unicast;
2496 error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_netkeys(&req, &netkeys));
2497 if (error_code != BT_ERROR_NONE) {
2498 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2499 g_ptr_array_free(netkeys, TRUE);
2503 BT_INFO("Mesh: Total netkeys added in node is [%d]", netkeys->len);
2504 for (i = 0; i < netkeys->len; i++) {
2505 bt_mesh_netkey_s *netkey_local;
2506 netkey_idx = g_ptr_array_index(netkeys, i);
2508 /* Check if netkey index is present in network or not */
2509 BT_INFO("Mesh: NetKey IDX [%d]", *netkey_idx);
2510 netkey_local = __bt_mesh_network_is_netkey_added(network_s, *netkey_idx);
2511 if (!netkey_local) {
2512 BT_ERR("Mesh: Network does not contain the netKey index, possibly reloaded");
2513 /* Create Netkey object */
2514 netkey_local = g_malloc0(sizeof(bt_mesh_netkey_s));
2515 netkey_local->parent = network_s;
2516 netkey_local->netkey_index = *netkey_idx;
2517 network_s->netkeys = g_slist_append(network_s->netkeys, netkey_local);
2518 netkey_list = g_slist_append(netkey_list, netkey_local);
2520 if (!g_slist_find_custom(node_s->netkeys, GUINT_TO_POINTER(*netkey_idx),
2521 (GCompareFunc)__compare_netkey_index))
2522 node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
2524 /* Check if netkey index is present in target node or not */
2525 if (!g_slist_find_custom(node_s->netkeys,(gconstpointer) netkey_local,
2526 (GCompareFunc)__simple_compare)) {
2527 node_s->netkeys = g_slist_append(node_s->netkeys, netkey_local);
2530 BT_INFO("Mesh: Netkey is already added in node");
2534 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2535 BT_ERROR_OPERATION_FAILED);
2536 error_code = BT_ERROR_OPERATION_FAILED;
2541 total = g_slist_length(node_s->netkeys);
2543 BT_ERR("Mesh: Unexpcted: No netkey added in node!!");
2544 callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
2545 NULL, 0xFFFF, user_data);
2547 for (l = node_s->netkeys; l != NULL; l = g_slist_next(l)) {
2548 bt_mesh_netkey_s *netkey;
2551 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
2552 (bt_mesh_netkey_h) netkey,
2553 netkey->netkey_index, user_data)) {
2559 g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
2560 g_ptr_array_free(netkeys, TRUE);
2567 int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node, bt_mesh_netkey_h netkey,
2568 bt_mesh_node_appkey_info_cb callback, void *user_data)
2570 GPtrArray *appkeys = NULL;
2571 int error_code = BT_ERROR_NONE;
2573 bluetooth_mesh_node_discover_t req;
2574 uint16_t *appkey_idx = NULL;
2575 bt_mesh_network_s *network_s;
2576 bt_mesh_node_s *node_s;
2577 bt_mesh_netkey_s *netkey_s;
2580 BT_CHECK_MESH_SUPPORT();
2581 BT_CHECK_MESH_INIT_STATUS();
2582 BT_CHECK_INPUT_PARAMETER(node);
2583 BT_CHECK_INPUT_PARAMETER(netkey);
2584 BT_CHECK_INPUT_PARAMETER(callback);
2586 node_s = (bt_mesh_node_s*) node;
2587 network_s = node_s->parent;
2588 netkey_s = (bt_mesh_netkey_s*) netkey;
2590 BT_CHECK_INPUT_PARAMETER(network_s);
2591 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2592 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2593 BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
2595 /* Return error, if node is not attached */
2596 if (!node_s->is_attached)
2597 return BT_ERROR_INVALID_PARAMETER;
2599 appkeys = g_ptr_array_new();
2600 if (appkeys == NULL) {
2601 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2602 return BT_ERROR_OUT_OF_MEMORY;
2605 memset(&req, 0x00, sizeof(bluetooth_mesh_node_discover_t));
2607 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2608 req.unicast = node_s->unicast;
2609 req.netkey_idx = netkey_s->netkey_index;
2611 error_code = _bt_get_error_code(bluetooth_mesh_node_get_all_appkeys(&req, &appkeys));
2612 if (error_code != BT_ERROR_NONE) {
2613 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2614 g_ptr_array_free(appkeys, TRUE);
2618 BT_INFO("Mesh: Total appkeys found in Node [%d]", appkeys->len);
2619 for (i = 0; i < appkeys->len; i++) {
2620 bt_mesh_appkey_s *appkey_local;
2621 appkey_idx = g_ptr_array_index(appkeys, i);
2623 /* Check if appkey index is present in network or not */
2624 BT_INFO("Mesh: AppKey index [%d]", *appkey_idx);
2625 appkey_local = __bt_mesh_network_is_appkey_added(network_s, netkey_s->netkey_index, *appkey_idx);
2627 if (!appkey_local) {
2628 BT_ERR("Mesh: Network does not AppKey index, possibly Network reloaded!!");
2629 /* Create Appkey object */
2630 appkey_local = g_malloc0(sizeof(bt_mesh_appkey_s));
2631 appkey_local->parent = netkey_s;
2632 appkey_local->appkey_index = *appkey_idx;
2633 netkey_s->appkeys = g_slist_append(netkey_s->appkeys, appkey_local);
2634 appkey_list = g_slist_append(appkey_list, appkey_local);
2636 if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
2637 (GCompareFunc)__compare_appkey_index))
2638 node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
2640 /* Check if netkey index is present in target node or not */
2641 if (!g_slist_find_custom(node_s->appkeys, GUINT_TO_POINTER(*appkey_idx),
2642 (GCompareFunc)__compare_appkey_index)) {
2643 node_s->appkeys = g_slist_append(node_s->appkeys, appkey_local);
2646 BT_INFO("Mesh: AppKey is already added in node");
2650 if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, appkeys->len,
2651 (bt_mesh_netkey_h) netkey, (bt_mesh_appkey_h) appkey_local,
2652 appkey_local->appkey_index, user_data)) {
2656 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
2657 BT_ERROR_OPERATION_FAILED);
2658 error_code = BT_ERROR_OPERATION_FAILED;
2663 if (appkeys->len == 0) {
2664 BT_ERR("Mesh: No appkey configured for the bound netkey Idx [%d]",
2666 callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, 0,
2667 (bt_mesh_netkey_h) netkey_s, NULL, 0xFFFF, user_data);
2670 g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
2671 g_ptr_array_free(appkeys, TRUE);
2677 int bt_mesh_model_bind_appkey(bt_mesh_model_h model,
2678 bt_mesh_appkey_h appkey, bt_mesh_model_bind_cb callback,
2681 int error_code = BT_ERROR_NONE;
2682 bt_mesh_model_s *model_s;
2683 bt_mesh_element_s *element_s;
2684 bt_mesh_node_s *node_s;
2685 bt_mesh_network_s *network_s;
2686 bt_mesh_appkey_s *appkey_s;
2687 bluetooth_mesh_model_configure_t req;
2690 BT_CHECK_MESH_SUPPORT();
2691 BT_CHECK_MESH_INIT_STATUS();
2692 BT_CHECK_INPUT_PARAMETER(model);
2693 BT_CHECK_INPUT_PARAMETER(appkey);
2694 BT_CHECK_INPUT_PARAMETER(callback);
2696 model_s = (bt_mesh_model_s*) model;
2697 element_s = (bt_mesh_element_s*) model_s->parent;
2698 node_s = (bt_mesh_node_s*) element_s->parent;
2699 appkey_s = (bt_mesh_appkey_s*) appkey;
2700 network_s = (bt_mesh_network_s*) node_s->parent;
2702 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2703 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2704 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2705 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2706 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2708 /* Return error, if node is not attached */
2709 if (!node_s->is_attached)
2710 return BT_ERROR_INVALID_PARAMETER;
2712 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
2714 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2715 req.primary_unicast = node_s->unicast;
2716 req.elem_index = element_s->index;
2717 req.model = model_s->id;
2718 req.appkey_idx = appkey_s->appkey_index;
2721 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
2722 if (error_code != BT_ERROR_NONE) {
2723 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2728 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
2729 return BT_ERROR_NONE;
2732 int bt_mesh_model_unbind_appkey(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
2733 bt_mesh_model_unbind_cb callback, void *user_data)
2735 int error_code = BT_ERROR_NONE;
2736 bt_mesh_model_s *model_s;
2737 bt_mesh_element_s *element_s;
2738 bt_mesh_node_s *node_s;
2739 bt_mesh_appkey_s *appkey_s;
2740 bt_mesh_network_s *network_s;
2741 bluetooth_mesh_model_configure_t req;
2744 BT_CHECK_MESH_SUPPORT();
2745 BT_CHECK_MESH_INIT_STATUS();
2746 BT_CHECK_INPUT_PARAMETER(model);
2747 BT_CHECK_INPUT_PARAMETER(appkey);
2748 BT_CHECK_INPUT_PARAMETER(callback);
2750 model_s = (bt_mesh_model_s*) model;
2751 element_s = (bt_mesh_element_s*) model_s->parent;
2752 node_s = (bt_mesh_node_s*) element_s->parent;
2753 appkey_s = (bt_mesh_appkey_s*) appkey;
2754 network_s = (bt_mesh_network_s*) node_s->parent;
2756 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2757 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2758 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2759 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2760 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2762 /* Return error, if node is not attached */
2763 if (!node_s->is_attached)
2764 return BT_ERROR_INVALID_PARAMETER;
2766 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
2768 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2769 req.primary_unicast = node_s->unicast;
2770 req.elem_index = element_s->index;
2771 req.model = model_s->id;
2772 req.appkey_idx = appkey_s->appkey_index;
2773 req.is_bind = false;
2775 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_appkey(&req));
2776 if (error_code != BT_ERROR_NONE) {
2777 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2782 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED, callback, user_data);
2783 return BT_ERROR_NONE;
2786 int bt_mesh_model_get_appkey_list(bt_mesh_model_h model,
2787 bt_mesh_model_appkey_list_cb callback, void *user_data)
2789 int error_code = BT_ERROR_NONE;
2790 bt_mesh_model_s *model_s;
2791 bt_mesh_element_s *element_s;
2792 bt_mesh_node_s *node_s;
2793 bt_mesh_network_s *network_s;
2794 bluetooth_mesh_model_configure_t req;
2797 BT_CHECK_MESH_SUPPORT();
2798 BT_CHECK_MESH_INIT_STATUS();
2799 BT_CHECK_INPUT_PARAMETER(model);
2800 BT_CHECK_INPUT_PARAMETER(callback);
2802 model_s = (bt_mesh_model_s*) model;
2803 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2805 element_s = (bt_mesh_element_s*) model_s->parent;
2806 BT_CHECK_INPUT_PARAMETER(element_s);
2807 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2809 node_s = (bt_mesh_node_s*) element_s->parent;
2810 BT_CHECK_INPUT_PARAMETER(node_s);
2811 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2813 network_s = (bt_mesh_network_s*) node_s->parent;
2814 BT_CHECK_INPUT_PARAMETER(network_s);
2815 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2817 /* Return error, if node is not attached */
2818 if (!node_s->is_attached)
2819 return BT_ERROR_INVALID_PARAMETER;
2821 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
2823 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2824 req.primary_unicast = node_s->unicast;
2825 req.elem_index = element_s->index;
2826 req.model = model_s->id;
2828 error_code = _bt_get_error_code(bluetooth_mesh_model_get_all_appkeys(&req));
2829 if (error_code != BT_ERROR_NONE) {
2830 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2835 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_APPKEY_LIST, callback, user_data);
2839 int bt_mesh_model_send_msg(bt_mesh_model_h model,
2840 bt_mesh_appkey_h appkey, bt_mesh_model_msg_params_s *msg_params,
2841 bt_mesh_model_msg_cb callback, void *user_data)
2843 int error_code = BT_ERROR_NONE;
2844 bt_mesh_model_s *model_s;
2845 bt_mesh_element_s *element_s;
2846 bt_mesh_node_s *node_s;
2847 bt_mesh_network_s *network_s;
2848 bt_mesh_appkey_s *appkey_s;
2849 bluetooth_mesh_model_msg_t req;
2852 BT_CHECK_MESH_SUPPORT();
2853 BT_CHECK_MESH_INIT_STATUS();
2854 BT_CHECK_INPUT_PARAMETER(model);
2855 BT_CHECK_INPUT_PARAMETER(appkey);
2856 BT_CHECK_INPUT_PARAMETER(msg_params);
2857 BT_CHECK_INPUT_PARAMETER(callback);
2859 model_s = (bt_mesh_model_s*) model;
2860 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
2862 element_s = (bt_mesh_element_s*) model_s->parent;
2863 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
2865 node_s = (bt_mesh_node_s*) element_s->parent;
2866 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
2868 appkey_s = (bt_mesh_appkey_s*) appkey;
2869 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2871 network_s = (bt_mesh_network_s*) node_s->parent;
2872 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2874 /* Return error, if node is not attached */
2875 if (!node_s->is_attached)
2876 return BT_ERROR_INVALID_PARAMETER;
2878 BT_INFO("Mesh: Model msg opcode: 0x%2.2X",msg_params->opcode);
2880 memset(&req, 0x00, sizeof(bluetooth_mesh_model_msg_t));
2882 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2883 req.primary_unicast = node_s->unicast;
2884 req.elem_index = element_s->index;
2885 req.model = model_s->id;
2886 req.appkey_idx = appkey_s->appkey_index;
2887 req.opcode = msg_params->opcode;
2888 if (msg_params->data) {
2889 BT_INFO("Mesh: model msg strlen %zd message: %s",
2890 strlen(msg_params->data), msg_params->data);
2892 req.msg_len = strlen(msg_params->data);
2893 g_strlcpy(req.msg, msg_params->data, sizeof(msg_params->data) + 1);
2898 error_code = _bt_get_error_code(bluetooth_mesh_model_send_msg(&req));
2899 if (error_code != BT_ERROR_NONE) {
2900 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2905 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_EXECUTE_MSG_COMPLETED, callback, user_data);
2906 return BT_ERROR_NONE;
2909 int bt_mesh_group_send_msg(bt_mesh_group_h group,
2910 bt_mesh_appkey_h appkey, bt_mesh_model_msg_params_s *msg_params,
2911 bt_mesh_model_msg_cb callback, void *user_data)
2913 int error_code = BT_ERROR_NONE;
2914 bt_mesh_group_s *group_s;
2915 bt_mesh_network_s *network_s;
2916 bt_mesh_appkey_s *appkey_s;
2917 bluetooth_mesh_model_msg_t req;
2920 BT_CHECK_MESH_SUPPORT();
2921 BT_CHECK_MESH_INIT_STATUS();
2922 BT_CHECK_INPUT_PARAMETER(group);
2923 BT_CHECK_INPUT_PARAMETER(appkey);
2924 BT_CHECK_INPUT_PARAMETER(msg_params);
2925 BT_CHECK_INPUT_PARAMETER(callback);
2927 group_s = (bt_mesh_group_s*) group;
2928 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
2930 appkey_s = (bt_mesh_appkey_s*) appkey;
2931 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
2933 network_s = (bt_mesh_network_s*) group_s->parent;
2934 BT_MESH_VALIDATE_HANDLE(network_s, networks);
2936 BT_INFO("Mesh: Model msg opcode: 0x%2.2X",msg_params->opcode);
2938 memset(&req, 0x00, sizeof(bluetooth_mesh_model_msg_t));
2939 g_strlcpy(req.net_uuid, network_s->uuid, 33);
2940 req.primary_unicast = group_s->addr;
2941 req.appkey_idx = appkey_s->appkey_index;
2942 req.opcode = msg_params->opcode;
2944 if (msg_params->data) {
2945 BT_INFO("Mesh: Group msg strlen %zd message: %s",
2946 strlen(msg_params->data), msg_params->data);
2948 req.msg_len = strlen(msg_params->data);
2949 g_strlcpy(req.msg, msg_params->data, sizeof(msg_params->data) + 1);
2954 error_code = _bt_get_error_code(bluetooth_mesh_model_send_msg(&req));
2955 if (error_code != BT_ERROR_NONE) {
2956 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
2961 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_EXECUTE_MSG_COMPLETED, callback, user_data);
2962 return BT_ERROR_NONE;
2965 int bt_mesh_network_foreach_groups(bt_mesh_network_h network,
2966 bt_mesh_network_group_info_cb callback, void *user_data)
2968 int error_code = BT_ERROR_NONE;
2969 bluetooth_mesh_network_t net;
2970 bt_mesh_network_s *network_s;
2971 GPtrArray *groups = NULL;
2973 bluetooth_mesh_network_group_info_t *group_info = NULL;
2978 BT_CHECK_MESH_SUPPORT();
2979 BT_CHECK_MESH_INIT_STATUS();
2980 BT_CHECK_INPUT_PARAMETER(network);
2981 BT_CHECK_INPUT_PARAMETER(callback);
2983 BT_MESH_VALIDATE_HANDLE(network, networks);
2985 groups = g_ptr_array_new();
2986 if (groups == NULL) {
2987 BT_ERR("Mesh: OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
2988 return BT_ERROR_OUT_OF_MEMORY;
2991 network_s = (bt_mesh_network_s*)network;
2992 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
2994 g_strlcpy(net.uuid, network_s->uuid, 33);
2995 g_strlcpy(net.token.token, network_s->token, 17);
2996 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
2998 error_code = _bt_get_error_code(bluetooth_mesh_network_get_all_groups(&net, &groups));
2999 if (error_code != BT_ERROR_NONE) {
3000 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3001 g_ptr_array_free(groups, TRUE);
3005 BT_INFO("Mesh: Total number of Groups in network [%d]", groups->len);
3006 for (i = 0; i < groups->len; i++) {
3007 group_info = g_ptr_array_index(groups, i);
3009 BT_INFO("Mesh: Group Is Virtual [%s] Group Addr [0x%2.2x]",
3010 group_info->is_virtual ? "YES" : "NO", group_info->group_addr);
3012 if (group_info->is_virtual)
3013 BT_INFO("Mesh: Virtual label UUID [%s]", group_info->label_uuid);
3015 BT_INFO("Mesh: Total groups already present in Network [%d]",
3016 g_slist_length(network_s->groups));
3017 /* Find or create group in network list */
3018 if (!g_slist_find_custom(network_s->groups,
3019 GUINT_TO_POINTER(group_info->group_addr),
3020 (GCompareFunc)__compare_network_group_address)) {
3021 BT_INFO("Mesh: Its a new Group, add in network");
3022 bt_mesh_group_s *group_s;
3023 group_s = g_malloc0(sizeof(bt_mesh_group_s));
3024 group_s->addr = group_info->group_addr;
3025 group_s->parent = network_s;
3026 group_s->is_virtual = group_info->is_virtual;
3027 if (group_s->is_virtual)
3028 g_strlcpy(group_s->label_uuid, group_info->label_uuid,
3029 sizeof(group_s->label_uuid));
3030 BT_INFO("Mesh: Group [0x%2.2x] added in network", group_s->addr);
3032 network_s->groups = g_slist_append(network_s->groups, group_s);
3033 group_list = g_slist_append(group_list, group_s);
3035 BT_INFO("Mesh: Group [0x%2.2x] Already Added in network",
3036 group_info->group_addr);
3038 BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
3039 BT_ERROR_OPERATION_FAILED);
3040 error_code = BT_ERROR_OPERATION_FAILED;
3045 total = g_slist_length(network_s->groups);
3046 BT_INFO("Mesh: Total number of groups [%d]", total);
3048 BT_INFO("Mesh: No Groups added in network");
3049 callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
3052 for (l = network_s->groups; l != NULL; l = g_slist_next(l)) {
3053 bt_mesh_group_s *group_s;
3056 if (!callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total,
3057 (bt_mesh_group_h) group_s,
3062 g_ptr_array_foreach(groups, (GFunc)g_free, NULL);
3063 g_ptr_array_free(groups, TRUE);
3069 int bt_mesh_network_create_virtual_group(bt_mesh_network_h network,
3070 bt_mesh_group_h *group)
3072 int error_code = BT_ERROR_NONE;
3073 bt_mesh_network_s *network_s;
3074 bt_mesh_group_s *group_s;
3075 bluetooth_mesh_network_group_info_t req;
3076 bluetooth_mesh_network_t net;
3079 BT_CHECK_MESH_SUPPORT();
3080 BT_CHECK_MESH_INIT_STATUS();
3081 BT_CHECK_INPUT_PARAMETER(network);
3083 network_s = (bt_mesh_network_s*) network;
3085 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3087 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3088 memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3090 g_strlcpy(net.uuid, network_s->uuid, 33);
3091 g_strlcpy(net.token.token, network_s->token, 17);
3092 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3094 error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, true, 0x0000, &req));
3095 if (error_code != BT_ERROR_NONE) {
3096 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3100 group_s = g_malloc0(sizeof(bt_mesh_group_s));
3101 group_s->addr = req.group_addr;
3102 group_s->is_virtual = true;
3103 group_s->parent = network_s;
3104 g_strlcpy(group_s->label_uuid, req.label_uuid, BT_MESH_UUID_STRING_LEN + 1);
3105 BT_INFO("Mesh: Virtual Group created : Addr [0x%2.2x]", req.group_addr);
3106 BT_INFO("Mesh: Virtual Group label UUID [%s]", group_s->label_uuid);
3108 network_s->groups = g_slist_append(network_s->groups, group_s);
3109 group_list = g_slist_append(group_list, group_s);
3111 *group = (bt_mesh_group_h) group_s;
3116 int bt_mesh_network_remove_group(bt_mesh_group_h group)
3118 int error_code = BT_ERROR_NONE;
3119 bt_mesh_network_s *network_s;
3120 bt_mesh_group_s *group_s;
3121 bluetooth_mesh_network_group_info_t req;
3122 bluetooth_mesh_network_t net;
3125 BT_CHECK_MESH_SUPPORT();
3126 BT_CHECK_INPUT_PARAMETER(group);
3128 group_s = (bt_mesh_group_s*) group;
3129 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3130 network_s = group_s->parent;
3132 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3133 memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3135 BT_INFO("Mesh: Remove Group [0x%2.2x] from network", group_s->addr);
3136 BT_INFO("Mesh: Is Group Virtual [%s]", group_s->is_virtual? "YES": "NO");
3137 if (group_s->is_virtual)
3138 BT_INFO("Mesh: Group Label UUID [%s]", group_s->label_uuid);
3140 /* Fill Network Info */
3141 g_strlcpy(net.uuid, network_s->uuid, 33);
3142 g_strlcpy(net.token.token, network_s->token, 17);
3143 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3145 /* Fill Group Info */
3146 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3147 req.is_virtual = group_s->is_virtual;
3148 req.group_addr = group_s->addr;
3150 g_strlcpy(req.label_uuid, group_s->label_uuid, sizeof(req.label_uuid));
3152 error_code = _bt_get_error_code(bluetooth_mesh_network_remove_group(&net, &req));
3153 if (error_code != BT_ERROR_NONE) {
3154 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3159 network_s->groups = g_slist_remove(network_s->groups, group_s);
3160 group_list = g_slist_remove(group_list, group_s);
3164 return BT_ERROR_NONE;
3167 int bt_mesh_network_create_group(bt_mesh_network_h network,
3168 uint16_t grp_addr, bt_mesh_group_h *group)
3170 int error_code = BT_ERROR_NONE;
3171 bt_mesh_network_s *network_s;
3172 bt_mesh_group_s *group_s;
3173 bluetooth_mesh_network_t net;
3174 bluetooth_mesh_network_group_info_t req;
3178 BT_CHECK_MESH_SUPPORT();
3179 BT_CHECK_MESH_INIT_STATUS();
3180 BT_CHECK_INPUT_PARAMETER(network);
3181 BT_CHECK_INPUT_PARAMETER(group);
3183 network_s = (bt_mesh_network_s*) network;
3185 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3187 /* Check for valid Group Address */
3188 if (!BT_MESH_IS_GROUP(grp_addr)) {
3189 BT_INFO("Mesh: group Address [0x%2.2x] is not valid Group Address",
3191 return BT_ERROR_INVALID_PARAMETER;
3194 l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(grp_addr),
3195 (GCompareFunc)__compare_group_address);
3198 BT_INFO("Mesh: Group [0x%2.2x]Already exist", grp_addr);
3200 *group = (bt_mesh_group_h) group_s;
3204 memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
3205 memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
3207 /* Fill Network Info */
3208 g_strlcpy(net.uuid, network_s->uuid, 33);
3209 g_strlcpy(net.token.token, network_s->token, 17);
3210 g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
3212 error_code = _bt_get_error_code(bluetooth_mesh_network_create_group(&net, false, grp_addr, &req));
3213 if (error_code != BT_ERROR_NONE) {
3214 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3218 BT_INFO("Mesh: Group created [0x%2.2x]", grp_addr);
3219 group_s = g_malloc0(sizeof(bt_mesh_group_s));
3220 group_s->addr = grp_addr;
3221 group_s->is_virtual = false;
3222 group_s->parent = network_s;
3224 network_s->groups = g_slist_append(network_s->groups, group_s);
3225 group_list = g_slist_append(group_list, group_s);
3227 *group = (bt_mesh_group_h) group_s;
3232 int bt_mesh_model_configure_group_subscription(bt_mesh_model_subscription_op_e model_op,
3233 bt_mesh_model_h model, bt_mesh_group_h group,
3234 bt_mesh_model_subscription_op_cb callback, void *user_data)
3236 int error_code = BT_ERROR_NONE;
3237 bt_mesh_model_s *model_s;
3238 bt_mesh_element_s *element_s;
3239 bt_mesh_node_s *node_s;
3240 bt_mesh_network_s *network_s;
3241 bt_mesh_group_s *group_s;
3242 bluetooth_mesh_model_configure_t req;
3245 BT_CHECK_MESH_SUPPORT();
3246 BT_CHECK_MESH_INIT_STATUS();
3247 BT_CHECK_INPUT_PARAMETER(model);
3248 BT_CHECK_INPUT_PARAMETER(group);
3249 BT_CHECK_INPUT_PARAMETER(callback);
3251 model_s = (bt_mesh_model_s*) model;
3252 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3254 group_s = (bt_mesh_group_s*) group;
3255 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3257 element_s = (bt_mesh_element_s*) model_s->parent;
3258 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3260 node_s = (bt_mesh_node_s*) element_s->parent;
3261 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3263 network_s = (bt_mesh_network_s*) node_s->parent;
3264 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3266 BT_INFO("Mesh: Configure Group Request [%d]", model_op);
3267 BT_INFO("Mesh: Group Addr [0x%2.2x] Is Virtual [%s]",
3268 group_s->addr, group_s->is_virtual? "YES" : "NO");
3270 /* Check group belongs to the same network */
3271 if (network_s != group_s->parent)
3272 return BT_ERROR_INVALID_PARAMETER;
3274 /* Check group is non virtual */
3275 if (group_s->is_virtual)
3276 return BT_ERROR_INVALID_PARAMETER;
3278 /* Return error, if node is not attached */
3279 if (!node_s->is_attached)
3280 return BT_ERROR_INVALID_PARAMETER;
3282 if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
3283 req.sub_addr = group_s->addr;
3284 req.is_virtual_sub = false;
3286 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3287 req.primary_unicast = node_s->unicast;
3288 req.elem_index = element_s->index;
3289 req.model = model_s->id;
3291 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_group_sub(&req));
3292 if (error_code != BT_ERROR_NONE) {
3293 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3298 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_SUB, callback, user_data);
3302 int bt_mesh_model_configure_virtual_group_subscription(bt_mesh_model_subscription_op_e model_op,
3303 bt_mesh_model_h model, bt_mesh_group_h group,
3304 bt_mesh_model_subscription_op_cb callback,
3307 int error_code = BT_ERROR_NONE;
3308 bt_mesh_model_s *model_s;
3309 bt_mesh_element_s *element_s;
3310 bt_mesh_node_s *node_s;
3311 bt_mesh_network_s *network_s;
3312 bt_mesh_group_s *group_s;
3313 bluetooth_mesh_model_configure_t req;
3316 BT_CHECK_MESH_SUPPORT();
3317 BT_CHECK_MESH_INIT_STATUS();
3318 BT_CHECK_INPUT_PARAMETER(model);
3319 BT_CHECK_INPUT_PARAMETER(group);
3320 BT_CHECK_INPUT_PARAMETER(callback);
3322 model_s = (bt_mesh_model_s*) model;
3323 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3325 group_s = (bt_mesh_group_s*) group;
3326 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3328 element_s = (bt_mesh_element_s*) model_s->parent;
3329 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3331 node_s = (bt_mesh_node_s*) element_s->parent;
3332 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3334 network_s = (bt_mesh_network_s*) node_s->parent;
3335 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3337 BT_INFO("Mesh: Configure Virtual Group Request [%d]", model_op);
3338 BT_INFO("Mesh: Group Addr [0x%2.2x] Is Virtual [%s]",
3339 group_s->addr, group_s->is_virtual? "YES" : "NO");
3341 /* Check group belongs to the same network */
3342 if (network_s != group_s->parent)
3343 return BT_ERROR_INVALID_PARAMETER;
3345 /* Check group is non virtual */
3346 if (!group_s->is_virtual)
3347 return BT_ERROR_INVALID_PARAMETER;
3349 /* Return error, if node is not attached */
3350 if (!node_s->is_attached)
3351 return BT_ERROR_INVALID_PARAMETER;
3353 if (model_op != BT_MESH_MODEL_SUBSCRIPTION_DELETE_ALL)
3354 req.sub_addr = group_s->addr;
3355 req.is_virtual_sub = true;
3357 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3358 req.primary_unicast = node_s->unicast;
3359 req.elem_index = element_s->index;
3360 req.model = model_s->id;
3362 error_code = _bt_get_error_code(bluetooth_mesh_model_configure_virtual_group_sub(&req));
3363 if (error_code != BT_ERROR_NONE) {
3364 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3369 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_GROUP_VIR_SUB, callback, user_data);
3373 int bt_mesh_model_get_subscription_list(bt_mesh_model_h model,
3374 bt_mesh_model_subscription_list_cb callback, void *user_data)
3376 int error_code = BT_ERROR_NONE;
3377 bt_mesh_model_s *model_s;
3378 bt_mesh_element_s *element_s;
3379 bt_mesh_node_s *node_s;
3380 bt_mesh_network_s *network_s;
3381 bluetooth_mesh_model_configure_t req;
3384 BT_CHECK_MESH_SUPPORT();
3385 BT_CHECK_MESH_INIT_STATUS();
3386 BT_CHECK_INPUT_PARAMETER(model);
3387 BT_CHECK_INPUT_PARAMETER(callback);
3389 model_s = (bt_mesh_model_s*) model;
3390 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3392 element_s = (bt_mesh_element_s*) model_s->parent;
3393 BT_CHECK_INPUT_PARAMETER(element_s);
3394 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3396 node_s = (bt_mesh_node_s*) element_s->parent;
3397 BT_CHECK_INPUT_PARAMETER(node_s);
3398 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3400 network_s = (bt_mesh_network_s*) node_s->parent;
3401 BT_CHECK_INPUT_PARAMETER(network_s);
3402 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3404 /* Return error, if node is not attached */
3405 if (!node_s->is_attached)
3406 return BT_ERROR_INVALID_PARAMETER;
3408 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3410 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3411 req.primary_unicast = node_s->unicast;
3412 req.elem_index = element_s->index;
3413 req.model = model_s->id;
3415 error_code = _bt_get_error_code(bluetooth_mesh_model_get_subscriptopn_list(&req));
3416 if (error_code != BT_ERROR_NONE) {
3417 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3422 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_SUB_LIST, callback, user_data);
3426 int bt_mesh_model_set_publication(bt_mesh_model_h model, bt_mesh_appkey_h appkey,
3427 bt_mesh_group_h group,
3428 bt_mesh_model_pub_params_s *params,
3429 bt_mesh_model_publication_status_cb callback,
3432 int error_code = BT_ERROR_NONE;
3433 bt_mesh_model_s *model_s;
3434 bt_mesh_element_s *element_s;
3435 bt_mesh_node_s *node_s;
3436 bt_mesh_appkey_s *appkey_s;
3437 bt_mesh_network_s *network_s;
3438 bt_mesh_group_s *group_s;
3439 bluetooth_mesh_model_configure_t req;
3442 BT_CHECK_MESH_SUPPORT();
3443 BT_CHECK_MESH_INIT_STATUS();
3444 BT_CHECK_INPUT_PARAMETER(model);
3445 BT_CHECK_INPUT_PARAMETER(appkey);
3446 BT_CHECK_INPUT_PARAMETER(group);
3447 BT_CHECK_INPUT_PARAMETER(params);
3448 BT_CHECK_INPUT_PARAMETER(callback);
3450 model_s = (bt_mesh_model_s*) model;
3451 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3453 appkey_s = (bt_mesh_appkey_s*) appkey;
3454 BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
3456 group_s = (bt_mesh_group_s*) group;
3457 BT_MESH_VALIDATE_HANDLE(group_s, group_list);
3459 element_s = (bt_mesh_element_s*) model_s->parent;
3460 BT_CHECK_INPUT_PARAMETER(element_s);
3461 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3463 node_s = (bt_mesh_node_s*) element_s->parent;
3464 BT_CHECK_INPUT_PARAMETER(node_s);
3465 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3467 network_s = (bt_mesh_network_s*) node_s->parent;
3468 BT_CHECK_INPUT_PARAMETER(network_s);
3469 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3471 if (group_s->parent != network_s)
3472 return BT_ERROR_INVALID_PARAMETER;
3474 if (params->num_steps > BT_MESH_MAX_PUBISH_PERIOD_STEPS)
3475 return BT_ERROR_INVALID_PARAMETER;
3476 if (params->retrans_cnt > BT_MESH_MAX_PUBISH_RETRANSMIT_COUNT)
3477 return BT_ERROR_INVALID_PARAMETER;
3478 if (params->retrans_step > BT_MESH_MAX_PUBISH_RETRANSMIT_INTERVAL_STEPS)
3479 return BT_ERROR_INVALID_PARAMETER;
3481 /* Return error, if node is not attached */
3482 if (!node_s->is_attached)
3483 return BT_ERROR_INVALID_PARAMETER;
3485 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3487 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3488 req.primary_unicast = node_s->unicast;
3489 req.elem_index = element_s->index;
3490 req.model = model_s->id;
3491 req.appkey_idx = appkey_s->appkey_index;
3492 req.pub_addr = group_s->addr;
3494 req.ttl = params->ttl;
3495 req.period = params->num_steps;
3496 req.period = req.period << 2;
3497 req.period |= params->per_res;
3498 req.retransmit = params->retrans_cnt;
3499 req.retransmit = req.retransmit << 5;
3500 req.retransmit |= params->retrans_step;
3502 error_code = _bt_get_error_code(bluetooth_mesh_model_set_publication(&req));
3503 if (error_code != BT_ERROR_NONE) {
3504 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3509 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);
3513 int bt_mesh_model_get_publication(bt_mesh_model_h model,
3514 bt_mesh_model_publication_status_cb callback, void *user_data)
3516 int error_code = BT_ERROR_NONE;
3517 bt_mesh_model_s *model_s;
3518 bt_mesh_element_s *element_s;
3519 bt_mesh_node_s *node_s;
3520 bt_mesh_network_s *network_s;
3521 bluetooth_mesh_model_configure_t req;
3524 BT_CHECK_MESH_SUPPORT();
3525 BT_CHECK_MESH_INIT_STATUS();
3526 BT_CHECK_INPUT_PARAMETER(model);
3527 BT_CHECK_INPUT_PARAMETER(callback);
3529 model_s = (bt_mesh_model_s*) model;
3530 BT_MESH_VALIDATE_HANDLE(model_s, model_list);
3532 element_s = (bt_mesh_element_s*) model_s->parent;
3533 BT_CHECK_INPUT_PARAMETER(element_s);
3534 BT_MESH_VALIDATE_HANDLE(element_s, element_list);
3536 node_s = (bt_mesh_node_s*) element_s->parent;
3537 BT_CHECK_INPUT_PARAMETER(node_s);
3538 BT_MESH_VALIDATE_HANDLE(node_s, node_list);
3540 network_s = (bt_mesh_network_s*) node_s->parent;
3541 BT_CHECK_INPUT_PARAMETER(network_s);
3542 BT_MESH_VALIDATE_HANDLE(network_s, networks);
3544 /* Return error, if node is not attached */
3545 if (!node_s->is_attached)
3546 return BT_ERROR_INVALID_PARAMETER;
3548 memset(&req, 0x00, sizeof(bluetooth_mesh_model_configure_t));
3550 g_strlcpy(req.net_uuid, network_s->uuid, 33);
3551 req.primary_unicast = node_s->unicast;
3552 req.elem_index = element_s->index;
3553 req.model = model_s->id;
3555 error_code = _bt_get_error_code(bluetooth_mesh_model_get_publication(&req));
3556 if (error_code != BT_ERROR_NONE) {
3557 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
3562 _bt_set_cb(BT_EVENT_MESH_NODE_MODEL_PUBLICATION, callback, user_data);