diff options
author | Matthew Starr <mstarr@hedonline.com> | 2019-06-12 16:24:04 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2019-09-13 18:13:26 +0000 |
commit | e93b5c1c1f4f5afce4a3476c239e4d9aa15c9b32 (patch) | |
tree | 7a7a0fc7b9f5bce13eae556428f7b9cbeda68cc6 /src/mm-broadband-bearer.c | |
parent | 2ecb96b6adbc288df7c92eac9c87b1d8b1d7c49e (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/mm-broadband-bearer.c')
-rw-r--r-- | src/mm-broadband-bearer.c | 31 |
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; } |