Hi Bertrand, On 04/06/2012 08:34 AM, Bertrand Aygon wrote: > Add speedup_set_online. > Add a polling mechanism since most speedup dongles failed in couple of AT > commands following the CFUN=1 when they are offline. > > --- > plugins/speedup.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 106 insertions(+), 0 deletions(-) > > diff --git a/plugins/speedup.c b/plugins/speedup.c > index ca6ed13..905f462 100644 > --- a/plugins/speedup.c > +++ b/plugins/speedup.c > @@ -47,12 +47,16 @@ > #include > #include > > +static const char *creg_prefix[] = { "+CREG:", NULL }; > static const char *none_prefix[] = { NULL }; > > struct speedup_data { > GAtChat *modem; > GAtChat *aux; > gboolean have_sim; > + guint online_poll_source; > + guint online_poll_count; > + struct cb_data *online_cbd; You need to free these in case the modem is removed when the online operation is in progress. > struct at_util_sim_state_query *sim_state_query; > }; > > @@ -238,6 +242,107 @@ static int speedup_disable(struct ofono_modem *modem) > return -EINPROGRESS; > } > > +static gboolean creg_online_check(gpointer user_data); > + > +static void creg_online_cb(gboolean ok, GAtResult *result, > + gpointer user_data) > +{ > + struct speedup_data *data = user_data; > + ofono_modem_online_cb_t cb = data->online_cbd->cb; > + > + if (ok) { > + CALLBACK_WITH_SUCCESS(cb, data->online_cbd->data); > + goto done; > + } > + > + data->online_poll_count++; > + > + if (data->online_poll_count > 15) > + goto failure; > + > + data->online_poll_source = g_timeout_add_seconds(2, > + creg_online_check, data); > + return; > + > +failure: > + CALLBACK_WITH_FAILURE(cb, data->online_cbd->data); > + > +done: > + g_free(data->online_cbd); > + data->online_cbd = NULL; > +} > + > +static gboolean creg_online_check(gpointer user_data) > +{ > + struct speedup_data *data = user_data; > + > + data->online_poll_source = 0; > + > + g_at_chat_send(data->aux, "AT+CREG=?", creg_prefix, > + creg_online_cb, data, NULL); Just for my understanding, the modem stops responding to all commands when CFUN=1 is issued, hence you're polling that CREG is supported? > + > + return FALSE; > +} > + > +static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data) > +{ > + struct ofono_modem *modem = user_data; > + struct speedup_data *data = ofono_modem_get_data(modem); > + > + if (!ok) { > + ofono_modem_online_cb_t cb = data->online_cbd->cb; > + > + CALLBACK_WITH_FAILURE(cb, data->online_cbd->data); > + > + g_free(data->online_cbd); > + data->online_cbd = NULL; > + return; > + } > + > + data->online_poll_count = 0; > + > + creg_online_check(data); > +} > + > +static void set_offline_cb(gboolean ok, GAtResult *result, gpointer user_data) > +{ > + struct cb_data *cbd = user_data; > + ofono_modem_online_cb_t cb = cbd->cb; > + struct ofono_error error; > + > + decode_at_error(&error, g_at_result_final_response(result)); > + cb(&error, cbd->data); > +} > + > +static void speedup_set_online(struct ofono_modem *modem, ofono_bool_t online, > + ofono_modem_online_cb_t cb, void *user_data) > +{ > + struct speedup_data *data = ofono_modem_get_data(modem); > + > + DBG("modem %p %s", modem, online ? "online" : "offline"); > + > + if (online == TRUE) { > + data->online_cbd = cb_data_new(cb, user_data); > + > + if (g_at_chat_send(data->aux, "AT+CFUN=1", none_prefix, > + set_online_cb, modem, NULL) > 0) > + return; > + > + g_free(data->online_cbd); > + data->online_cbd = NULL; > + } else { > + struct cb_data *cbd = cb_data_new(cb, user_data); > + > + if (g_at_chat_send(data->aux, "AT+CFUN=4", > + none_prefix, set_offline_cb, cbd, g_free) > 0) > + return; > + > + g_free(cbd); > + } > + > + CALLBACK_WITH_FAILURE(cb, user_data); > +} > + > static void speedup_pre_sim(struct ofono_modem *modem) > { > struct speedup_data *data = ofono_modem_get_data(modem); > @@ -292,6 +397,7 @@ static struct ofono_modem_driver speedup_driver = { > .remove = speedup_remove, > .enable = speedup_enable, > .disable = speedup_disable, > + .set_online = speedup_set_online, > .pre_sim = speedup_pre_sim, > .post_sim = speedup_post_sim, > .post_online = speedup_post_online, Regards, -Denis