diff --git a/src/manager.c b/src/manager.c index 9b13ca2..38e71a6 100644 --- a/src/manager.c +++ b/src/manager.c @@ -145,7 +145,35 @@ void modem_configure(struct EG25Manager *manager) at_sequence_configure(manager); } -static gboolean modem_reset_done(struct EG25Manager* manager) +static gboolean modem_gpio_reset_done(struct EG25Manager *manager) +{ + gpio_sequence_poweron(manager); + manager->modem_state = EG25_STATE_POWERED; + manager->complete_reset_timer = 0; + + return G_SOURCE_REMOVE; +} + +static gboolean modem_at_reset_done(struct EG25Manager* manager) +{ + /* + * If the modem was successfully rebooted, then we should have received + * "RDY" by now which will transition the state to started. + */ + if (manager->modem_state != EG25_STATE_RESETTING) { + manager->complete_reset_timer = 0; + return G_SOURCE_REMOVE; + } + + g_message("AT reset failed, falling back to GPIO reset"); + + gpio_sequence_shutdown(manager); + manager->complete_reset_timer = g_timeout_add_seconds(30, G_SOURCE_FUNC(modem_gpio_reset_done), manager); + + return G_SOURCE_REMOVE; +} + +static gboolean modem_rebind_done(struct EG25Manager* manager) { manager->modem_state = EG25_STATE_RESUMING; manager->complete_reset_timer = 0; @@ -223,7 +251,7 @@ gboolean modem_reset(struct EG25Manager *manager) * 3s is long enough to make sure the modem has been bound back and * short enough to ensure it hasn't been acquired by ModemManager */ - manager->complete_reset_timer = g_timeout_add_seconds(3, G_SOURCE_FUNC(modem_reset_done), manager); + manager->complete_reset_timer = g_timeout_add_seconds(3, G_SOURCE_FUNC(modem_rebind_done), manager); return G_SOURCE_REMOVE; @@ -241,7 +269,7 @@ error: at_sequence_reset(manager); // Setup timer for making sure we don't queue other reset commands - manager->complete_reset_timer = g_timeout_add_seconds(30, G_SOURCE_FUNC(modem_reset_done), manager); + manager->complete_reset_timer = g_timeout_add_seconds(30, G_SOURCE_FUNC(modem_at_reset_done), manager); return G_SOURCE_REMOVE; }