Compare commits

...

11 Commits

Author SHA1 Message Date
Slava Monich
08bae57a2b Merge branch 'jb49714' into 'master'
Register settings atom as soon as we have IMSI

See merge request mer-core/ofono!262
2020-04-23 09:08:23 +00:00
Slava Monich
1915aeda76 [ril] Register settings atom as soon as we have IMSI. Fixes JB#49714
There's no need to wait for modem to get powered on. This is just a user
setting - if it can't be applied right away, it will be applied later at
appropriate time.
2020-04-23 04:20:28 +03:00
Slava Monich
51bfb17cbc Merge branch 'modem_offline' into 'master'
Take modem offline when ril_modem is deleted

See merge request mer-core/ofono!260
2020-04-01 16:33:23 +00:00
Slava Monich
a83b553032 [ril] Stop repeating requests on RADIO_NOT_AVAILABLE. JB#49471
If the modem is powered off, this error is repeated indefinitely,
causing unnecessary wakeups.
2020-03-30 21:19:40 +03:00
Slava Monich
ec00abd62d [ril] Tweaked power state confirmation logic. JB#49471
Changed ril_radio_confirm_power_on() to send RADIO_POWER request even if
we think that modem is powered on. Some RILs change power state without
letting us know and that's what this function is for - to make sure that
power is on when we think that it's on.
2020-03-29 01:38:58 +02:00
Slava Monich
80924d5787 [ril] Take modem offline when ril_modem is deleted. JB#49471
Also, mobile data need to be disallowed before deleting the modem
object, so that power keep-on request could be submitted before
bringing the modem offline, to keep power on while data call is
being deactivated (if there was one).
2020-03-29 01:34:39 +02:00
Slava Monich
2bdd05aa31 [ril] Fixed ref vs unref mixup.
RilRadioCapsManager was never freed :/

That was leaving 472 bytes in 8 blocks still reachable on exit.
2020-03-20 18:30:40 +02:00
Slava Monich
544f02e5a2 Merge branch 'jb49322' into 'master'
Improve network registration process

See merge request mer-core/ofono!256
2020-03-16 19:05:22 +00:00
Denis Grigorev
6d4638f9bf [ril] Do not trigger automatic PLMN selection if not needed. JB#49322
On some devices SET_NETWORK_SELECTION_AUTOMATIC takes significant time,
because it triggers a complete scan of available PLMNs. If applied, this
commit will make ofono to issue QUERY_NETWORK_SELECTION_MODE first and
check whether the mode actually needs to be changed.
2020-03-16 20:24:14 +03:00
Slava Monich
6584919e9d Merge branch 'configurable-netsel-timeout' into 'master'
Add networkSelectionTimeout config option

See merge request mer-core/ofono!257
2020-03-12 18:48:50 +00:00
Denis Grigorev
34fb44f4eb [ril] Add networkSelectionTimeout config option. JB#49322
On some devices (such as BQ Aquarius NS208) SET_NETWORK_SELECTION_AUTOMATIC
takes a long time and ofono fails with timeout. If applied, this commit
will make network selection timeout configurable.
2020-03-12 18:02:24 +03:00
10 changed files with 138 additions and 33 deletions

View File

