I did a simple test of connecting to a WiFi AP and then doing a disconnect
using connmanctl. I found that the connman crashed while trying to
decrement the network ref count from network_removed() function in
plugins/wifi.c

static void network_removed(GSupplicantNetwork *network){
        GSupplicantInterface *interface;
        struct wifi_data *wifi;
        const char *name, *identifier;
        struct connman_network *connman_network;

        interface = g_supplicant_network_get_interface(network);
        wifi = g_supplicant_interface_get_data(interface);
        identifier = g_supplicant_network_get_identifier(network);
        name = g_supplicant_network_get_name(network);

        DBG("name %s", name);

        if (!wifi)
                return;

        connman_network = connman_device_get_network(wifi->device, identifier);
        if (!connman_network)
                return;

        wifi->networks = g_slist_remove(wifi->networks, connman_network);

        connman_device_remove_network(wifi->device, connman_network);
        *connman_network_unref(connman_network);*}


In this function call to connman_network_ref() function and
connman_network_unref does not look symmetrical. The connman_network_ref is
called from network_connect() function:

static int network_connect(struct connman_network *network){
        struct connman_device *device = connman_network_get_device(network);
        struct wifi_data *wifi;
        GSupplicantInterface *interface;
        GSupplicantSSID *ssid;

        DBG("network %p", network);

        if (!device)
                return -ENODEV;

        wifi = connman_device_get_data(device);
        if (!wifi)
                return -ENODEV;

        ssid = g_try_malloc0(sizeof(GSupplicantSSID));
        if (!ssid)
                return -ENOMEM;

        interface = wifi->interface;

        ssid_init(ssid, network);

        if (wifi->disconnecting) {
                wifi->pending_network = network;
                g_free(ssid);
        } else {
                *wifi->network = connman_network_ref(network);*
                wifi->retries = 0;

                return g_supplicant_interface_connect(interface, ssid,
                                                connect_callback, network);
        }

        return -EINPROGRESS;}


This call is made just before adding the interface to supplicant for
connect process. In the subsequent call back from supplicant we do see that
the ref count is decremented:

static void connect_callback(int result, GSupplicantInterface *interface,
                                                        void *user_data){
        struct connman_network *network = user_data;

        DBG("network %p result %d", network, result);

        if (result == -ENOKEY) {
                connman_network_set_error(network,
                                        CONNMAN_NETWORK_ERROR_INVALID_KEY);
        } else if (result < 0) {
                connman_network_set_error(network,
                                        CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
        }

        *connman_network_unref(network); *}


So Looks like decrementing the ref count from network removed was not
correct. So either we add the network ref count from network_added
function in supplicant or remove it from the network_removed function.


Any thoughts?


Thanks

Naveen
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman

Reply via email to