iface-modem: periodically request to update current access technologies

This commit is contained in:
Aleksander Morgado
2012-01-22 12:55:23 +01:00
parent 59e903820d
commit 8321bd5875
2 changed files with 140 additions and 6 deletions

View File

@@ -24,16 +24,19 @@
#include "mm-bearer-list.h"
#include "mm-log.h"
#define SIGNAL_QUALITY_RECENT_TIMEOUT_SEC 60
#define SIGNAL_QUALITY_CHECK_TIMEOUT_SEC 30
#define SIGNAL_QUALITY_RECENT_TIMEOUT_SEC 60
#define SIGNAL_QUALITY_CHECK_TIMEOUT_SEC 30
#define ACCESS_TECHNOLOGIES_CHECK_TIMEOUT_SEC 30
#define STATE_UPDATE_CONTEXT_TAG "state-update-context-tag"
#define SIGNAL_QUALITY_UPDATE_CONTEXT_TAG "signal-quality-update-context-tag"
#define SIGNAL_QUALITY_CHECK_CONTEXT_TAG "signal-quality-check-context-tag"
#define STATE_UPDATE_CONTEXT_TAG "state-update-context-tag"
#define SIGNAL_QUALITY_UPDATE_CONTEXT_TAG "signal-quality-update-context-tag"
#define SIGNAL_QUALITY_CHECK_CONTEXT_TAG "signal-quality-check-context-tag"
#define ACCESS_TECHNOLOGIES_CHECK_CONTEXT_TAG "access-technologies-check-context-tag"
static GQuark state_update_context_quark;
static GQuark signal_quality_update_context_quark;
static GQuark signal_quality_check_context_quark;
static GQuark access_technologies_check_context_quark;
/*****************************************************************************/
@@ -391,6 +394,125 @@ mm_iface_modem_update_access_technologies (MMIfaceModem *self,
/*****************************************************************************/
typedef struct {
guint timeout_source;
gboolean running;
} AccessTechnologiesCheckContext;
static void
access_technologies_check_context_free (AccessTechnologiesCheckContext *ctx)
{
if (ctx->timeout_source)
g_source_remove (ctx->timeout_source);
g_free (ctx);
}
static void
access_technologies_check_ready (MMIfaceModem *self,
GAsyncResult *res)
{
GError *error = NULL;
MMModemAccessTechnology access_technologies = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
guint mask = MM_MODEM_ACCESS_TECHNOLOGY_ANY;
AccessTechnologiesCheckContext *ctx;
if (!MM_IFACE_MODEM_GET_INTERFACE (self)->load_access_technologies_finish (
self,
res,
&access_technologies,
&mask,
&error)) {
mm_dbg ("Couldn't refresh access technologies: '%s'", error->message);
g_error_free (error);
} else
mm_iface_modem_update_access_technologies (self, access_technologies, mask);
/* Remove the running tag */
ctx = g_object_get_qdata (G_OBJECT (self), access_technologies_check_context_quark);
ctx->running = FALSE;
}
static gboolean
periodic_access_technologies_check (MMIfaceModem *self)
{
AccessTechnologiesCheckContext *ctx;
ctx = g_object_get_qdata (G_OBJECT (self), access_technologies_check_context_quark);
/* Only launch a new one if not one running already OR if the last one run
* was more than 15s ago. */
if (!ctx->running) {
ctx->running = TRUE;
MM_IFACE_MODEM_GET_INTERFACE (self)->load_access_technologies (
self,
(GAsyncReadyCallback)access_technologies_check_ready,
NULL);
}
return TRUE;
}
static void
periodic_access_technologies_check_disable (MMIfaceModem *self)
{
if (G_UNLIKELY (!access_technologies_check_context_quark))
access_technologies_check_context_quark = (g_quark_from_static_string (
ACCESS_TECHNOLOGIES_CHECK_CONTEXT_TAG));
/* Clear access technology */
mm_iface_modem_update_access_technologies (self,
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
MM_MODEM_ACCESS_TECHNOLOGY_ANY);
/* Overwriting the data will free the previous context */
g_object_set_qdata (G_OBJECT (self),
access_technologies_check_context_quark,
NULL);
mm_dbg ("Periodic access technology checks disabled");
}
static void
periodic_access_technologies_check_enable (MMIfaceModem *self)
{
AccessTechnologiesCheckContext *ctx;
if (!MM_IFACE_MODEM_GET_INTERFACE (self)->load_access_technologies ||
!MM_IFACE_MODEM_GET_INTERFACE (self)->load_access_technologies_finish) {
/* If loading access technology not supported, don't even bother setting up
* a timeout */
return;
}
if (G_UNLIKELY (!access_technologies_check_context_quark))
access_technologies_check_context_quark = (g_quark_from_static_string (
ACCESS_TECHNOLOGIES_CHECK_CONTEXT_TAG));
ctx = g_object_get_qdata (G_OBJECT (self), access_technologies_check_context_quark);
/* If context is already there, we're already enabled */
if (ctx) {
periodic_access_technologies_check (self);
return;
}
/* Create context and keep it as object data */
mm_dbg ("Periodic access technology checks enabled");
ctx = g_new0 (AccessTechnologiesCheckContext, 1);
ctx->timeout_source = g_timeout_add_seconds (ACCESS_TECHNOLOGIES_CHECK_TIMEOUT_SEC,
(GSourceFunc)periodic_access_technologies_check,
self);
g_object_set_qdata_full (G_OBJECT (self),
access_technologies_check_context_quark,
ctx,
(GDestroyNotify)access_technologies_check_context_free);
/* Get first access technology value */
periodic_access_technologies_check (self);
}
/*****************************************************************************/
typedef struct {
time_t last_update;
guint recent_timeout_source;
@@ -705,16 +827,18 @@ mm_iface_modem_update_state (MMIfaceModem *self,
reason);
/* If we go to registered state (from unregistered), setup signal
* quality retrieval */
* quality and access technologies periodic retrieval */
if (new_state == MM_MODEM_STATE_REGISTERED &&
old_state < MM_MODEM_STATE_REGISTERED) {
periodic_signal_quality_check_enable (self);
periodic_access_technologies_check_enable (self);
}
/* If we go from a registered/connected state to unregistered,
* cleanup signal quality retrieval */
else if (old_state >= MM_MODEM_STATE_REGISTERED &&
new_state < MM_MODEM_STATE_REGISTERED) {
periodic_signal_quality_check_disable (self);
periodic_access_technologies_check_disable (self);
}
}

View File

@@ -136,6 +136,16 @@ struct _MMIfaceModem {
GAsyncResult *res,
GError **error);
/* Loading of the AccessTechnologies property */
void (*load_access_technologies) (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*load_access_technologies_finish) (MMIfaceModem *self,
GAsyncResult *res,
MMModemAccessTechnology *access_technologies,
guint *mask,
GError **error);
/* Asynchronous reset operation */
void (*reset) (MMIfaceModem *self,
GAsyncReadyCallback callback,