aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Starr <mstarr@hedonline.com>2019-06-12 16:24:04 -0500
committerDan Williams <dcbw@redhat.com>2019-09-13 18:13:26 +0000
commite93b5c1c1f4f5afce4a3476c239e4d9aa15c9b32 (patch)
tree7a7a0fc7b9f5bce13eae556428f7b9cbeda68cc6 /src
parent2ecb96b6adbc288df7c92eac9c87b1d8b1d7c49e (diff)
mm-broadband-bearer: fixed non-sequential CID selection
When a modem reported back non-sequential CIDs, MM was using the next larger CID number after the last CID found. In cases where the last CID found was the highest numbered CID allowed and is not a modifiable CID, MM would give up and fail to establish a data connection. The above issue occurs on u-blox TOBY-R200 modems as of firmware 30.33 A02.02. In this firmware version there are two default CIDs programmed into the modem, one at CID 1 and another at CID 31. The CID at 31 is the highest CID number that can be used and cannot be modified. This change makes it so while parsing CIDs for a match, if a jump in CID numbers is detected, so not sequential, the first open CID will be used before using the max CID +1 or replacing the max CID. If an exact match for IP type and APN is found, then that will still be used first.
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-bearer.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
index 0cda4b9b..b772c7a8 100644
--- a/src/mm-broadband-bearer.c
+++ b/src/mm-broadband-bearer.c
@@ -795,6 +795,7 @@ parse_pdp_list (MMBaseModem *modem,
GList *pdp_list;
GList *l;
guint cid;
+ guint prev_cid;
/* If cancelled, set result error */
if (g_cancellable_is_cancelled (ctx->cancellable)) {
@@ -832,6 +833,7 @@ parse_pdp_list (MMBaseModem *modem,
}
cid = 0;
+ prev_cid = 0;
/* Show all found PDP contexts in debug log */
mm_dbg ("Found '%u' PDP contexts", g_list_length (pdp_list));
@@ -871,14 +873,33 @@ parse_pdp_list (MMBaseModem *modem,
break;
}
- /* PDP with no APN set? we may use that one if not exact match found */
- if (!pdp->apn || !pdp->apn[0]) {
- mm_dbg ("Found PDP context with CID %u and no APN",
- pdp->cid);
- cid = pdp->cid;
+ /* If an open CID was not found yet and the previous CID is not (CID - 1),
+ * this means that (previous CID + 1) is a blank CID that can be used.
+ */
+ if (prev_cid != G_MAXUINT && (prev_cid + 1) < pdp->cid) {
+ mm_dbg ("Found the first unused PDP context with CID %u", (prev_cid + 1));
+ cid = prev_cid + 1;
+
+ /* Set prev_cid to G_MAXUINT to show an open CID was found and only an
+ * exact APN match would change the CID after
+ */
+ prev_cid = G_MAXUINT;
+ } else {
+ /* PDP with no APN set? we may use that one if not exact match found */
+ if (!pdp->apn || !pdp->apn[0]) {
+ mm_dbg ("Found PDP context with CID %u and no APN",
+ pdp->cid);
+ cid = pdp->cid;
+ }
}
}
+ /* Update previous CID value to the current CID for use in the next loop,
+ * unless an unused CID was found
+ */
+ if (prev_cid != G_MAXUINT)
+ prev_cid = pdp->cid;
+
if (ctx->max_cid < pdp->cid)
ctx->max_cid = pdp->cid;
}