4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6 * @author: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
32 #include "bt-service-common.h"
33 #include "bt-service-core-adapter.h"
34 #include "bt-service-event-receiver.h"
35 #include "bt-request-handler.h"
36 #include "bluetooth-api.h"
38 #include "bluetooth-api.h"
39 #include "bluetooth-mesh-api.h"
40 #include "bt-internal-types.h"
41 #include "bt-service-util.h"
42 #include "bt-service-common.h"
43 #include "bt-service-event.h"
45 #include "bt-service-mesh-network.h"
46 #include "bt-service-mesh-cdb.h"
47 #include "bt-service-mesh-main.h"
48 #include "bt-service-mesh-nodes.h"
49 #include "bt-service-mesh-keys.h"
50 #include "bt-service-mesh-util.h"
52 #include "bt-internal-types.h"
54 #include <oal-hardware.h>
55 #include <oal-manager.h>
56 #include <oal-event.h>
57 #include <oal-adapter-mgr.h>
58 #include <oal-device-mgr.h>
61 /* Temp local node structure.
62 Create & save node temporarily till network creation */
66 bluetooth_mesh_vendor_info_t vendor_info;
67 uint8_t node_uuid[16];
69 uint16_t prim_unicast;
73 /* List of CDB's for the created networks */
74 static GSList *cdb_list = NULL;
76 /* List of local ndoes to be created: Free memory once saved in DB */
77 static GSList *temp_nodes = NULL;
79 /* Scanning state: Unprovisioned device scan */
80 static bool bt_mesh_is_scanning = false;
82 /* Provisoning state */
83 static bool bt_mesh_is_provisoning = false;
85 static gint __mesh_compare_hex_uuid(gconstpointer data,
86 gconstpointer user_data)
88 const mesh_local_node_t *u1 = data;
89 const uint8_t *u2 = user_data;
91 retv_if(NULL == u1, -1);
92 retv_if(NULL == u2, -1);
94 return memcmp(u1->node_uuid, u2, 16);
97 static gint __mesh_compare_app_network_uuid(
98 gconstpointer data, gconstpointer user_data)
100 const _bt_mesh_cdb_t *cdb = data;
101 const uint8_t *net_uuid = user_data;
103 retv_if(NULL == cdb, -1);
104 retv_if(NULL == net_uuid, -1);
106 return memcmp(net_uuid, cdb->uuid, 16);
109 static gint __mesh_compare_app_cdb_token(gconstpointer data,
110 gconstpointer user_data)
113 const _bt_mesh_cdb_t *cdb = data;
114 const char *token = user_data;
116 retv_if(NULL == cdb, -1);
117 retv_if(NULL == token, -1);
119 _bt_mesh_util_convert_hex_to_string((uint8_t *) cdb->token,
122 BT_INFO("Mesh: Match Token 1[%s] Token 2 [%s]",
124 return g_strcmp0(token_str, token);
127 static gint __mesh_compare_addr(
128 const void *a, const void *b)
130 const _bt_mesh_group_t *grp = a;
131 uint16_t addr = GPOINTER_TO_UINT(b);
132 BT_INFO("Mesh: Network group addr [0x%2.2x]", grp->grp_addr);
133 BT_INFO("Mesh: To be matched group addr [0x%2.2x]", addr);
135 return (grp->grp_addr - addr);
138 int _bt_mesh_load_app_networks(const char *app_cred)
140 int ret = BLUETOOTH_ERROR_NONE;
142 /* Load Mesh Networks for the current app */
143 if (!_bt_mesh_util_is_directory_exists(MESH_CDB_DEFAULT_DIR_PATH))
144 return BLUETOOTH_ERROR_INTERNAL;
149 static void __bt_mesh_free_temp_node(mesh_local_node_t *tmp)
153 temp_nodes = g_slist_remove(temp_nodes, tmp);
154 g_free((gpointer)tmp->app_cred);
155 g_free((gpointer)tmp->sender);
156 /* Do not free tmp->model_list here
157 This memory is also being used in HAL layer
158 This memory will be freed with the call of __mesh_client_disconnected */
159 tmp->model_list = NULL;
163 int _bt_mesh_network_request_provisioning_data_request(uint8_t net_uuid[],
167 int ret = OAL_STATUS_SUCCESS;
169 char uuid_string[33];
171 _bt_mesh_util_convert_hex_to_string(net_uuid, 16,
172 uuid_string, sizeof(uuid_string));
173 BT_INFO("Mesh: Provisioning Data requested for network [%s]",
176 unicast = _bt_mesh_node_get_next_unicast(net_uuid,
177 MESH_DEFAULT_START_ADDRESS,
178 MESH_DEFAULT_MAX_ADDRESS, count);
179 BT_INFO("Mesh: Network: Got unicast [%4.4x]", unicast);
181 memcpy(uuid.uuid, net_uuid, 16);
182 /* Register Mesh Node */
183 ret = mesh_network_send_provisioning_data(&uuid,
184 MESH_PRIMARY_NET_IDX, unicast);
185 if (ret != OAL_STATUS_SUCCESS) {
186 BT_ERR("ret: %d", ret);
187 return BLUETOOTH_ERROR_INTERNAL;
189 return BLUETOOTH_ERROR_NONE;
192 int _bt_mesh_network_remove_node_configuration(
193 bluetooth_mesh_node_info_t *node)
196 _bt_mesh_cdb_t *cdb_cfg = NULL;
197 uint8_t net_uuid[16];
198 BT_INFO("Mesh: Remove Node Configuration: Unicast [0x%2.2x]",
199 node->primary_unicast);
201 _bt_mesh_util_convert_string_to_hex(node->net_uuid,
202 strlen(node->net_uuid), net_uuid, 16);
205 l = g_slist_find_custom(cdb_list, net_uuid,
206 __mesh_compare_app_network_uuid);
208 BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
209 return BLUETOOTH_ERROR_INVALID_PARAM;
212 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
214 if (_bt_mesh_conf_delete_node(cdb_cfg, node->primary_unicast)) {
215 BT_INFO("Mesh: Node Entry deleted from Config DB");
216 if (!_bt_mesh_node_del_node(cdb_cfg, node->primary_unicast)) {
217 BT_ERR("Mesh: Node Entry could not be unloaded from memory");
218 return BLUETOOTH_ERROR_INTERNAL;
221 BT_ERR("Mesh: Node Entry could not be deleted from Config DB");
222 return BLUETOOTH_ERROR_INTERNAL;
224 return BLUETOOTH_ERROR_NONE;
227 void _bt_check_mesh_app_termination(const char *name)
230 _bt_mesh_cdb_t *cdb_cfg = NULL;
231 const char *app_cred = NULL;
232 BT_INFO("Mesh: App terminated [%s]", name);
234 /* TODO: Fetch app cred, when support is added */
236 for (l = cdb_list; l != NULL;) {
237 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
240 if (g_strcmp0(cdb_cfg->owner, name) == 0) {
242 bluetooth_mesh_network_t network;
243 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
245 _bt_mesh_util_convert_hex_to_string((uint8_t *) cdb_cfg->uuid,
246 16, network.uuid, sizeof(network.uuid));
248 BT_INFO("Mesh: Got Network for unloading: UUID [%s]",
251 if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_unload(app_cred, name, &network))
252 BT_ERR("Mesh: Network unloading failed!!");
254 BT_INFO("Mesh: Network unloading Success!!");
257 _bt_mesh_handle_app_termination(name);
260 void _bt_mesh_network_unload_net_configuration(_bt_mesh_cdb_t *cdb_cfg)
262 BT_INFO("Mesh: Unload Network Configuration");
264 /* Unload Network from Keys */
265 _bt_mesh_keys_unload_net(cdb_cfg->uuid);
267 /* Unload Network from Nodes */
268 _bt_mesh_node_unload_net(cdb_cfg->uuid);
270 cdb_list = g_slist_remove(cdb_list, cdb_cfg);
271 _bt_mesh_conf_free(cdb_cfg);
272 BT_INFO("Mesh: CDB freed from memory: Remaining Networks [%d]",
273 g_slist_length(cdb_list));
276 int _bt_mesh_network_remove_net_configuration(
277 bluetooth_mesh_network_t *net)
281 _bt_mesh_cdb_t *cdb_cfg = NULL;
282 uint8_t net_uuid[16];
283 BT_INFO("Mesh: Remove network Configuration");
285 _bt_mesh_util_convert_string_to_hex(net->uuid,
286 strlen(net->uuid), net_uuid, 16);
289 l = g_slist_find_custom(cdb_list, net_uuid,
290 __mesh_compare_app_network_uuid);
292 BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
293 return BLUETOOTH_ERROR_INVALID_PARAM;
296 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
298 /* Create the CDB for the network */
299 file_path = g_strdup_printf("%s.bak", cdb_cfg->cfg_fname);
301 BT_INFO("Mesh: CDB File path[%s]", cdb_cfg->cfg_fname);
302 BT_INFO("Mesh: CDB Backup File path[%s]", file_path);
304 /* Remove the config */
305 if (!_bt_mesh_util_delete_file(cdb_cfg->cfg_fname))
306 return BLUETOOTH_ERROR_INTERNAL;
308 /* Remove the config backup */
309 if (!_bt_mesh_util_delete_file(file_path))
310 return BLUETOOTH_ERROR_INTERNAL;
311 BT_INFO("Mesh: Config DB file removed!!");
313 cdb_list = g_slist_remove(cdb_list, cdb_cfg);
314 _bt_mesh_conf_free(cdb_cfg);
315 BT_INFO("Mesh: CDB freed from memory");
320 /* Unload Network from Keys */
321 _bt_mesh_keys_unload_net(net_uuid);
323 /* Unload Network from Nodes */
324 _bt_mesh_node_unload_net(net_uuid);
326 BT_INFO("Mesh: Cleanup Done!");
327 return BLUETOOTH_ERROR_NONE;
330 int _bt_mesh_network_create_cdb(int result,
331 const char *sender, const char *app_creds,
332 uint8_t uuid[16], uint8_t token[8],
335 char *dir_path = NULL;
336 char *file_path = NULL;
338 mesh_local_node_t *tmp;
339 _bt_mesh_cdb_t *cdb_cfg = NULL;
340 char uuid_string[33];
341 char token_string[17];
343 _bt_mesh_util_convert_hex_to_string(uuid, 16,
344 uuid_string, sizeof(uuid_string));
345 _bt_mesh_util_convert_hex_to_string(token, 8,
346 token_string, sizeof(token_string));
347 BT_INFO("Mesh: Create CDB request for network UUID [%s] token [%s]",
348 uuid_string, token_string);
349 BT_INFO("Mesh: Temporary node count [%d]",
350 g_slist_length(temp_nodes));
353 l = g_slist_find_custom(temp_nodes, uuid,
354 __mesh_compare_hex_uuid);
356 BT_ERR("Mesh: Temp Node not found for the UUID [%s]",
358 return BLUETOOTH_ERROR_INTERNAL;
361 tmp = (mesh_local_node_t*)l->data;
363 if (result != BLUETOOTH_ERROR_NONE) {
364 /* Free the node structure */
365 __bt_mesh_free_temp_node(tmp);
369 BT_INFO("Mesh: Create CDB for the New Network [%s]",
371 /* Stat/Create directory for new CDB file */
372 dir_path = g_strdup_printf(MESH_CDB_DEFAULT_DIR_PATH"/%s/",
374 BT_INFO("Mesh: Directory path for new Network CDB [%s]",
376 if (!_bt_mesh_util_create_directory(dir_path)) {
378 __bt_mesh_free_temp_node(tmp);
379 return BLUETOOTH_ERROR_INTERNAL;
382 BT_INFO("Mesh: Directory Created successfully");
383 /* Create the CDB for the network */
384 file_path = g_strdup_printf("%s%s_config.json",
385 dir_path, uuid_string);
386 BT_INFO("Mesh: CDB File path[%s]", file_path);
387 BT_INFO("Mesh: CDB App Cred[%s]", app_creds);
388 cdb_cfg = _bt_mesh_conf_database_create(file_path, uuid,
389 token, network, sender, app_creds);
396 /* Free the memory of temporary node
397 which was created during Network creation */
398 __bt_mesh_free_temp_node(tmp);
399 return BLUETOOTH_ERROR_INTERNAL;
401 BT_INFO("Mesh: CDB CFG file created successfully");
403 _bt_mesh_conf_set_unicast_address_range(cdb_cfg,
404 MESH_DEFAULT_START_ADDRESS,
405 MESH_DEFAULT_MAX_ADDRESS);
406 BT_INFO("Mesh: Address range Set for network");
408 /* Create new network for saving network specific Keys */
409 _bt_mesh_keys_load_net(cdb_cfg->uuid);
410 BT_INFO("Mesh: Address range Set for network");
411 _bt_mesh_keys_add_net_key(cdb_cfg->uuid,
412 MESH_PRIMARY_NET_IDX);
413 BT_INFO("Mesh: Primary net key added to network memeory");
414 _bt_mesh_conf_insert_network_key(cdb_cfg,
415 MESH_PRIMARY_NET_IDX,
416 MESH_KEY_REFRESH_PHASE_NONE);
417 BT_INFO("Mesh: Primary net key added to CDB");
419 /* Create new network for saving network specific nodes */
420 _bt_mesh_node_load_net(cdb_cfg->uuid);
421 BT_INFO("Mesh: local Node loaded to memory");
422 _bt_mesh_node_add_node(cdb_cfg->uuid, tmp->node_uuid,
423 tmp->prim_unicast, tmp->num_elems,
424 MESH_PRIMARY_NET_IDX);
425 BT_INFO("Mesh: Added basic info (num elems, UUID, primary NetIDx)");
427 /* Add Primary Node as 1st entry in CDB */
428 _bt_mesh_conf_insert_node_object(cdb_cfg, /* Dev UUID */uuid,
429 tmp->num_elems, tmp->prim_unicast,
430 MESH_PRIMARY_NET_IDX);
431 BT_INFO("Mesh: Added Local node's basic info in CDB");
433 cdb_list = g_slist_append(cdb_list, cdb_cfg);
434 BT_INFO("Mesh: CDB added to list");
436 __bt_mesh_free_temp_node(tmp);
437 BT_INFO("Mesh: temp node freed");
438 return BLUETOOTH_ERROR_NONE;
441 int _bt_mesh_network_unload(const char *app_cred,
442 const char *sender, bluetooth_mesh_network_t *network)
446 _bt_mesh_cdb_t *cdb_cfg;
447 int ret = OAL_STATUS_SUCCESS;
449 BT_INFO("Mesh: Unload Network Configuration");
450 /* If Scanning is going on */
451 if (_bt_mesh_is_provisioning() ||
452 _bt_mesh_is_scanning()) {
453 BT_ERR("Device is buzy..");
454 return BLUETOOTH_ERROR_DEVICE_BUSY;
457 _bt_mesh_util_convert_string_to_hex(network->uuid,
458 strlen(network->uuid), net_uuid.uuid, 16);
460 /* Release Mesh Network */
461 ret = mesh_network_release(&net_uuid);
462 if (ret != OAL_STATUS_SUCCESS) {
463 BT_ERR("ret: %d", ret);
464 return BLUETOOTH_ERROR_INTERNAL;
467 BT_INFO("Mesh: Network released");
470 l = g_slist_find_custom(cdb_list, net_uuid.uuid,
471 __mesh_compare_app_network_uuid);
473 BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
474 return BLUETOOTH_ERROR_INVALID_PARAM;
477 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
479 _bt_mesh_network_unload_net_configuration(cdb_cfg);
480 return BLUETOOTH_ERROR_NONE;
483 int _bt_mesh_network_destroy(const char *app_cred,
484 const char *sender, bluetooth_mesh_network_t *network)
486 int ret = OAL_STATUS_SUCCESS;
489 /* If Scanning is going on */
490 if (_bt_mesh_is_provisioning() ||
491 _bt_mesh_is_scanning()) {
492 BT_ERR("Device is buzy..");
493 return BLUETOOTH_ERROR_DEVICE_BUSY;
495 _bt_mesh_util_convert_string_to_hex(network->uuid,
496 strlen(network->uuid), net_uuid.uuid, 16);
497 /* Destroy Mesh Network */
498 ret = mesh_network_destroy(&net_uuid);
499 if (ret != OAL_STATUS_SUCCESS) {
500 BT_ERR("ret: %d", ret);
501 return BLUETOOTH_ERROR_INTERNAL;
504 return BLUETOOTH_ERROR_NONE;
507 int _bt_mesh_network_scan(const char *app_cred,
509 bluetooth_mesh_network_t *network,
510 bluetooth_mesh_scan_param_t *param)
512 int ret = OAL_STATUS_SUCCESS;
515 /* If Scanning is going on */
516 if (_bt_mesh_is_provisioning() ||
517 _bt_mesh_is_scanning()) {
518 BT_ERR("Device is buzy..");
519 return BLUETOOTH_ERROR_DEVICE_BUSY;
521 _bt_mesh_util_convert_string_to_hex(network->uuid,
522 strlen(network->uuid), net_uuid.uuid, 16);
523 /* Register Mesh Node */
524 ret = mesh_network_start_scan(&net_uuid,
525 (oal_mesh_scan_params_t*) param);
526 if (ret != OAL_STATUS_SUCCESS) {
527 BT_ERR("ret: %d", ret);
528 return BLUETOOTH_ERROR_INTERNAL;
531 /* Set scanning state to true */
532 _bt_mesh_set_scanning_state(true);
533 return BLUETOOTH_ERROR_NONE;
536 int _bt_mesh_network_scan_cancel(const char *app_cred,
537 const char *sender, bluetooth_mesh_network_t *network)
539 int ret = OAL_STATUS_SUCCESS;
542 if (!_bt_mesh_is_scanning()) {
543 BT_INFO("Mesh: Scanning is not ongoing");
544 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
546 _bt_mesh_util_convert_string_to_hex(network->uuid,
547 strlen(network->uuid), net_uuid.uuid, 16);
549 /* Cancel unprovisioned device scan */
550 ret = mesh_network_scan_cancel(&net_uuid);
551 if (ret != OAL_STATUS_SUCCESS) {
552 BT_ERR("ret: %d", ret);
553 return BLUETOOTH_ERROR_INTERNAL;
556 return BLUETOOTH_ERROR_NONE;
559 int _bt_mesh_network_set_provisioner_caps(const char *app_cred,
560 const char *sender, bluetooth_mesh_network_t *network,
561 bluetooth_mesh_provisioner_caps_t *caps)
563 int ret = OAL_STATUS_SUCCESS;
566 _bt_mesh_util_convert_string_to_hex(network->uuid,
567 strlen(network->uuid), net_uuid.uuid, 16);
569 /* Set provisioning capabilities */
570 ret = mesh_network_set_provisioning_capabilities(&net_uuid,
571 (oal_mesh_capabilities_t*) caps);
572 if (ret != OAL_STATUS_SUCCESS) {
573 BT_ERR("ret: %d", ret);
574 return BLUETOOTH_ERROR_INTERNAL;
577 return BLUETOOTH_ERROR_NONE;
580 bool _bt_mesh_is_scanning(void)
582 return bt_mesh_is_scanning;
585 void _bt_mesh_set_scanning_state(bool state)
587 bt_mesh_is_scanning = state;
590 bool _bt_mesh_is_provisioning(void)
592 return bt_mesh_is_provisoning;
595 void _bt_mesh_set_provisioning_state(bool state)
597 bt_mesh_is_provisoning = state;
600 int _bt_mesh_network_provision_device(const char *app_cred,
602 bluetooth_mesh_provisioning_request_t *req)
604 int ret = OAL_STATUS_SUCCESS;
608 /* If Scanning is going on */
609 if (_bt_mesh_is_provisioning() ||
610 _bt_mesh_is_scanning()) {
611 BT_ERR("Device is buzy..");
612 return BLUETOOTH_ERROR_DEVICE_BUSY;
615 _bt_mesh_util_convert_string_to_hex(req->net_uuid,
616 strlen(req->net_uuid), net_uuid.uuid, 16);
617 _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
618 strlen(req->dev_uuid), dev_uuid.uuid, 16);
620 ret = mesh_network_provision_device(&net_uuid, &dev_uuid);
622 if (ret != OAL_STATUS_SUCCESS) {
623 BT_ERR("ret: %d", ret);
624 return BLUETOOTH_ERROR_INTERNAL;
627 /* Set Provisioning state */
628 _bt_mesh_set_provisioning_state(true);
630 return BLUETOOTH_ERROR_NONE;
633 int _bt_mesh_authentication_reply(int auth_type,
634 const char *auth_value, gboolean reply)
636 int ret = OAL_STATUS_SUCCESS;
638 if (!_bt_mesh_is_provisioning())
639 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
642 return BLUETOOTH_ERROR_INVALID_PARAM;
644 ret = mesh_authentication_reply(
645 (oal_mesh_variant_authentication_e)auth_type,
648 if (ret != OAL_STATUS_SUCCESS) {
649 BT_ERR("ret: %d", ret);
650 return BLUETOOTH_ERROR_INTERNAL;
653 BT_INFO("Mesh: Scheduled Prov Auth Reply!");
654 return BLUETOOTH_ERROR_NONE;
657 int _bt_mesh_network_get_netkeys(const char *app_cred, const char *sender,
658 bluetooth_mesh_network_t *network, GArray **out_param)
661 _bt_mesh_cdb_t *cdb_cfg = NULL;
664 l = g_slist_find_custom(cdb_list, network->token.token,
665 __mesh_compare_app_cdb_token);
667 return BLUETOOTH_ERROR_INVALID_PARAM;
669 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
671 if (_bt_mesh_keys_get_netkey_list(cdb_cfg->uuid, out_param))
672 return BLUETOOTH_ERROR_NONE;
674 return BLUETOOTH_ERROR_INTERNAL;
677 int _bt_mesh_network_get_appkeys(const char *app_cred, const char *sender,
678 bluetooth_mesh_network_t *network, uint16_t net_idx,
682 _bt_mesh_cdb_t *cdb_cfg = NULL;
685 l = g_slist_find_custom(cdb_list, network->token.token,
686 __mesh_compare_app_cdb_token);
688 return BLUETOOTH_ERROR_INVALID_PARAM;
690 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
692 if (_bt_mesh_keys_get_appkey_list(cdb_cfg->uuid,
694 return BLUETOOTH_ERROR_NONE;
696 return BLUETOOTH_ERROR_INTERNAL;
699 int _bt_mesh_network_node_get_netkeys(const char *app_cred,
700 bluetooth_mesh_node_discover_t *node,
704 _bt_mesh_cdb_t *cdb_cfg = NULL;
705 uint8_t net_uuid[16];
707 _bt_mesh_util_convert_string_to_hex(node->net_uuid,
708 strlen(node->net_uuid), net_uuid, 16);
711 l = g_slist_find_custom(cdb_list, net_uuid,
712 __mesh_compare_app_network_uuid);
714 return BLUETOOTH_ERROR_INVALID_PARAM;
716 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
718 if (_bt_mesh_node_get_all_netkeys(cdb_cfg->uuid,
719 node->unicast, out_param))
720 return BLUETOOTH_ERROR_NONE;
722 return BLUETOOTH_ERROR_INTERNAL;
725 int _bt_mesh_network_node_get_appkeys(const char *app_cred,
726 const char *sender, bluetooth_mesh_node_discover_t *node,
730 _bt_mesh_cdb_t *cdb_cfg = NULL;
731 uint8_t net_uuid[16];
733 _bt_mesh_util_convert_string_to_hex(node->net_uuid,
734 strlen(node->net_uuid), net_uuid, 16);
737 l = g_slist_find_custom(cdb_list, net_uuid,
738 __mesh_compare_app_network_uuid);
740 return BLUETOOTH_ERROR_INVALID_PARAM;
742 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
744 if (_bt_mesh_node_get_all_appkeys(cdb_cfg->uuid,
745 node->unicast, node->netkey_idx, out_param))
746 return BLUETOOTH_ERROR_NONE;
748 return BLUETOOTH_ERROR_INTERNAL;
751 int _bt_mesh_element_get_models(const char *app_cred, const char *sender,
752 bluetooth_mesh_network_t *network, uint16_t unicast,
753 int elem_idx, GArray **out_param)
756 _bt_mesh_cdb_t *cdb_cfg = NULL;
759 l = g_slist_find_custom(cdb_list, network->token.token,
760 __mesh_compare_app_cdb_token);
762 return BLUETOOTH_ERROR_INVALID_PARAM;
764 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
766 if (_bt_mesh_node_get_models(cdb_cfg->uuid, unicast,
767 elem_idx, out_param))
768 return BLUETOOTH_ERROR_NONE;
770 return BLUETOOTH_ERROR_INTERNAL;
773 int _bt_mesh_network_handle_netkey_added(
774 uint8_t net_uuid[], uint16_t netkey_idx)
777 _bt_mesh_cdb_t *cdb_cfg = NULL;
779 BT_INFO("Mesh: Handle Netkey Added");
781 l = g_slist_find_custom(cdb_list, net_uuid,
782 __mesh_compare_app_network_uuid);
784 return BLUETOOTH_ERROR_INVALID_PARAM;
786 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
788 _bt_mesh_keys_add_net_key(cdb_cfg->uuid, netkey_idx);
790 if (!_bt_mesh_conf_insert_network_key(cdb_cfg,
791 netkey_idx, MESH_KEY_REFRESH_PHASE_NONE))
792 return BLUETOOTH_ERROR_INTERNAL;
794 return BLUETOOTH_ERROR_NONE;
797 int _bt_mesh_network_handle_netkey_deleted(
798 uint8_t net_uuid[], uint16_t netkey_idx)
801 _bt_mesh_cdb_t *cdb_cfg = NULL;
803 BT_INFO("Mesh: Handle Netkey Deleted");
805 l = g_slist_find_custom(cdb_list, net_uuid,
806 __mesh_compare_app_network_uuid);
808 return BLUETOOTH_ERROR_INVALID_PARAM;
810 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
812 _bt_mesh_keys_del_net_key(cdb_cfg->uuid, netkey_idx, cdb_cfg);
814 if (!_bt_mesh_conf_delete_network_key(cdb_cfg, netkey_idx))
815 return BLUETOOTH_ERROR_INTERNAL;
817 return BLUETOOTH_ERROR_NONE;
820 int _bt_mesh_network_handle_netkey_updated(
821 uint8_t net_uuid[], uint16_t netkey_idx)
824 _bt_mesh_cdb_t *cdb_cfg = NULL;
826 BT_INFO("Mesh: Handle Netkey Updated");
828 l = g_slist_find_custom(cdb_list, net_uuid,
829 __mesh_compare_app_network_uuid);
831 return BLUETOOTH_ERROR_INVALID_PARAM;
833 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
835 _bt_mesh_keys_set_net_key_phase(cdb_cfg,
836 netkey_idx, MESH_KEY_REFRESH_PHASE_ONE, true);
838 return BLUETOOTH_ERROR_NONE;
841 int _bt_mesh_network_handle_appkey_added(uint8_t net_uuid[],
842 uint16_t netkey_idx, uint16_t appkey_idx)
845 _bt_mesh_cdb_t *cdb_cfg = NULL;
847 BT_INFO("Mesh: Handle Appkey Added");
849 l = g_slist_find_custom(cdb_list, net_uuid,
850 __mesh_compare_app_network_uuid);
852 return BLUETOOTH_ERROR_INVALID_PARAM;
854 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
856 _bt_mesh_keys_add_app_key(cdb_cfg->uuid,
857 netkey_idx, appkey_idx);
859 if (!_bt_mesh_conf_insert_application_key(cdb_cfg,
860 netkey_idx, appkey_idx))
861 return BLUETOOTH_ERROR_INTERNAL;
863 return BLUETOOTH_ERROR_NONE;
866 int _bt_mesh_network_handle_appkey_deleted(uint8_t net_uuid[],
867 uint16_t netkey_idx, uint16_t appkey_idx)
870 _bt_mesh_cdb_t *cdb_cfg = NULL;
872 BT_INFO("Mesh: Handle Appkey Deleted");
874 l = g_slist_find_custom(cdb_list, net_uuid,
875 __mesh_compare_app_network_uuid);
877 return BLUETOOTH_ERROR_INVALID_PARAM;
879 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
881 _bt_mesh_keys_del_app_key(cdb_cfg->uuid, appkey_idx);
883 if (!_bt_mesh_conf_delete_application_key(cdb_cfg, appkey_idx))
884 return BLUETOOTH_ERROR_INTERNAL;
886 return BLUETOOTH_ERROR_NONE;
889 int _bt_mesh_network_set_name(const char *app_cred, const char *sender,
890 bluetooth_mesh_network_t *network)
893 _bt_mesh_cdb_t *cdb_cfg = NULL;
894 BT_INFO("Mesh: Set network name, app_creds [%s]", app_cred);
895 BT_INFO("Mesh: UUID [%s]", network->uuid);
896 BT_INFO("Mesh: Token[%s]", network->token.token);
897 BT_INFO("Mesh: Name to be set[%s]", network->name.name);
900 l = g_slist_find_custom(cdb_list,
901 network->token.token, __mesh_compare_app_cdb_token);
903 return BLUETOOTH_ERROR_INVALID_PARAM;
905 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
906 if (_bt_mesh_conf_set_network_friendly_name(cdb_cfg, network->name.name))
907 return BLUETOOTH_ERROR_NONE;
909 return BLUETOOTH_ERROR_INTERNAL;
912 int _bt_mesh_network_add_netkey(const char *app_cred,
913 const char *sender, bluetooth_mesh_network_t *network)
915 int ret = OAL_STATUS_SUCCESS;
917 _bt_mesh_cdb_t *cdb_cfg = NULL;
919 oal_mesh_key_op_e op = OAL_MESH_KEY_ADD;
923 l = g_slist_find_custom(cdb_list,
924 network->token.token, __mesh_compare_app_cdb_token);
926 return BLUETOOTH_ERROR_INVALID_PARAM;
928 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
930 if (!_bt_mesh_keys_get_new_netkey_index(cdb_cfg->uuid, &idx))
931 return BLUETOOTH_ERROR_INVALID_PARAM;
933 _bt_mesh_util_convert_string_to_hex(network->uuid,
934 strlen(network->uuid), net_uuid.uuid, 16);
936 BT_INFO("Mesh: netkey index to be created [%u]", idx);
937 ret = mesh_network_subnet_execute(&net_uuid, op, idx);
939 if (ret != OAL_STATUS_SUCCESS) {
940 BT_ERR("ret: %d", ret);
941 return BLUETOOTH_ERROR_INTERNAL;
944 return BLUETOOTH_ERROR_NONE;
947 int _bt_mesh_network_delete_netkey(const char *app_cred,
948 const char *sender, bluetooth_mesh_network_t *network,
951 int ret = OAL_STATUS_SUCCESS;
953 _bt_mesh_cdb_t *cdb_cfg = NULL;
955 oal_mesh_key_op_e op = OAL_MESH_KEY_DELETE;
958 l = g_slist_find_custom(cdb_list, network->token.token,
959 __mesh_compare_app_cdb_token);
961 return BLUETOOTH_ERROR_INVALID_PARAM;
963 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
965 /* Check if NetKey entry is present in local Network */
966 if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, index))
967 return BLUETOOTH_ERROR_INVALID_PARAM;
969 /* Check if NetKey is already added to one of the provisioned nodes */
970 if (_bt_mesh_node_is_netkey_added_in_network(cdb_cfg->uuid, index)) {
971 BT_INFO("Mesh: NetKey index [0x%2.2x] can not be deleted", index);
972 return BLUETOOTH_ERROR_INVALID_PARAM;
975 _bt_mesh_util_convert_string_to_hex(network->uuid,
976 strlen(network->uuid), net_uuid.uuid, 16);
978 BT_INFO("Mesh: netkey index to be deleted [%u]", index);
979 ret = mesh_network_subnet_execute(&net_uuid, op, index);
981 if (ret != OAL_STATUS_SUCCESS) {
982 BT_ERR("ret: %d", ret);
983 return BLUETOOTH_ERROR_INTERNAL;
986 return BLUETOOTH_ERROR_NONE;
989 int _bt_mesh_network_update_netkey(const char *app_cred,
990 const char *sender, bluetooth_mesh_network_t *network,
993 int ret = OAL_STATUS_SUCCESS;
995 _bt_mesh_cdb_t *cdb_cfg = NULL;
997 oal_mesh_key_op_e op = OAL_MESH_KEY_UPDATE;
1000 l = g_slist_find_custom(cdb_list, network->token.token,
1001 __mesh_compare_app_cdb_token);
1003 return BLUETOOTH_ERROR_INVALID_PARAM;
1005 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1007 /* Check if NetKey entry is present in local Network */
1008 if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, index))
1009 return BLUETOOTH_ERROR_INVALID_PARAM;
1011 _bt_mesh_util_convert_string_to_hex(network->uuid,
1012 strlen(network->uuid), net_uuid.uuid, 16);
1014 BT_INFO("Mesh: netkey index to be updated [%u]", index);
1015 ret = mesh_network_subnet_execute(&net_uuid, op, index);
1017 if (ret != OAL_STATUS_SUCCESS) {
1018 BT_ERR("ret: %d", ret);
1019 return BLUETOOTH_ERROR_INTERNAL;
1022 return BLUETOOTH_ERROR_NONE;
1025 int _bt_mesh_network_add_appkey(const char *app_cred,
1026 const char *sender, bluetooth_mesh_network_t *network,
1027 uint16_t netkey_idx)
1029 int ret = OAL_STATUS_SUCCESS;
1031 _bt_mesh_cdb_t *cdb_cfg = NULL;
1032 oal_uuid_t net_uuid;
1033 oal_mesh_key_op_e op = OAL_MESH_KEY_ADD;
1037 l = g_slist_find_custom(cdb_list, network->token.token,
1038 __mesh_compare_app_cdb_token);
1040 return BLUETOOTH_ERROR_INVALID_PARAM;
1042 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1044 /* Check if NetKey entry is present in local Network */
1045 if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1046 return BLUETOOTH_ERROR_INVALID_PARAM;
1048 if (!_bt_mesh_keys_get_new_appkey_index(cdb_cfg->uuid, &idx))
1049 return BLUETOOTH_ERROR_INVALID_PARAM;
1051 _bt_mesh_util_convert_string_to_hex(network->uuid,
1052 strlen(network->uuid), net_uuid.uuid, 16);
1054 BT_INFO("Mesh: AppKey index to be created [%u]", idx);
1055 ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, idx);
1057 if (ret != OAL_STATUS_SUCCESS) {
1058 BT_ERR("ret: %d", ret);
1059 return BLUETOOTH_ERROR_INTERNAL;
1062 return BLUETOOTH_ERROR_NONE;
1065 int _bt_mesh_network_update_appkey(const char *app_cred,
1066 const char *sender, bluetooth_mesh_network_t *network,
1067 uint16_t netkey_idx, uint16_t appkey_idx)
1069 int ret = OAL_STATUS_SUCCESS;
1071 _bt_mesh_cdb_t *cdb_cfg = NULL;
1072 oal_uuid_t net_uuid;
1073 oal_mesh_key_op_e op = OAL_MESH_KEY_UPDATE;
1076 l = g_slist_find_custom(cdb_list, network->token.token,
1077 __mesh_compare_app_cdb_token);
1079 return BLUETOOTH_ERROR_INVALID_PARAM;
1081 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1083 /* Check if NetKey entry is present in local Network */
1084 if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1085 return BLUETOOTH_ERROR_INVALID_PARAM;
1087 _bt_mesh_util_convert_string_to_hex(network->uuid,
1088 strlen(network->uuid), net_uuid.uuid, 16);
1090 BT_INFO("Mesh: AppKey index to be updated [%u]", appkey_idx);
1091 ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, appkey_idx);
1093 if (ret != OAL_STATUS_SUCCESS) {
1094 BT_ERR("ret: %d", ret);
1095 return BLUETOOTH_ERROR_INTERNAL;
1098 return BLUETOOTH_ERROR_NONE;
1101 int _bt_mesh_network_delete_appkey(const char *app_cred,
1102 const char *sender, bluetooth_mesh_network_t *network,
1103 uint16_t netkey_idx, uint16_t appkey_idx)
1105 int ret = OAL_STATUS_SUCCESS;
1107 _bt_mesh_cdb_t *cdb_cfg = NULL;
1108 oal_uuid_t net_uuid;
1109 oal_mesh_key_op_e op = OAL_MESH_KEY_DELETE;
1112 l = g_slist_find_custom(cdb_list, network->token.token,
1113 __mesh_compare_app_cdb_token);
1115 return BLUETOOTH_ERROR_INVALID_PARAM;
1117 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1119 /* Check if NetKey entry is present in local Network */
1120 if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1121 return BLUETOOTH_ERROR_INVALID_PARAM;
1123 /* Check if AppKey is already added to one of the provisioned nodes */
1124 if (_bt_mesh_node_is_appkey_added_in_network(cdb_cfg->uuid, appkey_idx))
1125 return BLUETOOTH_ERROR_INVALID_PARAM;
1127 _bt_mesh_util_convert_string_to_hex(network->uuid,
1128 strlen(network->uuid), net_uuid.uuid, 16);
1130 BT_INFO("Mesh: AppKey index to be deleted [%u]", appkey_idx);
1131 ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, appkey_idx);
1133 if (ret != OAL_STATUS_SUCCESS) {
1134 BT_ERR("ret: %d", ret);
1135 return BLUETOOTH_ERROR_INTERNAL;
1138 return BLUETOOTH_ERROR_NONE;
1141 int _bt_mesh_network_create(const char *app_cred, const char *sender,
1142 const char *network_name, bluetooth_mesh_node_t *node,
1145 int ret = OAL_STATUS_SUCCESS;
1147 BT_INFO("Mesh: App Credential#### [%s] sender [%s] network [%s]",
1148 app_cred, sender, network_name);
1150 /* TODO Handle Buzy status */
1151 /* Sanity Check: CDB directory creation */
1152 if (!_bt_mesh_util_is_directory_exists(MESH_CDB_DEFAULT_DIR_PATH)) {
1153 BT_INFO("MESH: CDB directory does not exist");
1154 if (!_bt_mesh_util_create_directory(MESH_CDB_DEFAULT_DIR_PATH)) {
1155 BT_ERR("MESH: Fail to create Mesh CDB directory");
1156 return BLUETOOTH_ERROR_INTERNAL;
1160 BT_INFO("Mesh: Send Local Network Creation Request to OAL");
1162 /* Register Mesh Node */
1163 ret = mesh_register_node((oal_mesh_node_t*)node, model_list, true);
1164 if (ret != OAL_STATUS_SUCCESS) {
1165 BT_ERR("ret: %d", ret);
1166 return BLUETOOTH_ERROR_INTERNAL;
1169 BT_INFO("Mesh: Request Sent to Stack successfully");
1170 /* Create a temporary node & wait for Network Created event */
1171 mesh_local_node_t *temp = g_malloc0(sizeof(mesh_local_node_t));
1172 memcpy(temp->node_uuid, node->uuid, 16);
1173 temp->num_elems = node->num_elements;
1174 temp->prim_unicast = node->primary_unicast;
1175 temp->sender = g_strdup(sender);
1176 temp->app_cred = g_strdup(app_cred);
1177 temp->vendor_info = node->vendor_info;
1178 temp->model_list = model_list;
1179 temp_nodes = g_slist_append(temp_nodes, temp);
1181 return BLUETOOTH_ERROR_NONE;
1184 bool _bt_mesh_network_save_remote_node_appkey(
1185 uint8_t net_uuid[], uint16_t remote_unicast,
1186 uint16_t netkey_idx, uint16_t appkey_idx)
1189 _bt_mesh_cdb_t *cdb_cfg = NULL;
1191 BT_INFO("Mesh: Add Appkey [0x%2.2x] to node", appkey_idx);
1193 l = g_slist_find_custom(cdb_list, net_uuid,
1194 __mesh_compare_app_network_uuid);
1198 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1200 if (_bt_mesh_node_is_appkey_exists(net_uuid,
1201 remote_unicast, appkey_idx)) {
1202 BT_INFO("Mesh: AppKey is already added to Node");
1205 if (_bt_mesh_node_add_app_key(net_uuid,
1206 remote_unicast, appkey_idx)) {
1207 BT_INFO("Mesh: Add App Key Idx [0x%2.2x] in CDB", appkey_idx);
1208 return _bt_mesh_conf_node_insert_application_key(cdb_cfg,
1209 remote_unicast, appkey_idx);
1212 BT_INFO("Mesh: AppKey idx [0x%2.2x] Failed to add in Node", appkey_idx);
1216 bool _bt_mesh_network_delete_remote_node_appkey(
1217 uint8_t net_uuid[], uint16_t remote_unicast,
1218 uint16_t netkey_idx, uint16_t appkey_idx)
1221 _bt_mesh_cdb_t *cdb_cfg = NULL;
1222 bool is_deleted = false;
1224 BT_INFO("Mesh: Delete Appkey Idx[0x%2.2x]from Node Unicast [0x%2.2x]",
1225 appkey_idx, remote_unicast);
1227 l = g_slist_find_custom(cdb_list, net_uuid,
1228 __mesh_compare_app_network_uuid);
1232 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1234 if (_bt_mesh_node_del_app_key(net_uuid,
1235 remote_unicast, appkey_idx)) {
1236 BT_INFO("Mesh: Removed Appkey from node");
1237 is_deleted = _bt_mesh_conf_node_delete_application_key(cdb_cfg,
1238 remote_unicast, appkey_idx);
1240 BT_INFO("Mesh: AppKey removed from CDB Node Entry");
1242 BT_INFO("Mesh: AppKey could not be removed from CDB Node Entry");
1248 bool _bt_mesh_network_save_remote_node_ttl(
1249 uint8_t net_uuid[], uint16_t remote_unicast,
1253 _bt_mesh_cdb_t *cdb_cfg = NULL;
1256 l = g_slist_find_custom(cdb_list, net_uuid,
1257 __mesh_compare_app_network_uuid);
1261 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1263 return _bt_mesh_conf_node_set_timetolive_value(cdb_cfg,
1264 remote_unicast, ttl);
1267 bool _bt_mesh_network_save_remote_node_netkey(
1268 uint8_t net_uuid[], uint16_t remote_unicast,
1269 uint16_t netkey_idx)
1272 _bt_mesh_cdb_t *cdb_cfg = NULL;
1275 l = g_slist_find_custom(cdb_list, net_uuid,
1276 __mesh_compare_app_network_uuid);
1280 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1282 if (_bt_mesh_node_is_netkey_exists(net_uuid,
1283 remote_unicast, netkey_idx)) {
1284 BT_INFO("Mesh: NetKey is already added to Node");
1287 if (_bt_mesh_node_add_net_key(net_uuid,
1288 remote_unicast, netkey_idx))
1289 return _bt_mesh_conf_node_insert_network_key(cdb_cfg,
1290 remote_unicast, netkey_idx);
1295 bool _bt_mesh_network_delete_remote_node_netkey(
1296 uint8_t net_uuid[], uint16_t remote_unicast,
1297 uint16_t netkey_idx)
1300 _bt_mesh_cdb_t *cdb_cfg = NULL;
1303 l = g_slist_find_custom(cdb_list, net_uuid,
1304 __mesh_compare_app_network_uuid);
1308 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1310 if (_bt_mesh_node_del_net_key(cdb_cfg, net_uuid,
1311 remote_unicast, netkey_idx))
1312 return _bt_mesh_conf_node_delete_network_key(cdb_cfg,
1313 remote_unicast, netkey_idx);
1317 bool _bt_mesh_network_save_remote_node_composition(
1318 uint8_t net_uuid[], uint16_t remote_unicast,
1319 uint8_t *data, uint16_t data_len)
1322 _bt_mesh_cdb_t *cdb_cfg = NULL;
1325 l = g_slist_find_custom(cdb_list, net_uuid,
1326 __mesh_compare_app_network_uuid);
1330 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1332 return _bt_mesh_conf_set_node_comp_data(cdb_cfg,
1333 remote_unicast, data, data_len);
1336 int _bt_mesh_network_add_remote_node(uint8_t net_uuid[],
1337 uint8_t dev_uuid[], uint16_t unicast, uint8_t count)
1340 _bt_mesh_cdb_t *cdb_cfg = NULL;
1343 l = g_slist_find_custom(cdb_list, net_uuid,
1344 __mesh_compare_app_network_uuid);
1346 return BLUETOOTH_ERROR_INVALID_PARAM;
1348 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1350 _bt_mesh_node_add_node(net_uuid, dev_uuid,
1351 unicast, count, MESH_PRIMARY_NET_IDX);
1353 /* Add Remote Node entry in CDB */
1354 _bt_mesh_conf_insert_node_object(cdb_cfg, /* Dev UUID */ dev_uuid,
1355 count, unicast, MESH_PRIMARY_NET_IDX);
1357 return BLUETOOTH_ERROR_NONE;
1360 bool _bt_mesh_node_get_vendor_features(uint8_t net_uuid[],
1361 uint16_t unicast, bluetooth_mesh_node_features_t *feats)
1364 _bt_mesh_cdb_t *cdb_cfg = NULL;
1365 BT_INFO("Mesh: Attempt to get vendor features: unicast [0x%2.2x]", unicast);
1367 l = g_slist_find_custom(cdb_list, net_uuid,
1368 __mesh_compare_app_network_uuid);
1372 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1374 BT_INFO("Mesh: Read Vendor Features from CDB");
1375 return _bt_mesh_conf_fetch_vendor_specific_info(cdb_cfg, unicast,
1376 &feats->vendor_info.companyid, &feats->vendor_info.vendorid,
1377 &feats->vendor_info.versionid, &feats->vendor_info.crpl,
1378 &feats->features.relay, &feats->features.frnd,
1379 &feats->features.proxy, &feats->features.lpn);
1382 int _bt_mesh_network_load_cdb(int result, const char *sender,
1383 const char *app_creds,
1384 uint8_t uuid[16], uint8_t token[8],
1389 _bt_mesh_cdb_t *cdb_cfg = NULL;
1391 token_str = _bt_service_convert_hex_to_string(token, 8);
1394 l = g_slist_find_custom(cdb_list, token_str,
1395 __mesh_compare_app_cdb_token);
1397 return BLUETOOTH_ERROR_INTERNAL;
1400 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1402 if (result != BLUETOOTH_ERROR_NONE)
1405 /* Create new network for saving network specific Keys */
1406 _bt_mesh_keys_load_net(cdb_cfg->uuid);
1407 if (!_bt_mesh_conf_load_all_keys(cdb_cfg)) {
1408 _bt_mesh_keys_unload_net(cdb_cfg->uuid);
1412 /* Create new network for saving network specific nodes */
1413 _bt_mesh_node_load_net(cdb_cfg->uuid);
1414 if (!_bt_mesh_conf_load_all_nodes(cdb_cfg)) {
1415 _bt_mesh_node_unload_net(cdb_cfg->uuid);
1419 /* Load Groups Created */
1420 cdb_cfg->groups = _bt_mesh_conf_load_group_info(cdb_cfg);
1422 /* Fetch Network name */
1423 *network = (char*)_bt_mesh_conf_get_network_friendly_name(cdb_cfg);
1424 BT_INFO("Mesh: Attached Network [%s]", *network);
1425 return BLUETOOTH_ERROR_NONE;
1427 /* Free the CDB object */
1428 _bt_mesh_conf_free(cdb_cfg);
1429 return BLUETOOTH_ERROR_INTERNAL;
1432 int _bt_mesh_network_load(const char *app_cred,
1433 const char *sender, const char *token)
1435 int ret = OAL_STATUS_SUCCESS;
1437 char *dir_path = NULL;
1438 _bt_mesh_cdb_t *cdb_cfg = NULL;
1439 oal_mesh_node_t node;
1440 GSList *models = NULL;
1442 /* Check CDB directory exist or not */
1443 dir_path = g_strdup_printf(MESH_CDB_DEFAULT_DIR_PATH"/%s/", "default");
1444 if (!_bt_mesh_util_is_directory_exists(dir_path)) {
1445 BT_ERR("Mesh: CDB dir [%s]does not exist for app", dir_path);
1447 return BLUETOOTH_ERROR_INTERNAL;
1451 l = g_slist_find_custom(cdb_list, token,
1452 __mesh_compare_app_cdb_token);
1454 BT_INFO("Mesh: Already loaded");
1456 return BLUETOOTH_ERROR_NONE;
1458 BT_INFO("Mesh: Not loaded");
1459 /* Attempt to load CDB's present in app's
1461 const char *filename;
1462 GDir *dir = g_dir_open(dir_path, 0, NULL);
1464 BT_ERR("Mesh: Could not open directory");
1466 return BLUETOOTH_ERROR_INTERNAL;
1469 while ((filename = g_dir_read_name(dir)) != NULL) {
1471 if ((g_file_test(filename, G_FILE_TEST_IS_SYMLINK) == TRUE) ||
1472 (g_str_has_suffix(filename, ".json") == FALSE))
1475 BT_INFO("Mesh: File name [%s]", filename);
1476 cdb_cfg = _bt_mesh_conf_load(filename, token);
1483 BT_ERR("Mesh: Could not find CDB for the token!! Possibly not authorized!!");
1484 return BLUETOOTH_ERROR_ACCESS_DENIED;
1487 /* Fill the Mesh node info */
1488 memset(&node, 0x00, sizeof(oal_mesh_node_t));
1489 memcpy(node.uuid.uuid, cdb_cfg->uuid, sizeof(oal_uuid_t));
1490 _bt_mesh_util_convert_string_to_hex(token, strlen(token), node.token.u8, 8);
1491 if (!_bt_mesh_conf_get_element_count(cdb_cfg, &node.num_elements)) {
1492 _bt_mesh_conf_free(cdb_cfg);
1493 return BLUETOOTH_ERROR_INTERNAL;
1496 if (!_bt_mesh_conf_fetch_vendor_specific_info(cdb_cfg, 0x0001 /* Local Node Unicast */,
1497 &node.vendor_info.companyid, &node.vendor_info.vendorid,
1498 &node.vendor_info.versionid, &node.vendor_info.crpl,
1499 &node.vendor_info.relay, &node.vendor_info.frnd,
1500 &node.vendor_info.proxy, &node.vendor_info.lpn)) {
1502 _bt_mesh_conf_free(cdb_cfg);
1503 return BLUETOOTH_ERROR_INTERNAL;
1506 for (int i = 0; i < node.num_elements; i++) {
1508 uint16_t **model_array = _bt_mesh_conf_get_all_model_info(
1509 cdb_cfg, i, &num_models);
1511 _bt_mesh_conf_free(cdb_cfg);
1512 return BLUETOOTH_ERROR_INTERNAL;
1515 for (int j = 0; j < num_models; j++) {
1516 bluetooth_mesh_model_t *mod;
1517 mod = g_malloc0(sizeof(bluetooth_mesh_model_t));
1518 mod->elem_index = i;
1519 mod->model_id = *model_array[j];
1520 models = g_slist_append(models, mod);
1522 /* Free all model(s) */
1523 for (int j = 0; j < num_models; j++)
1524 g_free(model_array[j]);
1527 /* Register Mesh Node */
1528 ret = mesh_register_node((oal_mesh_node_t*)&node,
1532 g_slist_free_full(models, g_free);
1534 if (ret != OAL_STATUS_SUCCESS) {
1535 BT_ERR("Mesh: Load Network Failed ret: %d", ret);
1536 _bt_mesh_conf_free(cdb_cfg);
1537 return BLUETOOTH_ERROR_INTERNAL;
1540 /* Save till Network attached */
1541 cdb_list = g_slist_append(cdb_list, cdb_cfg);
1545 bool _bt_mesh_network_get_label_uuid_from_sub_addr(
1546 uint8_t net_uuid[], uint16_t sub_addr,
1550 _bt_mesh_cdb_t *cdb_cfg = NULL;
1553 l = g_slist_find_custom(cdb_list, net_uuid,
1554 __mesh_compare_app_network_uuid);
1558 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1560 l1 = g_slist_find_custom(cdb_cfg->groups,
1561 GUINT_TO_POINTER(sub_addr), __mesh_compare_addr);
1566 _bt_mesh_group_t *grp = l1->data;
1567 memcpy(label, grp->label_uuid, 16);
1572 int _bt_mesh_network_remove_group(const char *app_cred,
1573 const char *sender, bluetooth_mesh_network_t *net,
1574 bluetooth_mesh_network_group_info_t *req)
1577 _bt_mesh_cdb_t *cdb_cfg = NULL;
1578 _bt_mesh_group_t *grp;
1579 uint8_t net_uuid[16];
1581 _bt_mesh_util_convert_string_to_hex(net->uuid,
1582 strlen(net->uuid), net_uuid, 16);
1584 l = g_slist_find_custom(cdb_list, net_uuid,
1585 __mesh_compare_app_network_uuid);
1587 return BLUETOOTH_ERROR_INVALID_PARAM;
1589 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1590 BT_INFO("Mesh: Total groups stored in network [%d]",
1591 g_slist_length(cdb_cfg->groups));
1593 l1 = g_slist_find_custom(cdb_cfg->groups,
1594 GUINT_TO_POINTER(req->group_addr), __mesh_compare_addr);
1597 BT_ERR("Mesh: To be Removed Group: [0x%2.2x] Not Found!", req->group_addr);
1598 return BLUETOOTH_ERROR_INVALID_PARAM;
1600 grp = (_bt_mesh_group_t*)l1->data;
1602 BT_INFO("Mesh: To be Removed Group: [0x%2.2x]", req->group_addr);
1603 if (!_bt_mesh_conf_delete_group_entry(cdb_cfg, req->group_addr)) {
1604 BT_ERR("Mesh: Failed to remove Group: [0x%2.2x]", req->group_addr);
1605 return BLUETOOTH_ERROR_INTERNAL;
1608 BT_INFO("Mesh: Successfully removed Group: [0x%2.2x]", req->group_addr);
1609 cdb_cfg->groups = g_slist_remove(cdb_cfg->groups, grp);
1610 BT_INFO("Mesh: Total groups after update [%d]",
1611 g_slist_length(cdb_cfg->groups));
1613 return BLUETOOTH_ERROR_NONE;
1616 int _bt_mesh_network_create_group(const char *app_cred,
1617 const char *sender, bluetooth_mesh_network_t *net,
1618 bool is_virtual, uint16_t addr,
1619 bluetooth_mesh_network_group_info_t *req)
1621 GSList *l, *l1, *l2;
1622 _bt_mesh_cdb_t *cdb_cfg = NULL;
1623 uint8_t net_uuid[16];
1625 _bt_mesh_util_convert_string_to_hex(net->uuid,
1626 strlen(net->uuid), net_uuid, 16);
1628 l = g_slist_find_custom(cdb_list, net_uuid,
1629 __mesh_compare_app_network_uuid);
1631 return BLUETOOTH_ERROR_INVALID_PARAM;
1633 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1634 BT_INFO("Mesh: Total Groups present in Network already [%d]",
1635 g_slist_length(cdb_cfg->groups));
1638 uint8_t max_tries = 5;
1639 _bt_mesh_group_t *grp = NULL;
1640 grp = g_malloc0(sizeof(_bt_mesh_group_t));
1641 BT_INFO("Mesh: Network Create Virtual group");
1643 l_getrandom(grp->label_uuid, 16);
1644 _bt_mesh_util_crypto_create_virtual_address(
1645 grp->label_uuid, &grp->grp_addr);
1647 /* For simplicity sake, avoid labels that map to the same hash */
1648 l1 = g_slist_find_custom(cdb_cfg->groups,
1649 GUINT_TO_POINTER(grp->grp_addr), __mesh_compare_addr);
1652 if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
1653 BT_ERR("Mesh: unable to save group in Conf DB!!");
1655 return BLUETOOTH_ERROR_INTERNAL;
1657 req->is_virtual = true;
1658 req->group_addr = grp->grp_addr;
1659 _bt_mesh_util_convert_hex_to_string(
1660 (uint8_t *) grp->label_uuid, 16, req->label_uuid,
1661 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1663 cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
1664 BT_INFO("Mesh: Virtual Group[0x%2.2x] inserted in List",
1666 BT_INFO("Mesh: Total groups present in Network after update [%d]",
1667 g_slist_length(cdb_cfg->groups));
1668 return BLUETOOTH_ERROR_NONE;
1676 /* Failed to create a unique hash */
1677 return BLUETOOTH_ERROR_INTERNAL;
1679 BT_INFO("Mesh: Network Create group Addr: [0x%2.2x]", addr);
1681 if (!MESH_IS_GROUP(addr)) {
1682 BT_ERR("Mesh: Group Address [0x%2.2x] is not valid!", addr);
1683 return BLUETOOTH_ERROR_INVALID_PARAM;
1686 l2 = g_slist_find_custom(cdb_cfg->groups,
1687 GUINT_TO_POINTER(addr), __mesh_compare_addr);
1690 _bt_mesh_group_t *grp = l2->data;
1691 req->is_virtual = false;
1692 req->group_addr = grp->grp_addr;
1693 BT_INFO("Mesh: Group already found: addr [0x%2.2x]", grp->grp_addr);
1695 /* Group is not present */
1696 _bt_mesh_group_t *grp = g_malloc0(sizeof(_bt_mesh_group_t));
1697 grp->grp_addr = addr;
1698 if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
1699 BT_ERR("Mesh: unable to save group in Conf DB!!");
1701 return BLUETOOTH_ERROR_INTERNAL;
1703 cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
1704 req->is_virtual = false;
1705 req->group_addr = grp->grp_addr;
1706 BT_INFO("Mesh: Group[0x%2.2x] inserted in List",
1709 BT_INFO("Mesh: Total groups present in Network after update [%d]",
1710 g_slist_length(cdb_cfg->groups));
1713 return BLUETOOTH_ERROR_NONE;
1716 int _bt_mesh_network_get_groups(const char *app_cred, const char *sender,
1717 bluetooth_mesh_network_t *network,
1721 _bt_mesh_cdb_t *cdb_cfg = NULL;
1722 uint8_t net_uuid[16];
1724 BT_INFO("Mesh: Get All groups from Network [%s]", network->uuid);
1725 _bt_mesh_util_convert_string_to_hex(network->uuid,
1726 strlen(network->uuid), net_uuid, 16);
1728 l = g_slist_find_custom(cdb_list, net_uuid,
1729 __mesh_compare_app_network_uuid);
1731 return BLUETOOTH_ERROR_INVALID_PARAM;
1733 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1734 BT_INFO("Mesh: Got CDB");
1736 BT_INFO("Mesh: Total groups present in Network [%d]",
1737 g_slist_length(cdb_cfg->groups));
1739 for (l = cdb_cfg->groups; l; l = l->next) {
1740 bluetooth_mesh_network_group_info_t grp;
1741 _bt_mesh_group_t *group = l->data;
1742 memset(&grp, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
1743 g_strlcpy(grp.net_uuid, network->uuid, sizeof(grp.net_uuid));
1744 if (MESH_IS_GROUP(group->grp_addr) && !MESH_IS_VIRTUAL(group->grp_addr)) {
1745 grp.is_virtual = false;
1746 grp.group_addr = group->grp_addr;
1747 BT_INFO("Mesh: Found Non-Virtual group, addr[0x%2.2x]", group->grp_addr);
1748 } else if (MESH_IS_VIRTUAL(group->grp_addr)) {
1749 grp.is_virtual = true;
1750 grp.group_addr = group->grp_addr;
1751 _bt_mesh_util_convert_hex_to_string((uint8_t *) group->label_uuid,
1752 16, grp.label_uuid, sizeof(grp.label_uuid));
1753 BT_INFO("Mesh: Found Virtual group, addr[0x%2.2x]", group->grp_addr);
1754 BT_INFO("Mesh: Label UUID[%s]", grp.label_uuid);
1757 g_array_append_vals(*out_param,
1758 &grp, sizeof(bluetooth_mesh_network_group_info_t));
1761 return BLUETOOTH_ERROR_NONE;
1764 int _bt_mesh_network_get_nodes(const char *app_cred,
1765 const char *sender, bluetooth_mesh_network_t *network,
1769 _bt_mesh_cdb_t *cdb_cfg = NULL;
1772 l = g_slist_find_custom(cdb_list, network->token.token,
1773 __mesh_compare_app_cdb_token);
1775 return BLUETOOTH_ERROR_INVALID_PARAM;
1777 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1779 if (_bt_mesh_node_get_all(cdb_cfg->uuid, out_param))
1780 return BLUETOOTH_ERROR_NONE;
1782 return BLUETOOTH_ERROR_INTERNAL;