Hey,

I tried to reconstruct what I did to work around the problem.

1. When dial in takes place, I check upfront whether there is an active context that matches the requested one. If there is one, I use it, and skip activating another one. This prevents creating a secondary context when the default context is already active (which might fail as shown by the recent bug report -- some providers do not allow a secondary context, e.g. vodafone DE).

2. I seen cases where the default context does not match the APN at all. In this case, the first step would not detect the active context as the right one and create a second one. In case I've seen that, the creation of the second context succeeded, but the context is not used by the modem (because ublox does not set routes to the secondary context). Therefore, I also adapt the routes in the modem to match the new context.

I think that what I did is far from perfects, because theses two measures will fail when only one context is allowed AND the default context does not match the default one (although I never seen this so far). Also, it is not the recommended way from the ublox manuals, since they request to use set default eps bearer in case the network provided one does not work.

I attach the patch I use at the moment (based on version 1.7.999.) Please be aware that this also includes (inactive) code from other things I tried, e.g. setting the default bearer as requested by the ublox manuals.

That's unfortunately all I can provide at the moment, sorry for that.

Best regards,

Uli

Am 10.12.2019 um 10:23 schrieb Aleksander Morgado:
On Fri, Dec 6, 2019 at 9:11 AM Ulrich Mohr <u.m...@semex-engcon.com> wrote:
Hi,

I am not sure, but I think that this is a problem with the UBlox modems I was 
facing before with a TOBY 210.

The problem is that the modem does an automatic registration on the LTE network 
using its default APN (that it gets from the network, when I understand right). 
That is what you see (m2m.com.attz.mnc170.mcc310.gprs) as context 4:  (which is 
the default LTE bearer on TOBY). Unfortunately, that does not match the one 
your have given manually, so ModemManager tries to build up a connection using 
the secondary context with the APN settings you have given -- which fails, 
because the service provider does not allow a secondary connection while the 
first one is active.

What I am not completely clear about is, under which circumstances you get such 
a long default APN name (not matching the 'official' ones) from the network.

The "long" name you get is when the bearer is already connected to
that APN, so the name includes the MCCMNC of the operator.
ModemManager already does a "loose" matching of the APNs and they
should already match that one in context 4 if available:
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/blob/master/src/mm-modem-helpers.c#L1506

As you said, MM should have attempted to use context #4 instead of #1
as #4 was already connected. The problem is that the logic looking for
which context to use stops as soon as it finds a matching one, and in
this case it found #1 before #4. We could extend the logic to "prefer"
an APN that is reported with MCCMNC if there are more than one
matching, and I believe that should work.

@Aleksander: See 
https://lists.freedesktop.org/archives/modemmanager-devel/2018-August/006633.html

I heavily change the ublox plugin to work around that -- unfortunately I never 
found the time to bring it to a deliverable state, and at the moment, I can't 
even remember what exactly I did. But I can provide the sources if needed....
Yes, please, can you do that?


--
Best regards / Mit freundlichen Grüßen / Salutations distinguées

Ulrich Mohr

SEMEX-EngCon GmbH
Carl-Merz-Strass 26
76275 Ettlingen
Phone: +49 (0) 7243 5143596
email:  u.m...@semex-engcon.com
___________________________________________
Executive board: A. Stiegler, H.-J. Nitzpon
Commercial register: Mannheim, HRB 718881
Company domicile: Ettlingen

diff '--exclude=.git*' '--exclude=Makefile*' '--exclude=config*' -ur 
ModemManager-1.8/plugins/ublox/77-mm-ublox-port-types.rules 
ModemManager-1.7.990/plugins/ublox/77-mm-ublox-port-types.rules
--- ModemManager-1.8/plugins/ublox/77-mm-ublox-port-types.rules 2019-04-24 
08:27:00.498976998 +0200
+++ ModemManager-1.7.990/plugins/ublox/77-mm-ublox-port-types.rules     
2018-11-05 14:40:13.000000000 +0100
@@ -17,4 +17,22 @@
 ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1010", ENV{.MM_USBIFNUM}=="06", 
