diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2011-06-03 13:05:37 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-02-17 13:25:02 +0100 |
commit | 85de9bbcc9146447153fe82cc22efbd1e45a44fd (patch) | |
tree | f2fe698c27905626553e686ce6af79d46be5d2e9 | |
parent | b7b37c4738180b589aabc904402657ec5cc518b9 (diff) |
iridium: override signal quality retrieval command
-rw-r--r-- | plugins/mm-modem-iridium-gsm.c | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/plugins/mm-modem-iridium-gsm.c b/plugins/mm-modem-iridium-gsm.c index dce0dae6..731be930 100644 --- a/plugins/mm-modem-iridium-gsm.c +++ b/plugins/mm-modem-iridium-gsm.c @@ -27,7 +27,10 @@ #include "mm-modem-iridium-gsm.h" #include "mm-log.h" -G_DEFINE_TYPE (MMModemIridiumGsm, mm_modem_iridium_gsm, MM_TYPE_GENERIC_GSM); +static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class); + +G_DEFINE_TYPE_EXTENDED (MMModemIridiumGsm, mm_modem_iridium_gsm, MM_TYPE_GENERIC_GSM, 0, + G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)) MMModem * mm_modem_iridium_gsm_new (const char *device, @@ -51,6 +54,81 @@ mm_modem_iridium_gsm_new (const char *device, } static void +get_csqf_done (MMAtSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + gboolean parsed = FALSE; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + goto done; + } + + if (response && strstr (response->str, "+CSQ:")) { + /* Got valid reply */ + const char *str; + int quality; + + str = strstr (response->str, "+CSQ:") + 5; + + /* Skip possible whitespaces after '+CSQF:' and before the response */ + while (*str == ' ') + str++; + + if (sscanf (str, "%d", &quality)) { + /* Normalize the quality. <rssi> is NOT given in dBs, + * given as a relative value between 0 and 5 */ + quality = CLAMP (quality, 0, 5) * 100 / 5; + + mm_generic_gsm_update_signal_quality (MM_GENERIC_GSM (info->modem), quality); + mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL); + parsed = TRUE; + } + } + + if (!parsed && !info->error) { + info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Could not parse signal quality results"); + } + +done: + mm_callback_info_schedule (info); +} + +static void +get_signal_quality (MMModemGsmNetwork *modem, + MMModemUIntFn callback, + gpointer user_data) +{ + MMCallbackInfo *info; + MMAtSerialPort *port; + MMModemGsmNetwork *parent_iface; + + port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), NULL); + if (!port) { + /* Let the superclass handle it, will return cached value */ + parent_iface = g_type_interface_peek_parent (MM_MODEM_GSM_NETWORK_GET_INTERFACE (modem)); + parent_iface->get_signal_quality (modem, callback, user_data); + return; + } + + info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); + + /* The iridium modem may have a huge delay to get signal quality if we pass + * AT+CSQ, so we'll default to use AT+CSQF, which is a fast version that + * returns right away the last signal quality value retrieved */ + mm_at_serial_port_queue_command (port, "+CSQF", 3, get_csqf_done, info); +} + +static void get_sim_iccid (MMGenericGsm *modem, MMModemStringFn callback, gpointer callback_data) @@ -117,6 +195,12 @@ get_property (GObject *object, /*****************************************************************************/ static void +modem_gsm_network_init (MMModemGsmNetwork *network_class) +{ + network_class->get_signal_quality = get_signal_quality; +} + +static void mm_modem_iridium_gsm_init (MMModemIridiumGsm *self) { } |