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:
Jimmy Gysens 2019-11-19 10:53:20 +00:00 committed by Denis Kenzior
parent cd13b2b5f3
commit d7d49eb1d5
1 changed files with 4 additions and 3 deletions

View File

@ -583,9 +583,6 @@ static void modem_disconnect(gpointer user_data)
g_at_chat_unref(data->modem);
data->modem = NULL;
/* close gprs context driver */
ofono_gprs_context_remove(data->gc);
/* reopen modem channel */
data->modem = open_device(modem, "Modem", "Modem: ");
@ -594,6 +591,10 @@ static void modem_disconnect(gpointer user_data)
return;
}
/* close previous gprs context driver */
if (data->gc)
ofono_gprs_context_remove(data->gc);
/* configure modem channel */
g_at_chat_set_disconnect_function(data->modem, modem_disconnect, modem);
g_at_chat_set_slave(data->modem, data->pcui);