Mesh: Apply stabilization fixes in CAPI 13/239513/2
authorAnupam Roy <anupam.r@samsung.com>
Mon, 27 Jul 2020 08:37:48 +0000 (14:07 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Mon, 27 Jul 2020 08:45:55 +0000 (08:45 +0000)
Some of the notable changes are following-

1. Add 'Model Configure AppKey event handling'
2. Fix bug in fetching model from element
   [Fixed wrong handling og GSLists]
3. Apply exception handling in deleting NetKey from a node
   [Application crash in case of invalid NetKey handle]
4. Fix bug in handling appkeys bound to a NetKey of a node
   [Return AppKey(s) bound to NetKey, instead of reurning ALL AppKeys]
5. Fix application crash due to double free
   [Double Free of Model AppKey List items]

Change-Id: Icea2e305d5cd2059b2db35d80aa269b9d547b176
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
src/bluetooth-common.c
src/bluetooth-mesh.c

index 889696d..2827aa2 100644 (file)
@@ -292,7 +292,7 @@ static bt_event2index_table_t event2index[] = {
        { BLUETOOTH_EVENT_MESH_NODE_VENDOR_FEATURES, BT_EVENT_MESH_NODE_VENDOR_FEATURES },
        { BLUETOOTH_EVENT_MESH_NODE_KEY_CONFIGURED, BT_EVENT_MESH_NODE_KEY_CONFIGURATION_COMPLETED },
        { BLUETOOTH_EVENT_MESH_NODE_TTL_CONFIGURED, BT_EVENT_MESH_NODE_TTL_EXECUTE_COMPLETED },
-       { BLUETOOTH_EVENT_MESH_NODE_MODEL_APPKEY_BIND, BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED },
+       { BLUETOOTH_EVENT_MESH_MODEL_APPKEY_BIND, BT_EVENT_MESH_NODE_MODEL_BIND_APPKEY_COMPLETED },
        { BLUETOOTH_EVENT_MESH_MODEL_APPKEY_LIST, BT_EVENT_MESH_NODE_MODEL_APPKEY_LIST },
        { BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_LIST, BT_EVENT_MESH_NODE_MODEL_SUB_LIST },
        { BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED, BT_EVENT_MESH_NODE_MODEL_GROUP_SUB },
@@ -1423,6 +1423,7 @@ static bool __bt_need_to_handle(int event)
        case BLUETOOTH_EVENT_MESH_NODE_KEY_CONFIGURED:
        case BLUETOOTH_EVENT_MESH_NODE_TTL_CONFIGURED:
        case BLUETOOTH_EVENT_MESH_MODEL_APPKEY_LIST:
+       case BLUETOOTH_EVENT_MESH_MODEL_APPKEY_BIND:
        case BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED:
        case BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED:
        case BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS:
@@ -3870,6 +3871,49 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                                        bt_event_slot_container[event_index].user_data);
                break;
        }
