diff --git a/src/manager.c b/src/manager.c index 26e0d67..be72c57 100644 --- a/src/manager.c +++ b/src/manager.c @@ -110,10 +110,27 @@ void modem_configure(struct EG25Manager *manager) at_sequence_configure(manager); } +static gboolean modem_reset_done(struct EG25Manager* manager) +{ + manager->modem_state = EG25_STATE_RESUMING; + manager->reset_timer = 0; + return FALSE; +} + void modem_reset(struct EG25Manager *manager) { int fd, ret, len = strlen(manager->modem_usb_id); + if (manager->reset_timer) + return; + + if (manager->suspend_source) { + g_source_remove(manager->suspend_source); + manager->suspend_source = 0; + } + + manager->modem_state = EG25_STATE_RESETTING; + fd = open("/sys/bus/usb/drivers/usb/unbind", O_WRONLY); if (fd < 0) goto error; @@ -127,16 +144,20 @@ void modem_reset(struct EG25Manager *manager) goto error; ret = write(fd, manager->modem_usb_id, len); if (ret < len) - g_warning("Couldn't unbind modem: wrote %d/%d bytes", ret, len); - + g_warning("Couldn't bind modem: wrote %d/%d bytes", ret, len); close(fd); + /* + * 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->reset_timer = g_timeout_add_seconds(3, G_SOURCE_FUNC(modem_reset_done), manager); + return; error: // Everything else failed, reset the modem at_sequence_reset(manager); - manager->modem_state = EG25_STATE_RESETTING; } void modem_suspend(struct EG25Manager *manager) diff --git a/src/manager.h b/src/manager.h index 714a812..8c12741 100644 --- a/src/manager.h +++ b/src/manager.h @@ -26,6 +26,11 @@ enum EG25State { struct EG25Manager { GMainLoop *loop; + guint reset_timer; + + int at_fd; + guint at_source; + GList *at_cmds; enum EG25State modem_state; gchar *modem_usb_id; @@ -40,10 +45,6 @@ struct EG25Manager { guint suspend_source; - int at_fd; - guint at_source; - GList *at_cmds; - struct gpiod_chip *gpiochip[2]; struct gpiod_line *gpio_out[5]; struct gpiod_line *gpio_in[2]; diff --git a/src/mm-iface.c b/src/mm-iface.c index 0d7e5b6..76c5138 100644 --- a/src/mm-iface.c +++ b/src/mm-iface.c @@ -35,7 +35,10 @@ static void add_modem(struct EG25Manager *manager, GDBusObject *object) g_assert(manager->mm_modem != NULL); if (manager->modem_state == EG25_STATE_RESUMING) { - g_source_remove(manager->suspend_source); + if (manager->suspend_source) { + g_source_remove(manager->suspend_source); + manager->suspend_source = 0; + } modem_resume_post(manager); manager->modem_state = EG25_STATE_CONFIGURED; } diff --git a/src/suspend.c b/src/suspend.c index c15bdd0..4aa5de6 100644 --- a/src/suspend.c +++ b/src/suspend.c @@ -20,6 +20,7 @@ static gboolean check_modem_resume(struct EG25Manager *manager) { g_message("Modem wasn't probed in time, restart it!"); + manager->suspend_source = 0; modem_reset(manager); return FALSE;