I was trying to use the latest connman and I found that it was crashing during the very first wifi scan and is to do with newly introduced functions *wifi_data_ref* and *wifi_data_unref*. This is the scenario:
After wpa_supplicant has created the interface it is gonna call connman supplied callback "interface_create_callback". In this function connman is going to initiate the device scan. This is the sequence of call that would happen: interface_create_callback --> finalize_interface_creation --> connman_device_set_powered -->device->driver->scan (which is a function defined in wifi_plugins) (Function called would be wifi_scan). As a result of this scan operation the wifi_data_ref count would go up to 2 (the initial value of the ref count is 1 when wifi struct got allocated as a part of wifi_probe). The problem is that after starting the scan when finalize_intreface_creation returns, it is gonna decrement the ref count by 1 (which is wrong) because when scan_callback_done is called it will again try to decrement it by 1 and then the value would be 0 causing wifi memory to be freed. This is the piece of code that I am talking about: static void interface_create_callback(int result, GSupplicantInterface *interface, void *user_data) { struct wifi_data *wifi = user_data; DBG("result %d ifname %s, wifi %p", result, g_supplicant_interface_get_ifname(interface), wifi); if (result < 0 || wifi_link_removed(wifi)) goto done; wifi->interface = interface; g_supplicant_interface_set_data(interface, wifi); if (g_supplicant_interface_get_ready(interface)) { wifi->interface_ready = true; finalize_interface_creation(wifi); } done: if (wifi != NULL) { DBG("calling unref 6"); /* Remove ref added in wifi_enable */ wifi_data_unref(wifi); ==> *This code would decrement the count even in the successful case* } } I suggest to make following change: static void interface_create_callback(int result, GSupplicantInterface *interface, void *user_data) { static void interface_create_callback(int result, GSupplicantInterface *interface, void *user_data) { struct wifi_data *wifi = user_data; DBG("result %d ifname %s, wifi %p", result, g_supplicant_interface_get_ifname(interface), wifi); if (result < 0 || wifi_link_removed(wifi)) goto done; wifi->interface = interface; g_supplicant_interface_set_data(interface, wifi); if (g_supplicant_interface_get_ready(interface)) { wifi->interface_ready = true; finalize_interface_creation(wifi); wifi = NULL; } done: if (wifi != NULL) { DBG("calling unref 6"); /* Remove ref added in wifi_enable */ wifi_data_unref(wifi); } } if (g_supplicant_interface_get_ready(interface)) { wifi->interface_ready = true; finalize_interface_creation(wifi); *wifi = NULL; ==> make wifi as NULL again so that we can distinguish b/w failure and successful case.* } done: if (wifi != NULL) { DBG("calling unref 6"); /* Remove ref added in wifi_enable */ wifi_data_unref(wifi); } } Regards Naveen _______________________________________________ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman