Merge request !1378 from 'suspend-bearer-timeout'
base-manager: increase suspend timeout for each active bearer https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/1378
This commit is contained in:
+22
-2
@@ -1167,6 +1167,7 @@ mm_base_manager_cleanup (MMBaseManager *self,
|
|||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
MMDevice *device;
|
MMDevice *device;
|
||||||
gboolean disable, remove, low_power, terse;
|
gboolean disable, remove, low_power, terse;
|
||||||
|
guint active_bearers = 0;
|
||||||
|
|
||||||
g_return_if_fail (self != NULL);
|
g_return_if_fail (self != NULL);
|
||||||
g_return_if_fail (MM_IS_BASE_MANAGER (self));
|
g_return_if_fail (MM_IS_BASE_MANAGER (self));
|
||||||
@@ -1193,7 +1194,20 @@ mm_base_manager_cleanup (MMBaseManager *self,
|
|||||||
g_hash_table_iter_init (&iter, self->priv->devices);
|
g_hash_table_iter_init (&iter, self->priv->devices);
|
||||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &device)) {
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &device)) {
|
||||||
DeviceCleanupContext *dctx;
|
DeviceCleanupContext *dctx;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
|
MMBaseModem *modem;
|
||||||
|
|
||||||
|
modem = mm_device_peek_modem (device);
|
||||||
|
if (modem) {
|
||||||
|
guint count = 0;
|
||||||
|
|
||||||
|
mm_iface_modem_count_bearers (MM_IFACE_MODEM (modem),
|
||||||
|
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_ACTIVE,
|
||||||
|
&count,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
active_bearers += count;
|
||||||
|
}
|
||||||
|
|
||||||
task = g_task_new (device,
|
task = g_task_new (device,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -1201,12 +1215,18 @@ mm_base_manager_cleanup (MMBaseManager *self,
|
|||||||
ctx);
|
ctx);
|
||||||
ctx->tasks = g_slist_append (ctx->tasks, task);
|
ctx->tasks = g_slist_append (ctx->tasks, task);
|
||||||
|
|
||||||
dctx = device_cleanup_context_new (mm_device_peek_modem (device), flags);
|
dctx = device_cleanup_context_new (modem, flags);
|
||||||
g_task_set_task_data (task, dctx, (GDestroyNotify)device_cleanup_context_free);
|
g_task_set_task_data (task, dctx, (GDestroyNotify)device_cleanup_context_free);
|
||||||
|
|
||||||
device_cleanup_step (task);
|
device_cleanup_step (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Increase cleanup timeout for each connected bearer; disconnecting a
|
||||||
|
* bearer can take many seconds.
|
||||||
|
*/
|
||||||
|
if (active_bearers)
|
||||||
|
mm_sleep_context_timeout_backoff (sleep_ctx, active_bearers * 20);
|
||||||
|
|
||||||
/* Complete cleanup if there were no devices */
|
/* Complete cleanup if there were no devices */
|
||||||
manager_cleanup_context_maybe_complete (ctx, NULL, NULL, FALSE);
|
manager_cleanup_context_maybe_complete (ctx, NULL, NULL, FALSE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1459,10 +1459,11 @@ load_settings_from_bearer (MMBearerMbim *self,
|
|||||||
guint max_multiplexed_bearers;
|
guint max_multiplexed_bearers;
|
||||||
const gchar *data_port_driver;
|
const gchar *data_port_driver;
|
||||||
|
|
||||||
if (!mm_broadband_modem_get_active_multiplexed_bearers (MM_BROADBAND_MODEM (ctx->modem),
|
if (!mm_iface_modem_count_bearers (MM_IFACE_MODEM (ctx->modem),
|
||||||
¤t_multiplexed_bearers,
|
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED,
|
||||||
&max_multiplexed_bearers,
|
¤t_multiplexed_bearers,
|
||||||
error))
|
&max_multiplexed_bearers,
|
||||||
|
error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Check multiplex support in the kernel and the device */
|
/* Check multiplex support in the kernel and the device */
|
||||||
|
|||||||
+5
-4
@@ -2425,10 +2425,11 @@ load_settings_from_bearer (MMBearerQmi *self,
|
|||||||
guint max_multiplexed_bearers;
|
guint max_multiplexed_bearers;
|
||||||
gboolean multiplex_supported = TRUE;
|
gboolean multiplex_supported = TRUE;
|
||||||
|
|
||||||
if (!mm_broadband_modem_get_active_multiplexed_bearers (MM_BROADBAND_MODEM (ctx->modem),
|
if (!mm_iface_modem_count_bearers (MM_IFACE_MODEM (ctx->modem),
|
||||||
¤t_multiplexed_bearers,
|
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED,
|
||||||
&max_multiplexed_bearers,
|
¤t_multiplexed_bearers,
|
||||||
error))
|
&max_multiplexed_bearers,
|
||||||
|
error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Check multiplex support in the kernel and the device */
|
/* Check multiplex support in the kernel and the device */
|
||||||
|
|||||||
@@ -13809,52 +13809,6 @@ mm_broadband_modem_get_current_charset (MMBroadbandModem *self)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
|
||||||
bearer_count_multiplexed_connected (MMBaseBearer *bearer,
|
|
||||||
guint *count)
|
|
||||||
{
|
|
||||||
/* The Multiplexed property is only set if connected, so it's enough to check
|
|
||||||
* that one to see if we're connected and multiplexed */
|
|
||||||
if (mm_gdbus_bearer_get_multiplexed (MM_GDBUS_BEARER (bearer)))
|
|
||||||
*count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
mm_broadband_modem_get_active_multiplexed_bearers (MMBroadbandModem *self,
|
|
||||||
guint *out_current,
|
|
||||||
guint *out_max,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
g_autoptr(MMBearerList) list = NULL;
|
|
||||||
guint max;
|
|
||||||
guint count = 0;
|
|
||||||
|
|
||||||
g_object_get (self,
|
|
||||||
MM_IFACE_MODEM_BEARER_LIST, &list,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!list) {
|
|
||||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Bearer list unavailable");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
max = mm_bearer_list_get_max_active_multiplexed (list);
|
|
||||||
|
|
||||||
mm_bearer_list_foreach (list,
|
|
||||||
(MMBearerListForeachFunc)bearer_count_multiplexed_connected,
|
|
||||||
&count);
|
|
||||||
g_assert (!(!max && count));
|
|
||||||
|
|
||||||
if (out_max)
|
|
||||||
*out_max = max;
|
|
||||||
if (out_current)
|
|
||||||
*out_current = count;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
mm_broadband_modem_create_device_identifier (MMBroadbandModem *self,
|
mm_broadband_modem_create_device_identifier (MMBroadbandModem *self,
|
||||||
const gchar *ati,
|
const gchar *ati,
|
||||||
|
|||||||
@@ -135,12 +135,6 @@ gboolean mm_broadband_modem_sim_hot_swap_ports_context_init (MMBroadbandModem
|
|||||||
GError **error);
|
GError **error);
|
||||||
void mm_broadband_modem_sim_hot_swap_ports_context_reset (MMBroadbandModem *self);
|
void mm_broadband_modem_sim_hot_swap_ports_context_reset (MMBroadbandModem *self);
|
||||||
|
|
||||||
/* Helper to manage multiplexed bearers */
|
|
||||||
gboolean mm_broadband_modem_get_active_multiplexed_bearers (MMBroadbandModem *self,
|
|
||||||
guint *out_current,
|
|
||||||
guint *out_max,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
/* Helper to manage initial EPS bearer */
|
/* Helper to manage initial EPS bearer */
|
||||||
gint mm_broadband_modem_get_initial_eps_bearer_cid (MMBroadbandModem *self);
|
gint mm_broadband_modem_get_initial_eps_bearer_cid (MMBroadbandModem *self);
|
||||||
|
|
||||||
|
|||||||
@@ -6784,6 +6784,74 @@ mm_iface_modem_get_current_modes (MMIfaceModem *self,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const MMIfaceModemCountBearersFlags flags;
|
||||||
|
guint count;
|
||||||
|
} CountBearersContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
bearer_count (MMBaseBearer *bearer,
|
||||||
|
CountBearersContext *ctx)
|
||||||
|
{
|
||||||
|
MMBearerStatus status;
|
||||||
|
|
||||||
|
status = mm_base_bearer_get_status (MM_BASE_BEARER (bearer));
|
||||||
|
|
||||||
|
if (ctx->flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED) {
|
||||||
|
/* The Multiplexed property is only set if connected, so it's enough to check
|
||||||
|
* that one to see if we're connected and multiplexed */
|
||||||
|
if (mm_gdbus_bearer_get_multiplexed (MM_GDBUS_BEARER (bearer)))
|
||||||
|
ctx->count++;
|
||||||
|
} else if (ctx->flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_CONNECTED) {
|
||||||
|
if (status == MM_BEARER_STATUS_CONNECTED)
|
||||||
|
ctx->count++;
|
||||||
|
} else if (ctx->flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_ACTIVE) {
|
||||||
|
if (status >= MM_BEARER_STATUS_CONNECTING)
|
||||||
|
ctx->count++;
|
||||||
|
} else
|
||||||
|
ctx->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_iface_modem_count_bearers (MMIfaceModem *self,
|
||||||
|
MMIfaceModemCountBearersFlags flags,
|
||||||
|
guint *out_current,
|
||||||
|
guint *out_max,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autoptr(MMBearerList) list = NULL;
|
||||||
|
guint max = 0;
|
||||||
|
CountBearersContext ctx = {
|
||||||
|
.flags = flags,
|
||||||
|
.count = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
g_object_get (self,
|
||||||
|
MM_IFACE_MODEM_BEARER_LIST, &list,
|
||||||
|
NULL);
|
||||||
|
if (!list) {
|
||||||
|
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Bearer list unavailable");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED)
|
||||||
|
max = mm_bearer_list_get_max_active_multiplexed (list);
|
||||||
|
else
|
||||||
|
max = mm_bearer_list_get_max_active (list);
|
||||||
|
|
||||||
|
mm_bearer_list_foreach (list, (MMBearerListForeachFunc)bearer_count, &ctx);
|
||||||
|
g_assert (max >= ctx.count);
|
||||||
|
|
||||||
|
if (out_max)
|
||||||
|
*out_max = max;
|
||||||
|
if (out_current)
|
||||||
|
*out_current = ctx.count;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mm_iface_modem_default_init (MMIfaceModemInterface *iface)
|
mm_iface_modem_default_init (MMIfaceModemInterface *iface)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -622,4 +622,19 @@ void mm_iface_modem_process_sim_event (MMIfaceModem *self);
|
|||||||
|
|
||||||
gboolean mm_iface_modem_is_primary_sim_slot_switch_ongoing (MMIfaceModem *self);
|
gboolean mm_iface_modem_is_primary_sim_slot_switch_ongoing (MMIfaceModem *self);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* Connecting or connected bearers */
|
||||||
|
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_ACTIVE = 0x1,
|
||||||
|
/* Fully connected bearers */
|
||||||
|
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_CONNECTED = 0x2,
|
||||||
|
/* Multiplexed implies connected */
|
||||||
|
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED = 0x4,
|
||||||
|
} MMIfaceModemCountBearersFlags;
|
||||||
|
|
||||||
|
gboolean mm_iface_modem_count_bearers (MMIfaceModem *self,
|
||||||
|
MMIfaceModemCountBearersFlags flags,
|
||||||
|
guint *out_current,
|
||||||
|
guint *out_max,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
#endif /* MM_IFACE_MODEM_H */
|
#endif /* MM_IFACE_MODEM_H */
|
||||||
|
|||||||
+30
-3
@@ -27,6 +27,7 @@ G_DEFINE_TYPE_EXTENDED (MMSleepContext, mm_sleep_context, G_TYPE_OBJECT, 0,
|
|||||||
struct _MMSleepContextPrivate {
|
struct _MMSleepContextPrivate {
|
||||||
GTask *task;
|
GTask *task;
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
|
gint64 timeout_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -52,6 +53,7 @@ timeout_cleanup (MMSleepContext *self)
|
|||||||
if (self->priv->timeout_id)
|
if (self->priv->timeout_id)
|
||||||
g_source_remove (self->priv->timeout_id);
|
g_source_remove (self->priv->timeout_id);
|
||||||
self->priv->timeout_id = 0;
|
self->priv->timeout_id = 0;
|
||||||
|
self->priv->timeout_start = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -95,6 +97,33 @@ operation_ready (MMSleepContext *self,
|
|||||||
g_signal_emit (self, signals[DONE], 0, error);
|
g_signal_emit (self, signals[DONE], 0, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
timeout_add (MMSleepContext *self,
|
||||||
|
guint interval)
|
||||||
|
{
|
||||||
|
timeout_cleanup (self);
|
||||||
|
self->priv->timeout_start = g_get_monotonic_time ();
|
||||||
|
self->priv->timeout_id = g_timeout_add_seconds (interval,
|
||||||
|
(GSourceFunc)operation_timeout,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_sleep_context_timeout_backoff (MMSleepContext *self,
|
||||||
|
guint more_seconds)
|
||||||
|
{
|
||||||
|
gint64 cur_time;
|
||||||
|
gint64 new_interval;
|
||||||
|
|
||||||
|
new_interval = more_seconds * G_USEC_PER_SEC;
|
||||||
|
if (self->priv->timeout_start) {
|
||||||
|
cur_time = g_get_monotonic_time ();
|
||||||
|
new_interval += (cur_time - self->priv->timeout_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout_add (self, new_interval / G_USEC_PER_SEC);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
MMSleepContext *
|
MMSleepContext *
|
||||||
@@ -107,9 +136,7 @@ mm_sleep_context_new (guint timeout_seconds)
|
|||||||
NULL,
|
NULL,
|
||||||
(GAsyncReadyCallback)operation_ready,
|
(GAsyncReadyCallback)operation_ready,
|
||||||
NULL);
|
NULL);
|
||||||
self->priv->timeout_id = g_timeout_add_seconds (timeout_seconds,
|
timeout_add (self, timeout_seconds);
|
||||||
(GSourceFunc)operation_timeout,
|
|
||||||
self);
|
|
||||||
mm_obj_dbg (self, "new context with %d second timeout", timeout_seconds);
|
mm_obj_dbg (self, "new context with %d second timeout", timeout_seconds);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMSleepContext, g_object_unref)
|
|||||||
|
|
||||||
MMSleepContext *mm_sleep_context_new (guint timeout_seconds);
|
MMSleepContext *mm_sleep_context_new (guint timeout_seconds);
|
||||||
|
|
||||||
|
void mm_sleep_context_timeout_backoff (MMSleepContext *self,
|
||||||
|
guint more_seconds);
|
||||||
|
|
||||||
/* The MMSleepContext assumes ownership of @error */
|
/* The MMSleepContext assumes ownership of @error */
|
||||||
void mm_sleep_context_complete (MMSleepContext *self,
|
void mm_sleep_context_complete (MMSleepContext *self,
|
||||||
GError *error);
|
GError *error);
|
||||||
|
|||||||
Reference in New Issue
Block a user