Compare commits

...

24 Commits

Author SHA1 Message Date
chriadam
4e067fa827 Merge branch 'jb50214' into 'master'
[ofono] Don't support '.' as a DTMF pause character. Contributes to JB#50214

See merge request mer-core/ofono!271
2020-07-13 00:36:38 +00:00
Chris Adams
2ee5e4c827 [ofono] Don't support '.' as a DTMF pause character. Contributes to JB#50214 2020-07-13 10:35:30 +10:00
Niels Breet
1366e426be Merge branch 'jb49681' into 'master'
[aarch64] Use macros for unitdir. Contributes to JB#49681

See merge request mer-core/ofono!272
2020-07-08 13:19:30 +00:00
Niels Breet
586c9b9262 [aarch64] Use macros for unitdir. Contributes to JB#49681 2020-07-08 13:19:30 +00:00
Slava Monich
83554e071a Merge branch 'cbs_retry' into 'master'
Tweak CBS request retry logic

See merge request mer-core/ofono!270
2020-06-25 21:12:01 +00:00
Slava Monich
dc41c2d003 [ril] Allow CBS PDU arrive from RIL as a plain blob. JB#5761
I swear I've seen such cases!
2020-06-25 20:21:09 +03:00
Slava Monich
550d41ae37 [ril] Tweaked CBS request retry logic. JB#5761
There's no need for RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, since we
are not using its result anyway. Better just register for notifications
which would simply never arrive if CBS doesn't work at all.

Important requests, however, better be retried on RIL_E_INVALID_STATE.
2020-06-25 20:05:31 +03:00
Slava Monich
60e4246d93 Merge branch 'cbs' into 'master'
Allow the last CBS fragment to be truncated.

See merge request mer-core/ofono!269
2020-06-19 13:18:21 +00:00
Slava Monich
50619607b0 [cbs] Allow the last CBS fragment to be truncated. JB#5761
That does happen in real life.
2020-06-18 11:59:06 +03:00
Slava Monich
98b357f365 Merge branch 'recap' into 'master'
Refactring radio caps code

See merge request mer-core/ofono!261
2020-06-17 16:00:13 +00:00
Denis Grigorev
56c488d10c [ril] Select the best network for LTE. JB#49391
The radio caps manager will not do anything until the roles are assigned
to modems, so data manager must select the modem with highest capabilities
for LTE instead of the first one.
2020-06-17 18:03:40 +03:00
Denis Grigorev
944cd603e8 [ril] Fix typo. JB#49391 2020-06-17 17:52:41 +03:00
Denis Grigorev
77be0d5e98 [ril] Assert the network mode at startup. JB#49391
At startup, the device may have an inconsistency between data and voice
network modes, so it needs to be asserted.
2020-06-17 17:52:15 +03:00
Denis Grigorev
d8dd20092c [ril] Fix a memory leak in ril_plugin_shutdown_slot(). JB#49391 2020-06-17 17:49:11 +03:00
Slava Monich
c7faa21172 [ril] Refactored radio caps code. JB#49391 2020-06-13 13:29:24 +03:00
Slava Monich
98ffc61a03 Merge branch 'oemraw-access' into 'master'
OemRaw access control

See merge request mer-core/ofono!265
2020-06-11 22:08:55 +00:00
Slava Monich
f2b1625872 Merge branch 'scan' into 'master'
Workaround for bogus operator names in network scan

See merge request mer-core/ofono!152
2020-06-11 22:06:17 +00:00
Slava Monich
2d5a22284e Merge branch 'cbs' into 'master'
Fix parsing of NEW_BROADCAST_SMS packet

See merge request mer-core/ofono!268
2020-06-10 21:09:47 +00:00
Slava Monich
9d742180ab [ril] Fixed parsing of NEW_BROADCAST_SMS packet. JB#5761
It's 4-byte length followed by the specified number of bytes
zero-padded to 4-byte boundary. Kind of like a string.
2020-06-10 15:01:59 +03:00
Slava Monich
f8b0ccc1b4 [ril] Workaround for bogus operator names in network scan. JB#49900
Some RILs (e.g. Sony Xperia X, MediaTek) report bogus operator names
in response to QUERY_AVAILABLE_NETWORKS request. We can make user's
life easier by looking up possible operator name in MBPI database
based on MCC and MNC (assuming those are reported correctly) in case
if weirdness is detected.

To turn this feature on, add this to /etc/ofono/ril_subscription.conf
config file:

replaceStrangeOperatorNames=true
2020-06-05 20:15:35 +03:00
Slava Monich
6dfce4b5e9 [ril] Housekeeping 2020-05-15 15:24:03 +03:00
Slava Monich
4ec3568d71 [ril] Added access control for OemRaw interface. JB#49309 2020-05-15 15:22:09 +03:00
Slava Monich
9b2b7127ef [unit] Added test for OemRaw access control. JB#49309 2020-05-15 15:20:35 +03:00
Slava Monich
1053577376 [ofono] Add OemRaw to D-Bus access control framework. JB#49309
Even though it's RIL specific, it makes sense to reuse the
existing access control mechanism.
2020-05-15 15:19:51 +03:00
26 changed files with 1196 additions and 660 deletions

View File

