gprs: Only release detachable context on de-attach

Currently there is an issue if the attach state changes and
there are active contexts of which the driver does not
implement the detach_shutdown.
In that case we just release the context (clears CID and
active state), but nothing is signalled on D-Bus or towards
the modem.
Ofono is then out of sync with both the connection manager
and the modem, this manifests itself later on if the modem
changes state of the context, then ofono will not find it
since the CID is cleared, and the connection manager won't
be notified.
This commit is contained in:
Richard Röjfors 2019-09-17 18:25:48 +02:00 committed by Denis Kenzior
parent 336a5b4274
commit da871669a3
1 changed files with 40 additions and 15 deletions

View File

@ -1521,6 +1521,27 @@ static gboolean have_active_contexts(struct ofono_gprs *gprs)
return FALSE;
}
static gboolean have_detachable_active_contexts(struct ofono_gprs *gprs)
{
GSList *l;
for (l = gprs->contexts; l; l = l->next) {
struct pri_context *ctx;
struct ofono_gprs_context *gc;
ctx = l->data;
gc = ctx->context_driver;
if (!gc || !gc->driver->detach_shutdown)
continue;
if (ctx->active == TRUE)
return TRUE;
}
return FALSE;
}
static bool have_read_settings(struct ofono_gprs *gprs)
{
GSList *l;
@ -1535,7 +1556,7 @@ static bool have_read_settings(struct ofono_gprs *gprs)
return false;
}
static void release_active_contexts(struct ofono_gprs *gprs)
static void detach_active_contexts(struct ofono_gprs *gprs)
{
GSList *l;
struct pri_context *ctx;
@ -1599,23 +1620,27 @@ static void gprs_attached_update(struct ofono_gprs *gprs)
* at driver level. "Attached" = TRUE property can't be signalled to
* the applications registered on GPRS properties.
* Active contexts have to be release at driver level.
*
* Skip that for LTE since the condition to be attached on LTE
* is that a context gets activated
*/
if (attached == FALSE) {
release_active_contexts(gprs);
gprs->bearer = -1;
} else if (have_active_contexts(gprs) == TRUE && !on_lte(gprs)) {
/*
* Some times the context activates after a detach event and
* right before an attach. We close it to avoid unexpected open
* contexts.
* Skip that for LTE since the condition to be attached on LTE
* is that a context gets activated
*/
release_active_contexts(gprs);
gprs->flags |= GPRS_FLAG_ATTACHED_UPDATE;
return;
if (have_detachable_active_contexts(gprs) && !on_lte(gprs)) {
detach_active_contexts(gprs);
if (attached == TRUE) {
/*
* Some times the context activates after a detach event
* and right before an attach. We close it to avoid
* unexpected open contexts.
*/
gprs->flags |= GPRS_FLAG_ATTACHED_UPDATE;
return;
}
}
if (attached == FALSE)
gprs->bearer = -1;
gprs_set_attached_property(gprs, attached);
}