Hi Denis, On 30/03/2011 22:59, Denis Kenzior wrote: > Hi Guillaume, > > On 03/25/2011 10:25 AM, Guillaume Zajac wrote: >> --- >> gatchat/gsmdial.c | 164 ++++++++++++++++++++++++++++++++++++++++++++-------- >> 1 files changed, 138 insertions(+), 26 deletions(-) >> >> diff --git a/gatchat/gsmdial.c b/gatchat/gsmdial.c >> index 92a7ff2..f1b485e 100644 >> --- a/gatchat/gsmdial.c >> +++ b/gatchat/gsmdial.c >> @@ -40,6 +40,8 @@ >> >> #define IFCONFIG_PATH "/sbin/ifconfig" >> >> +#define GUARD_TIMEOUTS 1500 >> + >> static const char *none_prefix[] = { NULL }; >> static const char *cfun_prefix[] = { "+CFUN:", NULL }; >> static const char *creg_prefix[] = { "+CREG:", NULL }; >> @@ -238,32 +240,6 @@ static gboolean execute(const char *cmd) >> return TRUE; >> } >> >> -static void ppp_connect(const char *iface, const char *local, const char *peer, >> - const char *dns1, const char *dns2, >> - gpointer user_data) >> -{ >> - char buf[512]; >> - >> - /* print out the negotiated address and dns server */ >> - g_print("Network Device: %s\n", iface); >> - g_print("IP Address: %s\n", local); >> - g_print("Peer IP Address: %s\n", peer); >> - g_print("Primary DNS Server: %s\n", dns1); >> - g_print("Secondary DNS Server: %s\n", dns2); >> - >> - if (getuid() != 0) { >> - g_print("Need root privilege to config PPP interface\n"); >> - return; >> - } >> - >> - snprintf(buf, sizeof(buf), "%s %s up", IFCONFIG_PATH, iface); >> - execute(buf); >> - >> - snprintf(buf, sizeof(buf), "%s %s %s pointopoint %s", IFCONFIG_PATH, >> - iface, local, peer); >> - execute(buf); >> -} >> - >> static void no_carrier_notify(GAtResult *result, gpointer user_data) >> { >> char buf[64]; >> @@ -294,6 +270,142 @@ static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data) >> g_at_chat_resume(modem); >> } >> >> +static void power_down_ppp(gboolean ok, GAtResult *result, gpointer user_data) >> +{ >> + if (!ok) >> + return; >> + >> + g_at_ppp_unref(ppp); >> + ppp = NULL; >> +} >> + >> +static gboolean send_ATH0(gpointer user_data) >> +{ >> + /* Resume AT chat to send ATH0 */ >> + g_at_chat_resume(modem); >> + g_at_chat_send(modem, "ATH0", none_prefix, power_down_ppp, NULL, NULL); >> + >> + return FALSE; >> +} >> + >> +static gboolean suspend_and_close(gpointer user_data) >> +{ >> + g_print("Send +++\n"); >> + /* Send the escape sequence to suspend PPP server*/ >> + g_at_io_write(g_at_chat_get_io(modem), "+++", 3); >> + >> + /* >> + * Wait GUARD_TIMEOUTS ms before sending ATH0 cmd >> + * according to guard timeouts >> + */ >> + g_timeout_add(GUARD_TIMEOUTS, send_ATH0, NULL); >> + >> + return FALSE; >> +} >> + >> +static void ppp_suspend_close(gpointer data) >> +{ >> + /* Delete the write done CB */ >> + g_at_io_set_write_done(g_at_chat_get_io(modem), NULL, NULL); >> + >> + /* >> + * We are sure there are no more PPP packets to be written, >> + * we can suspend PPP client >> + */ >> + g_at_ppp_suspend(ppp); >> + >> + /* Wait GUARD_TIMEOUTS ms before sending escape sequence */ >> + g_timeout_add(GUARD_TIMEOUTS, suspend_and_close, NULL); >> +} >> + >> +static void suspend_gat_chat(gboolean ok, GAtResult *result, gpointer user_data) >> +{ >> + /* >> + * As soon as the command is treated by AT server >> + * we can suspend AT chat and resume PPP client >> + */ >> + g_at_chat_suspend(modem); >> + g_at_ppp_resume(ppp); >> + >> + /* >> + * We wait for another PPP packet to be written >> + * to suspend again PPP server and close it >> + */ >> + g_at_io_set_write_done(g_at_chat_get_io(modem), ppp_suspend_close, NULL); >> +} >> + >> +static gboolean send_ATO0(gpointer user_data) >> +{ >> + /* Resume AT chat to send ATO0 */ >> + g_at_chat_resume(modem); >> + g_at_chat_send(modem, "ATO0", none_prefix, suspend_gat_chat, NULL, NULL); >> + >> + return FALSE; >> +} >> + >> +static gboolean suspend_resume(gpointer user_data) >> +{ >> + g_print("Send +++\n"); >> + /* Send the escape sequence to suspend PPP server*/ >> + g_at_io_write(g_at_chat_get_io(modem), "+++", 3); >> + >> + /* >> + * Wait GUARD_TIMEOUTS ms before sending ATO0 cmd >> + * according to guard timeouts >> + */ >> + g_timeout_add(GUARD_TIMEOUTS, send_ATO0, NULL); >> + >> + return FALSE; >> +} >> + >> +static void ppp_suspend_resume(gpointer data) >> +{ >> + /* Delete the write done CB */ >> + g_at_io_set_write_done(g_at_chat_get_io(modem), NULL, NULL); >> + >> + /* >> + * We are sure there are no more PPP packets to be written, >> + * we can suspend PPP client >> + */ >> + g_at_ppp_suspend(ppp); >> + >> + /* Wait GUARD_TIMEOUTS ms before sending escape sequence */ >> + g_timeout_add(GUARD_TIMEOUTS, suspend_resume, NULL); >> +} >> + > The logic for sending a guard timeout, +++, guard timeout should really > belong in GAtChat, otherwise every single client has to repeat the same > state machine. I can implement a g_at_chat_send_escape_sequence() to manage: --> +++ timing I would still write directly on at_chat GAtIO because using at_chat_send_common() would add a '\r' that would cancel the suspend data call. Kind regards, Guillaume