iface-modem: periodically request to update current access technologies
This commit is contained in:
@@ -26,14 +26,17 @@
|
|||||||
|
|
||||||
#define SIGNAL_QUALITY_RECENT_TIMEOUT_SEC 60
|
#define SIGNAL_QUALITY_RECENT_TIMEOUT_SEC 60
|
||||||
#define SIGNAL_QUALITY_CHECK_TIMEOUT_SEC 30
|
#define SIGNAL_QUALITY_CHECK_TIMEOUT_SEC 30
|
||||||
|
#define ACCESS_TECHNOLOGIES_CHECK_TIMEOUT_SEC 30
|
||||||
|
|
||||||
#define STATE_UPDATE_CONTEXT_TAG "state-update-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_UPDATE_CONTEXT_TAG "signal-quality-update-context-tag"
|
||||||
#define SIGNAL_QUALITY_CHECK_CONTEXT_TAG "signal-quality-check-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 state_update_context_quark;
|
||||||
static GQuark signal_quality_update_context_quark;
|
static GQuark signal_quality_update_context_quark;
|
||||||
static GQuark signal_quality_check_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 {
|
typedef struct {
|
||||||
time_t last_update;
|
time_t last_update;
|
||||||
guint recent_timeout_source;
|
guint recent_timeout_source;
|
||||||
@@ -705,16 +827,18 @@ mm_iface_modem_update_state (MMIfaceModem *self,
|
|||||||
reason);
|
reason);
|
||||||
|
|
||||||
/* If we go to registered state (from unregistered), setup signal
|
/* 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 &&
|
if (new_state == MM_MODEM_STATE_REGISTERED &&
|
||||||
old_state < MM_MODEM_STATE_REGISTERED) {
|
old_state < MM_MODEM_STATE_REGISTERED) {
|
||||||
periodic_signal_quality_check_enable (self);
|
periodic_signal_quality_check_enable (self);
|
||||||
|
periodic_access_technologies_check_enable (self);
|
||||||
}
|
}
|
||||||
/* If we go from a registered/connected state to unregistered,
|
/* If we go from a registered/connected state to unregistered,
|
||||||
* cleanup signal quality retrieval */
|
* cleanup signal quality retrieval */
|
||||||
else if (old_state >= MM_MODEM_STATE_REGISTERED &&
|
else if (old_state >= MM_MODEM_STATE_REGISTERED &&
|
||||||
new_state < MM_MODEM_STATE_REGISTERED) {
|
new_state < MM_MODEM_STATE_REGISTERED) {
|
||||||
periodic_signal_quality_check_disable (self);
|
periodic_signal_quality_check_disable (self);
|
||||||
|
periodic_access_technologies_check_disable (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -136,6 +136,16 @@ struct _MMIfaceModem {
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error);
|
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 */
|
/* Asynchronous reset operation */
|
||||||
void (*reset) (MMIfaceModem *self,
|
void (*reset) (MMIfaceModem *self,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
|
Reference in New Issue
Block a user