Skip to content

Commit

Permalink
Merge branch 'error55' into 'master'
Browse files Browse the repository at this point in the history
Workaround for data call status 55

See merge request mer-core/ofono!250
  • Loading branch information
monich committed Feb 12, 2020
2 parents cd118ce + 4f7398e commit 45424a3
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 22 deletions.
36 changes: 35 additions & 1 deletion ofono/drivers/ril/ril_constants.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2013 Canonical Ltd.
* Copyright (C) 2013-2019 Jolla Ltd.
* Copyright (C) 2013-2020 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -205,10 +205,44 @@ enum ril_data_call_fail_cause {
PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
PDP_FAIL_NSAPI_IN_USE = 0x23,
PDP_FAIL_REGULAR_DEACTIVATION = 0x24,
PDP_FAIL_QOS_NOT_ACCEPTED = 0x25,
PDP_FAIL_NETWORK_FAILURE = 0x26,
PDP_FAIL_UMTS_REACTIVATION_REQ = 0x27,
PDP_FAIL_FEATURE_NOT_SUPP = 0x28,
PDP_FAIL_TFT_SEMANTIC_ERROR = 0x29,
PDP_FAIL_TFT_SYTAX_ERROR = 0x2A,
PDP_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B,
PDP_FAIL_FILTER_SEMANTIC_ERROR = 0x2C,
PDP_FAIL_FILTER_SYTAX_ERROR = 0x2D,
PDP_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E,
PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32,
PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33,
PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
PDP_FAIL_ESM_INFO_NOT_RECEIVED = 0x35,
PDP_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36,
PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
PDP_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
PDP_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
PDP_FAIL_INVALID_TRANSACTION_ID = 0x51,
PDP_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F,
PDP_FAIL_INVALID_MANDATORY_INFO = 0x60,
PDP_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61,
PDP_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
PDP_FAIL_UNKNOWN_INFO_ELEMENT = 0x63,
PDP_FAIL_CONDITIONAL_IE_ERROR = 0x64,
PDP_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
PDP_FAIL_PROTOCOL_ERRORS = 0x6F,
PDP_FAIL_APN_TYPE_CONFLICT = 0x70,
PDP_FAIL_INVALID_PCSCF_ADDR = 0x71,
PDP_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
PDP_FAIL_EMM_ACCESS_BARRED = 0x73,
PDP_FAIL_EMERGENCY_IFACE_ONLY = 0x74,
PDP_FAIL_IFACE_MISMATCH = 0x75,
PDP_FAIL_COMPANION_IFACE_IN_USE = 0x76,
PDP_FAIL_IP_ADDRESS_MISMATCH = 0x77,
PDP_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
PDP_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
PDP_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
PDP_FAIL_DATA_REGISTRATION_FAIL = -2,
PDP_FAIL_SIGNAL_LOST = -3,
Expand Down
91 changes: 70 additions & 21 deletions ofono/drivers/ril/ril_data.c
@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2016-2020 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -29,6 +29,8 @@
#include <grilio_parser.h>
#include <grilio_request.h>

#include "common.h" /* ACCESS_TECHNOLOGY_EUTRAN */

/* Yes, it does sometimes take minutes in roaming */
#define SETUP_DATA_CALL_TIMEOUT (300*1000) /* ms */

Expand Down Expand Up @@ -115,6 +117,7 @@ struct ril_data_priv {
gulong io_event_id[IO_EVENT_COUNT];
gulong settings_event_id[SETTINGS_EVENT_COUNT];
GHashTable* grab;
gboolean downgraded_tech; /* Status 55 workaround */
};

enum ril_data_signal {
Expand Down Expand Up @@ -815,6 +818,31 @@ static gboolean ril_data_call_setup_retry(void *user_data)
return G_SOURCE_REMOVE;
}

static gboolean ril_data_call_retry(struct ril_data_request_setup *setup)
{
struct ril_data_request *req = &setup->req;
const struct ril_data_options *options = &req->data->priv->options;

if (setup->retry_count < options->data_call_retry_limit) {
req->pending_id = 0;
GASSERT(!setup->retry_delay_id);
if (!setup->retry_count) {
/* No delay first time */
setup->retry_count++;
DBG("silent retry %u out of %u", setup->retry_count,
options->data_call_retry_limit);
req->submit(req);
} else {
const guint ms = options->data_call_retry_delay_ms;
DBG("silent retry scheduled in %u ms", ms);
setup->retry_delay_id = g_timeout_add(ms,
ril_data_call_setup_retry, setup);
}
return TRUE;
}
return FALSE;
}

static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
const void *data, guint len, void *user_data)
{
Expand All @@ -839,33 +867,49 @@ static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
}
}

