Some modems can screw up everything and then we will need to do a silent
reset of the modem. This patch take the modem back to the OFFLINE state.
---
include/modem.h | 2 +
src/modem.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/include/modem.h b/include/modem.h
index 7b13ee0..a92eb88 100644
--- a/include/modem.h
+++ b/include/modem.h
@@ -46,6 +46,8 @@ int ofono_modem_register(struct ofono_modem *modem);
ofono_bool_t ofono_modem_is_registered(struct ofono_modem *modem);
void ofono_modem_remove(struct ofono_modem *modem);
+void ofono_modem_reset(struct ofono_modem *modem);
+
void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered);
ofono_bool_t ofono_modem_get_powered(struct ofono_modem *modem);
diff --git a/src/modem.c b/src/modem.c
index 3fb6809..f6d7585 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -70,6 +70,7 @@ struct ofono_modem {
guint interface_update;
ofono_bool_t powered;
ofono_bool_t powered_pending;
+ ofono_bool_t reset_pending;
guint timeout;
ofono_bool_t online;
GHashTable *properties;
@@ -784,7 +785,8 @@ void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t
powered)
return;
}
- ofono_dbus_signal_property_changed(conn, modem->path,
+ if (!modem->reset_pending)
+ ofono_dbus_signal_property_changed(conn, modem->path,
OFONO_MODEM_INTERFACE,
"Powered", DBUS_TYPE_BOOLEAN,
&dbus_powered);
@@ -799,14 +801,34 @@ void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t
powered)
} else
modem_change_state(modem, MODEM_STATE_POWER_OFF);
-out:
+ if (modem->reset_pending && !powering_down) {
+ int err;
+
+ modem->reset_pending = FALSE;
+
+ if (modem->powered) {
+ modem_change_state(modem, MODEM_STATE_OFFLINE);
+ } else {
+ err = set_powered(modem, TRUE);
+ if (err == -EINPROGRESS) {
+ modem->reset_pending = TRUE;
+ return;
+ }
+
+ modem_change_state(modem, MODEM_STATE_PRE_SIM);
+
+ modem_change_state(modem, MODEM_STATE_OFFLINE);
+ }
+ }
+out:
if (powering_down && powered == FALSE) {
modems_remaining -= 1;
if (modems_remaining == 0)
__ofono_exit();
}
+
}
ofono_bool_t ofono_modem_get_powered(struct ofono_modem *modem)
@@ -1566,6 +1588,37 @@ void ofono_modem_remove(struct ofono_modem *modem)
g_free(modem);
}
+static gboolean __reset_modem(void *data)
+{
+ struct ofono_modem *modem = data;
+ int err;
+
+ err = set_powered(modem, FALSE);
+ if (err == -EINPROGRESS) {
+ modem->reset_pending = TRUE;
+ return FALSE;
+ }
+
+ err = set_powered(modem, TRUE);
+ if (err == -EINPROGRESS) {
+ modem->reset_pending = TRUE;
+ return FALSE;
+ }
+
+ modem_change_state(modem, MODEM_STATE_PRE_SIM);
+
+ modem_change_state(modem, MODEM_STATE_OFFLINE);
+
+ return FALSE;
+}
+
+void ofono_modem_reset(struct ofono_modem *modem)
+{
+ DBG("%p", modem);
+
+ g_idle_add(__reset_modem, modem);
+}
+
int ofono_modem_driver_register(const struct ofono_modem_driver *d)
{
DBG("driver: %p, name: %s", d, d->name);
--
1.7.3.1