summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorJimmy Gysens <jimmy.gysens_ext@softathome.com>2019-11-19 10:53:20 +0000
committerDenis Kenzior <denkenz@gmail.com>2019-11-21 21:12:53 -0600
commitd7d49eb1d5a7d30c3415b6b569f7b5e1e2a480da (patch)
tree7d5dea4fa6a722638567718396c656dcc7d56ae7 /plugins
parentcd13b2b5f3cd747ef2163094cc66af4e06f59945 (diff)
downloadofono-d7d49eb1d5a7d30c3415b6b569f7b5e1e2a480da.tar.gz
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
Diffstat (limited to 'plugins')
-rw-r--r--plugins/huawei.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/plugins/huawei.c b/plugins/huawei.c
index bdf7bc39..bb876701 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -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);