---
src/modem.c | 47 +++++++++++++++++++++++++----------------------
1 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/src/modem.c b/src/modem.c
index 3776461..3fb6809 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -752,6 +752,7 @@ static GDBusSignalTable modem_signals[] = {
void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered)
{
DBusConnection *conn = ofono_dbus_get_connection();
+ dbus_bool_t dbus_powered = powered;
if (modem->timeout > 0) {
g_source_remove(modem->timeout);
@@ -771,32 +772,34 @@ void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t
powered)
modem->powered_pending = powered;
- if (modem->powered != powered) {
- dbus_bool_t dbus_powered = powered;
- modem->powered = powered;
+ if (modem->powered == powered)
+ goto out;
- if (modem->driver == NULL) {
- ofono_error("Calling ofono_modem_set_powered on a"
- "modem with no driver is not valid, "
- "please fix the modem driver.");
- return;
- }
+ modem->powered = powered;
- ofono_dbus_signal_property_changed(conn, modem->path,
- OFONO_MODEM_INTERFACE,
- "Powered", DBUS_TYPE_BOOLEAN,
- &dbus_powered);
+ if (modem->driver == NULL) {
+ ofono_error("Calling ofono_modem_set_powered on a"
+ "modem with no driver is not valid, "
+ "please fix the modem driver.");
+ return;
+ }
- if (powered) {
- modem_change_state(modem, MODEM_STATE_PRE_SIM);
+ ofono_dbus_signal_property_changed(conn, modem->path,
+ OFONO_MODEM_INTERFACE,
+ "Powered", DBUS_TYPE_BOOLEAN,
+ &dbus_powered);
- /* Force SIM Ready for devies with no sim atom */
- if (__ofono_modem_find_atom(modem,
- OFONO_ATOM_TYPE_SIM) == NULL)
- sim_state_watch(OFONO_SIM_STATE_READY, modem);
- } else
- modem_change_state(modem, MODEM_STATE_POWER_OFF);
- }
+ if (powered) {
+ modem_change_state(modem, MODEM_STATE_PRE_SIM);
+
+ /* Force SIM Ready for devies with no sim atom */
+ if (__ofono_modem_find_atom(modem,
+ OFONO_ATOM_TYPE_SIM) == NULL)
+ sim_state_watch(OFONO_SIM_STATE_READY, modem);
+ } else
+ modem_change_state(modem, MODEM_STATE_POWER_OFF);
+
+out:
if (powering_down && powered == FALSE) {
modems_remaining -= 1;
--
1.7.3.1
Show replies by thread
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
---
plugins/phonesim.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/plugins/phonesim.c b/plugins/phonesim.c
index d2faf42..7426da6 100644
--- a/plugins/phonesim.c
+++ b/plugins/phonesim.c
@@ -237,6 +237,13 @@ static void cfun_set_on_cb(gboolean ok, GAtResult *result, gpointer
user_data)
ofono_modem_set_powered(modem, ok);
}
+static void crst_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+
+ ofono_modem_reset(modem);
+}
+
static void phonesim_disconnected(gpointer user_data)
{
struct ofono_modem *modem = user_data;
@@ -389,6 +396,9 @@ static int phonesim_enable(struct ofono_modem *modem)
g_at_chat_send(data->chat, "AT+CSCS=\"GSM\"", none_prefix,
NULL, NULL, NULL);
+ g_at_chat_register(data->chat, "+CRST:",
+ crst_notify, FALSE, modem, NULL);
+
return 0;
}
--
1.7.3.1