summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAki Niemi <aki.niemi@nokia.com>2009-07-09 16:13:46 +0300
committerAki Niemi <aki.niemi@nokia.com>2009-07-09 16:15:56 +0300
commite56d92ce30f86dff615357044dad85e8496c2dfc (patch)
treebbcc30d4ee8854ccc65fe196bc78c1bc23d43f5b
parentc74ea2093fc869693ac6209b859f000a3a22b28a (diff)
downloadofono-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.c42
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);
}