aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Kästner <git@oliver-kaestner.de>2023-10-15 03:35:59 +0200
committerAleksander Morgado <aleksander@aleksander.es>2024-04-12 11:17:18 +0000
commit4f1864921acfa70b9f3d0aea68810ff3b2afc765 (patch)
treecb0323e3403676968022854acba6c87a68d97a5e
parent3adbcfb7897f0da3a85c63b96162e7a16b4039c6 (diff)
huawei: implement loading supported IP families
This uses the proprietary `^NDISSTATQRY` instead of the default `+CGDCONT` command, as the latter might return diffrent results (i.e. reporting v6 support, that can't be used via NDIS). Also add a fallback to `+CGDCONT?` for older modems that don't support ^NDISSTATQRY.
-rw-r--r--src/plugins/huawei/mm-broadband-modem-huawei.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/plugins/huawei/mm-broadband-modem-huawei.c b/src/plugins/huawei/mm-broadband-modem-huawei.c
index 82dc785d..88f97ad5 100644
--- a/src/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/src/plugins/huawei/mm-broadband-modem-huawei.c
@@ -1766,6 +1766,104 @@ set_current_modes (MMIfaceModem *_self,
}
/*****************************************************************************/
+/* Supported IP families (Modem interface) */
+static MMBearerIpFamily
+load_supported_ip_families_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ GError *inner_error = NULL;
+ gssize value;
+
+ value = g_task_propagate_int (G_TASK (res), &inner_error);
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return MM_BEARER_IP_FAMILY_NONE;
+ }
+ return (MMBearerIpFamily)value;
+}
+
+static void
+parent_load_supported_ip_families_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ MMBearerIpFamily families = MM_BEARER_IP_FAMILY_NONE;
+
+ families = iface_modem_parent->load_supported_ip_families_finish (self, res, &error);
+ if (error)
+ g_task_return_error (task, error);
+ else
+ g_task_return_int (task, families);
+ g_object_unref (task);
+}
+
+static void
+load_supported_ip_families_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ const gchar *response;
+ MMBearerIpFamily families = MM_BEARER_IP_FAMILY_NONE;
+ gboolean ipv4_available;
+ gboolean ipv4_connected;
+ gboolean ipv6_available;
+ gboolean ipv6_connected;
+ GError *error = NULL;
+
+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
+ if (!response) {
+ mm_obj_dbg (self, "failed to fetch supported IP families using ^NDISSTATQRY: %s", error->message);
+ /* fallback to generic detection with AT+CGDCONT=? */
+ iface_modem_parent->load_supported_ip_families (
+ self,
+ (GAsyncReadyCallback)parent_load_supported_ip_families_ready,
+ task);
+ g_error_free (error);
+ return;
+ }
+
+ if (mm_huawei_parse_ndisstatqry_response (response,
+ &ipv4_available,
+ &ipv4_connected,
+ &ipv6_available,
+ &ipv6_connected,
+ &error)) {
+ families |= ipv4_available ? MM_BEARER_IP_FAMILY_IPV4 : 0;
+ families |= ipv6_available ? MM_BEARER_IP_FAMILY_IPV6 : 0;
+ families |= (ipv4_available && ipv6_available) ? MM_BEARER_IP_FAMILY_IPV4V6 : 0;
+ }
+
+ if (error) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "failed to load supported IP families via ^NDISSTATQRY: %s", error->message);
+ g_error_free (error);
+ } else {
+ g_task_return_int (task, (gssize)families);
+ }
+
+ g_object_unref (task);
+}
+
+static void
+load_supported_ip_families (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "^NDISSTATQRY?",
+ 3,
+ TRUE,
+ (GAsyncReadyCallback)load_supported_ip_families_ready,
+ task);
+}
+
+/*****************************************************************************/
/* Setup/Cleanup unsolicited events (3GPP interface) */
static void
@@ -4905,6 +5003,8 @@ iface_modem_init (MMIfaceModem *iface)
iface->load_current_modes_finish = load_current_modes_finish;
iface->set_current_modes = set_current_modes;
iface->set_current_modes_finish = set_current_modes_finish;
+ iface->load_supported_ip_families = load_supported_ip_families;
+ iface->load_supported_ip_families_finish = load_supported_ip_families_finish;
iface->load_signal_quality = modem_load_signal_quality;
iface->load_signal_quality_finish = modem_load_signal_quality_finish;
iface->create_bearer = huawei_modem_create_bearer;