ENV{ID_MM_UBLOX_PRIMARY_PORT}="1"
 ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1010", ENV{.MM_USBIFNUM}=="08", 
ENV{ID_MM_PORT_IGNORE}="1"
 
-LABEL="mm_ublox_port_types_end"
\ No newline at end of file
+
+# Sara U270 port types
+#  ttyACM0 (if #0): secondary
+#  ttyACM1 (if #2): primary
+#  ttyACM2 (if #4): additional AT port
+#  ttyACM2 (if #6): GNSS tunneling
+#  ttyACM2 (if #8): primary log
+#  ttyACM2 (if #10): secondary log
+#  ttyACM2 (if #12): SAP
+
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1102", ENV{.MM_USBIFNUM}=="00", 
ENV{ID_MM_UBLOX_SECONDARY_PORT}="1"
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1102", ENV{.MM_USBIFNUM}=="02", 
ENV{ID_MM_UBLOX_PRIMARY_PORT}="1"
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1102", ENV{.MM_USBIFNUM}=="06", 
ENV{ID_MM_PORT_IGNORE}="1"
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1102", ENV{.MM_USBIFNUM}=="08", 
ENV{ID_MM_PORT_IGNORE}="1"
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1102", ENV{.MM_USBIFNUM}=="0a", 
ENV{ID_MM_PORT_IGNORE}="1"
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1102", ENV{.MM_USBIFNUM}=="0c", 
ENV{ID_MM_PORT_IGNORE}="1"
+
+
+LABEL="mm_ublox_port_types_end"
diff '--exclude=.git*' '--exclude=Makefile*' '--exclude=config*' -ur 
ModemManager-1.8/plugins/ublox/mm-broadband-bearer-ublox.c 
ModemManager-1.7.990/plugins/ublox/mm-broadband-bearer-ublox.c
--- ModemManager-1.8/plugins/ublox/mm-broadband-bearer-ublox.c  2019-04-24 
08:27:00.502975000 +0200
+++ ModemManager-1.7.990/plugins/ublox/mm-broadband-bearer-ublox.c      
2018-11-15 12:17:38.492286436 +0100
@@ -69,6 +69,7 @@
     gboolean                auth_required;
     /* For IPv4 settings */
     MMBearerIpConfig       *ip_config;
+    GError                 *pending_error;
 } CommonConnectContext;
 
 static void
@@ -81,6 +82,8 @@
     g_object_unref (ctx->self);
     g_object_unref (ctx->modem);
     g_object_unref (ctx->primary);
+    if (ctx->pending_error)
+        g_error_free(ctx->pending_error);
     g_slice_free (CommonConnectContext, ctx);
 }
 
@@ -102,6 +105,7 @@
     ctx->modem   = g_object_ref (modem);
     ctx->primary = g_object_ref (primary);
     ctx->cid     = cid;
+    ctx->pending_error = NULL;
 
     task = g_task_new (self, cancellable, callback, user_data);
     g_task_set_task_data (task, ctx, (GDestroyNotify) 
common_connect_context_free);
@@ -124,6 +128,31 @@
     return task;
 }
 
+
+#define SETDEFAULTBEARER (0)
+#define SETROUTE (1)
+
+#if SETDEFAULTBEARER
+static MMBearerIpFamily
+select_bearer_ip_family (MMBroadbandBearer *self)
+{
+    MMBearerIpFamily ip_family;
+
+    ip_family = mm_bearer_properties_get_ip_type (mm_base_bearer_peek_config 
(MM_BASE_BEARER (self)));
+    if (ip_family == MM_BEARER_IP_FAMILY_NONE || ip_family == 
MM_BEARER_IP_FAMILY_ANY) {
+        gchar *default_family;
+
+        ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER 
(self));
+        default_family = mm_bearer_ip_family_build_string_from_mask 
(ip_family);
+        mm_dbg ("No specific IP family requested, defaulting to %s", 
default_family);
+        g_free (default_family);
+    }
+
+    return ip_family;
+}
+#endif
+
+
 /*****************************************************************************/
 /* 3GPP IP config (sub-step of the 3GPP Connection sequence) */
 
