Bearer management upon out-of-coverage condition leading to re-connection failure: `failed to connect modem: Bearer currently being disconnected`
It looks there is an issue in then management of out-of-coverage condition (i.e MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN
).
As a matter of fact, once timer _MMBaseBearerPrivate::deferred_3gpp_unregistration_id
timer has expired, any NetworkManager attempt to restore the data connectivity (by triggering the Simple connect
procedure) fails this way:
Feb 25 17:40:16 ... ModemManager[404]: Connected bearer not registered in 3GPP network
Feb 25 17:40:32 ... ModemManager[404]: Forcing bearer disconnection, not registered in 3GPP network
...
Feb 25 17:40:43 ... ModemManager[404]: Simple connect started...
Feb 25 17:40:43 ... ModemManager[404]: Simple connect state (4/8): Wait to get fully enabled
Feb 25 17:40:43 ... ModemManager[404]: Simple connect state (5/8): Register
Feb 25 17:40:43 ... ModemManager[404]: Simple connect state (6/8): Bearer
Feb 25 17:40:43 ... NetworkManager[378]: <warn> [1614274843.5319] modem-broadband[ttyACM0]: failed to connect modem: Bearer currently being disconnected
The relevant setup details are listed herafter.
ModemManager | NetworkManager | Modem |
---|---|---|
1.12.4 + patch | 1.10.6 | u-blox LARA-R2... |
The ModemManager has been patched with the following changes which has entered a more recent release and it is required to have _MMBaseBearerPrivate::deferred_3gpp_unregistration_id
timer activated upon out-of-coverage:
@@ -1515,7 +1525,8 @@ __iface_modem_update_state_internal (MMIfaceModem *self,
/* While connected we don't want registration status changes to change
* the modem's state away from CONNECTED. */
- if ((new_state == MM_MODEM_STATE_SEARCHING ||
+ if ((new_state == MM_MODEM_STATE_ENABLED ||
+ new_state == MM_MODEM_STATE_SEARCHING ||
new_state == MM_MODEM_STATE_REGISTERED) &&
bearer_list &&
old_state > MM_MODEM_STATE_REGISTERED) {
The main doubt is around _MMBaseBearerPrivate::ignore_disconnection_reports
, which is set to TRUE in case of PPP, and, as a consequence, it denies propagation of bearer disconnection event, so that the modem object stays in "disconnecting" state forever.
file | function type | function name | comments |
---|---|---|---|
mm-base-bearer.c | [callback] | deferred_3gpp_unregistration_cb() |
timer driven |
mm-base-bearer.c | ...> mm_base_bearer_disconnect_force() |
||
mm-base-bearer.c | ......> bearer_update_status(DISCONNECTING) |
||
mm-broadband-bearer.c | .........> disconnect() |
||
mm-base-bearer.c | [callback] | .........> disconnect_force_ready() |
called upon {{disconnect()}} completion |
mm-base-bearer.c | ............> mm_base_bearer_report_connection_status(DISCONNECTED) |
depends on {{ignore_disconnection_reports}}, if TRUE the flow stops here and below calls do not happen | |
mm-broadband-bearer.c | ...............> report_connection_status() |
||
mm-broadband-bearer.c | ..................> reset_bearer_connection() |
||
mm-base-bearer.c | ..................> report_connection_status() |
||
mm-base-bearer.c | .....................> bearer_update_status (MM_BEARER_STATUS_DISCONNECTED) |
this propagates to mm-iface-modem domain | |
mm-iface-modem.c | [callback] | .....................> bearer_status_changed() |
driven by bearer connection status change |
It has been tested that, adding below line in deferred_3gpp_unregistration_cb()
before calling mm_base_bearer_disconnect_force()
solves the issue
self->priv->ignore_disconnection_reports = FALSE
Nevertheless, I'm not sure whether this may cause or not some side-effects. I also wonder whether the above change (i.e. self->priv->ignore_disconnection_reports = FALSE
) has to be moved into mm_base_bearer_disconnect_force()
or not.
That's why I'm submitting the ticket. Thanks for your support!