diff options
author | Aki Niemi <aki.niemi@nokia.com> | 2009-07-09 16:13:46 +0300 |
---|---|---|
committer | Aki Niemi <aki.niemi@nokia.com> | 2009-07-09 16:15:56 +0300 |
commit | e56d92ce30f86dff615357044dad85e8496c2dfc (patch) | |
tree | bbcc30d4ee8854ccc65fe196bc78c1bc23d43f5b | |
parent | c74ea2093fc869693ac6209b859f000a3a22b28a (diff) | |
download | ofono-e56d92ce30f86dff615357044dad85e8496c2dfc.tar.bz2 |
Fix isimodem segfault on modem removal
This fixes segfaults resulting either from destroying a NULL ISI
client, or when multiple ISI modems become available, and get removed
in the wrong order. To support multiple ISI modems concurrently, a
modem object needs to be exposed via the gisi API, and tracked by the
ISI driver. This is a TODO item to add.
-rw-r--r-- | drivers/isimodem/isimodem.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/drivers/isimodem/isimodem.c b/drivers/isimodem/isimodem.c index e63d0832..1cefe6c8 100644 --- a/drivers/isimodem/isimodem.c +++ b/drivers/isimodem/isimodem.c @@ -418,13 +418,31 @@ static void netlink_status_cb(bool up, uint8_t addr, unsigned idx, up ? "up" : "down", addr, idx); if (up) { - isi->modem = ofono_modem_register(&ops); - if (!isi->modem) - return; - ofono_modem_set_userdata(isi->modem, isi); + if (!client) { + client = g_isi_client_create(PN_PHONE_INFO); + if (!client) + return; + } + + if (!isi->modem) { + isi->modem = ofono_modem_register(&ops); + if (!isi->modem) + return; + + ofono_modem_set_userdata(isi->modem, isi); + } } else { clear_pending_reqs(); - ofono_modem_unregister(isi->modem); + + if (client) { + g_isi_client_destroy(client); + client = NULL; + } + + if (isi->modem) { + ofono_modem_unregister(isi->modem); + isi->modem = NULL; + } } } @@ -432,7 +450,6 @@ static int isimodem_init(void) { isi = g_new0(struct isi_data, 1); - client = g_isi_client_create(PN_PHONE_INFO); pn_link = g_pn_netlink_start(netlink_status_cb, isi); return 0; @@ -441,8 +458,17 @@ static int isimodem_init(void) static void isimodem_exit(void) { clear_pending_reqs(); - g_isi_client_destroy(client); - g_pn_netlink_stop(pn_link); + + if (client) { + g_isi_client_destroy(client); + client = NULL; + } + + if (pn_link) { + g_pn_netlink_stop(pn_link); + pn_link = NULL; + } + g_free(isi); } |