@@ -327,6 +356,69 @@
     return MM_PORT (g_task_propagate_pointer (G_TASK (res), error));
 }
 
+
+#if DEACTIVATESUB
+static void
+cgact_activate_ready (MMBaseModem  *modem,
+                      GAsyncResult *res,
+                      GTask        *task);
+
+
+static void
+cgact_query_ready (MMBaseModem  *modem,
+                            GAsyncResult *res,
+                            GTask        *task)
+{
+    const gchar              *response;
+    GError                   *error = NULL;
+    GList                    *pdp_active_list = NULL;
+    GList                    *l;
+
+    CommonConnectContext *ctx;
+
+    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+
+    response = mm_base_modem_at_command_finish (modem, res, &error);
+    if (response)
+        pdp_active_list = mm_3gpp_parse_cgact_read_response (response, &error);
+
+    if (error) {
+        g_assert (!pdp_active_list);
+        g_prefix_error (&error, "Couldn't check current list of active PDP 
contexts: ");
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+    for (l = pdp_active_list; l; l = g_list_next (l)) {
+        MM3gppPdpContextActive *pdp_active;
+
+        /* We look for he just assume the first active PDP context found is 
the one we're
+         * looking for. */
+        pdp_active = (MM3gppPdpContextActive *)(l->data);
+        if ((pdp_active->cid != ctx->cid) && (pdp_active->active)){
+           gchar *cmd;
+           mm_dbg("Found other active PDP context with CID=%d, disable it!\n", 
pdp_active->cid);
+           cmd = g_strdup_printf ("+CGACT=0,%u", pdp_active->cid);
+           mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
+                              cmd,
+                              40,
+                              FALSE,
+                              (GAsyncReadyCallback) cgact_activate_ready,
+                              task);
+           g_free (cmd);
+            mm_3gpp_pdp_context_active_list_free (pdp_active_list);
+            return;
+        }
+    }
+    mm_3gpp_pdp_context_active_list_free (pdp_active_list);
+
+
+    g_task_return_pointer (task, g_object_ref (ctx->data), g_object_unref);
+    g_object_unref (task);
+}
+
+
 static void
 cgact_activate_ready (MMBaseModem  *modem,
                       GAsyncResult *res,
@@ -339,13 +431,166 @@
     ctx = (CommonConnectContext *) g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
-    if (!response)
+    if (response) {
+        mm_base_modem_at_command (MM_BASE_MODEM (modem),
+                                   "+CGACT?",
+                                   40,
+                                   FALSE, /* allow cached */
+                                   (GAsyncReadyCallback) cgact_query_ready,
+                                   task);
+
+        return;
+    }
+
+    if (!response) {
         g_task_return_error (task, error);
-    else
-        g_task_return_pointer (task, g_object_ref (ctx->data), g_object_unref);
+        g_object_unref (task);
+    }
+}
+
+#endif
+
+#if SETROUTE
+
+static void uiproute_ready(MMBaseModem  *modem,
+                      GAsyncResult *res,
+                      GTask        *task)
+{
+    CommonConnectContext *ctx;
+    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+
+
+    g_task_return_pointer (task, g_object_ref (ctx->data), g_object_unref);
+    g_object_unref (task);
+
+}
+
+
+
+static void
+activate_uipaddr_ready(MMBaseModem  *modem,
+                      GAsyncResult *res,
+                      GTask        *task)
+{
+    const gchar          *response;
+    GError               *error = NULL;
+    CommonConnectContext *ctx;
+    gchar                *cmd;
+    gchar                *gw_ipv4_address;
+
+    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+
+    response = mm_base_modem_at_command_finish (modem, res, &error);
+    if (!response) {
+        g_task_return_error (task, error);
+        g_object_unref (task);
+       return;
+    }
+
+    mm_ublox_parse_uipaddr_response (response,
+                                     NULL, /* cid */
+                                     NULL, /* if_name */
+                                     &gw_ipv4_address,
+                                     NULL, /* ipv4_subnet */
+                                     NULL, /* ipv6_global_address */
+                                     NULL, /* ipv6_link_local_address */
+                                     &error);
+
+
+    cmd = g_strdup_printf ("+UIPROUTE=\"add default gw %s\"", gw_ipv4_address);
+    mm_dbg ("setting default route #%u...", ctx->cid);
+    mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
+                              cmd,
+                              120,
+                              FALSE,
+                              (GAsyncReadyCallback) uiproute_ready,
+                              task);
+
+    g_free(gw_ipv4_address);
+    g_free(cmd);
+}
+
+
+static void
+cgact_activate_ready (MMBaseModem  *modem,
+                      GAsyncResult *res,
+                      GTask        *task)
+{
+    const gchar          *response;
+    GError               *error = NULL;
+    CommonConnectContext *ctx;
+    gchar                *cmd;
+
+    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+
+    response = mm_base_modem_at_command_finish (modem, res, &error);
+    if (!response) {
+        g_task_return_error (task, error);
+        g_object_unref (task);
+       return;
+    }
+
+
+    cmd = g_strdup_printf ("+UIPADDR=%u", ctx->cid);
+    mm_base_modem_at_command (MM_BASE_MODEM (modem),
+                              cmd,
+                              40,
+                              FALSE, /* allow cached */
+                              (GAsyncReadyCallback) activate_uipaddr_ready,
+                              task);
+    g_free(cmd);
+
+}
+
+static void
+activate_3gpp (GTask *task)
+{
+    CommonConnectContext *ctx;
+    gchar                *cmd;
+
+    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+
+    cmd = g_strdup_printf ("+CGACT=1,%u", ctx->cid);
+    mm_dbg ("activating PDP context #%u...", ctx->cid);
+
+    mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
+                              cmd,
+                              120,
+                              FALSE,
+                              (GAsyncReadyCallback) cgact_activate_ready,
+                              task);
+    g_free (cmd);
+}
+
+#else
+
+
+static void
+cgact_activate_ready (MMBaseModem  *modem,
+                      GAsyncResult *res,
+                      GTask        *task)
+{
+
+    const gchar          *response;
+    GError               *error = NULL;
+    CommonConnectContext *ctx;
+    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+
+
+    response = mm_base_modem_at_command_finish (modem, res, &error);
+    if (!response) {
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+
+    g_task_return_pointer (task, g_object_ref (ctx->data), g_object_unref);
     g_object_unref (task);
 }
 
+
+
 static void
 activate_3gpp (GTask *task)
 {
@@ -365,6 +610,8 @@
     g_free (cmd);
 }
 
+#endif
+
 static void
 uauthreq_ready (MMBaseModem  *modem,
                 GAsyncResult *res,
@@ -457,8 +704,8 @@
         cmd = g_strdup_printf ("+UAUTHREQ=%u,%u,%s,%s",
                                ctx->cid,
                                ublox_auth,
-                               quoted_password,
-                               quoted_user);
+                               quoted_user,
+                               quoted_password);
 
         g_free (quoted_user);
         g_free (quoted_password);
@@ -547,6 +794,63 @@
                               task);
 }
 
