mirror of git://git.sysmocom.de/ofono
huawei: Fix infinite loop on modem removal
After unplugging a Huawei USB dongle, the 'atoms' in oFono are removed via 'flush_atoms'. Every atom has a destruct function pointer, used as destructor. This includes the gprs_context atom that is currently active. The function calls are: flush_atoms -> destruct -> gprs_context_remove -> at_gprs_context_remove -> modem_disconnect Because the device is physically removed, the IO channel for the AT port is gone. In 'at_gprs_context_remove', there is an attempt to resume communication over that AT port, but that is not possible. This is detected, and 'io_disconnect' (pointer to 'modem_disconnect') is called. 'modem_disconnect' has the same atom and tries to remove it again, so it calls the same destructor. This continues infinitely. This patch moves the GPRS context removal so that it only happens if the modem port could be re-opened successfully. If the port cannot be re-opened (in the case of modem removal), the atom is already in the process of being removed by the process kicked off in flush_atoms. This fix is limited to Huawei devices and has been tested using the following devices: - E3531i-2 - E3372 - E3531s-2 - E369 - E1552
This commit is contained in:
parent
cd13b2b5f3
commit
d7d49eb1d5
|
@ -583,9 +583,6 @@ static void modem_disconnect(gpointer user_data)
|
||||||
g_at_chat_unref(data->modem);
|
g_at_chat_unref(data->modem);
|
||||||
data->modem = NULL;
|
data->modem = NULL;
|
||||||
|
|
||||||
/* close gprs context driver */
|
|
||||||
ofono_gprs_context_remove(data->gc);
|
|
||||||
|
|
||||||
/* reopen modem channel */
|
/* reopen modem channel */
|
||||||
data->modem = open_device(modem, "Modem", "Modem: ");
|
data->modem = open_device(modem, "Modem", "Modem: ");
|
||||||
|
|
||||||
|
@ -594,6 +591,10 @@ static void modem_disconnect(gpointer user_data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* close previous gprs context driver */
|
||||||
|
if (data->gc)
|
||||||
|
ofono_gprs_context_remove(data->gc);
|
||||||
|
|
||||||
/* configure modem channel */
|
/* configure modem channel */
|
||||||
g_at_chat_set_disconnect_function(data->modem, modem_disconnect, modem);
|
g_at_chat_set_disconnect_function(data->modem, modem_disconnect, modem);
|
||||||
g_at_chat_set_slave(data->modem, data->pcui);
|
g_at_chat_set_slave(data->modem, data->pcui);
|
||||||
|
|
Loading…
Reference in New Issue