+       case BLUETOOTH_EVENT_MESH_MODEL_APPKEY_BIND: {
+               BT_INFO("BLUETOOTH_EVENT_MESH_MODEL_APPKEY_BIND");
+               bluetooth_mesh_model_configure_t *res = NULL;
+               bt_mesh_model_s *model_s = NULL;
+               bt_mesh_appkey_s *appkey_s = NULL;
+               bt_mesh_network_s *network_s = NULL;
+               res = (bluetooth_mesh_model_configure_t *)(param->param_data);
+
+               network_s = _bt_mesh_get_network_handle_info(res->net_uuid);
+               if (!network_s)
+                       break;
+
+               BT_INFO("Mesh: Model AppKey %s Result", res->is_bind? "Bind" : "UnBind");
+               model_s = _bt_mesh_get_node_get_model_from_element(res->net_uuid,
+                               res->primary_unicast, res->elem_index, res->model);
+               if (!model_s)
+                       break;
+
+               appkey_s = _bt_mesh_network_get_appkey_from_index(network_s, res->appkey_idx);
+               if (!appkey_s)
+                       break;
+
+               if (_bt_get_error_code(param->result) == BT_ERROR_NONE)
+                       BT_INFO("Mesh: Model AppKey Configuration: SUCCESS");
+               else
+                       BT_INFO("Mesh: Model AppKey Configuration: FAILED");
+
+               if (res->is_bind)
+                       ((bt_mesh_model_bind_cb)
+                               bt_event_slot_container[event_index].callback)
+                                       (_bt_get_error_code(param->result),
+                                       (bt_mesh_model_h) model_s,
+                                       (bt_mesh_appkey_h) appkey_s,
+                                       bt_event_slot_container[event_index].user_data);
+               else
+                       ((bt_mesh_model_unbind_cb)
+                               bt_event_slot_container[event_index].callback)
+                                       (_bt_get_error_code(param->result),
+                                       (bt_mesh_model_h) model_s,
+                                       (bt_mesh_appkey_h)appkey_s,
+                                       bt_event_slot_container[event_index].user_data);
+               break;
+       }
        /* Fall through */
        case BLUETOOTH_EVENT_MESH_MODEL_SUBSCRIPTION_CONFGURED:
        case BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED: {
@@ -3979,42 +4023,42 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                bluetooth_mesh_model_configure_t *res = NULL;
                bt_mesh_network_s *info = NULL;
                bt_mesh_node_s *node_s = NULL;
+               bt_mesh_model_s *model_s;
+               bt_mesh_element_s *element_s;
                GSList *appkeylist = NULL;
                int total = 0;
                res = (bluetooth_mesh_model_configure_t *)(param->param_data);
+               BT_INFO("Mesh: Model AppKey List result for Network [%s]",
+                       res->net_uuid);
 
                info = _bt_mesh_get_network_handle_info(res->net_uuid);
                if (!info)
                        break;
+               model_s = _bt_mesh_get_node_get_model_from_element(res->net_uuid,
+                               res->primary_unicast, res->elem_index, res->model);
+               if (!model_s)
+                       break;
+
+               element_s = model_s->parent;
+               node_s = element_s->parent;
 
                if (_bt_get_error_code(param->result) == BT_ERROR_NONE)
                        BT_INFO("Mesh: Node Model AppKeyList: SUCCESS");
                else
                        BT_INFO("Mesh: Node Model AppKeyList : FAILED");
 
-               node_s = _bt_mesh_get_node_from_unicast(res->net_uuid,
-                       res->primary_unicast);
-               if (!node_s)
-                       break;
-               bt_mesh_model_s *model_s;
-               bt_mesh_element_s *element_s;
                total = res->appkeylist_count;
+               BT_INFO("Mesh: Total Appkeys Bound to Model [%d]", total);
 
                for (int i = 0; i < total; i++) {
                        bt_mesh_appkey_s *appkey;
                        appkey = _bt_mesh_node_get_appkey(node_s, *res->appkey_list[i]);
-                       if (appkey)
+                       if (appkey) {
+                               BT_INFO("Mesh: AppKey found for Index [%d]", *res->appkey_list[i]);
                                appkeylist = g_slist_append(appkeylist, appkey);
-                       /* Free memory */
-                       g_free(res->appkey_list[i]);
+                       }
                }
 
-               element_s = _bt_mesh_get_element_from_index(node_s, res->elem_index);
-               if (!element_s)
-                       break;
-               model_s = _bt_mesh_get_model_from_modelid(element_s, res->model);
-               if (!model_s)
-                       break;
                ((bt_mesh_model_appkey_list_cb)
                         bt_event_slot_container[event_index].callback)
                                (_bt_get_error_code(param->result), (bt_mesh_model_h) model_s,
index a848b26..7eb0b8f 100644 (file)
@@ -442,21 +442,21 @@ bt_mesh_model_s *_bt_mesh_get_node_get_model_from_element(
        if (!l)
                return NULL;
 
-       network_s = l->data;
+       network_s = (bt_mesh_network_s*) l->data;
 
        l1 = g_slist_find_custom(network_s->nodes, GUINT_TO_POINTER(unicast),
                        (GCompareFunc)__compare_node_primary_unicast);
        if (!l1)
                return NULL;
 
-       node_s = l1->data;
+       node_s = (bt_mesh_node_s*) l1->data;
 
        l2 = g_slist_find_custom(node_s->elements, GUINT_TO_POINTER(elem_idx),
                        (GCompareFunc)__compare_node_element_index);
        if (!l2)
                return NULL;
 
-       element_s =  (bt_mesh_element_s*) l->data;
+       element_s =  (bt_mesh_element_s*) l2->data;
 
 
        l3 = g_slist_find_custom(element_s->models, GUINT_TO_POINTER(model),
@@ -464,7 +464,7 @@ bt_mesh_model_s *_bt_mesh_get_node_get_model_from_element(
        if (!l3)
                return NULL;
 
-       return (bt_mesh_model_s*) l->data;
+       return (bt_mesh_model_s*) l3->data;
 }
 
 bt_mesh_element_s * _bt_mesh_get_node_get_element_from_index(char *net_uuid,
@@ -1408,10 +1408,9 @@ int bt_mesh_netkey_update(bt_mesh_netkey_h netkey)
        BT_CHECK_INPUT_PARAMETER(netkey);
 
        netkey_s = (bt_mesh_netkey_s*)netkey;
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
        network_s = netkey_s->parent;
-
        BT_MESH_VALIDATE_HANDLE(network_s, networks);
-       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
 
        memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
 
@@ -1440,13 +1439,13 @@ int bt_mesh_netkey_delete(bt_mesh_netkey_h netkey)
        FUNC_ENTRY;
        BT_CHECK_MESH_SUPPORT();
        BT_CHECK_MESH_INIT_STATUS();
+
        BT_CHECK_INPUT_PARAMETER(netkey);
 
        netkey_s = (bt_mesh_netkey_s*)netkey;
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
        network_s = netkey_s->parent;
-
        BT_MESH_VALIDATE_HANDLE(network_s, networks);
-       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
 
        memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
 
@@ -1481,14 +1480,14 @@ int bt_mesh_netkey_add_appkey(bt_mesh_netkey_h netkey,
        FUNC_ENTRY;
        BT_CHECK_MESH_SUPPORT();
        BT_CHECK_MESH_INIT_STATUS();
+
        BT_CHECK_INPUT_PARAMETER(netkey);
        BT_CHECK_INPUT_PARAMETER(appkey);
 
        netkey_s = (bt_mesh_netkey_s*)netkey;
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
        network_s = netkey_s->parent;
-
        BT_MESH_VALIDATE_HANDLE(network_s, networks);
-       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
 
        memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
 
@@ -1529,10 +1528,11 @@ int bt_mesh_appkey_update(bt_mesh_appkey_h appkey)
        BT_CHECK_INPUT_PARAMETER(appkey);
 
        appkey_s = (bt_mesh_appkey_s*)appkey;
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
        netkey_s = appkey_s->parent;
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
        network_s = netkey_s->parent;
-
-       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
 
        memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
 
@@ -1565,10 +1565,11 @@ int bt_mesh_appkey_delete(bt_mesh_appkey_h appkey)
        BT_CHECK_INPUT_PARAMETER(appkey);
 
        appkey_s = (bt_mesh_appkey_s*)appkey;
+       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
        netkey_s = appkey_s->parent;
+       BT_MESH_VALIDATE_HANDLE(netkey_s, netkey_list);
        network_s = netkey_s->parent;
-
-       BT_MESH_VALIDATE_HANDLE(appkey_s, appkey_list);
+       BT_MESH_VALIDATE_HANDLE(network_s, networks);
 
        memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
 
@@ -2260,11 +2261,6 @@ int bt_mesh_node_configure_appkey(bt_mesh_node_h node, bt_mesh_node_key_configur
        if (netkey_s->parent != network_s)
                return BT_ERROR_INVALID_PARAMETER;
 
-       /* Return Already done, if appkey is present in the node */
-       if (g_slist_find_custom(node_s->appkeys,(gconstpointer) appkey_s,
-                               (GCompareFunc)__simple_compare))
-               return BT_ERROR_ALREADY_DONE;
-
        memset(&req, 0x00, sizeof(bluetooth_mesh_key_configure_t));
 
        g_strlcpy(req.net_uuid, network_s->uuid, 33);
@@ -2511,8 +2507,10 @@ int bt_mesh_node_foreach_netkeys(bt_mesh_node_h node, bt_mesh_node_netkey_info_c
                }
        }
 
-       g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
-       g_ptr_array_free(netkeys, TRUE);
+       if (netkeys) {
+               g_ptr_array_foreach(netkeys, (GFunc)g_free, NULL);
+               g_ptr_array_free(netkeys, TRUE);
+       }
 
        FUNC_EXIT;
        return error_code;
@@ -2522,10 +2520,8 @@ int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node, bt_mesh_netkey_h netkey,
                bt_mesh_node_appkey_info_cb callback, void *user_data)
 {
        GPtrArray *appkeys = NULL;
-       GSList *l;
        int error_code = BT_ERROR_NONE;
        int i;
-       int total;
        bluetooth_mesh_node_discover_t req;
        uint16_t *appkey_idx = NULL;
        bt_mesh_network_s *network_s;
@@ -2602,6 +2598,12 @@ int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node, bt_mesh_netkey_h netkey,
                                        BT_INFO("Mesh: AppKey is already added in node");
                                }
                        }
+                       /* Send CallBack */
+                       if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, appkeys->len,
+                                               (bt_mesh_netkey_h) netkey, (bt_mesh_appkey_h) appkey_local,
+                                               appkey_local->appkey_index, user_data)) {
+                               break;
+                       }
                } else {
                        BT_ERR("Mesh: OPERATION_FAILED(0x%08x)",
                                        BT_ERROR_OPERATION_FAILED);
@@ -2610,26 +2612,16 @@ int bt_mesh_node_foreach_appkeys(bt_mesh_node_h node, bt_mesh_netkey_h netkey,
                }
        }
 
-       total = g_slist_length(node_s->appkeys);
-       if (total == 0) {
-               BT_ERR("Mesh:Possible: No appkey added in node!!");
-               callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
+       if (appkeys->len == 0) {
+               BT_ERR("Mesh: No appkey configured for the bound netkey Idx [%d]",
+                       req.netkey_idx);
+               callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, 0,
                                (bt_mesh_netkey_h) netkey_s, NULL, 0xFFFF, user_data);
        }
-       for (l = node_s->appkeys; l != NULL; l = g_slist_next(l)) {
-               bt_mesh_appkey_s *appkey_s;
-               appkey_s = l->data;
-
-               if (!callback(BT_ERROR_NONE, (bt_mesh_node_h)node_s, total,
-                                       (bt_mesh_netkey_h) netkey, (bt_mesh_appkey_h) appkey_s,
-                                       appkey_s->appkey_index, user_data)) {
-                       break;
-               }
+       if (appkeys) {
+               g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
+               g_ptr_array_free(appkeys, TRUE);
        }
-
-       g_ptr_array_foreach(appkeys, (GFunc)g_free, NULL);
-       g_ptr_array_free(appkeys, TRUE);
-
        FUNC_EXIT;
        return error_code;
 }
@@ -2760,18 +2752,18 @@ int bt_mesh_model_get_appkey_list(bt_mesh_model_h model,
        BT_CHECK_INPUT_PARAMETER(callback);
 
        model_s = (bt_mesh_model_s*) model;
-       element_s = (bt_mesh_element_s*) model_s->parent;
-       node_s = (bt_mesh_node_s*) element_s->parent;
-       network_s = (bt_mesh_network_s*) node_s->parent;
+       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
 
-       BT_CHECK_INPUT_PARAMETER(model_s);
+       element_s = (bt_mesh_element_s*) model_s->parent;
        BT_CHECK_INPUT_PARAMETER(element_s);
-       BT_CHECK_INPUT_PARAMETER(node_s);
-       BT_CHECK_INPUT_PARAMETER(network_s);
-
-       BT_MESH_VALIDATE_HANDLE(model_s, model_list);
        BT_MESH_VALIDATE_HANDLE(element_s, element_list);
+
+       node_s = (bt_mesh_node_s*) element_s->parent;
+       BT_CHECK_INPUT_PARAMETER(node_s);
        BT_MESH_VALIDATE_HANDLE(node_s, node_list);
+
+       network_s = (bt_mesh_network_s*) node_s->parent;
+       BT_CHECK_INPUT_PARAMETER(network_s);
        BT_MESH_VALIDATE_HANDLE(network_s, networks);
 
        /* Return error, if node is not attached */