+
+static void
+cgact_query_active_ready (MMBaseModem  *modem,
+                            GAsyncResult *res,
+                            GTask        *task)
+{
+    const gchar              *response;
+    GError                   *error = NULL;
+    GList                    *pdp_active_list = NULL;
+    GList                    *l;
+
+    CommonConnectContext *ctx;
+
+    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+
+    response = mm_base_modem_at_command_finish (modem, res, &error);
+    if (response)
+        pdp_active_list = mm_3gpp_parse_cgact_read_response (response, &error);
+
+    if (error) {
+        g_assert (!pdp_active_list);
+        g_prefix_error (&error, "Couldn't check current list of active PDP 
contexts: ");
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+    for (l = pdp_active_list; l; l = g_list_next (l)) {
+        MM3gppPdpContextActive *pdp_active;
+
+        pdp_active = (MM3gppPdpContextActive *)(l->data);
+        if ((pdp_active->cid == ctx->cid) && pdp_active->active) {
+            mm_dbg("Requested PDP %d already active, skip activation", 
pdp_active->cid);
+           mm_3gpp_pdp_context_active_list_free (pdp_active_list);
+            g_task_return_pointer (task, g_object_ref (ctx->data), 
g_object_unref);
+            g_object_unref (task);
+            return;
+        }
+    }
+    mm_3gpp_pdp_context_active_list_free (pdp_active_list);
+    check_supported_authentication_methods (task);
+}
+
+
+static void
+cgact_query_active (MMBaseModem  *modem,
+                      GTask        *task)
+{
+    mm_base_modem_at_command (MM_BASE_MODEM (modem),
+                              "+CGACT?",
+                              40,
+                              FALSE, /* allow cached */
+                              (GAsyncReadyCallback) cgact_query_active_ready,
+                              task);
+}
+
+
 static void
 dial_3gpp (MMBroadbandBearer   *self,
            MMBaseModem         *modem,
@@ -568,7 +872,7 @@
                                           user_data)))
         return;
 
