connect using a specific PDP CID
matthew stanger
stangerm2 at gmail.com
Fri Mar 8 18:47:16 UTC 2019
>
> I’m trying to use ModemManager 1.8.2 with a Verizon LTE Cat-M1 modem.
Aleksander wrote this for my team for this very case. I've re-based it to
1.8.2 so it should go on clean.
We should work on the new API at some point...
I really think the patch here is great to be honest. Again we are using it
not just for Vzw but also in Asia where a few carrier's require PDP #1.
>From da8bc6feb036cfdcd5db8280f00565c82685d794 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander at aleksander.es>
Date: Fri, 12 May 2017 18:24:13 +0200
Subject: [PATCH 1/1] allow specifying the PDP CID to use
Some operators, most notably Verizon, require connection to be
performed through a specific PDP context. This API update allows the
user to specify the PDP cid via a new 'pdp-cid' parameter given in
either the Simple.Connect() or the Modem.CreateBearer() methods.
Signed-off-by: mstanger <matthew_stanger at trimble.com>
---
cli/mmcli-bearer.c | 9 ++++
docs/reference/libmm-glib/libmm-glib-sections.txt | 4 ++
.../org.freedesktop.ModemManager1.Modem.xml | 2 +
libmm-glib/mm-bearer-properties.c | 59
+++++++++++++++++++++-
libmm-glib/mm-bearer-properties.h | 3 ++
libmm-glib/mm-simple-connect-properties.c | 34 +++++++++++++
libmm-glib/mm-simple-connect-properties.h | 3 ++
src/mm-broadband-bearer.c | 41 ++++++++++-----
src/mm-iface-modem-simple.c | 13 +++--
9 files changed, 150 insertions(+), 18 deletions(-)
diff --git a/cli/mmcli-bearer.c b/cli/mmcli-bearer.c
index cd9ecca..daa8614 100644
--- a/cli/mmcli-bearer.c
+++ b/cli/mmcli-bearer.c
@@ -163,11 +163,18 @@ print_bearer_info (MMBearer *bearer)
if (properties) {
gchar *ip_family_str;
+ gchar *pdp_cid_str = NULL;
+ guint pdp_cid;
ip_family_str = (mm_bearer_ip_family_build_string_from_mask (
mm_bearer_properties_get_ip_type
(properties)));
+
+ if ((pdp_cid = mm_bearer_properties_get_pdp_cid (properties)) != 0)
+ pdp_cid_str = g_strdup_printf ("%u", pdp_cid);
+
g_print (" -------------------------\n"
" Properties | apn: '%s'\n"
+ " | PDP CID: '%s'\n"
" | roaming: '%s'\n"
" | IP type: '%s'\n"
" | user: '%s'\n"
@@ -175,6 +182,7 @@ print_bearer_info (MMBearer *bearer)
" | number: '%s'\n"
" | Rm protocol: '%s'\n",
VALIDATE_NONE (mm_bearer_properties_get_apn (properties)),
+ VALIDATE_NONE (pdp_cid_str),
mm_bearer_properties_get_allow_roaming (properties) ?
"allowed" : "forbidden",
VALIDATE_UNKNOWN (ip_family_str),
VALIDATE_NONE (mm_bearer_properties_get_user
(properties)),
@@ -183,6 +191,7 @@ print_bearer_info (MMBearer *bearer)
VALIDATE_UNKNOWN (mm_modem_cdma_rm_protocol_get_string (
mm_bearer_properties_get_rm_protocol (properties))));
g_free (ip_family_str);
+ g_free (pdp_cid_str);
}
/* IPv4 */
diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt
b/docs/reference/libmm-glib/libmm-glib-sections.txt
index 46f2d92..077e7ee 100644
--- a/docs/reference/libmm-glib/libmm-glib-sections.txt
+++ b/docs/reference/libmm-glib/libmm-glib-sections.txt
@@ -779,6 +779,8 @@ mm_simple_connect_properties_get_operator_id
mm_simple_connect_properties_set_operator_id
mm_simple_connect_properties_get_apn
mm_simple_connect_properties_set_apn
+mm_simple_connect_properties_get_pdp_cid
+mm_simple_connect_properties_set_pdp_cid
mm_simple_connect_properties_get_allowed_auth
mm_simple_connect_properties_set_allowed_auth
mm_simple_connect_properties_get_user
@@ -1064,6 +1066,8 @@ mm_bearer_properties_new
<SUBSECTION GettersSetters>
mm_bearer_properties_get_apn
mm_bearer_properties_set_apn
+mm_bearer_properties_get_pdp_cid
+mm_bearer_properties_set_pdp_cid
mm_bearer_properties_get_allowed_auth
mm_bearer_properties_set_allowed_auth
mm_bearer_properties_get_user
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.xml
b/introspection/org.freedesktop.ModemManager1.Modem.xml
index a5a236c..23c14ed 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.xml
@@ -61,6 +61,8 @@
<variablelist>
<varlistentry><term><literal>"apn"</literal></term>
<listitem><para>Access Point Name, given as a string value
(signature <literal>"s"</literal>). Required in
3GPP.</para></listitem></varlistentry>
+ <varlistentry><term><literal>"pdp-cid"</literal></term>
+ <listitem><para>PDP context identifier, given as an unsigned
32-bit integer value (signature <literal>"u"</literal>). Optional in
3GPP.</para></listitem></varlistentry>
<varlistentry><term><literal>"ip-type"</literal></term>
<listitem><para>Addressing type, given as a <link
linkend="MMBearerIpFamily">MMBearerIpFamily</link> value (signature
<literal>"u"</literal>). Optional in 3GPP and
CDMA.</para></listitem></varlistentry>
<varlistentry><term><literal>"allowed-auth"</literal></term>
diff --git a/libmm-glib/mm-bearer-properties.c
b/libmm-glib/mm-bearer-properties.c
index c87068f..8e54f10 100644
--- a/libmm-glib/mm-bearer-properties.c
+++ b/libmm-glib/mm-bearer-properties.c
@@ -34,6 +34,7 @@
G_DEFINE_TYPE (MMBearerProperties, mm_bearer_properties, G_TYPE_OBJECT);
#define PROPERTY_APN "apn"
+#define PROPERTY_PDP_CID "pdp-cid"
#define PROPERTY_ALLOWED_AUTH "allowed-auth"
#define PROPERTY_USER "user"
#define PROPERTY_PASSWORD "password"
@@ -45,6 +46,8 @@ G_DEFINE_TYPE (MMBearerProperties, mm_bearer_properties,
G_TYPE_OBJECT);
struct _MMBearerPropertiesPrivate {
/* APN */
gchar *apn;
+ /* PDP CID */
+ guint pdp_cid;
/* IP type */
MMBearerIpFamily ip_type;
/* Allowed auth */
@@ -100,6 +103,40 @@ mm_bearer_properties_get_apn (MMBearerProperties *self)
/*****************************************************************************/
/**
+ * mm_bearer_properties_set_pdp_cid:
+ * @self: a #MMBearerProperties.
+ * @pdp_cid: PDP context ID.
+ *
+ * Sets the PDP context ID to use in the connection attempt.
+ */
+void
+mm_bearer_properties_set_pdp_cid (MMBearerProperties *self,
+ guint pdp_cid)
+{
+ g_return_if_fail (MM_IS_BEARER_PROPERTIES (self));
+
+ self->priv->pdp_cid = pdp_cid;
+}
+
+/**
+ * mm_bearer_properties_get_pdp_cid:
+ * @self: a #MMBearerProperties.
+ *
+ * Gets the PDP context ID to use in the connection attempt.
+ *
+ * Returns: the context number, or 0 if not set.
+ */
+guint
+mm_bearer_properties_get_pdp_cid (MMBearerProperties *self)
+{
+ g_return_val_if_fail (MM_IS_BEARER_PROPERTIES (self), 0);
+
+ return self->priv->pdp_cid;
+}
+
+/*****************************************************************************/
+
+/**
* mm_bearer_properties_set_allowed_auth:
* @self: a #MMBearerProperties.
* @allowed_auth: a bitmask of #MMBearerAllowedAuth values.
%MM_BEARER_ALLOWED_AUTH_UNKNOWN may be given to request the modem-default
method.
@@ -361,6 +398,12 @@ mm_bearer_properties_get_dictionary
(MMBearerProperties *self)
PROPERTY_APN,
g_variant_new_string (self->priv->apn));
+ if (self->priv->pdp_cid)
+ g_variant_builder_add (&builder,
+ "{sv}",
+ PROPERTY_PDP_CID,
+ g_variant_new_uint32 (self->priv->pdp_cid));
+
if (self->priv->allowed_auth != MM_BEARER_ALLOWED_AUTH_UNKNOWN)
g_variant_builder_add (&builder,
"{sv}",
@@ -428,7 +471,16 @@ mm_bearer_properties_consume_string
(MMBearerProperties *self,
if (g_str_equal (key, PROPERTY_APN))
mm_bearer_properties_set_apn (self, value);
- else if (g_str_equal (key, PROPERTY_ALLOWED_AUTH)) {
+ else if (g_str_equal (key, PROPERTY_PDP_CID)) {
+ guint aux;
+
+ if (!mm_get_uint_from_str (value, &aux)) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Invalid PDP CID given: %s", value);
+ return FALSE;
+ }
+ mm_bearer_properties_set_pdp_cid (self, aux);
+ }else if (g_str_equal (key, PROPERTY_ALLOWED_AUTH)) {
GError *inner_error = NULL;
MMBearerAllowedAuth allowed_auth;
@@ -548,6 +600,10 @@ mm_bearer_properties_consume_variant
(MMBearerProperties *properties,
mm_bearer_properties_set_apn (
properties,
g_variant_get_string (value, NULL));
+ else if (g_str_equal (key, PROPERTY_PDP_CID))
+ mm_bearer_properties_set_pdp_cid (
+ properties,
+ g_variant_get_uint32 (value));
else if (g_str_equal (key, PROPERTY_ALLOWED_AUTH))
mm_bearer_properties_set_allowed_auth (
properties,
@@ -664,6 +720,7 @@ mm_bearer_properties_cmp (MMBearerProperties *a,
MMBearerProperties *b)
{
return ((!g_strcmp0 (a->priv->apn, b->priv->apn)) &&
+ (a->priv->pdp_cid == b->priv->pdp_cid) &&
(a->priv->ip_type == b->priv->ip_type) &&
(!g_strcmp0 (a->priv->number, b->priv->number)) &&
(a->priv->allowed_auth == b->priv->allowed_auth) &&
diff --git a/libmm-glib/mm-bearer-properties.h
b/libmm-glib/mm-bearer-properties.h
index 361c867..6fc1347 100644
--- a/libmm-glib/mm-bearer-properties.h
+++ b/libmm-glib/mm-bearer-properties.h
@@ -59,6 +59,8 @@ MMBearerProperties *mm_bearer_properties_new (void);
void mm_bearer_properties_set_apn (MMBearerProperties *self,
const gchar *apn);
+void mm_bearer_properties_set_pdp_cid (MMBearerProperties *self,
+ guint pdp_cid);
void mm_bearer_properties_set_allowed_auth (MMBearerProperties *self,
MMBearerAllowedAuth
allowed_auth);
void mm_bearer_properties_set_user (MMBearerProperties *self,
@@ -75,6 +77,7 @@ void mm_bearer_properties_set_rm_protocol
(MMBearerProperties *self,
MMModemCdmaRmProtocol
protocol);
const gchar *mm_bearer_properties_get_apn
(MMBearerProperties *self);
+guint mm_bearer_properties_get_pdp_cid
(MMBearerProperties *self);
MMBearerAllowedAuth mm_bearer_properties_get_allowed_auth
(MMBearerProperties *self);
const gchar *mm_bearer_properties_get_user
(MMBearerProperties *self);
const gchar *mm_bearer_properties_get_password
(MMBearerProperties *self);
diff --git a/libmm-glib/mm-simple-connect-properties.c
b/libmm-glib/mm-simple-connect-properties.c
index 200b7c3..c696f50 100644
--- a/libmm-glib/mm-simple-connect-properties.c
+++ b/libmm-glib/mm-simple-connect-properties.c
@@ -153,6 +153,40 @@ mm_simple_connect_properties_get_apn
(MMSimpleConnectProperties *self)
/*****************************************************************************/
/**
+ * mm_simple_connect_properties_set_pdp_cid:
+ * @self: a #MMSimpleConnectProperties.
+ * @pdp_cid: PDP context ID.
+ *
+ * Sets the PDP context ID to use in the connection attempt.
+ */
+void
+mm_simple_connect_properties_set_pdp_cid (MMSimpleConnectProperties *self,
+ guint
pdp_cid)
+{
+ g_return_if_fail (MM_IS_SIMPLE_CONNECT_PROPERTIES (self));
+
+ mm_bearer_properties_set_pdp_cid (self->priv->bearer_properties,
pdp_cid);
+}
+
+/**
+ * mm_simple_connect_properties_get_pdp_cid:
+ * @self: a #MMSimpleConnectProperties.
+ *
+ * Gets the PDP context ID to use in the connection attempt.
+ *
+ * Returns: the context number, or 0 if not set.
+ */
+guint
+mm_simple_connect_properties_get_pdp_cid (MMSimpleConnectProperties *self)
+{
+ g_return_val_if_fail (MM_IS_SIMPLE_CONNECT_PROPERTIES (self), 0);
+
+ return mm_bearer_properties_get_pdp_cid
(self->priv->bearer_properties);
+}
+
+/*****************************************************************************/
+
+/**
* mm_simple_connect_properties_set_allowed_auth:
* @self: a #MMSimpleConnectProperties.
* @allowed_auth: a bitmask of #MMBearerAllowedAuth values.
%MM_BEARER_ALLOWED_AUTH_UNKNOWN may be given to request the modem-default
method.
diff --git a/libmm-glib/mm-simple-connect-properties.h
b/libmm-glib/mm-simple-connect-properties.h
index 3167db0..5378c5e 100644
--- a/libmm-glib/mm-simple-connect-properties.h
+++ b/libmm-glib/mm-simple-connect-properties.h
@@ -65,6 +65,8 @@ void mm_simple_connect_properties_set_operator_id
(MMSimpleConnectProperties *
const gchar
*operator_id);
void mm_simple_connect_properties_set_apn
(MMSimpleConnectProperties *self,
const gchar *apn);
+void mm_simple_connect_properties_set_pdp_cid
(MMSimpleConnectProperties *self,
+ guint pdp_cid);
void mm_simple_connect_properties_set_allowed_auth
(MMSimpleConnectProperties *self,
MMBearerAllowedAuth
allowed_auth);
void mm_simple_connect_properties_set_user
(MMSimpleConnectProperties *self,
@@ -81,6 +83,7 @@ void mm_simple_connect_properties_set_number
(MMSimpleConnectProperties *
const gchar *mm_simple_connect_properties_get_pin
(MMSimpleConnectProperties *self);
const gchar *mm_simple_connect_properties_get_operator_id
(MMSimpleConnectProperties *self);
const gchar *mm_simple_connect_properties_get_apn
(MMSimpleConnectProperties *self);
+guint mm_simple_connect_properties_get_pdp_cid
(MMSimpleConnectProperties *self);
MMBearerAllowedAuth mm_simple_connect_properties_get_allowed_auth
(MMSimpleConnectProperties *self);
const gchar *mm_simple_connect_properties_get_user
(MMSimpleConnectProperties *self);
const gchar *mm_simple_connect_properties_get_password
(MMSimpleConnectProperties *self);
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
index ac70173..de4fa72 100644
--- a/src/mm-broadband-bearer.c
+++ b/src/mm-broadband-bearer.c
@@ -732,25 +732,17 @@ initialize_pdp_context_ready (MMBaseModem *modem,
}
static void
-find_cid_ready (MMBaseModem *modem,
- GAsyncResult *res,
- GTask *task)
+initialize_pdp_context (GTask *task)
{
gchar *apn;
gchar *command;
- GError *error = NULL;
const gchar *pdp_type;
CidSelection3gppContext *ctx;
ctx = (CidSelection3gppContext *) g_task_get_task_data (task);
- mm_base_modem_at_sequence_full_finish (modem, res, NULL, &error);
- if (error) {
- mm_warn ("Couldn't find best CID to use: '%s'", error->message);
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
+ /* If no error reported, we must have a valid CID to be used */
+ g_assert (ctx->cid != 0);
/* Validate requested PDP type */
pdp_type = mm_3gpp_get_pdp_type_from_ip_family (ctx->ip_family);
@@ -766,9 +758,6 @@ find_cid_ready (MMBaseModem *modem,
return;
}
- /* If no error reported, we must have a valid CID to be used */
- g_assert (ctx->cid != 0);
-
/* If there's already a PDP context defined, just use it */
if (ctx->use_existing_cid) {
g_task_return_int (task, (gssize) ctx->cid);
@@ -792,6 +781,24 @@ find_cid_ready (MMBaseModem *modem,
g_free (command);
}
+static void
+find_cid_ready (MMBaseModem *modem,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+
+ mm_base_modem_at_sequence_full_finish (modem, res, NULL, &error);
+ if (error) {
+ mm_warn ("Couldn't find best CID to use: '%s'", error->message);
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ initialize_pdp_context (task);
+}
+
static gboolean
parse_cid_range (MMBaseModem *modem,
CidSelection3gppContext *ctx,
@@ -998,6 +1005,12 @@ cid_selection_3gpp (MMBroadbandBearer *self,
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify)
cid_selection_3gpp_context_free);
+ if ((ctx->cid = mm_bearer_properties_get_pdp_cid
(mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)))) != 0) {
+ mm_dbg ("Explicit CID requested by the user: %u", ctx->cid);
+ initialize_pdp_context (task);
+ return;
+ }
+
mm_dbg ("Looking for best CID...");
mm_base_modem_at_sequence_full (ctx->modem,
ctx->primary,
diff --git a/src/mm-iface-modem-simple.c b/src/mm-iface-modem-simple.c
index a16adb1..59d980e 100644
--- a/src/mm-iface-modem-simple.c
+++ b/src/mm-iface-modem-simple.c
@@ -651,9 +651,10 @@ connect_auth_ready (MMBaseModem *self,
/* Log about all the parameters being used for the simple connect */
{
- MMBearerAllowedAuth allowed_auth;
- gchar *str;
- MMBearerIpFamily ip_family;
+ MMBearerAllowedAuth allowed_auth;
+ gchar *str;
+ MMBearerIpFamily ip_family;
+ guint aux_uint;
#define VALIDATE_UNSPECIFIED(str) (str ? str : "unspecified")
@@ -665,6 +666,12 @@ connect_auth_ready (MMBaseModem *self,
mm_dbg (" APN: %s", VALIDATE_UNSPECIFIED
(mm_simple_connect_properties_get_apn (ctx->properties)));
+ aux_uint = mm_simple_connect_properties_get_pdp_cid
(ctx->properties);
+ if (aux_uint)
+ mm_dbg (" PDP CID: %u", aux_uint);
+ else
+ mm_dbg (" PDP CID: unspecified");
+
ip_family = mm_simple_connect_properties_get_ip_type
(ctx->properties);
if (ip_family != MM_BEARER_IP_FAMILY_NONE) {
str = mm_bearer_ip_family_build_string_from_mask (ip_family);
--
1.9.1
On Fri, Mar 8, 2019 at 11:40 AM Aleksander Morgado <aleksander at aleksander.es>
wrote:
> > I’m trying to use ModemManager 1.8.2 with a Verizon LTE Cat-M1 modem.
> Verizon requires using PDP context #3 for the internet connection. I read
> the thread from 2017 (
> https://lists.freedesktop.org/archives/modemmanager-devel/2017-May/004663.html)
> in which a patch was proposed to handle this case in ModemManager, but saw
> that the thread ended with a plan to develop a new API for managing
> profiles instead of that patch.
> >
> >
> >
> > But I haven’t been able to find this new API, and it doesn’t look like
> the original patch was applied either. Is this profile management API
> available in 1.8.2, or in a newer version? How do I force ModemManager to
> use PDP context #3 for the internet connection?
> >
>
> Right now, you could manually create the PDP context with the settings
> you want, and MM should re-use the already created context if the
> settings requested match the existing ones.
>
> We should work on the new API at some point...
>
> --
> Aleksander
> https://aleksander.es
> _______________________________________________
> ModemManager-devel mailing list
> ModemManager-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/modemmanager-devel/attachments/20190308/46429a59/attachment-0001.html>
More information about the ModemManager-devel
mailing list