From 96c43eaedd9442277e836a70f158dfe77ed1ed86 Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Wed, 29 Jul 2020 12:09:56 +0530 Subject: [PATCH] Mesh: Refactor Mesh network group handling logics This patch handles following - Add Conf DB removal of group along with CAPI handles - Refactor Get Network foreach groups Change-Id: I90ed5afca3d83763d3d81bb6ba8d721022501abe Signed-off-by: Anupam Roy --- src/bluetooth-common.c | 2 +- src/bluetooth-mesh.c | 130 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 112 insertions(+), 20 deletions(-) diff --git a/src/bluetooth-common.c b/src/bluetooth-common.c index e553f3f..cfc6278 100644 --- a/src/bluetooth-common.c +++ b/src/bluetooth-common.c @@ -4105,7 +4105,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us bt_mesh_group_s *group_s; group_s = _bt_mesh_network_get_group(network_s, *res->sub_list[i]); sublist = g_slist_append(sublist, group_s); - g_free(res->sub_list[i]); + g_free(res->sub_list[i]); } ((bt_mesh_model_subscription_list_cb) bt_event_slot_container[event_index].callback) diff --git a/src/bluetooth-mesh.c b/src/bluetooth-mesh.c index bedd7a0..43e9c9f 100644 --- a/src/bluetooth-mesh.c +++ b/src/bluetooth-mesh.c @@ -37,6 +37,18 @@ #define BT_MESH_MAX_NODES 32767 #define BT_MESH_MAX_SUBNETS 4096 +#define BT_MESH_FIXED_GROUP_LOW 0xff00 +#define BT_MESH_FIXED_GROUP_HIGH 0xffff +#define BT_MESH_ALL_NODES_ADDRESS 0xffff +#define BT_MESH_VIRTUAL_ADDRESS_LOW 0x8000 +#define BT_MESH_VIRTUAL_ADDRESS_HIGH 0xbfff +#define BT_MESH_GROUP_ADDRESS_LOW 0xc000 +#define BT_MESH_GROUP_ADDRESS_HIGH 0xfeff + +#define BT_MESH_IS_GROUP(x) ((((x) >= BT_MESH_GROUP_ADDRESS_LOW) && \ + ((x) < BT_MESH_FIXED_GROUP_HIGH)) || \ + ((x) == BT_MESH_ALL_NODES_ADDRESS)) + static bool is_mesh_initialized = false; /**< List of Local handles >*/ @@ -109,6 +121,14 @@ size_t __bt_mesh_util_convert_hex_to_string(uint8_t *in, return i; } +static int __compare_group_address(gconstpointer a, gconstpointer b) +{ + const bt_mesh_group_s *group = a; + uint16_t addr = GPOINTER_TO_UINT(b); + + return (group->addr - addr); +} + static int __compare_node_primary_unicast(gconstpointer a, gconstpointer b) { const bt_mesh_node_s *node = a; @@ -244,7 +264,7 @@ bt_mesh_group_s* _bt_mesh_network_get_group( if (!l) { group_s = g_malloc0(sizeof(bt_mesh_group_s)); group_s->addr = group_addr; - if (group_addr >= 0x8000 && group_addr <= 0xbfff) + if (!BT_MESH_IS_GROUP(group_addr)) group_s->is_virtual = true; else group_s->is_virtual = false; @@ -2795,8 +2815,8 @@ int bt_mesh_network_foreach_groups(bt_mesh_network_h network, bluetooth_mesh_network_t net; bt_mesh_network_s *network_s; GPtrArray *groups = NULL; - GSList *l; - uint16_t *group_addr = NULL; + GSList *l = NULL; + bluetooth_mesh_network_group_info_t *group_info = NULL; int i; int total; @@ -2828,16 +2848,38 @@ int bt_mesh_network_foreach_groups(bt_mesh_network_h network, return error_code; } + BT_INFO("Mesh: Total number of Groups in network [%d]", groups->len); for (i = 0; i < groups->len; i++) { - group_addr = g_ptr_array_index(groups, i); - if (group_addr) { + group_info = g_ptr_array_index(groups, i); + if (group_info) { + BT_INFO("Mesh: Group Is Virtual [%s] Group Addr [0x%2.2x]", + group_info->is_virtual ? "YES" : "NO", group_info->group_addr); + + if (group_info->is_virtual) + BT_INFO("Mesh: Virtual label UUID [%s]", group_info->label_uuid); + + BT_INFO("Mesh: Total groups already present in Network [%d]", + g_slist_length(network_s->groups)); /* Find or create group in network list */ - if (!_bt_mesh_network_get_group(network_s, *group_addr)) { - BT_ERR("Mesh: OPERATION_FAILED(0x%08x)", - BT_ERROR_OPERATION_FAILED); - error_code = BT_ERROR_OPERATION_FAILED; - break; - } + if (!g_slist_find_custom(network_s->groups, + GUINT_TO_POINTER(group_info->group_addr), + (GCompareFunc)__compare_network_group_address)) { + BT_INFO("Mesh: Its a new Group, add in network"); + bt_mesh_group_s *group_s; + group_s = g_malloc0(sizeof(bt_mesh_group_s)); + group_s->addr = group_info->group_addr; + group_s->parent = network_s; + group_s->is_virtual = group_info->is_virtual; + if (group_s->is_virtual) + g_strlcpy(group_s->label_uuid, group_info->label_uuid, + sizeof(group_s->label_uuid)); + BT_INFO("Mesh: Group [0x%2.2x] added in network", group_s->addr); + + network_s->groups = g_slist_append(network_s->groups, group_s); + group_list = g_slist_append(group_list, group_s); + } else + BT_INFO("Mesh: Group [0x%2.2x] Already Added in network", + group_info->group_addr); } else { BT_ERR("Mesh: OPERATION_FAILED(0x%08x)", BT_ERROR_OPERATION_FAILED); @@ -2847,6 +2889,7 @@ int bt_mesh_network_foreach_groups(bt_mesh_network_h network, } total = g_slist_length(network_s->groups); + BT_INFO("Mesh: Total number of groups [%d]", total); if (total == 0) { BT_INFO("Mesh: No Groups added in network"); callback(BT_ERROR_NONE, (bt_mesh_network_h)network_s, total, @@ -2904,13 +2947,13 @@ int bt_mesh_network_create_virtual_group(bt_mesh_network_h network, group_s->addr = req.group_addr; group_s->is_virtual = true; group_s->parent = network_s; - if (g_slist_append(network_s->groups, group_s)) - BT_INFO("Mesh: Group created"); - - __bt_mesh_util_convert_hex_to_string((uint8_t *)req.label_uuid, 16, - group_s->label_uuid, sizeof(group_s->label_uuid)); + g_strlcpy(group_s->label_uuid, req.label_uuid, BT_MESH_UUID_STRING_LEN + 1); + BT_INFO("Mesh: Virtual Group created : Addr [0x%2.2x]", req.group_addr); + BT_INFO("Mesh: Virtual Group label UUID [%s]", group_s->label_uuid); + network_s->groups = g_slist_append(network_s->groups, group_s); group_list = g_slist_append(group_list, group_s); + *group = (bt_mesh_group_h) group_s; FUNC_EXIT; return error_code; @@ -2918,17 +2961,46 @@ int bt_mesh_network_create_virtual_group(bt_mesh_network_h network, int bt_mesh_network_remove_group(bt_mesh_group_h group) { + int error_code = BT_ERROR_NONE; bt_mesh_network_s *network_s; bt_mesh_group_s *group_s; + bluetooth_mesh_network_group_info_t req; + bluetooth_mesh_network_t net; FUNC_ENTRY; BT_CHECK_MESH_SUPPORT(); BT_CHECK_INPUT_PARAMETER(group); group_s = (bt_mesh_group_s*) group; + BT_MESH_VALIDATE_HANDLE(group_s, group_list); network_s = group_s->parent; - BT_MESH_VALIDATE_HANDLE(group_s, group_list); + memset(&net, 0x00, sizeof(bluetooth_mesh_network_t)); + memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t)); + + BT_INFO("Mesh: Remove Group [0x%2.2x] from network", group_s->addr); + BT_INFO("Mesh: Is Group Virtual [%s]", group_s->is_virtual? "YES": "NO"); + if (group_s->is_virtual) + BT_INFO("Mesh: Group Label UUID [%s]", group_s->label_uuid); + + /* Fill Network Info */ + g_strlcpy(net.uuid, network_s->uuid, 33); + g_strlcpy(net.token.token, network_s->token, 17); + g_strlcpy(net.name.name, network_s->name, BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1); + + /* Fill Group Info */ + g_strlcpy(req.net_uuid, network_s->uuid, 33); + req.is_virtual = group_s->is_virtual; + req.group_addr = group_s->addr; + if (req.is_virtual) + g_strlcpy(req.label_uuid, group_s->label_uuid, sizeof(req.label_uuid)); + + error_code = _bt_get_error_code(bluetooth_mesh_network_remove_group(&net, &req)); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + FUNC_EXIT; + return error_code; + } network_s->groups = g_slist_remove(network_s->groups, group_s); group_list = g_slist_remove(group_list, group_s); @@ -2946,16 +3018,35 @@ int bt_mesh_network_create_group(bt_mesh_network_h network, bt_mesh_group_s *group_s; bluetooth_mesh_network_t net; bluetooth_mesh_network_group_info_t req; + GSList *l; FUNC_ENTRY; BT_CHECK_MESH_SUPPORT(); BT_CHECK_MESH_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(network); + BT_CHECK_INPUT_PARAMETER(group); network_s = (bt_mesh_network_s*) network; BT_MESH_VALIDATE_HANDLE(network_s, networks); + /* Check for valid Group Address */ + if (!BT_MESH_IS_GROUP(grp_addr)) { + BT_INFO("Mesh: group Address [0x%2.2x] is not valid Group Address", + grp_addr); + return BT_ERROR_INVALID_PARAMETER; + } + + l = g_slist_find_custom(network_s->groups, GUINT_TO_POINTER(grp_addr), + (GCompareFunc)__compare_group_address); + + if (l) { + BT_INFO("Mesh: Group [0x%2.2x]Already exist", grp_addr); + group_s = l->data; + *group = (bt_mesh_group_h) group_s; + FUNC_EXIT; + return error_code; + } memset(&net, 0x00, sizeof(bluetooth_mesh_network_t)); memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t)); @@ -2970,14 +3061,15 @@ int bt_mesh_network_create_group(bt_mesh_network_h network, return error_code; } + BT_INFO("Mesh: Group created [0x%2.2x]", grp_addr); group_s = g_malloc0(sizeof(bt_mesh_group_s)); group_s->addr = grp_addr; group_s->is_virtual = false; group_s->parent = network_s; - if (g_slist_append(network_s->groups, group_s)) - BT_INFO("Mesh: Group created"); + network_s->groups = g_slist_append(network_s->groups, group_s); group_list = g_slist_append(group_list, group_s); + *group = (bt_mesh_group_h) group_s; FUNC_EXIT; return error_code; -- 2.7.4