-    check_supported_authentication_methods (task);
+    cgact_query_active(modem, task);
 }
 
 /*****************************************************************************/
@@ -632,6 +936,277 @@
     g_free (cmd);
 }
 
+#if SETDEFAULTBEARER
+
+typedef struct {
+    MMBroadbandBearer *self;
+    MMBaseModem       *modem;
+    MMPortSerialAt     *primary;
+    GCancellable       *cancellable;
+    MMBearerIpFamily ip_family;
+} CidSelection3gppUBloxContext;
+
+
+static void
+cid_selection_3gpp_ublox_context_free (CidSelection3gppUBloxContext *ctx)
+{
+    g_object_unref (ctx->self);
+    g_object_unref (ctx->modem);
+    g_object_unref (ctx->primary);
+    g_object_unref (ctx->cancellable);
+    g_slice_free (CidSelection3gppUBloxContext, ctx);
+}
+
+
+static void
+select_cid_end (MMBroadbandBearer *self,
+                GAsyncResult *res,
+                GTask        *task)
+{
+    guint cid;
+    GError  *error = NULL;
+
+    mm_dbg ("Return from parent CID selection (%p, %p, %p)", self, res, task);
+
+    cid = 
MM_BROADBAND_BEARER_CLASS(mm_broadband_bearer_ublox_parent_class)->cid_selection_3gpp_finish(self,
 res, &error);
+    mm_dbg("Called base finish successfully (%d, %p)", cid, error);
+    if (error) {
+        g_task_return_error(task, error);
+    } else {
+        g_task_return_int(task, (gssize) cid);
+    }
+    g_object_unref(task);
+}
+
+
+static void
+select_cfun1_ready (MMBaseModem  *modem,
+                    GAsyncResult *res,
+                    GTask        *task)
+{
+    GError                  *error = NULL;
+    CidSelection3gppUBloxContext *ctx;
+
+    ctx = (CidSelection3gppUBloxContext *) g_task_get_task_data (task);
+
+    mm_base_modem_at_command_full_finish (ctx->modem, res, &error);
+    if (error) {
+        mm_warn ("Couldn't set default APN to use: '%s'", error->message);
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+    mm_dbg ("Call parent CID selection");
+    
MM_BROADBAND_BEARER_CLASS(mm_broadband_bearer_ublox_parent_class)->cid_selection_3gpp(ctx->self,
 ctx->modem, ctx->primary, ctx->cancellable, 
(GAsyncReadyCallback)select_cid_end, task);
+}
+
+static void
+select_cid_ready (MMBaseModem  *modem,
+                    GAsyncResult *res,
+                    GTask        *task)
+{
+    gchar *command;
+
+    GError                  *error = NULL;
+    CidSelection3gppUBloxContext *ctx;
+
+    ctx = (CidSelection3gppUBloxContext *) g_task_get_task_data (task);
+
+    mm_base_modem_at_command_full_finish (ctx->modem, res, &error);
+    if (error) {
+        mm_warn ("Couldn't set default APN to use: '%s'", error->message);
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+    command = g_strdup_printf ("+CFUN=1");
+    mm_base_modem_at_command_full (ctx->modem,
+                                   ctx->primary,
+                                   command,
+                                   3,
+                                   FALSE,
+                                   FALSE, /* raw */
+                                   NULL, /* cancellable */
+                                   (GAsyncReadyCallback) select_cfun1_ready,
+                                   task);
+    g_free (command);
+}
+
+
+
+static void
+select_cfun4_ready (MMBaseModem  *modem,
+                    GAsyncResult *res,
+                    GTask        *task)
+{
+    gchar *apn;
+    gchar *user;
+    gchar *password;
+    gchar *command;
+    const gchar             *pdp_type;
+
+    GError                  *error = NULL;
+    CidSelection3gppUBloxContext *ctx;
+    MMBearerProperties * bearer_config;
+
+
+    ctx = (CidSelection3gppUBloxContext *) g_task_get_task_data (task);
+
+    mm_base_modem_at_command_full_finish (ctx->modem, res, &error);
+    if (error) {
+        mm_warn ("Couldn't set default APN to use: '%s'", error->message);
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+
+    /* Validate requested PDP type */
+    pdp_type = mm_3gpp_get_pdp_type_from_ip_family (ctx->ip_family);
+    if (!pdp_type) {
+        gchar * str;
+
+        str = mm_bearer_ip_family_build_string_from_mask (ctx->ip_family);
+        g_task_return_new_error (task,
+                                 MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
+                                 "Unsupported IP type requested: '%s'", str);
+        g_object_unref (task);
+        g_free (str);
+        return;
+    }
+
+    bearer_config = mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self));
+    apn = mm_port_serial_at_quote_string (mm_bearer_properties_get_apn 
(bearer_config));
+    user = mm_port_serial_at_quote_string (mm_bearer_properties_get_user 
(bearer_config));
+    password = mm_port_serial_at_quote_string 
(mm_bearer_properties_get_password (bearer_config));
+
+    command = g_strdup_printf 
("+UCGDFLT=1,\"%s\",%s,,,,,,,,,,,,,,,,,,%d,%s,%s", pdp_type, apn, 
mm_bearer_properties_get_allowed_auth (bearer_config), user, password);
+    mm_dbg("Cmd: %s", command);
+    g_free (apn);
+    g_free (user);
+    g_free (password);
+    mm_base_modem_at_command_full (ctx->modem,
+                                   ctx->primary,
+                                   command,
+                                   3,
+                                   FALSE,
+                                   FALSE, /* raw */
+                                   NULL, /* cancellable */
+                                   (GAsyncReadyCallback) select_cid_ready,
+                                   task);
+    g_free (command);
+}
+
+
+static guint
+cid_selection_3gpp_finish (MMBroadbandBearer  *self,
+                           GAsyncResult       *res,
+                           GError            **error)
+{
+    gssize cid;
+
+    /* We return 0 as an invalid CID, not -1 */
+    cid = g_task_propagate_int (G_TASK (res), error);
+    return (guint) (cid < 0 ? 0 : cid);
+}
+
+static void
+read_default_eps (MMBaseModem  *modem,
+                    GAsyncResult *res,
+                    GTask        *task)
+{
+    gchar *command;
+    gchar *apn;
+    MMBearerIpFamily ip_family;
+    const gchar              *response;
+    gboolean found_apn = FALSE;
+
+    GError                  *error = NULL;
+    CidSelection3gppUBloxContext *ctx;
+
+    ctx = (CidSelection3gppUBloxContext *) g_task_get_task_data (task);
+
+    response = mm_base_modem_at_command_finish (modem, res, &error);
+    if (error) {
+        mm_warn ("Couldn't set default APN to use: '%s'", error->message);
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+
+    mm_3gpp_parse_ucgdflt_read_response(response, &ip_family, &apn, &error);
+    if (ip_family  == ctx->ip_family) {
+        if (mm_3gpp_cmp_apn_name (apn, mm_bearer_properties_get_apn 
(mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self))))) {
+            found_apn = TRUE;
+        }
+    }
+    if (apn) {
+        g_free(apn);
+    }
+
+    if (!found_apn) {
+
+         command = g_strdup_printf ("+CFUN=4");
+        mm_base_modem_at_command_full (ctx->modem,
+                                   ctx->primary,
+                                   command,
+                                   3,
+                                   FALSE,
+                                   FALSE, /* raw */
+                                   NULL, /* cancellable */
+                                   (GAsyncReadyCallback) select_cfun4_ready,
+                                   task);
+        g_free (command);
+
+    } else {
+        mm_dbg ("Call parent CID selection");
+        
MM_BROADBAND_BEARER_CLASS(mm_broadband_bearer_ublox_parent_class)->cid_selection_3gpp(ctx->self,
 ctx->modem, ctx->primary, ctx->cancellable, 
(GAsyncReadyCallback)select_cid_end, task);
+    }
+}
+
+
+static void  cid_selection_3gpp (MMBroadbandBearer *self,
+                                 MMBaseModem *modem,
+                                 MMPortSerialAt *primary,
+                                 GCancellable *cancellable,
+                                 GAsyncReadyCallback callback,
+                                 gpointer user_data) {
+
+
+    GTask                   *task;
+    CidSelection3gppUBloxContext *ctx;
+    gchar *command;
+
+    ctx = g_slice_new0 (CidSelection3gppUBloxContext);
+    ctx->self        = g_object_ref (self);
+    ctx->modem       = g_object_ref (modem);
+    ctx->primary     = g_object_ref (primary);
+    ctx->cancellable = g_object_ref (cancellable);
+    ctx->ip_family = select_bearer_ip_family (self);
+
+    task = g_task_new (self, cancellable, callback, user_data);
+    g_task_set_task_data (task, ctx, (GDestroyNotify) 
cid_selection_3gpp_ublox_context_free);
+
+
+    command = g_strdup_printf("+UCGDFLT?");
+    mm_base_modem_at_command_full(ctx->modem,
+                                 ctx->primary,
+                                  command,
+                                  3,
+                                  FALSE,
+                                  FALSE,
+                                  NULL,
+                                  (GAsyncReadyCallback) read_default_eps,
+                                  task);
+    g_free( command);
+}
+
+
+#endif
+
 /*****************************************************************************/
 /* Reload statistics */
 
