broadband-modem: implement on demand signal quality checks with AT+CIND?

This commit is contained in:
Aleksander Morgado
2012-03-15 14:14:40 +01:00
parent e06d42c868
commit 08b7620b7a
+120 -8
View File
@@ -734,6 +734,121 @@ load_signal_quality_csf (MMBroadbandModem *self,
result);
}
static void
load_signal_quality_cind_ready (MMBroadbandModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
const gchar *result;
GByteArray *indicators;
result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!error)
indicators = mm_parse_cind_query_response (result, &error);
if (error) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
if (indicators->len >= self->priv->cind_indicator_signal_quality) {
guint quality;
quality = g_array_index (indicators, guint8, self->priv->cind_indicator_signal_quality);
quality = CLAMP (quality, 0, 5) * 20;
g_simple_async_result_set_op_res_gpointer (simple,
GUINT_TO_POINTER (quality),
NULL);
g_byte_array_free (indicators, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
g_simple_async_result_set_error (simple,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Could not parse CIND signal quality results "
"signal index (%u) outside received range (0-%u)",
self->priv->cind_indicator_signal_quality,
indicators->len);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_signal_quality_cind (MMBroadbandModem *self,
GSimpleAsyncResult *result)
{
mm_base_modem_at_command (MM_BASE_MODEM (self),
"+CIND?",
3,
FALSE,
NULL, /* cancellable */
(GAsyncReadyCallback)load_signal_quality_cind_ready,
result);
}
static void
check_cind_supported_ready (MMBroadbandModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GHashTable *indicators = NULL;
GError *error = NULL;
const gchar *result;
result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error)
g_error_free (error);
else
indicators = mm_parse_cind_test_response (result, NULL);
if (indicators) {
CindResponse *r;
r = g_hash_table_lookup (indicators, "signal");
if (r) {
self->priv->cind_indicator_signal_quality = cind_response_get_index (r);
self->priv->signal_quality_method = SIGNAL_QUALITY_METHOD_CSQ;
load_signal_quality_cind (self, simple);
}
/* TODO: also handle roam/service indicators */
/* r = g_hash_table_lookup (indicators, "roam"); */
/* if (r) */
/* priv->roam_ind = cind_response_get_index (r); */
/* r = g_hash_table_lookup (indicators, "service"); */
/* if (r) */
/* priv->service_ind = cind_response_get_index (r); */
/* TODO: Enable CMER in the primary and secondary ports */
g_hash_table_destroy (indicators);
return;
}
/* CIND won't be supported, default to CSQ */
self->priv->signal_quality_method = SIGNAL_QUALITY_METHOD_CSQ;
load_signal_quality_csf (self, simple);
}
static void
check_cind_supported (MMBroadbandModem *self,
GSimpleAsyncResult *result)
{
mm_base_modem_at_command (MM_BASE_MODEM (self),
"+CIND=?",
3,
TRUE,
NULL, /* cancellable */
(GAsyncReadyCallback)check_cind_supported_ready,
result);
}
static void
load_signal_quality (MMIfaceModem *self,
GAsyncReadyCallback callback,
@@ -741,8 +856,6 @@ load_signal_quality (MMIfaceModem *self,
{
GSimpleAsyncResult *result;
MM_BROADBAND_MODEM (self)->priv->signal_quality_method = SIGNAL_QUALITY_METHOD_CSQ;
mm_dbg ("loading signal quality...");
result = g_simple_async_result_new (G_OBJECT (self),
callback,
@@ -751,16 +864,15 @@ load_signal_quality (MMIfaceModem *self,
switch (MM_BROADBAND_MODEM (self)->priv->signal_quality_method) {
case SIGNAL_QUALITY_METHOD_UNKNOWN:
/* Check if CIND supported */
return;
check_cind_supported (MM_BROADBAND_MODEM (self), result);
break;
case SIGNAL_QUALITY_METHOD_CSQ:
load_signal_quality_csf (MM_BROADBAND_MODEM (self), result);
return;
break;
case SIGNAL_QUALITY_METHOD_CIND:
return;
load_signal_quality_cind (MM_BROADBAND_MODEM (self), result);
break;
}
g_assert_not_reached ();
}
/*****************************************************************************/