@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2016-2020 Jolla Ltd.
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* 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
@@ -344,11 +345,24 @@ static void ril_cell_info_set_rate_cb(GRilIoChannel *io, int status,
self->set_rate_id = 0;
}
static gboolean ril_cell_info_retry(GRilIoRequest* request, int ril_status,
const void* response_data, guint response_len, void* user_data)
{
switch (ril_status) {
case RIL_E_SUCCESS:
case RIL_E_RADIO_NOT_AVAILABLE:
return FALSE;
default:
return TRUE;
}
}
static void ril_cell_info_query(struct ril_cell_info *self)
{
GRilIoRequest *req = grilio_request_new();
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
grilio_request_set_retry_func(req, ril_cell_info_retry);
grilio_channel_cancel_request(self->io, self->query_id, FALSE);
self->query_id = grilio_channel_send_request_full(self->io, req,
RIL_REQUEST_GET_CELL_INFO_LIST, ril_cell_info_list_cb,
@@ -362,6 +376,7 @@ static void ril_cell_info_set_rate(struct ril_cell_info *self)
(self->update_rate_ms > 0) ? self->update_rate_ms : INT_MAX);
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
grilio_request_set_retry_func(req, ril_cell_info_retry);
grilio_channel_cancel_request(self->io, self->set_rate_id, FALSE);
self->set_rate_id = grilio_channel_send_request_full(self->io, req,
RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE,

View File

@@ -382,6 +382,12 @@ enum ril_unsolicited_response_filter {
RIL_UR_DATA_CALL_DORMANCY_CHANGED = 0x04
};
/* RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE result */
enum ril_network_selection_mode {
RIL_NETWORK_SELECTION_MODE_AUTO = 0,
RIL_NETWORK_SELECTION_MODE_MANUAL = 1
};
#endif /*__RIL_CONSTANTS_H */
/*

View File

@@ -218,22 +218,21 @@ static void ril_modem_schedule_online_check(struct ril_modem_data *md)
static void ril_modem_update_radio_settings(struct ril_modem_data *md)
{
struct ril_modem *m = &md->modem;
if (m->radio->state == RADIO_STATE_ON && md->watch->imsi) {
struct ofono_radio_settings *rs = ril_modem_radio_settings(m);
if (md->watch->imsi) {
/* radio-settings.c assumes that IMSI is available */
if (!ril_modem_radio_settings(m)) {
if (!rs) {
DBG_(md, "initializing radio settings interface");
ofono_radio_settings_create(m->ofono, 0,
RILMODEM_DRIVER, md);
}
} else if (rs) {
DBG_(md, "removing radio settings interface");
ofono_radio_settings_remove(rs);
} else {
/* ofono core may remove radio settings atom internally */
struct ofono_radio_settings *rs = ril_modem_radio_settings(m);
if (rs) {
DBG_(md, "removing radio settings interface");
ofono_radio_settings_remove(rs);
} else {
DBG_(md, "radio settings interface is already gone");
}
DBG_(md, "radio settings interface is already gone");
}
}
@@ -242,7 +241,6 @@ static void ril_modem_radio_state_cb(struct ril_radio *radio, void *data)
struct ril_modem_data *md = data;
GASSERT(md->modem.radio == radio);
ril_modem_update_radio_settings(md);
ril_modem_update_online_state(md);
}
@@ -424,6 +422,7 @@ static void ril_modem_remove(struct ofono_modem *ofono)
ril_radio_remove_handler(modem->radio, md->radio_state_event_id);
ril_radio_power_off(modem->radio, RADIO_POWER_TAG(md));
ril_radio_set_online(modem->radio, FALSE);
ril_radio_unref(modem->radio);
ril_sim_settings_unref(modem->sim_settings);

View File

