iridium: override signal quality retrieval command

This commit is contained in:
Aleksander Morgado
2011-06-03 13:05:37 +02:00
parent b7b37c4738
commit 85de9bbcc9

View File

@@ -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,
@@ -50,6 +53,81 @@ mm_modem_iridium_gsm_new (const char *device,
NULL));
}
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,
@@ -116,6 +194,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)
{