@@ -904,6 +1479,11 @@
     broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
     broadband_bearer_class->get_ip_config_3gpp = get_ip_config_3gpp;
     broadband_bearer_class->get_ip_config_3gpp_finish = 
get_ip_config_3gpp_finish;
+#if SETDEFAULTBEARER
+    broadband_bearer_class->cid_selection_3gpp = cid_selection_3gpp;
+    broadband_bearer_class->cid_selection_3gpp_finish = 
cid_selection_3gpp_finish;
+#endif
+    klass->cid_selection_parent = broadband_bearer_class->cid_selection_3gpp;
 
     properties[PROP_USB_PROFILE] =
         g_param_spec_enum (MM_BROADBAND_BEARER_UBLOX_USB_PROFILE,
diff '--exclude=.git*' '--exclude=Makefile*' '--exclude=config*' -ur 
ModemManager-1.8/plugins/ublox/mm-broadband-bearer-ublox.h 
ModemManager-1.7.990/plugins/ublox/mm-broadband-bearer-ublox.h
--- ModemManager-1.8/plugins/ublox/mm-broadband-bearer-ublox.h  2019-04-24 
08:27:00.502975000 +0200
+++ ModemManager-1.7.990/plugins/ublox/mm-broadband-bearer-ublox.h      
2018-11-05 14:40:13.000000000 +0100
@@ -46,6 +46,14 @@
 
 struct _MMBroadbandBearerUbloxClass {
     MMBroadbandBearerClass parent;
+
+    void  (* cid_selection_parent) (MMBroadbandBearer *self,
+                                         MMBaseModem *modem,
+                                         MMPortSerialAt *primary,
+                                         GCancellable *cancellable,
+                                         GAsyncReadyCallback callback,
+                                         gpointer user_data);
+
 };
 
 GType mm_broadband_bearer_ublox_get_type (void);
diff '--exclude=.git*' '--exclude=Makefile*' '--exclude=config*' -ur 
ModemManager-1.8/src/mm-modem-helpers.c 
ModemManager-1.7.990/src/mm-modem-helpers.c
--- ModemManager-1.8/src/mm-modem-helpers.c     2019-04-24 08:27:00.566943000 
+0200
+++ ModemManager-1.7.990/src/mm-modem-helpers.c 2018-11-05 14:40:13.000000000 
+0100
@@ -1441,6 +1441,56 @@
     return (a->cid - b->cid);
 }
 
