Toby-L201 connect failure Ubuntu 18.04 Modem Manager 1.10.6 Linux Kernel Version 4.20.7
Ulrich Mohr
u.mohr at semex-engcon.com
Tue Dec 10 11:02:21 UTC 2019
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.mohr at 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.mohr at semex-engcon.com
___________________________________________
Executive board: A. Stiegler, H.-J. Nitzpon
Commercial register: Mannheim, HRB 718881
Company domicile: Ettlingen
-------------- next part --------------
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;
More information about the ModemManager-devel
mailing list