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