modem: allow periodic signal check to be disabled
ModemManager decides to disable periodic signal check if either load_signal_quality is not implemented or load_signal_quality returns an unsupported error. However, in some cases, we want to use load_signal_quality to query the initial signal quality but rely on unsolicited signal quality updates from the modem afterwards without periodically polling for signal quality. To support that, this patch introduces a property in MMIfaceModem/MMBroadbandModem to indicate if the periodic signal check should be disabled.
This commit is contained in:

committed by
Aleksander Morgado

parent
b39dd2ec05
commit
708b00ae3b
@@ -117,6 +117,7 @@ enum {
|
|||||||
PROP_MODEM_SIMPLE_STATUS,
|
PROP_MODEM_SIMPLE_STATUS,
|
||||||
PROP_MODEM_SIM_HOT_SWAP_SUPPORTED,
|
PROP_MODEM_SIM_HOT_SWAP_SUPPORTED,
|
||||||
PROP_MODEM_SIM_HOT_SWAP_CONFIGURED,
|
PROP_MODEM_SIM_HOT_SWAP_CONFIGURED,
|
||||||
|
PROP_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED,
|
||||||
PROP_FLOW_CONTROL,
|
PROP_FLOW_CONTROL,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
@@ -136,6 +137,7 @@ struct _MMBroadbandModemPrivate {
|
|||||||
gboolean modem_init_run;
|
gboolean modem_init_run;
|
||||||
gboolean sim_hot_swap_supported;
|
gboolean sim_hot_swap_supported;
|
||||||
gboolean sim_hot_swap_configured;
|
gboolean sim_hot_swap_configured;
|
||||||
|
gboolean periodic_signal_check_disabled;
|
||||||
|
|
||||||
/*<--- Modem interface --->*/
|
/*<--- Modem interface --->*/
|
||||||
/* Properties */
|
/* Properties */
|
||||||
@@ -10809,6 +10811,9 @@ set_property (GObject *object,
|
|||||||
case PROP_MODEM_SIM_HOT_SWAP_CONFIGURED:
|
case PROP_MODEM_SIM_HOT_SWAP_CONFIGURED:
|
||||||
self->priv->sim_hot_swap_configured = g_value_get_boolean (value);
|
self->priv->sim_hot_swap_configured = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED:
|
||||||
|
self->priv->periodic_signal_check_disabled = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -10917,6 +10922,9 @@ get_property (GObject *object,
|
|||||||
case PROP_MODEM_SIM_HOT_SWAP_CONFIGURED:
|
case PROP_MODEM_SIM_HOT_SWAP_CONFIGURED:
|
||||||
g_value_set_boolean (value, self->priv->sim_hot_swap_configured);
|
g_value_set_boolean (value, self->priv->sim_hot_swap_configured);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED:
|
||||||
|
g_value_set_boolean (value, self->priv->periodic_signal_check_disabled);
|
||||||
|
break;
|
||||||
case PROP_FLOW_CONTROL:
|
case PROP_FLOW_CONTROL:
|
||||||
g_value_set_flags (value, self->priv->flow_control);
|
g_value_set_flags (value, self->priv->flow_control);
|
||||||
break;
|
break;
|
||||||
@@ -10949,6 +10957,7 @@ mm_broadband_modem_init (MMBroadbandModem *self)
|
|||||||
self->priv->current_sms_mem1_storage = MM_SMS_STORAGE_UNKNOWN;
|
self->priv->current_sms_mem1_storage = MM_SMS_STORAGE_UNKNOWN;
|
||||||
self->priv->current_sms_mem2_storage = MM_SMS_STORAGE_UNKNOWN;
|
self->priv->current_sms_mem2_storage = MM_SMS_STORAGE_UNKNOWN;
|
||||||
self->priv->sim_hot_swap_supported = FALSE;
|
self->priv->sim_hot_swap_supported = FALSE;
|
||||||
|
self->priv->periodic_signal_check_disabled = FALSE;
|
||||||
self->priv->modem_cmer_enable_mode = MM_3GPP_CMER_MODE_NONE;
|
self->priv->modem_cmer_enable_mode = MM_3GPP_CMER_MODE_NONE;
|
||||||
self->priv->modem_cmer_disable_mode = MM_3GPP_CMER_MODE_NONE;
|
self->priv->modem_cmer_disable_mode = MM_3GPP_CMER_MODE_NONE;
|
||||||
self->priv->modem_cmer_ind = MM_3GPP_CMER_IND_NONE;
|
self->priv->modem_cmer_ind = MM_3GPP_CMER_IND_NONE;
|
||||||
@@ -11430,6 +11439,11 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
|
|||||||
g_object_class_override_property (object_class,
|
g_object_class_override_property (object_class,
|
||||||
PROP_MODEM_SIM_HOT_SWAP_CONFIGURED,
|
PROP_MODEM_SIM_HOT_SWAP_CONFIGURED,
|
||||||
MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED);
|
MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
PROP_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED,
|
||||||
|
MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED);
|
||||||
|
|
||||||
properties[PROP_FLOW_CONTROL] =
|
properties[PROP_FLOW_CONTROL] =
|
||||||
g_param_spec_flags (MM_BROADBAND_MODEM_FLOW_CONTROL,
|
g_param_spec_flags (MM_BROADBAND_MODEM_FLOW_CONTROL,
|
||||||
"Flow control",
|
"Flow control",
|
||||||
|
@@ -1263,15 +1263,6 @@ peridic_signal_check_step (MMIfaceModem *self)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If both tasks are unsupported, implicitly disable. Do NOT clear the
|
|
||||||
* values, because if we're told they are unsupported it may be that
|
|
||||||
* they're really updated via unsolicited messages. */
|
|
||||||
if (!ctx->access_technology_polling_supported && !ctx->signal_quality_polling_supported) {
|
|
||||||
mm_dbg ("Periodic signal checks not supported");
|
|
||||||
periodic_signal_check_disable (self, FALSE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Schedule when we poll next time.
|
/* Schedule when we poll next time.
|
||||||
* Initially we poll at a higher frequency until we get valid signal
|
* Initially we poll at a higher frequency until we get valid signal
|
||||||
* quality and access technology values. As soon as we get them, OR if
|
* quality and access technology values. As soon as we get them, OR if
|
||||||
@@ -1280,6 +1271,7 @@ peridic_signal_check_step (MMIfaceModem *self)
|
|||||||
if (ctx->interval == SIGNAL_CHECK_INITIAL_TIMEOUT_SEC) {
|
if (ctx->interval == SIGNAL_CHECK_INITIAL_TIMEOUT_SEC) {
|
||||||
gboolean signal_quality_ready;
|
gboolean signal_quality_ready;
|
||||||
gboolean access_technology_ready;
|
gboolean access_technology_ready;
|
||||||
|
gboolean initial_check_done;
|
||||||
|
|
||||||
/* Signal quality is ready if unsupported or if we got a valid
|
/* Signal quality is ready if unsupported or if we got a valid
|
||||||
* value reported */
|
* value reported */
|
||||||
@@ -1289,15 +1281,33 @@ peridic_signal_check_step (MMIfaceModem *self)
|
|||||||
access_technology_ready = (!ctx->access_technology_polling_supported ||
|
access_technology_ready = (!ctx->access_technology_polling_supported ||
|
||||||
((ctx->access_technologies & ctx->access_technologies_mask) != MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN));
|
((ctx->access_technologies & ctx->access_technologies_mask) != MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN));
|
||||||
|
|
||||||
if (signal_quality_ready && access_technology_ready) {
|
initial_check_done = ((signal_quality_ready && access_technology_ready) ||
|
||||||
mm_dbg ("Initial signal quality and access technology ready: fallback to default frequency");
|
(--ctx->initial_retries == 0));
|
||||||
ctx->interval = SIGNAL_CHECK_TIMEOUT_SEC;
|
if (initial_check_done) {
|
||||||
} else if (--ctx->initial_retries == 0) {
|
gboolean periodic_signal_check_disabled = FALSE;
|
||||||
mm_dbg ("Too many periodic signal checks at high frequency: fallback to default frequency");
|
|
||||||
|
g_object_get (self,
|
||||||
|
MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED,
|
||||||
|
&periodic_signal_check_disabled,
|
||||||
|
NULL);
|
||||||
|
/* If periodic signal check is disabled, treat it as
|
||||||
|
* unsupported after the initial check is done. */
|
||||||
|
if (periodic_signal_check_disabled)
|
||||||
|
ctx->signal_quality_polling_supported = FALSE;
|
||||||
|
|
||||||
ctx->interval = SIGNAL_CHECK_TIMEOUT_SEC;
|
ctx->interval = SIGNAL_CHECK_TIMEOUT_SEC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If both tasks are unsupported, implicitly disable. Do NOT clear the
|
||||||
|
* values, because if we're told they are unsupported it may be that
|
||||||
|
* they're really updated via unsolicited messages. */
|
||||||
|
if (!ctx->access_technology_polling_supported && !ctx->signal_quality_polling_supported) {
|
||||||
|
mm_dbg ("Periodic signal and access technologies checks not supported");
|
||||||
|
periodic_signal_check_disable (self, FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mm_dbg ("Periodic signal quality checks scheduled in %ds", ctx->interval);
|
mm_dbg ("Periodic signal quality checks scheduled in %ds", ctx->interval);
|
||||||
g_assert (!ctx->timeout_source);
|
g_assert (!ctx->timeout_source);
|
||||||
ctx->timeout_source = g_timeout_add_seconds (ctx->interval, (GSourceFunc) periodic_signal_check_cb, self);
|
ctx->timeout_source = g_timeout_add_seconds (ctx->interval, (GSourceFunc) periodic_signal_check_cb, self);
|
||||||
@@ -5366,6 +5376,15 @@ iface_modem_init (gpointer g_iface)
|
|||||||
"Whether the sim hot swap support is configured correctly.",
|
"Whether the sim hot swap support is configured correctly.",
|
||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_interface_install_property
|
||||||
|
(g_iface,
|
||||||
|
g_param_spec_boolean (MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED,
|
||||||
|
"Periodic signal check disabled",
|
||||||
|
"Whether periodic signal check is disabled.",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
|
||||||
initialized = TRUE;
|
initialized = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
#define MM_IFACE_MODEM_BEARER_LIST "iface-modem-bearer-list"
|
#define MM_IFACE_MODEM_BEARER_LIST "iface-modem-bearer-list"
|
||||||
#define MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED "iface-modem-sim-hot-swap-supported"
|
#define MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED "iface-modem-sim-hot-swap-supported"
|
||||||
#define MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED "iface-modem-sim-hot-swap-configured"
|
#define MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED "iface-modem-sim-hot-swap-configured"
|
||||||
|
#define MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED "iface-modem-periodic-signal-check-disabled"
|
||||||
|
|
||||||
typedef struct _MMIfaceModem MMIfaceModem;
|
typedef struct _MMIfaceModem MMIfaceModem;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user