+
+
+gboolean
+mm_3gpp_parse_ucgdflt_read_response (const gchar *reply,
+                                     MMBearerIpFamily * ip_family,
+                                     gchar ** apn,
+                                     GError **error)
+{
+    GError *inner_error = NULL;
+    GRegex *r;
+    GMatchInfo *match_info;
+    *apn = NULL;
+
+    r = g_regex_new ("\\+UCGDFLT:\\s*([^, \\)]*)\\s*,([^, \\)]*)\\s*",
+                     G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
+                     0, &inner_error);
+    if (r) {
+        g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, 
&inner_error);
+
+        while (!inner_error &&
+               g_match_info_matches (match_info)) {
+            gchar *str;
+
+            mm_dbg("Match %s %s\n", mm_get_string_unquoted_from_match_info 
(match_info, 1),mm_get_string_unquoted_from_match_info (match_info, 2));
+            str = mm_get_string_unquoted_from_match_info (match_info, 1);
+            *ip_family = mm_3gpp_get_ip_family_from_pdp_type (str);
+            g_free(str);
+
+            *apn = mm_get_string_unquoted_from_match_info (match_info, 2);
+            g_match_info_next (match_info, &inner_error);
+        }
+
+        g_match_info_free (match_info);
+        g_regex_unref (r);
+    }
+
+    if (inner_error) {
+       if (apn) {
+           g_free(apn);
+        }
+        g_propagate_error (error, inner_error);
+        g_prefix_error (error, "Couldn't properly parse default eps bearer. ");
+        return FALSE;
+    }
+    mm_dbg("udcgdflt response: %s -> %s, %d", reply, *apn, *ip_family);
+
+    return TRUE;
+}
+
+
 GList *
 mm_3gpp_parse_cgdcont_read_response (const gchar *reply,
                                      GError **error)
diff '--exclude=.git*' '--exclude=Makefile*' '--exclude=config*' -ur 
ModemManager-1.8/src/mm-modem-helpers.h 
ModemManager-1.7.990/src/mm-modem-helpers.h
--- ModemManager-1.8/src/mm-modem-helpers.h     2019-04-24 08:27:00.566943000 
+0200
+++ ModemManager-1.7.990/src/mm-modem-helpers.h 2018-11-05 14:40:13.000000000 
+0100
@@ -152,6 +152,15 @@
 gboolean mm_3gpp_cmp_apn_name (const gchar *requested,
                                const gchar *existing);
 
+
+gboolean
+mm_3gpp_parse_ucgdflt_read_response (const gchar *reply,
+                                     MMBearerIpFamily * ip_family,
+                                     gchar ** apn,
+                                     GError **error);
+
+
+
 /* AT+CGDCONT=? (PDP context format) test parser */
 typedef struct {
     guint min_cid;
_______________________________________________
ModemManager-devel mailing list
ModemManager-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel

Reply via email to