@@ -189,8 +189,8 @@ CFLAGS="$CFLAGS $GLIBUTIL_CFLAGS"
LIBS="$LIBS $GLIBUTIL_LIBS"
if (test "${enable_sailfish_rilmodem}" = "yes"); then
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.35, dummy=yes,
AC_MSG_ERROR(libgrilio >= 1.0.35 is required))
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.38, dummy=yes,
AC_MSG_ERROR(libgrilio >= 1.0.38 is required))
PKG_CHECK_MODULES(LIBMCE, libmce-glib >= 1.0.6, dummy=yes,
AC_MSG_ERROR(libmce-glib >= 1.0.6 is required))
CFLAGS="$CFLAGS $GRILIO_CFLAGS $LIBMCE_CFLAGS"

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2017 Jolla Ltd.
* Copyright (C) 2015-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
@@ -24,6 +24,7 @@ struct ril_cbs {
GRilIoChannel *io;
GRilIoQueue *q;
char *log_prefix;
guint register_id;
gulong event_id;
};
@@ -51,6 +52,12 @@ static struct ril_cbs_cbd *ril_cbs_cbd_new(struct ril_cbs *cd,
return cbd;
}
static gboolean ril_cbs_retry(GRilIoRequest *request, int ril_status,
const void *resp_data, guint resp_len, void *user_data)
{
return ril_status == RIL_E_INVALID_STATE;
}
static void ril_cbs_request_activation(struct ril_cbs *cd,
gboolean activate, GRilIoChannelResponseFunc response,
GDestroyNotify destroy, void* user_data)
@@ -61,6 +68,9 @@ static void ril_cbs_request_activation(struct ril_cbs *cd,
grilio_request_append_int32(req, activate ? 0 :1);
DBG_(cd, "%sactivating CB", activate ? "" : "de");
grilio_request_set_retry_func(req, ril_cbs_retry);
grilio_request_set_retry(req, RIL_CBS_CHECK_RETRY_MS,
RIL_CBS_CHECK_RETRY_COUNT);
grilio_queue_send_request_full(cd->q, req,
RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION,
response, destroy, user_data);
@@ -97,6 +107,9 @@ static void ril_cbs_set_config(struct ril_cbs *cd, const char *topics,
}
DBG_(cd, "configuring CB");
grilio_request_set_retry_func(req, ril_cbs_retry);
grilio_request_set_retry(req, RIL_CBS_CHECK_RETRY_MS,
RIL_CBS_CHECK_RETRY_COUNT);
grilio_queue_send_request_full(cd->q, req,
RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG,
response, destroy, user_data);
@@ -144,27 +157,41 @@ static void ril_cbs_notify(GRilIoChannel *io, guint code,
const void *data, guint len, void *user_data)
{
struct ril_cbs *cd = user_data;
GRilIoParser rilp;
guint32 pdu_len;
GASSERT(code == RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS);
DBG_(cd, "%u bytes", len);
ofono_cbs_notify(cd->cbs, data, len);
grilio_parser_init(&rilp, data, len);
if (grilio_parser_get_uint32(&rilp, &pdu_len)) {
const void* pdu = grilio_parser_get_bytes(&rilp, pdu_len);
/*
* By default assume that it's a length followed by the
* binary PDU data.
*/
if (pdu && grilio_parser_bytes_remaining(&rilp) < 4) {
DBG_(cd, "%u bytes", pdu_len);
ofono_cbs_notify(cd->cbs, pdu, pdu_len);
} else {
/*
* But I've seen cell broadcasts arriving without
* the length, simply as a blob.
*/
ofono_cbs_notify(cd->cbs, data, len);
}
}
}
static void ril_cbs_probe_done_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
static gboolean ril_cbs_register(void *user_data)
{
struct ril_cbs *cd = user_data;
if (status == RIL_E_SUCCESS) {
DBG_(cd, "registering for CB");
cd->event_id = grilio_channel_add_unsol_event_handler(cd->io,
ril_cbs_notify, RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS,
cd);
ofono_cbs_register(cd->cbs);
} else {
DBG_(cd, "failed to query CB config");
ofono_cbs_remove(cd->cbs);
}
DBG_(cd, "registering for CB");
cd->register_id = 0;
cd->event_id = grilio_channel_add_unsol_event_handler(cd->io,
ril_cbs_notify, RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, cd);
ofono_cbs_register(cd->cbs);
return G_SOURCE_REMOVE;
}
static int ril_cbs_probe(struct ofono_cbs *cbs, unsigned int vendor,
@@ -172,7 +199,6 @@ static int ril_cbs_probe(struct ofono_cbs *cbs, unsigned int vendor,
{
struct ril_modem *modem = data;
struct ril_cbs *cd = g_try_new0(struct ril_cbs, 1);
GRilIoRequest* req = grilio_request_new();
ofono_cbs_set_data(cbs, cd);
cd->log_prefix = (modem->log_prefix && modem->log_prefix[0]) ?
@@ -182,20 +208,7 @@ static int ril_cbs_probe(struct ofono_cbs *cbs, unsigned int vendor,
DBG_(cd, "");
cd->io = grilio_channel_ref(ril_modem_io(modem));
cd->q = grilio_queue_new(cd->io);
/*
* RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG often fails at startup
* especially if other RIL requests are running in parallel. We may
* have to retry a few times. Also, make it blocking in order to
* improve the chance of success.
*/
grilio_request_set_retry(req, RIL_CBS_CHECK_RETRY_MS,
RIL_CBS_CHECK_RETRY_COUNT);
grilio_request_set_blocking(req, TRUE);
grilio_queue_send_request_full(cd->q, req,
RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG,
ril_cbs_probe_done_cb, NULL, cd);
grilio_request_unref(req);
cd->register_id = g_idle_add(ril_cbs_register, cd);
return 0;
}
@@ -204,6 +217,9 @@ static void ril_cbs_remove(struct ofono_cbs *cbs)
struct ril_cbs *cd = ofono_cbs_get_data(cbs);
DBG_(cd, "");
if (cd->register_id) {
g_source_remove(cd->register_id);
}
ofono_cbs_set_data(cbs, NULL);
grilio_channel_remove_handler(cd->io, cd->event_id);
grilio_channel_unref(cd->io);

View File

@@ -2,7 +2,7 @@
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-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
@@ -81,6 +81,7 @@ typedef struct ril_data RilData;
enum ril_data_io_event_id {
IO_EVENT_DATA_CALL_LIST_CHANGED,
IO_EVENT_RESTRICTED_STATE_CHANGED,
IO_EVENT_EOF,
IO_EVENT_COUNT
};
@@ -192,6 +193,7 @@ struct ril_data_request_allow_data {
static void ril_data_manager_check_network_mode(struct ril_data_manager *dm);
static void ril_data_call_deact_cid(struct ril_data *data, int cid);
static void ril_data_cancel_all_requests(struct ril_data *self);
static void ril_data_power_update(struct ril_data *self);
static void ril_data_signal_emit(struct ril_data *self, enum ril_data_signal id)
{
@@ -1230,6 +1232,17 @@ static void ril_data_settings_changed(struct ril_sim_settings *settings,
ril_data_manager_check_network_mode(RIL_DATA(user_data)->priv->dm);
}
static void ril_data_ril_disconnected_cb(GRilIoChannel *io, void *user_data)
{
struct ril_data *self = RIL_DATA(user_data);
struct ril_data_priv *priv = self->priv;
DBG_(self, "disconnected");
priv->flags = RIL_DATA_FLAG_NONE;
priv->restricted_state = 0;
ril_data_cancel_all_requests(self);
}
static gint ril_data_compare_cb(gconstpointer a, gconstpointer b)
{
const struct ril_data *d1 = a;
@@ -1289,6 +1302,9 @@ struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
grilio_channel_add_unsol_event_handler(io,
ril_data_restricted_state_changed_cb,
RIL_UNSOL_RESTRICTED_STATE_CHANGED, self);
priv->io_event_id[IO_EVENT_EOF] =
grilio_channel_add_disconnected_handler(io,
ril_data_ril_disconnected_cb, self);
priv->settings_event_id[SETTINGS_EVENT_IMSI_CHANGED] =
ril_sim_settings_add_imsi_changed_handler(settings,
@@ -1415,6 +1431,20 @@ static void ril_data_cancel_requests(struct ril_data *self,
}
}
static void ril_data_cancel_all_requests(struct ril_data *self)
{
struct ril_data_priv *priv = self->priv;
struct ril_data_request *req = priv->req_queue;
ril_data_request_do_cancel(priv->pending_req);
while (req) {
struct ril_data_request *next = req->next;
ril_data_request_do_cancel(req);
req = next;
}
}
static void ril_data_disallow(struct ril_data *self)
{
struct ril_data_priv *priv = self->priv;
@@ -1586,24 +1616,11 @@ static void ril_data_dispose(GObject *object)
struct ril_data *self = RIL_DATA(object);
struct ril_data_priv *priv = self->priv;
struct ril_data_manager *dm = priv->dm;
struct ril_network *network = priv->network;
struct ril_sim_settings *settings = network->settings;
struct ril_data_request *req;
ril_sim_settings_remove_handlers(settings, priv->settings_event_id,
G_N_ELEMENTS(priv->settings_event_id));
grilio_channel_remove_all_handlers(priv->io, priv->io_event_id);
grilio_queue_cancel_all(priv->q, FALSE);
priv->query_id = 0;
ril_data_request_do_cancel(priv->pending_req);
req = priv->req_queue;
while (req) {
struct ril_data_request *next = req->next;
ril_data_request_do_cancel(req);
req = next;
}
ril_data_cancel_all_requests(self);
dm->data_list = g_slist_remove(dm->data_list, self);
ril_data_manager_check_data(dm);
g_hash_table_destroy(priv->grab);
@@ -1614,6 +1631,11 @@ static void ril_data_finalize(GObject *object)
{
struct ril_data *self = RIL_DATA(object);
struct ril_data_priv *priv = self->priv;
struct ril_network *network = priv->network;
struct ril_sim_settings *settings = network->settings;
ril_sim_settings_remove_all_handlers(settings, priv->settings_event_id);
grilio_channel_remove_all_handlers(priv->io, priv->io_event_id);
g_free(priv->log_prefix);
grilio_queue_unref(priv->q);
@@ -1699,34 +1721,39 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)
if ((self->flags & RIL_DATA_MANAGER_FORCE_GSM_ON_OTHER_SLOTS) &&
ril_data_manager_handover(self)) {
struct ril_network *lte_network = NULL;
int non_gsm_count = 0;
struct ril_network *lte_network = NULL, *best_network = NULL;
enum ofono_radio_access_mode best_mode =
OFONO_RADIO_ACCESS_MODE_ANY;
/*
* Count number of SIMs for which non-GSM mode is selected
*/
/* Find a SIM for internet access */
for (l= self->data_list; l; l = l->next) {
struct ril_data *data = l->data;
struct ril_data_priv *priv = data->priv;
struct ril_network *network = priv->network;
struct ril_sim_settings *sim = network->settings;
enum ofono_radio_access_mode mode;
if (sim->pref_mode != OFONO_RADIO_ACCESS_MODE_GSM) {
non_gsm_count++;
if ((priv->flags & RIL_DATA_FLAG_MAX_SPEED) &&
!lte_network) {
lte_network = network;
}
/* Select the first network with internet role */
if ((sim->pref_mode != OFONO_RADIO_ACCESS_MODE_GSM) &&
(priv->flags & RIL_DATA_FLAG_MAX_SPEED)) {
lte_network = network;
break;
}
/* At the same time, look for a suitable slot */
mode = ril_network_max_supported_mode(network);
if (mode > best_mode) {
best_network = network;
best_mode = mode;
}
}
/*
* If there's no SIM selected for internet access
* then choose the first slot for LTE.
* then use a slot with highest capabilities for LTE.
*/
if (!lte_network) {
struct ril_data *data = self->data_list->data;
lte_network = data->priv->network;
lte_network = best_network;
}
for (l= self->data_list; l; l = l->next) {

View File

@@ -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
@@ -79,12 +79,6 @@ struct ril_data_options {
unsigned int data_call_retry_delay_ms;
};
enum ril_data_role {
RIL_DATA_ROLE_NONE, /* Data not allowed */
RIL_DATA_ROLE_MMS, /* Data is allowed at any speed */
RIL_DATA_ROLE_INTERNET /* Data is allowed at full speed */
};
struct ril_data_manager;
struct ril_data_manager *ril_data_manager_new(enum ril_data_manager_flags flg);
struct ril_data_manager *ril_data_manager_ref(struct ril_data_manager *dm);

View File

@@ -421,6 +421,7 @@ static void ril_modem_remove(struct ofono_modem *ofono)
ofono_modem_set_data(ofono, NULL);
ril_radio_remove_handler(modem->radio, md->radio_state_event_id);
ril_radio_set_online(modem->radio, FALSE);
ril_radio_power_off(modem->radio, RADIO_POWER_TAG(md));
ril_radio_set_online(modem->radio, FALSE);
ril_radio_unref(modem->radio);

View File

@@ -20,9 +20,12 @@
#include "ril_vendor.h"
#include "ril_log.h"
#include "ofono.h"
#include "common.h"
#include "simutil.h"
#include <ofono/watch.h>
#define REGISTRATION_MAX_RETRIES (2)
enum ril_netreg_events {
@@ -40,9 +43,11 @@ enum ril_netreg_network_events {
struct ril_netreg {
GRilIoChannel *io;
GRilIoQueue *q;
gboolean replace_strange_oper;
gboolean network_selection_manual_0;
int signal_strength_dbm_weak;
int signal_strength_dbm_strong;
struct ofono_watch *watch;
struct ofono_netreg *netreg;
struct ril_network *network;
struct ril_vendor *vendor;
@@ -192,11 +197,74 @@ static void ril_netreg_current_operator(struct ofono_netreg *netreg,
ril_netreg_cbd_free);
}
static gboolean ril_netreg_strange(const struct ofono_network_operator *op,
struct ofono_sim *sim)
{
gsize mcclen;
if (sim && op->status != OPERATOR_STATUS_CURRENT) {
const char *spn = ofono_sim_get_spn(sim);
const char *mcc = ofono_sim_get_mcc(sim);
const char *mnc = ofono_sim_get_mnc(sim);
if (spn && mcc && mnc && !strcmp(op->name, spn) &&
(strcmp(op->mcc, mcc) || strcmp(op->mnc, mnc))) {
/*
* Status is not "current", SPN matches the SIM, but
* MCC and/or MNC don't (e.g. Sony Xperia X where all
* operators could be reported with the same name
* which equals SPN).
*/
DBG("%s %s%s (sim spn?)", op->name, op->mcc, op->mnc);
return TRUE;
}
}
mcclen = strlen(op->mcc);
if (!strncmp(op->name, op->mcc, mcclen) &&
!strcmp(op->name + mcclen, op->mnc)) {
/* Some MediaTek RILs only report numeric operator name */
DBG("%s %s%s (numeric?)", op->name, op->mcc, op->mnc);
return TRUE;
}
return FALSE;
}
static void ril_netreg_process_operators(struct ril_netreg *nd,
struct ofono_network_operator *ops, int nops)
{
if (nd->replace_strange_oper) {
int i;
for (i = 0; i < nops; i++) {
struct ofono_network_operator *op = ops + i;
struct ofono_gprs_provision_data *prov = NULL;
int np = 0;
if (ril_netreg_strange(op, nd->watch->sim) &&
__ofono_gprs_provision_get_settings(op->mcc,
op->mnc, NULL, &prov, &np)) {
/* Use the first entry */
if (np > 0 && prov->provider_name &&
prov->provider_name[0]) {
DBG("%s %s%s -> %s", op->name, op->mcc,
op->mnc, prov->provider_name);
strncpy(op->name, prov->provider_name,
OFONO_MAX_OPERATOR_NAME_LENGTH);
}
__ofono_gprs_provision_free_settings(prov, np);
}
}
}
}
static void ril_netreg_list_operators_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
struct ril_netreg_cbd *cbd = user_data;
ofono_netreg_operator_list_cb_t cb = cbd->cb.operator_list;
struct ril_netreg *nd = cbd->nd;
struct ofono_network_operator *list;
struct ofono_error error;
int noperators = 0, i;
@@ -238,21 +306,23 @@ static void ril_netreg_list_operators_cb(GRilIoChannel *io, int status,
}
/* Set the proper status */
if (!strcmp(status, "available")) {
list[i].status = OPERATOR_STATUS_AVAILABLE;
if (!status) {
op->status = OPERATOR_STATUS_UNKNOWN;
} else if (!strcmp(status, "available")) {
op->status = OPERATOR_STATUS_AVAILABLE;
} else if (!strcmp(status, "current")) {
list[i].status = OPERATOR_STATUS_CURRENT;
op->status = OPERATOR_STATUS_CURRENT;
} else if (!strcmp(status, "forbidden")) {
list[i].status = OPERATOR_STATUS_FORBIDDEN;
op->status = OPERATOR_STATUS_FORBIDDEN;
} else {
list[i].status = OPERATOR_STATUS_UNKNOWN;
op->status = OPERATOR_STATUS_UNKNOWN;
}
op->tech = -1;
ok = ril_parse_mcc_mnc(numeric, op);
if (ok) {
if (op->tech < 0) {
op->tech = cbd->nd->network->voice.access_tech;
op->tech = nd->network->voice.access_tech;
}
DBG("[operator=%s, %s, %s, status: %s]", op->name,
op->mcc, op->mnc, status);
@@ -267,6 +337,7 @@ static void ril_netreg_list_operators_cb(GRilIoChannel *io, int status,
}
if (ok) {
ril_netreg_process_operators(nd, list, noperators);
cb(ril_error_ok(&error), noperators, list, cbd->data);
} else {
cb(ril_error_failure(&error), 0, NULL, cbd->data);
@@ -594,9 +665,11 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
DBG_(nd, "%p", netreg);
nd->io = grilio_channel_ref(ril_modem_io(modem));
nd->q = grilio_queue_new(nd->io);
nd->watch = ofono_watch_new(ril_modem_get_path(modem));
nd->vendor = ril_vendor_ref(modem->vendor);
nd->network = ril_network_ref(modem->network);
nd->netreg = netreg;
nd->replace_strange_oper = config->replace_strange_oper;
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;
@@ -627,6 +700,7 @@ static void ril_netreg_remove(struct ofono_netreg *netreg)
g_source_remove(nd->current_operator_id);
}
ofono_watch_unref(nd->watch);
ril_network_remove_all_handlers(nd->network, nd->network_event_id);
ril_network_unref(nd->network);
ril_vendor_unref(nd->vendor);

View File

@@ -18,6 +18,7 @@
#include "ril_network.h"
#include "ril_radio.h"
#include "ril_radio_caps.h"
#include "ril_sim_card.h"
#include "ril_sim_settings.h"
#include "ril_vendor.h"
@@ -35,6 +36,7 @@
#include <ofono/watch.h>
#include <ofono/gprs.h>
#include "ofono.h"
#include "common.h"
#define SET_PREF_MODE_HOLDOFF_SEC RIL_RETRY_SECS
@@ -54,6 +56,12 @@ enum ril_network_radio_event {
RADIO_EVENT_COUNT
};
enum ril_network_radio_caps_mgr_events {
RADIO_CAPS_MGR_TX_DONE,
RADIO_CAPS_MGR_TX_ABORTED,
RADIO_CAPS_MGR_EVENT_COUNT
};
enum ril_network_sim_events {
SIM_EVENT_STATUS_CHANGED,
SIM_EVENT_IO_ACTIVE_CHANGED,
@@ -62,7 +70,6 @@ enum ril_network_sim_events {
enum ril_network_unsol_event {
UNSOL_EVENT_NETWORK_STATE,
UNSOL_EVENT_RADIO_CAPABILITY,
UNSOL_EVENT_COUNT
};
@@ -90,6 +97,7 @@ struct ril_network_priv {
GRilIoChannel *io;
GRilIoQueue *q;
struct ril_radio *radio;
struct ril_radio_caps *caps;
struct ril_sim_card *simcard;
struct ril_vendor *vendor;
struct ofono_watch *watch;
@@ -106,6 +114,8 @@ struct ril_network_priv {
gulong set_rat_id;
gulong unsol_event_id[UNSOL_EVENT_COUNT];
gulong settings_event_id;
gulong supported_modes_event_id;
gulong caps_mgr_event_id[RADIO_CAPS_MGR_EVENT_COUNT];
gulong radio_event_id[RADIO_EVENT_COUNT];
gulong simcard_event_id[SIM_EVENT_COUNT];
gulong watch_ids[WATCH_EVENT_COUNT];
@@ -125,7 +135,6 @@ enum ril_network_signal {
SIGNAL_VOICE_STATE_CHANGED,
SIGNAL_DATA_STATE_CHANGED,
SIGNAL_PREF_MODE_CHANGED,
SIGNAL_MAX_PREF_MODE_CHANGED,
SIGNAL_COUNT
};
@@ -133,7 +142,6 @@ enum ril_network_signal {
#define SIGNAL_VOICE_STATE_CHANGED_NAME "ril-network-voice-state-changed"
#define SIGNAL_DATA_STATE_CHANGED_NAME "ril-network-data-state-changed"
#define SIGNAL_PREF_MODE_CHANGED_NAME "ril-network-pref-mode-changed"
#define SIGNAL_MAX_PREF_MODE_CHANGED_NAME "ril-network-max-pref-mode-changed"
static guint ril_network_signals[SIGNAL_COUNT] = { 0 };
@@ -525,6 +533,17 @@ static int ril_network_mode_to_rat(struct ril_network *self,
}
}
enum ofono_radio_access_mode ril_network_max_supported_mode
(struct ril_network *self)
{
struct ril_sim_settings *settings = self->settings;
struct ril_network_priv *priv = self->priv;
const struct ril_radio_caps *caps = priv->caps;
return caps ? __ofono_radio_access_max_mode(caps->supported_modes) :
__ofono_radio_access_max_mode(settings->techs);
}
static enum ofono_radio_access_mode ril_network_actual_pref_mode
(struct ril_network *self)
{
@@ -548,9 +567,16 @@ static enum ofono_radio_access_mode ril_network_actual_pref_mode
* and max_pref_mode are not ANY, we pick the smallest value.
* Otherwise we take any non-zero value if there is one.
*/
return (settings->pref_mode && max_pref_mode) ?
const enum ofono_radio_access_mode pref_mode =
(settings->pref_mode && max_pref_mode) ?
MIN(settings->pref_mode, max_pref_mode) :
settings->pref_mode ? settings->pref_mode : max_pref_mode;
/* Do not try to set unsupported mode */
const enum ofono_radio_access_mode max_mode =
ril_network_max_supported_mode(self);
return pref_mode ? MIN(pref_mode, max_mode) : max_mode;
}
static gboolean ril_network_need_initial_attach_apn(struct ril_network *self)
@@ -561,9 +587,9 @@ static gboolean ril_network_need_initial_attach_apn(struct ril_network *self)
if (watch->gprs && radio->state == RADIO_STATE_ON) {
switch (ril_network_actual_pref_mode(self)) {
case OFONO_RADIO_ACCESS_MODE_ANY:
case OFONO_RADIO_ACCESS_MODE_LTE:
return TRUE;
case OFONO_RADIO_ACCESS_MODE_ANY:
case OFONO_RADIO_ACCESS_MODE_UMTS:
case OFONO_RADIO_ACCESS_MODE_GSM:
break;
@@ -968,6 +994,14 @@ static void ril_network_check_pref_mode(struct ril_network *self,
}
}
static void ril_network_assert_pref_mode(struct ril_network *self)
{
struct ril_network_priv *priv = self->priv;
priv->assert_rat = TRUE;
ril_network_check_pref_mode(self, FALSE);
}
static int ril_network_parse_pref_resp(const void *data, guint len)
{
GRilIoParser rilp;
@@ -997,10 +1031,10 @@ static void ril_network_startup_query_pref_mode_cb(GRilIoChannel *io,
}
/*
* Unlike ril_network_query_pref_mode_cb, this one always
* checks the preferred mode.
* At startup, the device may have an inconsistency between
* voice and data network modes, so it needs to be asserted.
*/
ril_network_check_pref_mode(self, FALSE);
ril_network_assert_pref_mode(self);
}
}
@@ -1053,19 +1087,79 @@ void ril_network_set_max_pref_mode(struct ril_network *self,
DBG_(self, "rat mode %d (%s)", max_mode,
ofono_radio_access_mode_to_string(max_mode));
self->max_pref_mode = max_mode;
ril_network_emit(self, SIGNAL_MAX_PREF_MODE_CHANGED);
ril_network_check_initial_attach_apn(self);
}
ril_network_check_pref_mode(self, TRUE);
}
}
void ril_network_assert_pref_mode(struct ril_network *self, gboolean immediate)
static void ril_network_supported_modes_handler(struct ril_radio_caps *caps,
void *user_data)
{
struct ril_network *self = RIL_NETWORK(user_data);
DBG_(self, "%s", ofono_radio_access_mode_to_string
(caps->supported_modes));
ril_network_check_pref_mode(self, TRUE);
}
static void ril_network_radio_capability_tx_done_cb
(struct ril_radio_caps_manager *mgr, void *user_data)
{
struct ril_network *self = RIL_NETWORK(user_data);
DBG_(self, "");
ril_network_assert_pref_mode(self);
}
static void ril_network_release_radio_caps(struct ril_network *self)
{
struct ril_network_priv *priv = self->priv;
struct ril_radio_caps *caps = priv->caps;
if (caps) {
ril_radio_caps_manager_remove_all_handlers(caps->mgr,
priv->caps_mgr_event_id);
ril_radio_caps_remove_handler(caps,
priv->supported_modes_event_id);
ril_radio_caps_unref(caps);
priv->caps = NULL;
priv->supported_modes_event_id = 0;
}
}
static void ril_network_attach_radio_caps(struct ril_network *self,
struct ril_radio_caps *caps)
{
struct ril_network_priv *priv = self->priv;
priv->assert_rat = TRUE;
ril_network_check_pref_mode(self, immediate);
priv->caps = ril_radio_caps_ref(caps);
priv->supported_modes_event_id =
ril_radio_caps_add_supported_modes_handler(caps,
ril_network_supported_modes_handler, self);
priv->caps_mgr_event_id[RADIO_CAPS_MGR_TX_DONE] =
ril_radio_caps_manager_add_tx_done_handler(caps->mgr,
ril_network_radio_capability_tx_done_cb, self);
priv->caps_mgr_event_id[RADIO_CAPS_MGR_TX_ABORTED] =
ril_radio_caps_manager_add_tx_aborted_handler(caps->mgr,
ril_network_radio_capability_tx_done_cb, self);
}
void ril_network_set_radio_caps(struct ril_network *self,
struct ril_radio_caps *caps)
{
if (self) {
struct ril_network_priv *priv = self->priv;
if (priv->caps != caps) {
ril_network_release_radio_caps(self);
if (caps) {
ril_network_attach_radio_caps(self, caps);
}
ril_network_check_pref_mode(self, TRUE);
}
}
}
gulong ril_network_add_operator_changed_handler(struct ril_network *self,
@@ -1096,13 +1190,6 @@ gulong ril_network_add_pref_mode_changed_handler(struct ril_network *self,
SIGNAL_PREF_MODE_CHANGED_NAME, G_CALLBACK(cb), arg) : 0;
}
gulong ril_network_add_max_pref_mode_changed_handler(struct ril_network *self,
ril_network_cb_t cb, void *arg)
{
return (G_LIKELY(self) && G_LIKELY(cb)) ? g_signal_connect(self,
SIGNAL_MAX_PREF_MODE_CHANGED_NAME, G_CALLBACK(cb), arg) : 0;
}
void ril_network_remove_handler(struct ril_network *self, gulong id)
{
if (G_LIKELY(self) && G_LIKELY(id)) {
@@ -1125,16 +1212,6 @@ static void ril_network_state_changed_cb(GRilIoChannel *io, guint code,
ril_network_poll_state(self);
}
static void ril_network_radio_capability_changed_cb(GRilIoChannel *io,
guint code, const void *data, guint len, void *user_data)
{
struct ril_network *self = RIL_NETWORK(user_data);
DBG_(self, "");
GASSERT(code == RIL_UNSOL_RADIO_CAPABILITY);
ril_network_assert_pref_mode(self, FALSE);
}
static void ril_network_radio_state_cb(struct ril_radio *radio, void *data)
{
struct ril_network *self = RIL_NETWORK(data);
@@ -1267,10 +1344,6 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
grilio_channel_add_unsol_event_handler(priv->io,
ril_network_state_changed_cb,
RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, self);
priv->unsol_event_id[UNSOL_EVENT_RADIO_CAPABILITY] =
grilio_channel_add_unsol_event_handler(priv->io,
ril_network_radio_capability_changed_cb,
RIL_UNSOL_RADIO_CAPABILITY, self);
priv->radio_event_id[RADIO_EVENT_STATE_CHANGED] =
ril_radio_add_state_changed_handler(priv->radio,
@@ -1365,6 +1438,7 @@ static void ril_network_finalize(GObject *object)
grilio_channel_remove_all_handlers(priv->io, priv->unsol_event_id);
grilio_channel_unref(priv->io);
grilio_queue_unref(priv->q);
ril_network_release_radio_caps(self);
ril_radio_remove_all_handlers(priv->radio, priv->radio_event_id);
ril_radio_unref(priv->radio);
ril_sim_card_remove_all_handlers(priv->simcard, priv->simcard_event_id);
@@ -1386,7 +1460,6 @@ static void ril_network_class_init(RilNetworkClass *klass)
RIL_NETWORK_SIGNAL(klass, VOICE_STATE);
RIL_NETWORK_SIGNAL(klass, DATA_STATE);
RIL_NETWORK_SIGNAL(klass, PREF_MODE);
RIL_NETWORK_SIGNAL(klass, MAX_PREF_MODE);
}
/*

View File

@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2015-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
@@ -21,6 +22,7 @@
#include <glib-object.h>
struct ofono_network_operator;
struct ril_radio_caps;
struct ril_registration_state {
int status; /* enum network_registration_status */
@@ -42,7 +44,6 @@ struct ril_network {
struct ril_sim_settings *settings;
};
struct ofono_sim;
typedef void (*ril_network_cb_t)(struct ril_network *net, void *arg);
struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
@@ -54,10 +55,13 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
struct ril_network *ril_network_ref(struct ril_network *net);
void ril_network_unref(struct ril_network *net);
void ril_network_set_radio_caps(struct ril_network *net,
struct ril_radio_caps *caps);
void ril_network_set_max_pref_mode(struct ril_network *net,
enum ofono_radio_access_mode max_pref_mode,
gboolean force_check);
void ril_network_assert_pref_mode(struct ril_network *net, gboolean immediate);
enum ofono_radio_access_mode ril_network_max_supported_mode
(struct ril_network *self);
void ril_network_query_registration_state(struct ril_network *net);
gulong ril_network_add_operator_changed_handler(struct ril_network *net,
ril_network_cb_t cb, void *arg);
@@ -67,8 +71,6 @@ gulong ril_network_add_data_state_changed_handler(struct ril_network *net,
ril_network_cb_t cb, void *arg);
gulong ril_network_add_pref_mode_changed_handler(struct ril_network *net,
ril_network_cb_t cb, void *arg);
gulong ril_network_add_max_pref_mode_changed_handler(struct ril_network *net,
ril_network_cb_t cb, void *arg);
void ril_network_remove_handler(struct ril_network *net, gulong id);
void ril_network_remove_handlers(struct ril_network *net, gulong *ids, int n);

View File

@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2017 Jolla Ltd.
* Copyright (C) 2015-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
@@ -32,6 +33,11 @@ struct ril_oem_raw {
#define DBG_(oem,fmt,args...) DBG("%s" fmt, (oem)->log_prefix, ##args)
static void ril_oem_raw_send_done(void *msg)
{
dbus_message_unref(msg);
}
static void ril_oem_raw_send_cb(GRilIoChannel *io, int ril_status,
const void *data, guint len, void *user_data)
{
@@ -40,20 +46,13 @@ static void ril_oem_raw_send_cb(GRilIoChannel *io, int ril_status,
if (ril_status == RIL_E_SUCCESS) {
DBusMessageIter it, array;
const guchar* bytes = data;
guint i;
reply = dbus_message_new_method_return(msg);
dbus_message_iter_init_append(reply, &it);
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE_AS_STRING, &array);
for (i = 0; i < len; i++) {
guchar byte = bytes[i];
dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE,
&byte);
}
dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
&data, len);
dbus_message_iter_close_container(&it, &array);
} else if (ril_status == GRILIO_STATUS_TIMEOUT) {
DBG("Timed out");
@@ -63,7 +62,7 @@ static void ril_oem_raw_send_cb(GRilIoChannel *io, int ril_status,
reply = __ofono_error_failed(msg);
}
__ofono_dbus_pending_reply(&msg, reply);
g_dbus_send_message(ofono_dbus_get_connection(), reply);
}
static DBusMessage *ril_oem_raw_send(DBusConnection *conn, DBusMessage *msg,
@@ -72,6 +71,12 @@ static DBusMessage *ril_oem_raw_send(DBusConnection *conn, DBusMessage *msg,
DBusMessageIter it;
struct ril_oem_raw *oem = user_data;
if (!__ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
OFONO_DBUS_ACCESS_INTF_OEMRAW,
OFONO_DBUS_ACCESS_OEMRAW_SEND, NULL)) {
return __ofono_error_access_denied(msg);
}
dbus_message_iter_init(msg, &it);
if (dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_ARRAY &&
dbus_message_iter_get_element_type(&it) == DBUS_TYPE_BYTE) {
@@ -94,7 +99,7 @@ static DBusMessage *ril_oem_raw_send(DBusConnection *conn, DBusMessage *msg,
grilio_request_append_bytes(req, data, data_len);
grilio_queue_send_request_full(oem->q, req,
RIL_REQUEST_OEM_HOOK_RAW, ril_oem_raw_send_cb,
NULL, dbus_message_ref(msg));
ril_oem_raw_send_done, dbus_message_ref(msg));
grilio_request_unref(req);
return NULL;
} else {

View File

@@ -94,6 +94,7 @@
#define RILMODEM_DEFAULT_LEGACY_IMEI_QUERY FALSE
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
#define RILMODEM_DEFAULT_REPLACE_STRANGE_OPER FALSE
#define RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0 TRUE
#define RILMODEM_DEFAULT_FORCE_GSM_WHEN_RADIO_OFF TRUE
#define RILMODEM_DEFAULT_USE_DATA_PROFILES FALSE
@@ -151,6 +152,7 @@
#define RILCONF_RADIO_POWER_CYCLE "radioPowerCycle"
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
#define RILCONF_SINGLE_DATA_CONTEXT "singleDataContext"
#define RILCONF_REPLACE_STRANGE_OPER "replaceStrangeOperatorNames"
#define RILCONF_NETWORK_SELECTION_MANUAL_0 "networkSelectionManual0"
#define RILCONF_FORCE_GSM_WHEN_RADIO_OFF "forceGsmWhenRadioOff"
#define RILCONF_USE_DATA_PROFILES "useDataProfiles"
@@ -228,6 +230,7 @@ typedef struct sailfish_slot_impl {
struct ril_modem *modem;
struct ril_radio *radio;
struct ril_radio_caps *caps;
struct ril_radio_caps_request *caps_req;
struct ril_network *network;
struct ril_sim_card *sim_card;
struct ril_sim_settings *sim_settings;
@@ -390,7 +393,10 @@ static void ril_plugin_shutdown_slot(ril_slot *slot, gboolean kill_io)
}
if (slot->caps) {
ril_radio_caps_unref(slot->caps);
ril_network_set_radio_caps(slot->network, NULL);
ril_radio_caps_request_free(slot->caps_req);
ril_radio_caps_drop(slot->caps);
slot->caps_req = NULL;
slot->caps = NULL;
}
@@ -904,7 +910,7 @@ static void ril_plugin_radio_caps_cb(const struct ril_radio_capability *cap,
plugin->caps_manager = ril_radio_caps_manager_new
(plugin->data_manager);
plugin->caps_manager_event_id =
ril_radio_caps_manager_add_aborted_handler(
ril_radio_caps_manager_add_tx_aborted_handler(
plugin->caps_manager,
ril_plugin_caps_switch_aborted,
plugin);
@@ -912,9 +918,10 @@ static void ril_plugin_radio_caps_cb(const struct ril_radio_capability *cap,
GASSERT(!slot->caps);
slot->caps = ril_radio_caps_new(plugin->caps_manager,
ril_plugin_log_prefix(slot), slot->io, slot->data,
slot->radio, slot->sim_card, slot->network,
&slot->config, cap);
ril_plugin_log_prefix(slot), slot->io, slot->watch,
slot->data, slot->radio, slot->sim_card,
slot->sim_settings, &slot->config, cap);
ril_network_set_radio_caps(slot->network, slot->caps);
}
}
@@ -1146,6 +1153,8 @@ static void ril_plugin_slot_modem_changed(struct ofono_watch *w,
slot->modem = NULL;
ril_data_allow(slot->data, RIL_DATA_ROLE_NONE);
ril_radio_caps_request_free(slot->caps_req);
slot->caps_req = NULL;
}
}
@@ -1214,6 +1223,7 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
config->enable_stk = RILMODEM_DEFAULT_ENABLE_STK;
config->query_available_band_mode =
RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE;
config->replace_strange_oper = RILMODEM_DEFAULT_REPLACE_STRANGE_OPER;
config->network_selection_manual_0 =
RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0;
config->force_gsm_when_radio_off =
@@ -1254,6 +1264,7 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
defaults.empty_pin_query = config->empty_pin_query;
defaults.mms_data_profile_id = config->mms_data_profile_id;
defaults.use_data_profiles = config->use_data_profiles;
defaults.replace_strange_oper = config->replace_strange_oper;
defaults.force_gsm_when_radio_off =
config->force_gsm_when_radio_off;
defaults.query_available_band_mode =
@@ -1266,6 +1277,7 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
config->empty_pin_query = defaults.empty_pin_query;
config->use_data_profiles = defaults.use_data_profiles;
config->mms_data_profile_id = defaults.mms_data_profile_id;
config->replace_strange_oper = defaults.replace_strange_oper;
config->force_gsm_when_radio_off =
defaults.force_gsm_when_radio_off;
config->query_available_band_mode =
@@ -1489,6 +1501,14 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
config->enable_stk ? "yes" : "no");
}
/* replaceStrangeOperatorNames */
if (ril_config_get_boolean(file, group,
RILCONF_REPLACE_STRANGE_OPER,
&config->replace_strange_oper)) {
DBG("%s: " RILCONF_REPLACE_STRANGE_OPER " %s", group,
config->replace_strange_oper ? "yes" : "no");
}
/* networkSelectionManual0 */
if (ril_config_get_boolean(file, group,
RILCONF_NETWORK_SELECTION_MANUAL_0,
@@ -2179,10 +2199,24 @@ static void ril_plugin_manager_free(ril_plugin *plugin)
static void ril_slot_set_data_role(ril_slot *slot, enum sailfish_data_role r)
{
ril_data_allow(slot->data,
enum ril_data_role role =
(r == SAILFISH_DATA_ROLE_INTERNET) ? RIL_DATA_ROLE_INTERNET :
(r == SAILFISH_DATA_ROLE_MMS) ? RIL_DATA_ROLE_MMS :
RIL_DATA_ROLE_NONE);
RIL_DATA_ROLE_NONE;
ril_data_allow(slot->data, role);
ril_radio_caps_request_free(slot->caps_req);
if (role == RIL_DATA_ROLE_NONE) {
slot->caps_req = NULL;
} else {
const enum ofono_radio_access_mode mode =
(r == SAILFISH_DATA_ROLE_MMS) ?
OFONO_RADIO_ACCESS_MODE_GSM :
__ofono_radio_access_max_mode
(slot->sim_settings->techs);
slot->caps_req = ril_radio_caps_request_new
(slot->caps, mode, role);
}
}
static void ril_slot_enabled_changed(struct sailfish_slot_impl *s)

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2017 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
@@ -19,12 +19,16 @@
#include "ril_types.h"
struct ril_data_manager;
struct ril_sim_settings;
struct ril_radio_caps;
struct ril_radio_caps_manager;
struct ril_radio_capability;
struct ril_radio_caps_request;
typedef void (*ril_radio_caps_cb_t)(struct ril_radio_caps *caps, void *arg);
typedef void (*ril_radio_caps_manager_cb_t)(struct ril_radio_caps_manager *mgr,
void *user_data);
/* ril_radio_capability pointer is NULL if functionality is unsupported */
typedef void (*ril_radio_caps_check_cb_t)
(const struct ril_radio_capability *cap, void *user_data);
@@ -39,21 +43,47 @@ struct ril_radio_caps_manager *ril_radio_caps_manager_new
struct ril_radio_caps_manager *ril_radio_caps_manager_ref
(struct ril_radio_caps_manager *mgr);
void ril_radio_caps_manager_unref(struct ril_radio_caps_manager *mgr);
gulong ril_radio_caps_manager_add_aborted_handler
gulong ril_radio_caps_manager_add_tx_aborted_handler
(struct ril_radio_caps_manager *mgr,
ril_radio_caps_manager_cb_t cb, void *arg);
gulong ril_radio_caps_manager_add_tx_done_handler
(struct ril_radio_caps_manager *mgr,
ril_radio_caps_manager_cb_t cb, void *arg);
void ril_radio_caps_manager_remove_handler(struct ril_radio_caps_manager *mgr,
gulong id);
gulong id);
void ril_radio_caps_manager_remove_handlers(struct ril_radio_caps_manager *mgr,
gulong *ids, int count);
#define ril_radio_caps_manager_remove_all_handlers(mgr, ids) \
ril_radio_caps_manager_remove_handlers(mgr, ids, G_N_ELEMENTS(ids))
/* And one ril_radio_caps object per modem */
struct ril_radio_caps {
struct ril_radio_caps_manager *mgr;
enum ofono_radio_access_mode supported_modes;
};
struct ril_radio_caps *ril_radio_caps_new(struct ril_radio_caps_manager *mgr,
const char *log_prefix, GRilIoChannel *io,
struct ofono_watch *watch,
struct ril_data *data, struct ril_radio *radio,
struct ril_sim_card *sim, struct ril_network *net,
struct ril_sim_card *sim, struct ril_sim_settings *settings,
const struct ril_slot_config *config,
const struct ril_radio_capability *cap);
struct ril_radio_caps *ril_radio_caps_ref(struct ril_radio_caps *caps);
void ril_radio_caps_unref(struct ril_radio_caps *caps);
void ril_radio_caps_drop(struct ril_radio_caps *caps);
gulong ril_radio_caps_add_supported_modes_handler
(struct ril_radio_caps *caps,
ril_radio_caps_cb_t cb, void *arg);
void ril_radio_caps_remove_handler(struct ril_radio_caps *caps, gulong id);
/* Data requests */
struct ril_radio_caps_request *ril_radio_caps_request_new
(struct ril_radio_caps *caps, enum ofono_radio_access_mode mode,
enum ril_data_role role);
void ril_radio_caps_request_free(struct ril_radio_caps_request *req);
#endif /* RIL_RADIO_CAPS_H */

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2018 Jolla Ltd.
* Copyright (C) 2016-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
@@ -45,6 +45,8 @@ gulong ril_sim_settings_add_pref_mode_changed_handler(struct ril_sim_settings *s
void ril_sim_settings_remove_handler(struct ril_sim_settings *s, gulong id);
void ril_sim_settings_remove_handlers(struct ril_sim_settings *s, gulong *ids,
int count);
#define ril_sim_settings_remove_all_handlers(s,ids) \
ril_sim_settings_remove_handlers(s, ids, G_N_ELEMENTS(ids))
#endif /* RIL_SIM_SETTINGS_H */

View File

@@ -282,6 +282,16 @@ socket=/dev/socket/rild
#
#singleDataContext=false
# With some RILs, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS returns strange
# operator names, i.e. numeric MCC+MNC values or the same name for all
# operators (which is actually SPN fetched from the SIM). Such strange
# names can be replaced with operator names from MBPI database, based
# on the operator's MCC and MNC. That may not be 100% accurate, though.
#
# Default false (i.e. trust RIL to report the actual names)
#
#replaceStrangeOperatorNames=false
# Configures whether +0 is added to MCCMNC string passed to
# RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL. Some Qualcomm RILs
# require it, some MediaTek RILs don't like it.

View File

@@ -24,6 +24,7 @@
#include <grilio_types.h>
#include <gutil_macros.h>
struct ofono_watch;
struct ofono_modem;
struct ofono_sim;
@@ -49,6 +50,12 @@ struct ril_network;
struct ril_sim_card;
struct ril_vendor;
enum ril_data_role {
RIL_DATA_ROLE_NONE, /* Mobile data not required */
RIL_DATA_ROLE_MMS, /* Data is needed at any speed */
RIL_DATA_ROLE_INTERNET /* Data is needed at full speed */
};
struct ril_slot_config {
guint slot;
enum ofono_radio_access_mode techs;
@@ -65,6 +72,7 @@ struct ril_slot_config {
gboolean enable_voicecall;
gboolean enable_cbs;
gboolean enable_stk;
gboolean replace_strange_oper;
gboolean network_selection_manual_0;
gboolean force_gsm_when_radio_off;
gboolean use_data_profiles;

View File

@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
* Copyright (C) 2016-2020 Jolla Ltd.
* 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
@@ -24,6 +24,7 @@ struct ril_vendor_defaults {
gboolean legacy_imei_query;
gboolean enable_cbs;
gboolean enable_stk;
gboolean replace_strange_oper;
gboolean query_available_band_mode;
gboolean use_data_profiles;
gboolean force_gsm_when_radio_off;

View File

@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
* Copyright (C) 2016-2020 Jolla Ltd.
* 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
@@ -509,6 +509,7 @@ static void ril_vendor_mtk_get_defaults(struct ril_vendor_defaults *defaults)
defaults->empty_pin_query = FALSE;
defaults->legacy_imei_query = TRUE;
defaults->force_gsm_when_radio_off = FALSE;
defaults->replace_strange_oper = TRUE;
}
static void ril_vendor_mtk_base_init(RilVendorMtk *self, GRilIoChannel *io,

View File

@@ -40,6 +40,7 @@ enum ofono_dbus_access_intf {
OFONO_DBUS_ACCESS_INTF_MODEM, /* org.ofono.Modem */
OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS, /* org.ofono.RadioSettings */
OFONO_DBUS_ACCESS_INTF_STK, /* org.ofono.SimToolkit */
OFONO_DBUS_ACCESS_INTF_OEMRAW, /* org.ofono.OemRaw */
OFONO_DBUS_ACCESS_INTF_COUNT
};
@@ -124,6 +125,12 @@ enum ofono_dbus_access_stk_method {
OFONO_DBUS_ACCESS_STK_METHOD_COUNT
};
/* OFONO_DBUS_ACCESS_INTF_OEMRAW */
enum ofono_dbus_access_oemraw_method {
OFONO_DBUS_ACCESS_OEMRAW_SEND,
OFONO_DBUS_ACCESS_OEMRAW_METHOD_COUNT
};
#define OFONO_DBUS_ACCESS_PRIORITY_LOW (-100)
#define OFONO_DBUS_ACCESS_PRIORITY_DEFAULT (0)
#define OFONO_DBUS_ACCESS_PRIORITY_HIGH (100)

View File

@@ -44,6 +44,8 @@ const char *ofono_dbus_access_intf_name(enum ofono_dbus_access_intf intf)
return OFONO_RADIO_SETTINGS_INTERFACE;
case OFONO_DBUS_ACCESS_INTF_STK:
return OFONO_STK_INTERFACE;
case OFONO_DBUS_ACCESS_INTF_OEMRAW:
return "org.ofono.OemRaw";
case OFONO_DBUS_ACCESS_INTF_COUNT:
break;
}
@@ -176,6 +178,14 @@ const char *ofono_dbus_access_method_name(enum ofono_dbus_access_intf intf,
break;
}
break;
case OFONO_DBUS_ACCESS_INTF_OEMRAW:
switch ((enum ofono_dbus_access_oemraw_method)method) {
case OFONO_DBUS_ACCESS_OEMRAW_SEND:
return "Send";
case OFONO_DBUS_ACCESS_OEMRAW_METHOD_COUNT:
break;
}
break;
case OFONO_DBUS_ACCESS_INTF_COUNT:
break;
}

View File

@@ -283,6 +283,10 @@ enum ofono_gprs_context_type __ofono_gprs_context_get_assigned_type(
struct ofono_gprs_context *gc);
#include <ofono/radio-settings.h>
enum ofono_radio_access_mode __ofono_radio_access_max_mode(
enum ofono_radio_access_mode modes);
#include <ofono/audio-settings.h>
#include <ofono/ctm.h>
#include <ofono/location-reporting.h>

View File

@@ -2,7 +2,8 @@
*
* oFono - Open Source Telephony
*
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2014-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
@@ -61,10 +62,22 @@ struct ofono_radio_settings {
struct ofono_atom *atom;
};
enum ofono_radio_access_mode __ofono_radio_access_max_mode(
enum ofono_radio_access_mode mask)
{
return (mask & OFONO_RADIO_ACCESS_MODE_LTE) ?
OFONO_RADIO_ACCESS_MODE_LTE :
(mask & OFONO_RADIO_ACCESS_MODE_UMTS) ?
OFONO_RADIO_ACCESS_MODE_UMTS :
(mask & OFONO_RADIO_ACCESS_MODE_GSM) ?
OFONO_RADIO_ACCESS_MODE_GSM :
OFONO_RADIO_ACCESS_MODE_ANY;
}
#define radio_access_mode_to_string ofono_radio_access_mode_to_string
const char *ofono_radio_access_mode_to_string(enum ofono_radio_access_mode m)
{
switch (m) {
switch (__ofono_radio_access_max_mode(m)) {
case OFONO_RADIO_ACCESS_MODE_ANY:
return "any";
case OFONO_RADIO_ACCESS_MODE_GSM:
@@ -76,6 +89,10 @@ const char *ofono_radio_access_mode_to_string(enum ofono_radio_access_mode m)
default:
return NULL;
}
return (m == OFONO_RADIO_ACCESS_MODE_ANY) ? "any" :
(m & OFONO_RADIO_ACCESS_MODE_LTE) ? "lte" :
(m & OFONO_RADIO_ACCESS_MODE_UMTS) ? "umts" :
(m & OFONO_RADIO_ACCESS_MODE_GSM) ? "gsm" : NULL;
}
#define radio_access_mode_from_string ofono_radio_access_mode_from_string
ofono_bool_t ofono_radio_access_mode_from_string(const char *str,

View File

@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-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
@@ -1757,7 +1758,7 @@ gboolean sms_udh_iter_init_from_cbs(const struct cbs *cbs,
return FALSE;
hdr = cbs->ud;
max_ud_len = 82;
max_ud_len = cbs->udlen;
/* Must have at least one information-element if udhi is true */
if (hdr[0] < 2)
@@ -3856,8 +3857,8 @@ gboolean cbs_dcs_decode(guint8 dcs, gboolean *udhi, enum sms_class *cls,
gboolean cbs_decode(const unsigned char *pdu, int len, struct cbs *out)
{
/* CBS is always a fixed length of 88 bytes */
if (len != 88)
/* CBS is (almost) always a fixed length of 88 bytes */
if (len < 6 || len > 88)
return FALSE;
out->gs = (enum cbs_geo_scope) ((pdu[0] >> 6) & 0x03);
@@ -3868,6 +3869,10 @@ gboolean cbs_decode(const unsigned char *pdu, int len, struct cbs *out)
out->max_pages = pdu[5] & 0xf;
out->page = (pdu[5] >> 4) & 0xf;
/* Allow the last fragment to be truncated */
if (len != 88 && out->max_pages != out->page)
return FALSE;
/*
* If a mobile receives the code 0000 in either the first field or
* the second field then it shall treat the CBS message exactly the
@@ -3879,7 +3884,10 @@ gboolean cbs_decode(const unsigned char *pdu, int len, struct cbs *out)
out->page = 1;
}
memcpy(out->ud, pdu + 6, 82);
out->udlen = (guint8)(len - 6);
memcpy(out->ud, pdu + 6, out->udlen);
if (out->udlen < 82)
memset(out->ud + out->udlen, 0, 82 - out->udlen);
return TRUE;
}
@@ -4072,7 +4080,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
if (iso639)
bufsize -= 3;
} else {
bufsize += 82;
bufsize += cbs->udlen;
if (iso639)
bufsize -= 2;
@@ -4089,7 +4097,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
if (sms_udh_iter_init_from_cbs(cbs, &iter))
taken = sms_udh_iter_get_udh_length(&iter) + 1;
unpack_7bit_own_buf(cbs->ud + taken, 82 - taken,
unpack_7bit_own_buf(cbs->ud + taken, cbs->udlen - taken,
taken, FALSE, 2,
NULL, 0,
(unsigned char *)iso639_lang);
@@ -4122,7 +4130,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
max_chars =
sms_text_capacity_gsm(CBS_MAX_GSM_CHARS, taken);
unpack_7bit_own_buf(ud + taken, 82 - taken,
unpack_7bit_own_buf(ud + taken, cbs->udlen - taken,
taken, FALSE, max_chars,
&written, 0, unpacked);
@@ -4156,7 +4164,7 @@ char *cbs_decode_text(GSList *cbs_list, char *iso639_lang)
* the check here since the specification isn't clear
*/
} else {
int num_ucs2_chars = (82 - taken) >> 1;
int num_ucs2_chars = (cbs->udlen - taken) >> 1;
int i = taken;
int max_offset = taken + num_ucs2_chars * 2;

View File

@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-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
@@ -398,6 +399,7 @@ struct cbs {
guint8 dcs; /* 8 bits */
guint8 max_pages; /* 4 bits */
guint8 page; /* 4 bits */
guint8 udlen;
guint8 ud[82];
};

View File

@@ -349,12 +349,12 @@ static int tone_queue(struct ofono_voicecall *vc, const char *tone_str,
/*
* Tones can be 0-9, *, #, A-D according to 27.007 C.2.11,
* and p for Pause.
* and p for Pause (also , for Pause as per ITU-T V.250 6.3.1.2).
*/
for (i = 0; tone_str[i]; i++)
if (!g_ascii_isdigit(tone_str[i]) && tone_str[i] != 'p' &&
tone_str[i] != 'P' && tone_str[i] != '*' &&
tone_str[i] != '.' && tone_str[i] != ',' &&
tone_str[i] != ',' &&
tone_str[i] != '#' && (tone_str[i] < 'A' ||
tone_str[i] > 'D'))
return -EINVAL;
@@ -4389,7 +4389,7 @@ static void tone_request_cb(const struct ofono_error *error, void *data)
goto done;
}
len = strspn(entry->left, "pP.,");
len = strspn(entry->left, "pP,");
entry->left += len;
done:
@@ -4423,7 +4423,7 @@ static gboolean tone_request_run(gpointer user_data)
if (entry == NULL)
return FALSE;
len = strcspn(entry->left, "pP.,");
len = strcspn(entry->left, "pP,");
if (len) {
if (len > 8) /* Arbitrary length limit per request */

View File

@@ -34,6 +34,12 @@ static enum ofono_dbus_access deny_method_access(const char *sender,
return OFONO_DBUS_ACCESS_DENY;
}
static enum ofono_dbus_access broken_method_access(const char *sender,
enum ofono_dbus_access_intf intf, int method, const char *arg)
{
return (enum ofono_dbus_access)(-1);
}
struct ofono_dbus_access_plugin access_inval;
struct ofono_dbus_access_plugin access_dontcare = {
.name = "DontCare",
@@ -51,6 +57,12 @@ struct ofono_dbus_access_plugin access_deny = {
.method_access = deny_method_access
};
struct ofono_dbus_access_plugin access_broken = {
.name = "Broken",
.priority = OFONO_DBUS_ACCESS_PRIORITY_LOW,
.method_access = broken_method_access
};
/*==========================================================================*
* Tests
*==========================================================================*/
@@ -107,6 +119,9 @@ static const struct test_method_name_data method_name_tests[] = {
},{
OFONO_DBUS_ACCESS_INTF_STK,
OFONO_DBUS_ACCESS_STK_METHOD_COUNT
},{
OFONO_DBUS_ACCESS_INTF_OEMRAW,
OFONO_DBUS_ACCESS_OEMRAW_METHOD_COUNT
}
};
@@ -156,6 +171,13 @@ static void test_register()
ofono_dbus_access_plugin_unregister(&access_deny);
ofono_dbus_access_plugin_unregister(&access_dontcare);
/* And here too */
g_assert(!ofono_dbus_access_plugin_register(&access_broken));
g_assert(!ofono_dbus_access_plugin_register(&access_deny));
g_assert(!__ofono_dbus_access_method_allowed(":1.0", 0, 1, NULL));
ofono_dbus_access_plugin_unregister(&access_deny);
ofono_dbus_access_plugin_unregister(&access_dontcare);
/* DontCare will allow everything */
g_assert(!ofono_dbus_access_plugin_register(&access_dontcare));
g_assert(__ofono_dbus_access_method_allowed(":1.0", 0, 1, NULL));

View File

@@ -2,12 +2,11 @@ Name: ofono
Summary: Open Source Telephony
Version: 1.23
Release: 1
Group: Communications/Connectivity Adaptation
License: GPLv2
URL: https://git.sailfishos.org/mer-core/ofono
Source: %{name}-%{version}.tar.bz2
%define libgrilio_version 1.0.35
%define libgrilio_version 1.0.38
%define libglibutil_version 1.0.30
%define libmce_version 1.0.6
@@ -38,13 +37,13 @@ BuildRequires: pkgconfig(mobile-broadband-provider-info)
BuildRequires: libtool
BuildRequires: automake
BuildRequires: autoconf
BuildRequires: systemd
%description
Telephony stack
%package devel
Summary: Headers for oFono
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
@@ -52,7 +51,6 @@ Development headers and libraries for oFono
%package tests
Summary: Test Scripts for oFono
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
Requires: dbus-python3
Requires: python3-gobject
@@ -64,7 +62,6 @@ Scripts for testing oFono and its functionality
%package configs-mer
Summary: Package to provide default configs for ofono
Group: Development/Tools
Provides: ofono-configs
%description configs-mer
@@ -72,7 +69,6 @@ This package provides default configs for ofono
%package doc
Summary: Documentation for %{name}
Group: Documentation
Requires: %{name} = %{version}-%{release}
%description doc
@@ -98,9 +94,9 @@ autoreconf --force --install
--disable-add-remove-context \
--disable-isimodem \
--disable-qmimodem \
--with-systemdunitdir="/%{_lib}/systemd/system"
--with-systemdunitdir=%{_unitdir}
make %{_smp_mflags}
%make_build
%check
# run unit tests
@@ -111,9 +107,9 @@ rm -rf %{buildroot}
%make_install
mkdir -p %{buildroot}/%{_sysconfdir}/ofono/push_forwarder.d
mkdir -p %{buildroot}/%{_lib}/systemd/system/network.target.wants
mkdir -p %{buildroot}%{_unitdir}/network.target.wants
mkdir -p %{buildroot}/var/lib/ofono
ln -s ../ofono.service %{buildroot}/%{_lib}/systemd/system/network.target.wants/ofono.service
ln -s ../ofono.service %{buildroot}%{_unitdir}/network.target.wants/ofono.service
mkdir -p %{buildroot}%{_docdir}/%{name}-%{version}
install -m0644 -t %{buildroot}%{_docdir}/%{name}-%{version} \
@@ -139,8 +135,8 @@ systemctl daemon-reload ||:
%license COPYING
%config %{_sysconfdir}/dbus-1/system.d/*.conf
%{_sbindir}/*
/%{_lib}/systemd/system/network.target.wants/ofono.service
/%{_lib}/systemd/system/ofono.service
%{_unitdir}/network.target.wants/ofono.service
%{_unitdir}/ofono.service
%dir %{_sysconfdir}/ofono/
%dir %{_sysconfdir}/ofono/push_forwarder.d
# This file is part of phonesim and not needed with ofono.