diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-bearer-mbim.c | 44 | ||||
-rw-r--r-- | src/mm-bearer-qmi.c | 37 | ||||
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 21 | ||||
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 17 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 46 | ||||
-rw-r--r-- | src/mm-broadband-modem.h | 6 |
6 files changed, 156 insertions, 15 deletions
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c index fc434c78..e956a90d 100644 --- a/src/mm-bearer-mbim.c +++ b/src/mm-bearer-mbim.c @@ -1221,10 +1221,19 @@ load_settings_from_bearer (MMBearerMbim *self, { MMBearerMultiplexSupport multiplex; gboolean multiplex_supported = TRUE; + guint current_multiplexed_bearers; + guint max_multiplexed_bearers; const gchar *data_port_driver; + if (!mm_broadband_modem_get_active_multiplexed_bearers (MM_BROADBAND_MODEM (ctx->modem), + ¤t_multiplexed_bearers, + &max_multiplexed_bearers, + error)) + return FALSE; + + /* Check multiplex support in the kernel and the device */ data_port_driver = mm_kernel_device_get_driver (mm_port_peek_kernel_device (ctx->data)); - if (!g_strcmp0 (data_port_driver, "mhi_net")) + if (!g_strcmp0 (data_port_driver, "mhi_net") || !max_multiplexed_bearers) multiplex_supported = FALSE; /* If no multiplex setting given by the user, assume none */ @@ -1236,17 +1245,32 @@ load_settings_from_bearer (MMBearerMbim *self, multiplex = MM_BEARER_MULTIPLEX_SUPPORT_NONE; } - if (multiplex_supported && - (multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUESTED || - multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUIRED)) { - /* the link prefix hint given must be modem-specific */ - ctx->link_prefix_hint = g_strdup_printf ("mbimmux%u.", mm_base_modem_get_dbus_id (MM_BASE_MODEM (ctx->modem))); + /* If multiplex unsupported, either abort or default to none */ + if (!multiplex_supported) { + if (multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUIRED) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Multiplexing required but not supported"); + return FALSE; + } + if (multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUESTED) { + mm_obj_dbg (self, "Multiplexing unsupported"); + multiplex = MM_BEARER_MULTIPLEX_SUPPORT_NONE; + } } - if (!multiplex_supported && multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUIRED) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, - "Multiplexing required but not supported by %s", data_port_driver); - return FALSE; + /* Go on with multiplexing enabled */ + if (multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUESTED || + multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUIRED) { + g_assert (multiplex_supported); + + if (current_multiplexed_bearers == max_multiplexed_bearers) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Maximum number of multiplexed bearers reached"); + return FALSE; + } + + /* the link prefix hint given must be modem-specific */ + ctx->link_prefix_hint = g_strdup_printf ("mbimmux%u.", mm_base_modem_get_dbus_id (MM_BASE_MODEM (ctx->modem))); } /* If profile id is given, we'll load all settings from the stored profile, diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c index caf925db..54f2e934 100644 --- a/src/mm-bearer-qmi.c +++ b/src/mm-bearer-qmi.c @@ -2442,8 +2442,21 @@ load_settings_from_bearer (MMBearerQmi *self, GError *inner_error = NULL; const gchar *str; const gchar *data_port_driver; + guint current_multiplexed_bearers; + guint max_multiplexed_bearers; + gboolean multiplex_supported = TRUE; + + if (!mm_broadband_modem_get_active_multiplexed_bearers (MM_BROADBAND_MODEM (ctx->modem), + ¤t_multiplexed_bearers, + &max_multiplexed_bearers, + error)) + return FALSE; + /* Check multiplex support in the kernel and the device */ data_port_driver = mm_kernel_device_get_driver (mm_port_peek_kernel_device (ctx->data)); + /* All drivers should support multiplexing */ + if (!max_multiplexed_bearers) + multiplex_supported = FALSE; /* If no multiplex setting given by the user, assume none; unless in IPA */ ctx->multiplex = mm_bearer_properties_get_multiplex (properties); @@ -2456,9 +2469,31 @@ load_settings_from_bearer (MMBearerQmi *self, ctx->multiplex = MM_BEARER_MULTIPLEX_SUPPORT_NONE; } - /* The link prefix hint given must be modem-specific */ + /* If multiplex unsupported, either abort or default to none */ + if (!multiplex_supported) { + if (ctx->multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUIRED) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Multiplexing required but not supported"); + return FALSE; + } + if (ctx->multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUESTED) { + mm_obj_dbg (self, "Multiplexing unsupported"); + ctx->multiplex = MM_BEARER_MULTIPLEX_SUPPORT_NONE; + } + } + + /* Go on with multiplexing enabled */ if (ctx->multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUESTED || ctx->multiplex == MM_BEARER_MULTIPLEX_SUPPORT_REQUIRED) { + g_assert (multiplex_supported); + + if (current_multiplexed_bearers == max_multiplexed_bearers) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Maximum number of multiplexed bearers reached"); + return FALSE; + } + + /* The link prefix hint given must be modem-specific */ ctx->link_prefix_hint = g_strdup_printf ("qmapmux%u.", mm_base_modem_get_dbus_id (MM_BASE_MODEM (modem))); } diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 48a235a9..81c81da0 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -29,6 +29,7 @@ #include "mm-sms-mbim.h" #include "ModemManager.h" +#include <ModemManager-tags.h> #include "mm-context.h" #include "mm-log-object.h" #include "mm-errors-types.h" @@ -2957,8 +2958,9 @@ modem_create_bearer (MMIfaceModem *self, static MMBearerList * modem_create_bearer_list (MMIfaceModem *self) { - guint n; - guint n_multiplexed; + MMPortMbim *port; + guint n; + guint n_multiplexed; /* The maximum number of available/connected modems is guessed from * the size of the data ports list. */ @@ -2969,6 +2971,21 @@ modem_create_bearer_list (MMIfaceModem *self) n_multiplexed = (MBIM_DEVICE_SESSION_ID_MAX - MBIM_DEVICE_SESSION_ID_MIN + 1); mm_obj_dbg (self, "allowed up to %u active multiplexed bearers", n_multiplexed); + port = mm_broadband_modem_mbim_peek_port_mbim (MM_BROADBAND_MODEM_MBIM (self)); + if (port && + mm_kernel_device_has_global_property (mm_port_peek_kernel_device (MM_PORT (port)), + ID_MM_MAX_MULTIPLEXED_LINKS)) { + guint n_multiplexed_limited; + + n_multiplexed_limited = mm_kernel_device_get_global_property_as_int ( + mm_port_peek_kernel_device (MM_PORT (port)), + ID_MM_MAX_MULTIPLEXED_LINKS); + if (n_multiplexed_limited < n_multiplexed) { + n_multiplexed = n_multiplexed_limited; + mm_obj_dbg (self, "limited to %u active multiplexed bearers", n_multiplexed); + } + } + /* by default, no multiplexing support */ return mm_bearer_list_new (n, n_multiplexed); } diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index 95cc56b0..153b420e 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -27,6 +27,7 @@ #include "mm-broadband-modem-qmi.h" #include "ModemManager.h" +#include <ModemManager-tags.h> #include "mm-log.h" #include "mm-errors-types.h" #include "mm-modem-helpers.h" @@ -435,10 +436,22 @@ modem_create_bearer_list (MMIfaceModem *self) } if (kernel_data_modes & (MM_PORT_QMI_KERNEL_DATA_MODE_MUX_RMNET | MM_PORT_QMI_KERNEL_DATA_MODE_MUX_QMIWWAN)) { - /* The maximum number of multiplexed links is retrieved from the - * MMPortQmi */ + /* The maximum number of multiplexed links is retrieved from the MMPortQmi */ n_multiplexed = mm_port_qmi_get_max_multiplexed_links (port); mm_obj_dbg (self, "allowed up to %u active multiplexed bearers", n_multiplexed); + + if (mm_kernel_device_has_global_property (mm_port_peek_kernel_device (MM_PORT (port)), + ID_MM_MAX_MULTIPLEXED_LINKS)) { + guint n_multiplexed_limited; + + n_multiplexed_limited = mm_kernel_device_get_global_property_as_int ( + mm_port_peek_kernel_device (MM_PORT (port)), + ID_MM_MAX_MULTIPLEXED_LINKS); + if (n_multiplexed_limited < n_multiplexed) { + n_multiplexed = n_multiplexed_limited; + mm_obj_dbg (self, "limited to %u active multiplexed bearers", n_multiplexed); + } + } } } diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index c733d938..d3892456 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -12860,6 +12860,52 @@ 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 * mm_broadband_modem_create_device_identifier (MMBroadbandModem *self, const gchar *ati, diff --git a/src/mm-broadband-modem.h b/src/mm-broadband-modem.h index d2ce65a5..e6463de6 100644 --- a/src/mm-broadband-modem.h +++ b/src/mm-broadband-modem.h @@ -134,4 +134,10 @@ gboolean mm_broadband_modem_sim_hot_swap_ports_context_init (MMBroadbandModem GError **error); 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); + #endif /* MM_BROADBAND_MODEM_H */ |