aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/mm-modem-iridium-gsm.c86
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)
{
}