@@ -23,7 +23,6 @@
#include "common.h"
#include "simutil.h"
#define REGISTRATION_TIMEOUT (100*1000) /* ms */
#define REGISTRATION_MAX_RETRIES (2)
enum ril_netreg_events {
@@ -53,6 +52,7 @@ struct ril_netreg {
guint current_operator_id;
gulong ril_event_id[NETREG_RIL_EVENT_COUNT];
gulong network_event_id[NETREG_NETWORK_EVENT_COUNT];
int network_selection_timeout;
};
struct ril_netreg_cbd {
@@ -301,18 +301,55 @@ static void ril_netreg_register_cb(GRilIoChannel *io, int status,
}
}
static void ril_netreg_set_register_auto(struct ril_netreg *nd,
ofono_netreg_register_cb_t cb, void *data)
{
GRilIoRequest *req = grilio_request_new();
ofono_info("nw select automatic");
grilio_request_set_timeout(req, nd->network_selection_timeout);
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
grilio_queue_send_request_full(nd->q, req,
RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
ril_netreg_register_cb, ril_netreg_cbd_free,
ril_netreg_cbd_new(nd, cb, data));
grilio_request_unref(req);
}
static void ril_netreg_query_register_auto_cb(GRilIoChannel *io, int status,
const void *data, guint len,
void *user_data)
{
struct ril_netreg_cbd *cbd = user_data;
ofono_netreg_register_cb_t cb = cbd->cb.reg;
if (status == RIL_E_SUCCESS) {
GRilIoParser rilp;
gint32 net_mode;
grilio_parser_init(&rilp, data, len);
if (grilio_parser_get_int32(&rilp, NULL) /* Array length */ &&
grilio_parser_get_int32(&rilp, &net_mode) &&
net_mode == RIL_NETWORK_SELECTION_MODE_AUTO) {
struct ofono_error error;
ofono_info("nw selection is already auto");
cb(ril_error_ok(&error), cbd->data);
return;
}
}
ril_netreg_set_register_auto(cbd->nd, cb, cbd->data);
}
static void ril_netreg_register_auto(struct ofono_netreg *netreg,
ofono_netreg_register_cb_t cb, void *data)
{
struct ril_netreg *nd = ril_netreg_get_data(netreg);
GRilIoRequest *req = grilio_request_new();
ofono_info("nw select automatic");
grilio_request_set_timeout(req, REGISTRATION_TIMEOUT);
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
grilio_queue_send_request_full(nd->q, req,
RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
ril_netreg_register_cb, ril_netreg_cbd_free,
RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE,
ril_netreg_query_register_auto_cb, ril_netreg_cbd_free,
ril_netreg_cbd_new(nd, cb, data));
grilio_request_unref(req);
}
@@ -327,7 +364,7 @@ static void ril_netreg_register_manual(struct ofono_netreg *netreg,
ofono_info("nw select manual: %s%s%s", mcc, mnc, suffix);
grilio_request_append_format(req, "%s%s%s", mcc, mnc, suffix);
grilio_request_set_timeout(req, REGISTRATION_TIMEOUT);
grilio_request_set_timeout(req, nd->network_selection_timeout);
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
grilio_queue_send_request_full(nd->q, req,
RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
@@ -563,6 +600,7 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
nd->network_selection_manual_0 = config->network_selection_manual_0;
nd->signal_strength_dbm_weak = config->signal_strength_dbm_weak;
nd->signal_strength_dbm_strong = config->signal_strength_dbm_strong;
nd->network_selection_timeout = config->network_selection_timeout;
ofono_netreg_set_data(netreg, nd);
nd->timer_id = g_idle_add(ril_netreg_register, nd);

View File

@@ -2,7 +2,7 @@
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
*
* 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
@@ -419,6 +419,18 @@ static void ril_network_poll_data_state_cb(GRilIoChannel *io, int req_status,
}
}
static gboolean ril_network_retry(GRilIoRequest* request, int ril_status,
const void* response_data, guint response_len, void* user_data)
{
switch (ril_status) {
case RIL_E_SUCCESS:
case RIL_E_RADIO_NOT_AVAILABLE:
return FALSE;
default:
return TRUE;
}
}
static guint ril_network_poll_and_retry(struct ril_network *self, guint id,
int code, GRilIoChannelResponseFunc fn)
{
@@ -431,6 +443,7 @@ static guint ril_network_poll_and_retry(struct ril_network *self, guint id,
GRilIoRequest *req = grilio_request_new();
grilio_request_set_retry(req, RIL_RETRY_SECS*1000, -1);
grilio_request_set_retry_func(req, ril_network_retry);
id = grilio_queue_send_request_full(priv->q, req, code, fn,
NULL, self);
grilio_request_unref(req);
@@ -998,22 +1011,22 @@ static void ril_network_query_pref_mode_cb(GRilIoChannel *io, int status,
struct ril_network_priv *priv = self->priv;
const enum ofono_radio_access_mode pref_mode = self->pref_mode;
/* This request never fails because in case of error it gets retried */
GASSERT(status == RIL_E_SUCCESS);
GASSERT(priv->query_rat_id);
priv->query_rat_id = 0;
priv->rat = ril_network_parse_pref_resp(data, len);
self->pref_mode = ril_network_rat_to_mode(priv->rat);
DBG_(self, "rat mode %d (%s)", priv->rat,
if (status == RIL_E_SUCCESS) {
priv->rat = ril_network_parse_pref_resp(data, len);
self->pref_mode = ril_network_rat_to_mode(priv->rat);
DBG_(self, "rat mode %d (%s)", priv->rat,
ofono_radio_access_mode_to_string(self->pref_mode));
if (self->pref_mode != pref_mode) {
ril_network_emit(self, SIGNAL_PREF_MODE_CHANGED);
}
if (self->pref_mode != pref_mode) {
ril_network_emit(self, SIGNAL_PREF_MODE_CHANGED);
}
if (ril_network_can_set_pref_mode(self)) {
ril_network_check_pref_mode(self, FALSE);
if (ril_network_can_set_pref_mode(self)) {
ril_network_check_pref_mode(self, FALSE);
}
}
}
@@ -1023,6 +1036,7 @@ static void ril_network_query_pref_mode(struct ril_network *self)
GRilIoRequest *req = grilio_request_new();
grilio_request_set_retry(req, RIL_RETRY_SECS*1000, -1);
grilio_request_set_retry_func(req, ril_network_retry);
grilio_queue_cancel_request(priv->q, priv->query_rat_id, FALSE);
priv->query_rat_id = grilio_queue_send_request_full(priv->q, req,
RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE,

View File

@@ -73,6 +73,7 @@
#define RILMODEM_DEFAULT_LTE_MODE PREF_NET_TYPE_LTE_GSM_WCDMA
#define RILMODEM_DEFAULT_UMTS_MODE PREF_NET_TYPE_GSM_WCDMA_AUTO
#define RILMODEM_DEFAULT_NETWORK_MODE_TIMEOUT (20*1000) /* ms */
#define RILMODEM_DEFAULT_NETWORK_SELECTION_TIMEOUT (100*1000) /* ms */
#define RILMODEM_DEFAULT_DBM_WEAK (-100) /* very weak, 0.0000000001 mW */
#define RILMODEM_DEFAULT_DBM_STRONG (-60) /* strong signal, 0.000001 mW */
#define RILMODEM_DEFAULT_ENABLE_VOICECALL TRUE
@@ -134,6 +135,7 @@
#define RILCONF_LTE_MODE "lteNetworkMode"
#define RILCONF_UMTS_MODE "umtsNetworkMode"
#define RILCONF_NETWORK_MODE_TIMEOUT "networkModeTimeout"
#define RILCONF_NETWORK_SELECTION_TIMEOUT "networkSelectionTimeout"
#define RILCONF_SIGNAL_STRENGTH_RANGE "signalStrengthRange"
#define RILCONF_UICC_WORKAROUND "uiccWorkaround"
#define RILCONF_ECCLIST_FILE "ecclistFile"
@@ -362,6 +364,7 @@ static void ril_plugin_remove_slot_handler(ril_slot *slot, int id)
static void ril_plugin_shutdown_slot(ril_slot *slot, gboolean kill_io)
{
if (slot->modem) {
ril_data_allow(slot->data, RIL_DATA_ROLE_NONE);
ril_modem_delete(slot->modem);
/* The above call is expected to result in
* ril_plugin_modem_removed getting called
@@ -1193,6 +1196,8 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
config->lte_network_mode = RILMODEM_DEFAULT_LTE_MODE;
config->umts_network_mode = RILMODEM_DEFAULT_UMTS_MODE;
config->network_mode_timeout = RILMODEM_DEFAULT_NETWORK_MODE_TIMEOUT;
config->network_selection_timeout =
RILMODEM_DEFAULT_NETWORK_SELECTION_TIMEOUT;
config->signal_strength_dbm_weak = RILMODEM_DEFAULT_DBM_WEAK;
config->signal_strength_dbm_strong = RILMODEM_DEFAULT_DBM_STRONG;
config->empty_pin_query = RILMODEM_DEFAULT_EMPTY_PIN_QUERY;
@@ -1565,6 +1570,14 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
config->network_mode_timeout);
}
/* networkSelectionTimeout */
if (ril_config_get_integer(file, group,
RILCONF_NETWORK_SELECTION_TIMEOUT,
&config->network_selection_timeout)) {
DBG("%s: " RILCONF_NETWORK_SELECTION_TIMEOUT " %d", group,
config->network_selection_timeout);
}
/* signalStrengthRange */
ints = ril_config_get_ints(file, group, RILCONF_SIGNAL_STRENGTH_RANGE);
if (gutil_ints_get_count(ints) == 2) {

View File

@@ -241,7 +241,19 @@ static void ril_radio_power_request(struct ril_radio *self, gboolean on,
void ril_radio_confirm_power_on(struct ril_radio *self)
{
if (G_LIKELY(self) && ril_radio_power_should_be_on(self)) {
ril_radio_power_request(self, TRUE, TRUE);
struct ril_radio_priv *priv = self->priv;
if (priv->pending_id) {
if (!priv->next_state) {
/* Wait for the pending request to complete */
priv->next_state_valid = TRUE;
priv->next_state = TRUE;
DBG_(self, "on (queued)");
}
} else {
DBG_(self, "on");
ril_radio_submit_power_request(self, TRUE);
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2017-2018 Jolla Ltd.
* Copyright (C) 2017-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
@@ -1414,7 +1414,7 @@ RilRadioCapsManager *ril_radio_caps_manager_ref(RilRadioCapsManager *self)
void ril_radio_caps_manager_unref(RilRadioCapsManager *self)
{
if (G_LIKELY(self)) {
g_object_ref(RADIO_CAPS_MANAGER(self));
g_object_unref(RADIO_CAPS_MANAGER(self));
}
}

View File

@@ -237,6 +237,13 @@ socket=/dev/socket/rild
#
#networkModeTimeout=20000
# Timeout for RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC and
# RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, in milliseconds.
#
# Default 100000 (100 seconds)
#
#networkSelectionTimeout=100000
# Comma-separated signal strength range, in dBm.
#
# These values are used for translating dBm values returned by the modem in

View File

@@ -55,6 +55,7 @@ struct ril_slot_config {
enum ril_pref_net_type lte_network_mode;
enum ril_pref_net_type umts_network_mode;
int network_mode_timeout;
int network_selection_timeout;
int signal_strength_dbm_weak;
int signal_strength_dbm_strong;
gboolean query_available_band_mode;