From b14bf797f1a7bc5501757c5e01830615dbfbba83 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 16 Feb 2012 19:54:48 +0100 Subject: [PATCH] iridium: override generic initialization We must send ATZ alone and once reply received, wait some time before sending the next initialization commands. Otherwise, the next commands will receive garbage as reply. The only way to handle this is to override the whole generic initialization phase. --- plugins/mm-broadband-modem-iridium.c | 98 ++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/plugins/mm-broadband-modem-iridium.c b/plugins/mm-broadband-modem-iridium.c index d8667b1c..9e4d72c5 100644 --- a/plugins/mm-broadband-modem-iridium.c +++ b/plugins/mm-broadband-modem-iridium.c @@ -40,6 +40,100 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemIridium, mm_broadband_modem_iridium, MM_ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)); +/*****************************************************************************/ +/* Initializing the modem (Modem interface) */ + +static gboolean +modem_init_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static const MMBaseModemAtCommand modem_init_sequence[] = { + /* Init command */ + { "E0 V1", 3, FALSE, NULL }, + { "+CMEE=1", 3, FALSE, NULL }, + { NULL } +}; + +static void +init_sequence_ready (MMBroadbandModem *self, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error); + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static gboolean +after_atz_sleep_cb (GSimpleAsyncResult *simple) +{ + MMBaseModem *self; + + self = MM_BASE_MODEM (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + /* Now, run the remaining sequence */ + mm_base_modem_at_sequence (self, + modem_init_sequence, + NULL, /* response_processor_context */ + NULL, /* response_processor_context_free */ + NULL, /* cancellable */ + (GAsyncReadyCallback)init_sequence_ready, + simple); + g_object_unref (self); + return FALSE; +} + +static void +atz_ready (MMBroadbandModem *self, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); + if (error) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); + return; + } + + /* Once ATZ reply is received, we need to wait a bit before going on, + * otherwise, the next commands given will receive garbage as reply + * (500ms should be enough) */ + g_timeout_add (500, (GSourceFunc)after_atz_sleep_cb, simple); +} + +static void +modem_init (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + + result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + modem_init); + /* First, send ATZ alone */ + mm_base_modem_at_command (MM_BASE_MODEM (self), + "Z", + 3, + TRUE, + NULL, /* cancellable */ + (GAsyncReadyCallback)atz_ready, + result); +} + /*****************************************************************************/ /* Operator Code and Name loading (3GPP interface) */ @@ -255,6 +349,10 @@ mm_broadband_modem_iridium_init (MMBroadbandModemIridium *self) static void iface_modem_init (MMIfaceModem *iface) { + /* Initialization */ + iface->modem_init = modem_init; + iface->modem_init_finish = modem_init_finish; + /* Create Iridium-specific SIM */ iface->create_sim = create_sim; iface->create_sim_finish = create_sim_finish;