if (call && call->status == PDP_FAIL_ERROR_UNSPECIFIED &&
setup->retry_count < priv->options.data_call_retry_limit) {
if (call) {
switch (call->status) {
/*
* According to the comment from ril.h we should silently
* retry. First time we retry immediately and if that doedsn't
* retry. First time we retry immediately and if that doesn't
* work, then after certain delay.
*/
req->pending_id = 0;
GASSERT(!setup->retry_delay_id);
if (!setup->retry_count) {
setup->retry_count++;
DBG("silent retry %u out of %u", setup->retry_count,
priv->options.data_call_retry_limit);
req->submit(req);
} else {
guint ms = priv->options.data_call_retry_delay_ms;
DBG("silent retry scheduled in %u ms", ms);
setup->retry_delay_id = g_timeout_add(ms,
ril_data_call_setup_retry, setup);
case PDP_FAIL_ERROR_UNSPECIFIED:
if (ril_data_call_retry(setup)) {
ril_data_call_list_free(list);
return;
}
break;
/*
* With some networks we sometimes start getting error 55
* (Multiple PDN connections for a given APN not allowed)
* when trying to setup an LTE data call and this error
* doesn't go away until we successfully establish a data
* call over 3G. Then we can switch back to LTE.
*/
case PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED:
if (priv->network->data.access_tech ==
ACCESS_TECHNOLOGY_EUTRAN &&
!priv->downgraded_tech) {
DBG("downgrading preferred technology");
priv->downgraded_tech = TRUE;
ril_data_manager_check_network_mode(priv->dm);
/* And let this call fail */
}
break;
default:
break;
}
ril_data_call_list_free(list);
return;
}

ril_data_request_completed(req);

if (call && call->status == PDP_FAIL_NONE) {
if (priv->downgraded_tech) {
DBG("done with status 55 workaround");
priv->downgraded_tech = FALSE;
ril_data_manager_check_network_mode(priv->dm);
}
if (ril_data_call_list_move_calls(self->data_calls, list) > 0) {
DBG("data call(s) added");
ril_data_signal_emit(self, SIGNAL_CALLS_CHANGED);
Expand Down Expand Up @@ -1151,6 +1195,11 @@ static struct ril_data_request *ril_data_allow_new(struct ril_data *data,
/*==========================================================================*
* ril_data
*==========================================================================*/
static enum ofono_radio_access_mode ril_data_max_mode(struct ril_data *self)
{
return self->priv->downgraded_tech ? OFONO_RADIO_ACCESS_MODE_UMTS :
OFONO_RADIO_ACCESS_MODE_ANY;
}

gulong ril_data_add_allow_changed_handler(struct ril_data *self,
ril_data_cb_t cb, void *arg)
Expand Down Expand Up @@ -1684,7 +1733,7 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)

ril_network_set_max_pref_mode(network,
(network == lte_network) ?
OFONO_RADIO_ACCESS_MODE_ANY :
ril_data_max_mode(data) :
OFONO_RADIO_ACCESS_MODE_GSM,
FALSE);
}
Expand All @@ -1694,7 +1743,7 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)
for (l= self->data_list; l; l = l->next) {
struct ril_data *data = l->data;
ril_network_set_max_pref_mode(data->priv->network,
OFONO_RADIO_ACCESS_MODE_ANY, FALSE);
ril_data_max_mode(data), FALSE);
}
}
}
Expand Down Expand Up @@ -1723,7 +1772,7 @@ static void ril_data_manager_switch_data_on(struct ril_data_manager *self,

if (ril_data_manager_handover(self)) {
ril_network_set_max_pref_mode(priv->network,
OFONO_RADIO_ACCESS_MODE_ANY, TRUE);
ril_data_max_mode(data), TRUE);
}

if (priv->options.allow_data == RIL_ALLOW_DATA_ENABLED) {
Expand Down

0 comments on commit 45424a3

Please sign in to comment.