[-]
[+]
|
Changed |
_service:tar_git:ofono.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:ofono.spec
^
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -1,7 +1,7 @@
<services>
<service name="tar_git">
<param name="url">https://git.merproject.org/slava/ofono.git</param>
- <param name="branch">rats</param>
- <param name="revision">49d8686</param>
+ <param name="branch">master</param>
+ <param name="revision">60e4246</param>
</service>
</services>
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/Makefile.am
^
|
@@ -151,8 +151,10 @@
drivers/ril/ril_devinfo.c \
drivers/ril/ril_devmon.c \
drivers/ril/ril_devmon_auto.c \
+ drivers/ril/ril_devmon_combine.c \
drivers/ril/ril_devmon_ds.c \
drivers/ril/ril_devmon_ss.c \
+ drivers/ril/ril_devmon_ur.c \
drivers/ril/ril_ecclist.c \
drivers/ril/ril_gprs.c \
drivers/ril/ril_gprs_context.c \
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/configure.ac
^
|
@@ -189,8 +189,8 @@
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"
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/qmimodem/lte.c
^
|
(renamed from drivers/qmimodem/lte.c)
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_cbs.c
^
|
@@ -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
@@ -144,10 +144,19 @@
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);
+
+ if (pdu) {
+ DBG_(cd, "%u bytes", pdu_len);
+ ofono_cbs_notify(cd->cbs, pdu, pdu_len);
+ }
+ }
}
static void ril_cbs_probe_done_cb(GRilIoChannel *io, int status,
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_cell_info.c
^
|
@@ -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 @@
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 @@
(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,
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_config.c
^
|
@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2015-2019 Jolla Ltd.
- * Copyright (C) 2019 Open Mobile Platform LLC.
+ * Copyright (C) 2015-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
@@ -186,6 +186,72 @@
return FALSE;
}
+gboolean ril_config_get_mask(GKeyFile *file, const char *group,
+ const char *key, int *result,
+ const char *name, int value, ...)
+{
+ char *str = ril_config_get_string(file, group, key);
+ gboolean ok = FALSE;
+
+ if (result) {
+ *result = 0;
+ }
+
+ if (str) {
+ /*
+ * Some people are thinking that # is a comment
+ * anywhere on the line, not just at the beginning
+ */
+ char *comment = strchr(str, '#');
+ char **values, **ptr;
+
+ if (comment) *comment = 0;
+ values = g_strsplit(str, "+", -1);
+
+ for (ok = TRUE, ptr = values; *ptr && ok; ptr++) {
+ const char* found_str = NULL;
+ const char* s = g_strstrip(*ptr);
+
+ if (!strcasecmp(s, name)) {
+ found_str = name;
+ if (result) {
+ *result |= value;
+ }
+ } else {
+ va_list args;
+ const char* known;
+
+ va_start(args, value);
+ while ((known = va_arg(args, char*)) != NULL) {
+ const int bit = va_arg(args, int);
+
+ if (!strcasecmp(s, known)) {
+ found_str = known;
+ if (result) {
+ *result |= bit;
+ }
+ break;
+ }
+ }
+ va_end(args);
+ }
+
+ if (!found_str) {
+ ofono_error("Unknown bit '%s' in %s", s, key);
+ ok = FALSE;
+ }
+ }
+
+ g_strfreev(values);
+ g_free(str);
+ }
+
+ if (!ok && result) {
+ *result = 0;
+ }
+ return ok;
+}
+
GUtilInts *ril_config_get_ints(GKeyFile *file, const char *group,
const char *key)
{
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_config.h
^
|
@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2015-2019 Jolla Ltd.
- * Copyright (C) 2019 Open Mobile Platform LLC.
+ * Copyright (C) 2015-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
@@ -35,7 +35,12 @@
const char *key, int flag, int *flags);
gboolean ril_config_get_enum(GKeyFile *file, const char *group,
const char *key, int *result,
- const char *name, int value, ...);
+ const char *name, int value, ...)
+ G_GNUC_NULL_TERMINATED;
+gboolean ril_config_get_mask(GKeyFile *file, const char *group,
+ const char *key, int *result,
+ const char *name, int value, ...)
+ G_GNUC_NULL_TERMINATED;
GUtilInts *ril_config_get_ints(GKeyFile *file, const char *group,
const char *key);
char *ril_config_ints_to_string(GUtilInts *ints, char separator);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/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
@@ -205,10 +205,44 @@
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,
@@ -341,6 +375,19 @@
#define RIL_FACILITY_UNLOCK "0"
#define RIL_FACILITY_LOCK "1"
+/* See RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER (RIL_VERSION >= 15) */
+enum ril_unsolicited_response_filter {
+ RIL_UR_SIGNAL_STRENGTH = 0x01,
+ RIL_UR_FULL_NETWORK_STATE = 0x02,
+ 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 */
/*
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_data.c
^
|
@@ -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
@@ -14,6 +14,8 @@
* GNU General Public License for more details.
*/
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#include "ril_data.h"
#include "ril_radio.h"
#include "ril_network.h"
@@ -29,6 +31,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 */
@@ -77,6 +81,7 @@
enum ril_data_io_event_id {
IO_EVENT_DATA_CALL_LIST_CHANGED,
IO_EVENT_RESTRICTED_STATE_CHANGED,
+ IO_EVENT_EOF,
IO_EVENT_COUNT
};
@@ -115,6 +120,7 @@
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 {
@@ -187,6 +193,7 @@
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)
{
@@ -815,6 +822,31 @@
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)
{
@@ -839,33 +871,49 @@
}
}
- 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);
@@ -1151,6 +1199,11 @@
/*==========================================================================*
* 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)
@@ -1179,6 +1232,17 @@
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;
@@ -1238,6 +1302,9 @@
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,
@@ -1364,6 +1431,20 @@
}
}
+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;
@@ -1535,24 +1616,11 @@
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);
@@ -1563,6 +1631,11 @@
{
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);
@@ -1648,34 +1721,39 @@
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) {
@@ -1684,7 +1762,7 @@
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);
}
@@ -1694,7 +1772,7 @@
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);
}
}
}
@@ -1723,7 +1801,7 @@
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) {
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_data.h
^
|
@@ -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 @@
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);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_devmon.h
^
|
@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2019 Jolla Ltd.
+ * Copyright (C) 2019-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
@@ -51,10 +52,21 @@
struct ril_devmon *ril_devmon_ds_new(void);
/*
+ * This Device Monitor implementation controls network state updates
+ * by sending SET_UNSOLICITED_RESPONSE_FILTER.
+ */
+struct ril_devmon *ril_devmon_ur_new(void);
+
+/*
* This one selects the type based on the RIL version.
*/
struct ril_devmon *ril_devmon_auto_new(void);
+/*
+ * This one combines several methods. Takes ownership of ril_devmon objects.
+ */
+struct ril_devmon *ril_devmon_combine(struct ril_devmon *devmon[], guint n);
+
/* Utilities (NULL tolerant) */
struct ril_devmon_io *ril_devmon_start_io(struct ril_devmon *devmon,
GRilIoChannel *channel, struct sailfish_cell_info *cell_info);
|
[-]
[+]
|
Added |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_devmon_combine.c
^
|
@@ -0,0 +1,104 @@
+/*
+ * oFono - Open Source Telephony - RIL-based devices
+ *
+ * Copyright (C) 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ril_devmon.h"
+
+#include <ofono/log.h>
+
+typedef struct ril_devmon_combine {
+ struct ril_devmon pub;
+ struct ril_devmon **impl;
+ guint count;
+} DevMon;
+
+typedef struct ril_devmon_combine_io {
+ struct ril_devmon_io pub;
+ struct ril_devmon_io **impl;
+ guint count;
+} DevMonIo;
+
+static inline DevMon *ril_devmon_combine_cast(struct ril_devmon *dm)
+{
+ return G_CAST(dm, DevMon, pub);
+}
+
+static inline DevMonIo *ril_devmon_ds_io_cast(struct ril_devmon_io *io)
+{
+ return G_CAST(io, DevMonIo, pub);
+}
+
+static void ril_devmon_combine_io_free(struct ril_devmon_io *io)
+{
+ guint i;
+ DevMonIo *self = ril_devmon_ds_io_cast(io);
+
+ for (i = 0; i < self->count; i++) {
+ ril_devmon_io_free(self->impl[i]);
+ }
+ g_free(self);
+}
+
+static struct ril_devmon_io *ril_devmon_combine_start_io(struct ril_devmon *dm,
+ GRilIoChannel *chan, struct sailfish_cell_info *ci)
+{
+ guint i;
+ DevMon *self = ril_devmon_combine_cast(dm);
+ DevMonIo *io = g_malloc0(sizeof(DevMonIo) +
+ sizeof(struct ril_devmon_io *) * self->count);
+
+ io->pub.free = ril_devmon_combine_io_free;
+ io->impl = (struct ril_devmon_io**)(io + 1);
+ io->count = self->count;
+ for (i = 0; i < io->count; i++) {
+ io->impl[i] = ril_devmon_start_io(self->impl[i], chan, ci);
+ }
+ return &io->pub;
+}
+
+static void ril_devmon_combine_free(struct ril_devmon *dm)
+{
+ DevMon *self = ril_devmon_combine_cast(dm);
+ guint i;
+
+ for (i = 0; i < self->count; i++) {
+ ril_devmon_free(self->impl[i]);
+ }
+ g_free(self);
+}
+
+struct ril_devmon *ril_devmon_combine(struct ril_devmon *dm[], guint n)
+{
+ guint i;
+ DevMon *self = g_malloc0(sizeof(DevMon) +
+ sizeof(struct ril_devmon *) * n);
+
+ self->pub.free = ril_devmon_combine_free;
+ self->pub.start_io = ril_devmon_combine_start_io;
+ self->impl = (struct ril_devmon **)(self + 1);
+ self->count = n;
+ for (i = 0; i < n; i++) {
+ self->impl[i] = dm[i];
+ }
+ return &self->pub;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-basic-offset: 8
+ * indent-tabs-mode: t
+ * End:
+ */
|
[-]
[+]
|
Added |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_devmon_ur.c
^
|
@@ -0,0 +1,254 @@
+/*
+ * oFono - Open Source Telephony - RIL-based devices
+ *
+ * Copyright (C) 2019 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ril_devmon.h"
+
+#include <ofono/log.h>
+#include <ofono/ril-constants.h>
+
+#include <mce_battery.h>
+#include <mce_charger.h>
+#include <mce_display.h>
+
+#include <grilio_channel.h>
+#include <grilio_request.h>
+
+#include <gutil_macros.h>
+
+#define RIL_UR_ENABLE_ALL (RIL_UR_SIGNAL_STRENGTH | \
+ RIL_UR_FULL_NETWORK_STATE | \
+ RIL_UR_DATA_CALL_DORMANCY_CHANGED)
+
+enum ril_devmon_ur_battery_event {
+ BATTERY_EVENT_VALID,
+ BATTERY_EVENT_STATUS,
+ BATTERY_EVENT_COUNT
+};
+
+enum ril_devmon_ur_charger_event {
+ CHARGER_EVENT_VALID,
+ CHARGER_EVENT_STATE,
+ CHARGER_EVENT_COUNT
+};
+
+enum ril_devmon_ur_display_event {
+ DISPLAY_EVENT_VALID,
+ DISPLAY_EVENT_STATE,
+ DISPLAY_EVENT_COUNT
+};
+
+typedef struct ril_devmon_ur {
+ struct ril_devmon pub;
+ MceBattery *battery;
+ MceCharger *charger;
+ MceDisplay *display;
+} DevMon;
+
+typedef struct ril_devmon_ur_io {
+ struct ril_devmon_io pub;
+ struct sailfish_cell_info *cell_info;
+ MceBattery *battery;
+ MceCharger *charger;
+ MceDisplay *display;
+ GRilIoChannel *io;
+ gboolean display_on;
+ gboolean unsol_filter_supported;
+ gulong battery_event_id[BATTERY_EVENT_COUNT];
+ gulong charger_event_id[CHARGER_EVENT_COUNT];
+ gulong display_event_id[DISPLAY_EVENT_COUNT];
+ guint req_id;
+} DevMonIo;
+
+#define DBG_(self,fmt,args...) DBG("%s: " fmt, (self)->io->name, ##args)
+
+inline static DevMon *ril_devmon_ur_cast(struct ril_devmon *pub)
+{
+ return G_CAST(pub, DevMon, pub);
+}
+
+inline static DevMonIo *ril_devmon_ur_io_cast(struct ril_devmon_io *pub)
+{
+ return G_CAST(pub, DevMonIo, pub);
+}
+
+static inline gboolean ril_devmon_ur_battery_ok(MceBattery *battery)
+{
+ return battery->valid && battery->status >= MCE_BATTERY_OK;
+}
+
+static inline gboolean ril_devmon_ur_charging(MceCharger *charger)
+{
+ return charger->valid && charger->state == MCE_CHARGER_ON;
+}
+
+static gboolean ril_devmon_ur_display_on(MceDisplay *display)
+{
+ return display->valid && display->state != MCE_DISPLAY_STATE_OFF;
+}
+
+static void ril_devmon_ur_io_unsol_response_filter_sent(GRilIoChannel *io,
+ int status, const void *data, guint len,
+ void *user_data)
+{
+ DevMonIo *self = user_data;
+
+ self->req_id = 0;
+ if (status == RIL_E_REQUEST_NOT_SUPPORTED) {
+ /* This is a permanent failure */
+ DBG_(self, "Unsolicited response filter is not supported");
+ self->unsol_filter_supported = FALSE;
+ }
+}
+
+static void ril_devmon_ur_io_set_unsol_response_filter(DevMonIo *self)
+{
+ if (self->unsol_filter_supported) {
+ const gint32 value = self->display_on ? RIL_UR_ENABLE_ALL : 0;
+ GRilIoRequest *req = grilio_request_array_int32_new(1, value);
+
+ DBG_(self, "Setting unsolicited response filter: %u", value);
+
+ grilio_channel_cancel_request(self->io, self->req_id, FALSE);
+ self->req_id =
+ grilio_channel_send_request_full(self->io, req,
+ RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER,
+ ril_devmon_ur_io_unsol_response_filter_sent,
+ NULL, self);
+ grilio_request_unref(req);
+ }
+}
+
+static void ril_devmon_ur_io_set_cell_info_update_interval(DevMonIo *self)
+{
+ sailfish_cell_info_set_update_interval(self->cell_info,
+ (self->display_on && (ril_devmon_ur_charging(self->charger) ||
+ ril_devmon_ur_battery_ok(self->battery))) ?
+ RIL_CELL_INFO_INTERVAL_SHORT_MS :
+ RIL_CELL_INFO_INTERVAL_LONG_MS);
+}
+
+static void ril_devmon_ur_io_battery_cb(MceBattery *battery, void *user_data)
+{
+ ril_devmon_ur_io_set_cell_info_update_interval(user_data);
+}
+
+static void ril_devmon_ur_io_charger_cb(MceCharger *charger, void *user_data)
+{
+ ril_devmon_ur_io_set_cell_info_update_interval(user_data);
+}
+
+static void ril_devmon_ur_io_display_cb(MceDisplay *display, void *user_data)
+{
+ DevMonIo *self = user_data;
+ const gboolean display_on = ril_devmon_ur_display_on(display);
+
+ if (self->display_on != display_on) {
+ self->display_on = display_on;
+ ril_devmon_ur_io_set_unsol_response_filter(self);
+ ril_devmon_ur_io_set_cell_info_update_interval(self);
+ }
+}
+
+static void ril_devmon_ur_io_free(struct ril_devmon_io *devmon_io)
+{
+ DevMonIo *self = ril_devmon_ur_io_cast(devmon_io);
+
+ mce_battery_remove_all_handlers(self->battery, self->battery_event_id);
+ mce_battery_unref(self->battery);
+
+ mce_charger_remove_all_handlers(self->charger, self->charger_event_id);
+ mce_charger_unref(self->charger);
+
+ mce_display_remove_all_handlers(self->display, self->display_event_id);
+ mce_display_unref(self->display);
+
+ grilio_channel_cancel_request(self->io, self->req_id, FALSE);
+ grilio_channel_unref(self->io);
+
+ sailfish_cell_info_unref(self->cell_info);
+ g_free(self);
+}
+
+static struct ril_devmon_io *ril_devmon_ur_start_io(struct ril_devmon *devmon,
+ GRilIoChannel *io, struct sailfish_cell_info *cell_info)
+{
+ DevMon *ur = ril_devmon_ur_cast(devmon);
+ DevMonIo *self = g_new0(DevMonIo, 1);
+
+ self->pub.free = ril_devmon_ur_io_free;
+ self->unsol_filter_supported = TRUE;
+ self->io = grilio_channel_ref(io);
+ self->cell_info = sailfish_cell_info_ref(cell_info);
+
+ self->battery = mce_battery_ref(ur->battery);
+ self->battery_event_id[BATTERY_EVENT_VALID] =
+ mce_battery_add_valid_changed_handler(self->battery,
+ ril_devmon_ur_io_battery_cb, self);
+ self->battery_event_id[BATTERY_EVENT_STATUS] =
+ mce_battery_add_status_changed_handler(self->battery,
+ ril_devmon_ur_io_battery_cb, self);
+
+ self->charger = mce_charger_ref(ur->charger);
+ self->charger_event_id[CHARGER_EVENT_VALID] =
+ mce_charger_add_valid_changed_handler(self->charger,
+ ril_devmon_ur_io_charger_cb, self);
+ self->charger_event_id[CHARGER_EVENT_STATE] =
+ mce_charger_add_state_changed_handler(self->charger,
+ ril_devmon_ur_io_charger_cb, self);
+
+ self->display = mce_display_ref(ur->display);
+ self->display_on = ril_devmon_ur_display_on(self->display);
+ self->display_event_id[DISPLAY_EVENT_VALID] =
+ mce_display_add_valid_changed_handler(self->display,
+ ril_devmon_ur_io_display_cb, self);
+ self->display_event_id[DISPLAY_EVENT_STATE] =
+ mce_display_add_state_changed_handler(self->display,
+ ril_devmon_ur_io_display_cb, self);
+
+ ril_devmon_ur_io_set_unsol_response_filter(self);
+ ril_devmon_ur_io_set_cell_info_update_interval(self);
+ return &self->pub;
+}
+
+static void ril_devmon_ur_free(struct ril_devmon *devmon)
+{
+ DevMon *self = ril_devmon_ur_cast(devmon);
+
+ mce_battery_unref(self->battery);
+ mce_charger_unref(self->charger);
+ mce_display_unref(self->display);
+ g_free(self);
+}
+
+struct ril_devmon *ril_devmon_ur_new()
+{
+ DevMon *self = g_new0(DevMon, 1);
+
+ self->pub.free = ril_devmon_ur_free;
+ self->pub.start_io = ril_devmon_ur_start_io;
+ self->battery = mce_battery_new();
+ self->charger = mce_charger_new();
+ self->display = mce_display_new();
+ return &self->pub;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-basic-offset: 8
+ * indent-tabs-mode: t
+ * End:
+ */
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_ecclist.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
@@ -14,6 +14,8 @@
* GNU General Public License for more details.
*/
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#include "ril_ecclist.h"
#include "ril_log.h"
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_modem.c
^
|
@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2015-2019 Jolla Ltd.
+ * Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
@@ -29,7 +29,6 @@
#include <ofono/watch.h>
-#define MAX_PDP_CONTEXTS (2)
#define ONLINE_TIMEOUT_SECS (15) /* 20 sec is hardcoded in ofono core */
enum ril_modem_power_state {
@@ -219,22 +218,21 @@
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");
}
}
@@ -243,7 +241,6 @@
struct ril_modem_data *md = data;
GASSERT(md->modem.radio == radio);
- ril_modem_update_radio_settings(md);
ril_modem_update_online_state(md);
}
@@ -307,15 +304,22 @@
ofono_sms_create(modem, 0, RILMODEM_DRIVER, md);
gprs = ofono_gprs_create(modem, 0, RILMODEM_DRIVER, md);
if (gprs) {
- int i;
+ guint i;
+ static const enum ofono_gprs_context_type ap_types[] = {
+ OFONO_GPRS_CONTEXT_TYPE_INTERNET,
+ OFONO_GPRS_CONTEXT_TYPE_MMS,
+ OFONO_GPRS_CONTEXT_TYPE_IMS
+ };
- for (i = 0; i < MAX_PDP_CONTEXTS; i++) {
+ /* Create a context for each type */
+ for (i = 0; i < G_N_ELEMENTS(ap_types); i++) {
struct ofono_gprs_context *gc =
ofono_gprs_context_create(modem, 0,
RILMODEM_DRIVER, md);
if (gc == NULL)
break;
+ ofono_gprs_context_set_type(gc, ap_types[i]);
ofono_gprs_add_context(gprs, gc);
}
}
@@ -417,7 +421,9 @@
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);
ril_sim_settings_unref(modem->sim_settings);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_netreg.c
^
|
@@ -20,10 +20,12 @@
#include "ril_vendor.h"
#include "ril_log.h"
+#include "ofono.h"
#include "common.h"
#include "simutil.h"
-#define REGISTRATION_TIMEOUT (100*1000) /* ms */
+#include <ofono/watch.h>
+
#define REGISTRATION_MAX_RETRIES (2)
enum ril_netreg_events {
@@ -41,9 +43,11 @@
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;
@@ -53,6 +57,7 @@
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 {
@@ -192,11 +197,74 @@
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 @@
}
/* 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 @@
}
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);
@@ -301,14 +372,13 @@
}
}
-static void ril_netreg_register_auto(struct ofono_netreg *netreg,
+static void ril_netreg_set_register_auto(struct ril_netreg *nd,
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_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,
@@ -317,6 +387,44 @@
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();
+
+ grilio_queue_send_request_full(nd->q, req,
+ 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);
+}
+
static void ril_netreg_register_manual(struct ofono_netreg *netreg,
const char *mcc, const char *mnc,
ofono_netreg_register_cb_t cb, void *data)
@@ -327,7 +435,7 @@
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,
@@ -557,12 +665,15 @@
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;
+ nd->network_selection_timeout = config->network_selection_timeout;
ofono_netreg_set_data(netreg, nd);
nd->timer_id = g_idle_add(ril_netreg_register, nd);
@@ -589,6 +700,7 @@
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);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_network.c
^
|
@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2015-2019 Jolla Ltd.
- * Copyright (C) 2019 Open Mobile Platform LLC.
+ * Copyright (C) 2015-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
@@ -14,8 +14,11 @@
* GNU General Public License for more details.
*/
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#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"
@@ -28,13 +31,12 @@
#include <gutil_misc.h>
#include <gutil_macros.h>
-#include <gutil_ints.h>
-#include <gutil_intarray.h>
#include <ofono/netreg.h>
#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 @@
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_unsol_event {
UNSOL_EVENT_NETWORK_STATE,
- UNSOL_EVENT_RADIO_CAPABILITY,
UNSOL_EVENT_COUNT
};
@@ -89,12 +96,14 @@
struct ril_network_priv {
GRilIoChannel *io;
GRilIoQueue *q;
- GUtilInts *supported_modes;
struct ril_radio *radio;
+ struct ril_radio_caps *caps;
struct ril_sim_card *simcard;
struct ril_vendor *vendor;
struct ofono_watch *watch;
int rat;
+ enum ril_pref_net_type lte_network_mode;
+ enum ril_pref_net_type umts_network_mode;
int network_mode_timeout;
char *log_prefix;
guint operator_poll_id;
@@ -105,13 +114,14 @@
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];
gboolean need_initial_attach_apn;
gboolean set_initial_attach_apn;
struct ofono_network_operator operator;
- int rats[OFONO_RADIO_ACCESS_MODE_ALL + 1];
gboolean assert_rat;
gboolean force_gsm_when_radio_off;
gboolean use_data_profiles;
@@ -125,7 +135,6 @@
SIGNAL_VOICE_STATE_CHANGED,
SIGNAL_DATA_STATE_CHANGED,
SIGNAL_PREF_MODE_CHANGED,
- SIGNAL_MAX_PREF_MODE_CHANGED,
SIGNAL_COUNT
};
@@ -133,7 +142,6 @@
#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 };
@@ -152,60 +160,14 @@
/* Some assumptions: */
G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_ANY == 0);
-G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_GSM == 1);
-G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_UMTS == 2);
-G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_LTE == 4);
-G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_ALL == 7);
-
-/* Default ofono_radio_access_mode -> ril_pref_net_type map */
-static const int ril_network_default_rats[OFONO_RADIO_ACCESS_MODE_ALL + 1] = {
- -1, /* ANY, it has a special meaning */
- PREF_NET_TYPE_GSM_ONLY, /* GSM */
- PREF_NET_TYPE_WCDMA, /* UMTS */
- PREF_NET_TYPE_GSM_WCDMA_AUTO, /* UMTS + GSM */
- PREF_NET_TYPE_LTE_ONLY, /* LTE */
- -1, /* LTE + GSM */
- /* PREF_NET_TYPE_LTE_WCDMA doesn't seem to work on Jolla1 */
- -1, /* LTE + UMTS */
- PREF_NET_TYPE_LTE_GSM_WCDMA, /* LTE + UMTS + GSM */
-};
+G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_GSM > OFONO_RADIO_ACCESS_MODE_ANY);
+G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_UMTS > OFONO_RADIO_ACCESS_MODE_GSM);
+G_STATIC_ASSERT(OFONO_RADIO_ACCESS_MODE_LTE > OFONO_RADIO_ACCESS_MODE_UMTS);
static void ril_network_query_pref_mode(struct ril_network *self);
static void ril_network_check_pref_mode(struct ril_network *self,
gboolean immediate);
-GUtilInts *ril_network_supported_modes(struct ril_network *self)
-{
- if (G_LIKELY(self)) {
- struct ril_network_priv *priv = self->priv;
-
- if (!priv->supported_modes) {
- GUtilIntArray *modes = gutil_int_array_new();
- int i;
-
- for (i = 0; i<G_N_ELEMENTS(priv->rats); i++) {
- /*
- * Check that the mask doesn't contain
- * any disabled technology and that
- * there is RIL mapping for this
- * combination of technologies.
- */
- if (!(i & ~self->settings->techs) &&
- priv->rats[i] >= 0) {
- gutil_int_array_append(modes, i);
- }
- }
-
- priv->supported_modes =
- gutil_int_array_free_to_ints(modes);
- }
-
- return priv->supported_modes;
- }
-
- return NULL;
-}
-
static void ril_network_emit(struct ril_network *self,
enum ril_network_signal sig)
{
@@ -465,6 +427,18 @@
}
}
+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)
{
@@ -477,6 +451,7 @@
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);
@@ -514,37 +489,59 @@
}
}
-static enum ofono_radio_access_mode ril_network_rat_to_mode
- (struct ril_network *self, int rat)
+static enum ofono_radio_access_mode ril_network_rat_to_mode(int rat)
{
- if (rat >= 0) {
- struct ril_network_priv *priv = self->priv;
- int i;
-
- for (i = 0; i < G_N_ELEMENTS(priv->rats); i++) {
- if (priv->rats[i] == rat) {
- return i;
- }
- }
+ switch (rat) {
+ case PREF_NET_TYPE_LTE_CDMA_EVDO:
+ case PREF_NET_TYPE_LTE_GSM_WCDMA:
+ case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
+ case PREF_NET_TYPE_LTE_ONLY:
+ case PREF_NET_TYPE_LTE_WCDMA:
+ return OFONO_RADIO_ACCESS_MODE_LTE;
+ case PREF_NET_TYPE_GSM_WCDMA_AUTO:
+ case PREF_NET_TYPE_WCDMA:
+ case PREF_NET_TYPE_GSM_WCDMA:
+ return OFONO_RADIO_ACCESS_MODE_UMTS;
+ default:
+ DBG("unexpected rat mode %d", rat);
+ case PREF_NET_TYPE_GSM_ONLY:
+ return OFONO_RADIO_ACCESS_MODE_GSM;
}
-
- DBG("unexpected rat mode %d", rat);
- return OFONO_RADIO_ACCESS_MODE_GSM;
}
static int ril_network_mode_to_rat(struct ril_network *self,
enum ofono_radio_access_mode mode)
{
+ struct ril_sim_settings *settings = self->settings;
struct ril_network_priv *priv = self->priv;
- int m = (mode == OFONO_RADIO_ACCESS_MODE_ANY) ?
- self->settings->techs : (mode & OFONO_RADIO_ACCESS_MODE_ALL);
- /* Turn lower bits off until we find the mapping */
- while (m && priv->rats[m] < 0) {
- m &= m - 1;
+ switch (mode) {
+ case OFONO_RADIO_ACCESS_MODE_ANY:
+ case OFONO_RADIO_ACCESS_MODE_LTE:
+ if (settings->techs & OFONO_RADIO_ACCESS_MODE_LTE) {
+ return priv->lte_network_mode;
+ }
+ /* no break */
+ default:
+ case OFONO_RADIO_ACCESS_MODE_UMTS:
+ if (settings->techs & OFONO_RADIO_ACCESS_MODE_UMTS) {
+ return priv->umts_network_mode;
+ }
+ /* no break */
+ case OFONO_RADIO_ACCESS_MODE_GSM:
+ return PREF_NET_TYPE_GSM_ONLY;
}
+}
- return priv->rats[m] >= 0 ? priv->rats[m] : PREF_NET_TYPE_GSM_ONLY;
+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
@@ -570,9 +567,16 @@
* 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)
@@ -583,9 +587,9 @@
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;
@@ -954,7 +958,7 @@
const enum ofono_radio_access_mode expected =
ril_network_actual_pref_mode(self);
const enum ofono_radio_access_mode actual =
- ril_network_rat_to_mode(self, priv->rat);
+ ril_network_rat_to_mode(priv->rat);
if (priv->timer[TIMER_FORCE_CHECK_PREF_MODE]) {
ril_network_stop_timer(self,
@@ -969,8 +973,8 @@
if (priv->rat >= 0 && actual != expected) {
DBG_(self, "rat %d (%s), expected %s", priv->rat,
- ril_access_mode_to_string(actual),
- ril_access_mode_to_string(expected));
+ ofono_radio_access_mode_to_string(actual),
+ ofono_radio_access_mode_to_string(expected));
}
if (immediate) {
@@ -990,6 +994,14 @@
}
}
+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;
@@ -1010,19 +1022,19 @@
const enum ofono_radio_access_mode pref_mode = self->pref_mode;
priv->rat = ril_network_parse_pref_resp(data, len);
- self->pref_mode = ril_network_rat_to_mode(self, priv->rat);
+ self->pref_mode = ril_network_rat_to_mode(priv->rat);
DBG_(self, "rat mode %d (%s)", priv->rat,
- ril_access_mode_to_string(self->pref_mode));
+ ofono_radio_access_mode_to_string(self->pref_mode));
if (self->pref_mode != pref_mode) {
ril_network_emit(self, SIGNAL_PREF_MODE_CHANGED);
}
/*
- * 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);
}
}
@@ -1033,22 +1045,22 @@
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(self, priv->rat);
- DBG_(self, "rat mode %d (%s)", priv->rat,
- ril_access_mode_to_string(self->pref_mode));
- if (self->pref_mode != pref_mode) {
- ril_network_emit(self, SIGNAL_PREF_MODE_CHANGED);
- }
+ 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 (ril_network_can_set_pref_mode(self)) {
- ril_network_check_pref_mode(self, FALSE);
+ 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);
+ }
}
}
@@ -1058,6 +1070,7 @@
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,
@@ -1071,34 +1084,82 @@
{
if (self && (self->max_pref_mode != max_mode || force_check)) {
if (self->max_pref_mode != max_mode) {
- guint i, n;
- GUtilInts *modes = ril_network_supported_modes(self);
- const int* values = gutil_ints_get_data(modes, &n);
- enum ofono_radio_access_mode full_max_mode = max_mode;
- /* Extend max_mode with additional lower bits */
- for (i = 0; i < n; i++) {
- enum ofono_radio_access_mode mode = values[i];
- if ((mode & max_mode) == max_mode &&
- max_mode > mode) {
- full_max_mode |= mode;
- }
- }
- DBG_(self, "rat mode %d (%s)", full_max_mode,
- ril_access_mode_to_string(full_max_mode));
- self->max_pref_mode = full_max_mode;
- ril_network_emit(self, SIGNAL_MAX_PREF_MODE_CHANGED);
+ DBG_(self, "rat mode %d (%s)", max_mode,
+ ofono_radio_access_mode_to_string(max_mode));
+ self->max_pref_mode = max_mode;
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;
- priv->assert_rat = TRUE;
- ril_network_check_pref_mode(self, immediate);
+ 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->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,
@@ -1129,13 +1190,6 @@
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)) {
@@ -1158,16 +1212,6 @@
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);
@@ -1288,9 +1332,8 @@
DBG_(self, "");
/* Copy relevant config values */
- memcpy(priv->rats, ril_network_default_rats, sizeof(priv->rats));
- priv->rats[OFONO_RADIO_ACCESS_MODE_UMTS] = config->umts_network_mode;
- priv->rats[OFONO_RADIO_ACCESS_MODE_ALL] = config->lte_network_mode;
+ priv->lte_network_mode = config->lte_network_mode;
+ priv->umts_network_mode = config->umts_network_mode;
priv->network_mode_timeout = config->network_mode_timeout;
priv->force_gsm_when_radio_off = config->force_gsm_when_radio_off;
priv->use_data_profiles = config->use_data_profiles;
@@ -1301,10 +1344,6 @@
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,
@@ -1399,6 +1438,7 @@
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);
@@ -1408,7 +1448,6 @@
ril_sim_settings_unref(self->settings);
ril_vendor_unref(priv->vendor);
g_slist_free_full(priv->data_profiles, g_free);
- gutil_ints_unref(priv->supported_modes);
g_free(priv->log_prefix);
G_OBJECT_CLASS(ril_network_parent_class)->finalize(object);
}
@@ -1421,7 +1460,6 @@
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);
}
/*
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_network.h
^
|
@@ -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_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,11 +55,13 @@
struct ril_network *ril_network_ref(struct ril_network *net);
void ril_network_unref(struct ril_network *net);
-GUtilInts *ril_network_supported_modes(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);
@@ -68,8 +71,6 @@
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);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_oem_raw.c
^
|
@@ -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 @@
#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 @@
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 @@
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 @@
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 @@
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 {
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_plugin.c
^
|
@@ -56,6 +56,10 @@
#include <ofono/storage.h>
#include <ofono/ril-transport.h>
+#define OFONO_RADIO_ACCESS_MODE_ALL (OFONO_RADIO_ACCESS_MODE_GSM |\
+ OFONO_RADIO_ACCESS_MODE_UMTS |\
+ OFONO_RADIO_ACCESS_MODE_LTE)
+
#define RIL_DEVICE_IDENTITY_RETRIES_LAST 2
#define RIL_SUB_SIZE 4
@@ -69,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
@@ -89,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
@@ -130,6 +136,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"
@@ -145,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"
@@ -175,10 +183,9 @@
};
enum ril_devmon_opt {
- RIL_DEVMON_NONE,
- RIL_DEVMON_AUTO,
- RIL_DEVMON_SS,
- RIL_DEVMON_DS
+ RIL_DEVMON_SS = 0x01,
+ RIL_DEVMON_DS = 0x02,
+ RIL_DEVMON_UR = 0x04
};
struct ril_plugin_identity {
@@ -223,6 +230,7 @@
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;
@@ -359,6 +367,7 @@
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
@@ -378,12 +387,16 @@
}
if (slot->cell_info) {
+ sailfish_manager_set_cell_info(slot->handle, NULL);
sailfish_cell_info_unref(slot->cell_info);
slot->cell_info = NULL;
}
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;
}
@@ -897,7 +910,7 @@
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);
@@ -905,9 +918,10 @@
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);
}
}
@@ -1035,13 +1049,13 @@
slot->path, slot->config.techs, slot->imei,
slot->imeisv, ril_plugin_sim_state(slot),
slot->slot_flags);
- sailfish_manager_set_cell_info(slot->handle, slot->cell_info);
grilio_channel_set_enabled(slot->io, slot->handle->enabled);
/* Check if this was the last slot we were waiting for */
ril_plugin_check_if_started(plugin);
}
+ sailfish_manager_set_cell_info(slot->handle, slot->cell_info);
ril_plugin_check_modem(slot);
ril_plugin_check_ready(slot);
}
@@ -1057,8 +1071,11 @@
static void ril_plugin_init_io(ril_slot *slot)
{
if (!slot->io) {
- slot->io = grilio_channel_new(ofono_ril_transport_connect
- (slot->transport_name, slot->transport_params));
+ struct grilio_transport *transport =
+ ofono_ril_transport_connect(slot->transport_name,
+ slot->transport_params);
+
+ slot->io = grilio_channel_new(transport);
if (slot->io) {
ril_debug_trace_update(slot);
ril_debug_dump_update(slot);
@@ -1090,6 +1107,7 @@
slot);
}
}
+ grilio_transport_unref(transport);
}
if (!slot->io) {
@@ -1135,6 +1153,8 @@
slot->modem = NULL;
ril_data_allow(slot->data, RIL_DATA_ROLE_NONE);
+ ril_radio_caps_request_free(slot->caps_req);
+ slot->caps_req = NULL;
}
}
@@ -1190,6 +1210,8 @@
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;
@@ -1201,6 +1223,7 @@
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 =
@@ -1241,6 +1264,7 @@
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 =
@@ -1253,6 +1277,7 @@
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 =
@@ -1476,6 +1501,14 @@
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,
@@ -1526,7 +1559,7 @@
break;
}
- if (!ril_access_mode_from_string(s, &m)) {
+ if (!ofono_radio_access_mode_from_string(s, &m)) {
ofono_warn("Unknown technology %s in [%s] "
"section of %s", s, group,
RILMODEM_CONF_FILE);
@@ -1562,6 +1595,14 @@
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) {
@@ -1702,23 +1743,32 @@
}
/* deviceStateTracking */
- if (ril_config_get_enum(file, group, RILCONF_DEVMON, &ival,
- "none", RIL_DEVMON_NONE,
- "auto", RIL_DEVMON_AUTO,
+ if (ril_config_get_mask(file, group, RILCONF_DEVMON, &ival,
"ds", RIL_DEVMON_DS,
- "ss", RIL_DEVMON_SS, NULL)) {
- DBG("%s: " RILCONF_DEVMON " %s", group,
- ival == RIL_DEVMON_NONE ? "off" :
- ival == RIL_DEVMON_DS ? "on" :
- ival == RIL_DEVMON_SS ? "legacy" :
- "auto");
- if (ival != RIL_DEVMON_AUTO) {
- /* Default is automatic, reallocate the object */
- ril_devmon_free(slot->devmon);
- slot->devmon =
- (ival == RIL_DEVMON_DS ? ril_devmon_ds_new() :
- ival == RIL_DEVMON_SS ? ril_devmon_ss_new() :
- NULL);
+ "ss", RIL_DEVMON_SS,
+ "ur", RIL_DEVMON_UR, NULL) && ival) {
+ int n = 0;
+ struct ril_devmon *devmon[3];
+
+ if (ival & RIL_DEVMON_DS) devmon[n++] = ril_devmon_ds_new();
+ if (ival & RIL_DEVMON_SS) devmon[n++] = ril_devmon_ss_new();
+ if (ival & RIL_DEVMON_UR) devmon[n++] = ril_devmon_ur_new();
+ DBG("%s: " RILCONF_DEVMON " 0x%x", group, ival);
+ ril_devmon_free(slot->devmon);
+ slot->devmon = ril_devmon_combine(devmon, n);
+ } else {
+ /* Try special values */
+ sval = ril_config_get_string(file, group, RILCONF_DEVMON);
+ if (sval) {
+ if (!g_ascii_strcasecmp(sval, "none")) {
+ DBG("%s: " RILCONF_DEVMON " %s", group, sval);
+ ril_devmon_free(slot->devmon);
+ slot->devmon = NULL;
+ } else if (!g_ascii_strcasecmp(sval, "auto")) {
+ DBG("%s: " RILCONF_DEVMON " %s", group, sval);
+ /* This is the default */
+ }
+ g_free(sval);
}
}
@@ -2149,10 +2199,24 @@
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)
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_radio.c
^
|
@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2015-2019 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
@@ -13,6 +13,8 @@
* GNU General Public License for more details.
*/
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#include "ril_radio.h"
#include "ril_util.h"
#include "ril_log.h"
@@ -239,7 +241,19 @@
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);
+ }
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_radio_caps.c
^
|
@@ -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
@@ -15,11 +15,9 @@
#include "ril_radio_caps.h"
#include "ril_radio.h"
-#include "ril_network.h"
#include "ril_sim_card.h"
#include "ril_sim_settings.h"
#include "ril_data.h"
-#include "ril_util.h"
#include "ril_log.h"
#include <grilio_queue.h>
@@ -27,6 +25,12 @@
#include <grilio_parser.h>
#include <grilio_request.h>
+#include <gutil_macros.h>
+#include <gutil_idlepool.h>
+#include <gutil_misc.h>
+
+#include <ofono/watch.h>
+
#define SET_CAPS_TIMEOUT_MS (30*1000)
#define GET_CAPS_TIMEOUT_MS (5*1000)
#define DATA_OFF_TIMEOUT_MS (10*1000)
@@ -41,6 +45,12 @@
* is doing.
*/
+enum ril_radio_caps_watch_events {
+ WATCH_EVENT_IMSI,
+ WATCH_EVENT_MODEM,
+ WATCH_EVENT_COUNT
+};
+
enum ril_radio_caps_sim_events {
SIM_EVENT_STATE_CHANGED,
SIM_EVENT_IO_ACTIVE_CHANGED,
@@ -49,7 +59,6 @@
enum ril_radio_caps_settings_events {
SETTINGS_EVENT_PREF_MODE,
- SETTINGS_EVENT_IMSI,
SETTINGS_EVENT_COUNT
};
@@ -60,32 +69,44 @@
IO_EVENT_COUNT
};
-struct ril_radio_caps {
- gint ref_count;
+enum ril_radio_events {
+ RADIO_EVENT_STATE,
+ RADIO_EVENT_ONLINE,
+ RADIO_EVENT_COUNT
+};
+
+typedef struct ril_radio_caps_object {
+ GObject object;
+ struct ril_radio_caps pub;
+ enum ofono_radio_access_mode requested_modes;
guint slot;
char *log_prefix;
GRilIoQueue *q;
GRilIoChannel *io;
+ GUtilIdlePool *idle_pool;
+ gulong watch_event_id[WATCH_EVENT_COUNT];
gulong settings_event_id[SETTINGS_EVENT_COUNT];
gulong simcard_event_id[SIM_EVENT_COUNT];
gulong io_event_id[IO_EVENT_COUNT];
- gulong max_pref_mode_event_id;
- gulong radio_event_id;
+ gulong radio_event_id[RADIO_EVENT_COUNT];
int tx_id;
int tx_pending;
+ struct ofono_watch *watch;
struct ril_data *data;
struct ril_radio *radio;
- struct ril_network *network;
+ struct ril_sim_settings *settings;
struct ril_sim_card *simcard;
- struct ril_radio_caps_manager *mgr;
struct ril_radio_capability cap;
struct ril_radio_capability old_cap;
struct ril_radio_capability new_cap;
-};
+} RilRadioCaps;
typedef struct ril_radio_caps_manager {
GObject object;
+ GUtilIdlePool *idle_pool;
GPtrArray *caps_list;
+ GPtrArray *order_list;
+ GPtrArray *requests;
guint check_id;
int tx_id;
int tx_phase_index;
@@ -93,6 +114,21 @@
struct ril_data_manager *data_manager;
} RilRadioCapsManager;
+typedef struct ril_radio_caps_closure {
+ GCClosure cclosure;
+ ril_radio_caps_cb_t cb;
+ void *user_data;
+} RilRadioCapsClosure;
+
+#define ril_radio_caps_closure_new() ((RilRadioCapsClosure *) \
+ g_closure_new_simple(sizeof(RilRadioCapsClosure), NULL))
+
+struct ril_radio_caps_request {
+ RilRadioCaps *caps;
+ enum ofono_radio_access_mode mode;
+ enum ril_data_role role;
+};
+
struct ril_radio_caps_check_data {
ril_radio_caps_check_cb_t cb;
void *data;
@@ -105,8 +141,22 @@
gboolean send_new_cap;
};
-typedef void (*ril_radio_caps_cb_t)(struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps);
+typedef void (*ril_radio_caps_enum_cb_t)(RilRadioCapsManager *self,
+ RilRadioCaps *caps);
+
+typedef GObjectClass RilRadioCapsClass;
+G_DEFINE_TYPE(RilRadioCaps, ril_radio_caps, G_TYPE_OBJECT)
+#define RADIO_CAPS_TYPE (ril_radio_caps_get_type())
+#define RADIO_CAPS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ RADIO_CAPS_TYPE, RilRadioCaps))
+
+enum ril_radio_caps_signal {
+ CAPS_SIGNAL_MODES_CHANGED,
+ CAPS_SIGNAL_COUNT
+};
+
+#define CAPS_SIGNAL_MODES_CHANGED_NAME "ril-modes-changed"
+static guint ril_radio_caps_signals[CAPS_SIGNAL_COUNT] = { 0 };
typedef GObjectClass RilRadioCapsManagerClass;
G_DEFINE_TYPE(RilRadioCapsManager, ril_radio_caps_manager, G_TYPE_OBJECT)
@@ -115,33 +165,84 @@
RADIO_CAPS_MANAGER_TYPE, RilRadioCapsManager))
enum ril_radio_caps_manager_signal {
- SIGNAL_ABORTED,
- SIGNAL_COUNT
+ CAPS_MANAGER_SIGNAL_ABORTED,
+ CAPS_MANAGER_SIGNAL_TX_DONE,
+ CAPS_MANAGER_SIGNAL_COUNT
};
-#define SIGNAL_ABORTED_NAME "ril-capsmgr-aborted"
-
-static guint ril_radio_caps_manager_signals[SIGNAL_COUNT] = { 0 };
+#define CAPS_MANAGER_SIGNAL_ABORTED_NAME "ril-capsmgr-aborted"
+#define CAPS_MANAGER_SIGNAL_TX_DONE_NAME "ril-capsmgr-tx-done"
+static guint ril_radio_caps_manager_signals[CAPS_MANAGER_SIGNAL_COUNT] = { 0 };
+
+static const struct ril_access_mode_raf {
+ enum ofono_radio_access_mode mode;
+ enum ril_radio_access_family raf;
+} ril_access_mode_raf_map[] = {
+ { OFONO_RADIO_ACCESS_MODE_GSM, RAF_EDGE | RAF_GPRS | RAF_GSM },
+ { OFONO_RADIO_ACCESS_MODE_UMTS, RAF_UMTS },
+ { OFONO_RADIO_ACCESS_MODE_LTE, RAF_LTE | RAF_LTE_CA }
+};
static const struct ril_radio_caps_request_tx_phase
ril_radio_caps_tx_phase[] = {
{ "START", RC_PHASE_START, RC_STATUS_NONE, FALSE },
{ "APPLY", RC_PHASE_APPLY, RC_STATUS_NONE, TRUE },
- { "FINISH", RC_PHASE_FINISH, RC_STATUS_SUCCESS, FALSE }
+ { "FINISH", RC_PHASE_FINISH, RC_STATUS_SUCCESS, TRUE }
};
static const struct ril_radio_caps_request_tx_phase
ril_radio_caps_fail_phase =
{ "ABORT", RC_PHASE_FINISH, RC_STATUS_FAIL, FALSE };
+static GUtilIdlePool *ril_radio_caps_shared_pool = NULL;
+
#define DBG_(caps, fmt, args...) DBG("%s" fmt, (caps)->log_prefix, ##args)
-static void ril_radio_caps_manager_next_phase
- (struct ril_radio_caps_manager *self);
-static void ril_radio_caps_manager_schedule_check
- (struct ril_radio_caps_manager *self);
-static void ril_radio_caps_manager_recheck_later
- (struct ril_radio_caps_manager *self);
+static void ril_radio_caps_manager_next_phase(RilRadioCapsManager *mgr);
+static void ril_radio_caps_manager_consider_requests(RilRadioCapsManager *mgr);
+static void ril_radio_caps_manager_schedule_check(RilRadioCapsManager *mgr);
+static void ril_radio_caps_manager_recheck_later(RilRadioCapsManager *mgr);
+static void ril_radio_caps_manager_add(RilRadioCapsManager *mgr,
+ RilRadioCaps *caps);
+static void ril_radio_caps_manager_remove(RilRadioCapsManager *mgr,
+ RilRadioCaps *caps);
+
+static void ril_radio_caps_permutate(GPtrArray *list, const guint *sample,
+ guint off, guint n)
+{
+ if (off < n) {
+ guint i;
+
+ ril_radio_caps_permutate(list, sample, off + 1, n);
+ for (i = off + 1; i < n; i++) {
+ guint *resample = g_memdup(sample, sizeof(guint) * n);
+
+ resample[off] = sample[i];
+ resample[i] = sample[off];
+ g_ptr_array_add(list, resample);
+ ril_radio_caps_permutate(list, resample, off + 1, n);
+ }
+ }
+}
+
+static void ril_radio_caps_generate_permutations(GPtrArray *list, guint n)
+{
+ g_ptr_array_set_size(list, 0);
+
+ if (n > 0) {
+ guint i;
+ guint *order = g_new(guint, n);
+
+ /*
+ * In a general case this gives n! of permutations (1, 2,
+ * 6, 24, ...) but typically no more than 2
+ */
+ for (i = 0; i < n; i++) order[i] = i;
+ g_ptr_array_set_free_func(list, g_free);
+ g_ptr_array_add(list, order);
+ ril_radio_caps_permutate(list, order, 0, n);
+ }
+}
static gboolean ril_radio_caps_parse(const char *log_prefix,
const void *data, guint len, struct ril_radio_capability *cap)
@@ -248,136 +349,127 @@
* ril_radio_caps
*==========================================================================*/
-static enum ofono_radio_access_mode ril_radio_caps_access_mode
- (const struct ril_radio_caps *caps)
+static inline RilRadioCaps *ril_radio_caps_cast(struct ril_radio_caps *caps)
{
- const enum ril_radio_access_family raf = caps->cap.rat;
-
- if (raf & (RAF_LTE | RAF_LTE_CA)) {
- return OFONO_RADIO_ACCESS_MODE_LTE;
- } else if (raf & RAF_UMTS) {
- return OFONO_RADIO_ACCESS_MODE_UMTS;
- } else if (raf & (RAF_EDGE | RAF_GPRS | RAF_GSM)) {
- return OFONO_RADIO_ACCESS_MODE_GSM;
- } else {
- return OFONO_RADIO_ACCESS_MODE_ANY;
- }
+ return caps ? RADIO_CAPS(G_CAST(caps,RilRadioCaps,pub)) : NULL;
}
-static enum ofono_radio_access_mode ril_radio_caps_pref_mode_limit
- (const struct ril_radio_caps *caps)
+static enum ofono_radio_access_mode ril_radio_caps_access_mode
+ (const RilRadioCaps *self)
{
- struct ril_network *network = caps->network;
- struct ril_sim_settings *settings = network->settings;
+ int i;
- if (network->max_pref_mode == settings->pref_mode) {
- return network->max_pref_mode;
- } else if (network->max_pref_mode == OFONO_RADIO_ACCESS_MODE_ANY) {
- return settings->pref_mode;
- } else {
- return network->max_pref_mode;
+ /* Returns the highest matched mode */
+ for (i = G_N_ELEMENTS(ril_access_mode_raf_map); i >= 0; i--) {
+ if (self->cap.rat & ril_access_mode_raf_map[i].raf) {
+ return ril_access_mode_raf_map[i].mode;
+ }
}
-}
-static gboolean ril_radio_caps_ready(const struct ril_radio_caps *caps)
-{
- /* We don't want to start messing with radio capabilities before
- * the user has entered the pin. Some RIL don't like it so much
- * thet they refuse to work after that. */
- return caps->radio->state == RADIO_STATE_ON && caps->simcard->status &&
- (caps->simcard->status->card_state != RIL_CARDSTATE_PRESENT ||
- caps->network->settings->imsi);
+ return OFONO_RADIO_ACCESS_MODE_ANY;
}
-static gboolean ril_radio_caps_ok(const struct ril_radio_caps *caps,
- const enum ofono_radio_access_mode limit)
+static enum ofono_radio_access_mode ril_radio_caps_modes
+ (const struct ril_radio_capability *cap)
{
- /* Check if the slot is happy with its present state */
- return caps->radio->state != RADIO_STATE_ON ||
- !caps->simcard->status ||
- caps->simcard->status->card_state != RIL_CARDSTATE_PRESENT ||
- !caps->network->settings->imsi ||
- limit == OFONO_RADIO_ACCESS_MODE_ANY ||
- ril_radio_caps_access_mode(caps) <= limit;
+ const enum ril_radio_access_family raf = cap->rat;
+ enum ofono_radio_access_mode modes = 0;
+ int i;
+
+ /* Bitwise-OR all matched modes */
+ for (i = 0; i < G_N_ELEMENTS(ril_access_mode_raf_map); i++) {
+ if (raf & ril_access_mode_raf_map[i].raf) {
+ modes |= ril_access_mode_raf_map[i].mode;
+ }
+ }
+ return modes;
}
-static gboolean ril_radio_caps_wants_upgrade(const struct ril_radio_caps *caps)
+static void ril_radio_caps_update_modes(RilRadioCaps *self)
{
- if (caps->radio->state == RADIO_STATE_ON &&
- caps->simcard->status &&
- caps->simcard->status->card_state == RIL_CARDSTATE_PRESENT &&
- caps->network->settings->imsi) {
- enum ofono_radio_access_mode limit =
- ril_radio_caps_pref_mode_limit(caps);
+ struct ril_radio_caps *caps = &self->pub;
+ const struct ril_radio_capability *cap = &self->cap;
+ const enum ofono_radio_access_mode modes = ril_radio_caps_modes(cap);
- if (!limit) limit = OFONO_RADIO_ACCESS_MODE_LTE;
- return ril_radio_caps_access_mode(caps) < limit;
+ if (caps->supported_modes != modes) {
+ caps->supported_modes = modes;
+ ril_radio_caps_manager_schedule_check(caps->mgr);
+ g_signal_emit(self, ril_radio_caps_signals
+ [CAPS_SIGNAL_MODES_CHANGED], 0);
}
- return FALSE;
}
-static int ril_radio_caps_index(const struct ril_radio_caps * caps)
+static int ril_radio_caps_score(const RilRadioCaps *self,
+ const struct ril_radio_capability *cap)
{
- guint i;
- const GPtrArray *list = caps->mgr->caps_list;
-
- for (i = 0; i < list->len; i++) {
- if (list->pdata[i] == caps) {
- return i;
+ if (!self->radio->online || !self->simcard->status ||
+ self->simcard->status->card_state != RIL_CARDSTATE_PRESENT) {
+ /* Unusable slot */
+ return -(int)ril_radio_caps_modes(cap);
+ } else if (self->requested_modes) {
+ if (ril_radio_caps_modes(cap) >= self->requested_modes) {
+ /* Happy slot (upgrade not required) */
+ return self->requested_modes;
+ } else {
+ /* Unhappy slot (wants upgrade) */
+ return -(int)self->requested_modes;
}
+ } else {
+ /* Whatever */
+ return 0;
}
-
- return -1;
}
static void ril_radio_caps_radio_event(struct ril_radio *radio, void *arg)
{
- struct ril_radio_caps *self = arg;
+ RilRadioCaps *self = RADIO_CAPS(arg);
DBG_(self, "");
- ril_radio_caps_manager_schedule_check(self->mgr);
+ ril_radio_caps_manager_schedule_check(self->pub.mgr);
}
static void ril_radio_caps_simcard_event(struct ril_sim_card *sim,
void *arg)
{
- struct ril_radio_caps *self = arg;
+ RilRadioCaps *self = RADIO_CAPS(arg);
DBG_(self, "");
- ril_radio_caps_manager_schedule_check(self->mgr);
+ ril_radio_caps_manager_schedule_check(self->pub.mgr);
}
-static void ril_radio_caps_settings_event(struct ril_sim_settings *settings,
- void *arg)
+static void ril_radio_caps_watch_event(struct ofono_watch *w, void *arg)
{
- struct ril_radio_caps *self = arg;
+ RilRadioCaps *self = RADIO_CAPS(arg);
DBG_(self, "");
- ril_radio_caps_manager_schedule_check(self->mgr);
+ ril_radio_caps_manager_schedule_check(self->pub.mgr);
}
-static void ril_radio_caps_network_event(struct ril_network *network,
+static void ril_radio_caps_settings_event(struct ril_sim_settings *settings,
void *arg)
{
- struct ril_radio_caps *self = arg;
+ RilRadioCaps *self = RADIO_CAPS(arg);
+ RilRadioCapsManager *mgr = self->pub.mgr;
DBG_(self, "");
- ril_radio_caps_manager_schedule_check(self->mgr);
+ ril_radio_caps_manager_consider_requests(mgr);
+ ril_radio_caps_manager_schedule_check(mgr);
}
static void ril_radio_caps_changed_cb(GRilIoChannel *io, guint code,
const void *data, guint len, void *arg)
{
- struct ril_radio_caps *self = arg;
+ RilRadioCaps *self = RADIO_CAPS(arg);
DBG_(self, "");
GASSERT(code == RIL_UNSOL_RADIO_CAPABILITY);
if (ril_radio_caps_parse(self->log_prefix, data, len, &self->cap)) {
- ril_radio_caps_manager_schedule_check(self->mgr);
+ ril_radio_caps_update_modes(self);
+ ril_radio_caps_manager_schedule_check(self->pub.mgr);
}
}
-static void ril_radio_caps_finish_init(struct ril_radio_caps *self)
+static void ril_radio_caps_finish_init(RilRadioCaps *self)
{
GASSERT(ril_radio_caps_access_mode(self));
@@ -388,47 +480,39 @@
self);
/* Schedule capability check */
- ril_radio_caps_manager_schedule_check(self->mgr);
+ ril_radio_caps_manager_schedule_check(self->pub.mgr);
}
static void ril_radio_caps_initial_query_cb(GRilIoChannel *io, int ril_status,
const void *data, guint len, void *user_data)
{
- struct ril_radio_caps *self = user_data;
+ RilRadioCaps *self = RADIO_CAPS(user_data);
if (ril_status == RIL_E_SUCCESS) {
ril_radio_caps_parse(self->log_prefix, data, len, &self->cap);
}
if (self->cap.rat) {
+ ril_radio_caps_update_modes(self);
ril_radio_caps_finish_init(self);
} else {
DBG_(self, "failed to query radio capabilities");
}
}
-static gint ril_caps_compare_cb(gconstpointer a, gconstpointer b)
+static void ril_radio_caps_finalize(GObject *object)
{
- const struct ril_radio_caps *c1 = *(void**)a;
- const struct ril_radio_caps *c2 = *(void**)b;
+ RilRadioCaps *self = RADIO_CAPS(object);
+ RilRadioCapsManager *mgr = self->pub.mgr;
- return c1->slot < c2->slot ? (-1) : c1->slot > c2->slot ? 1 : 0;
-}
-
-static void ril_radio_caps_free(struct ril_radio_caps *self)
-{
- struct ril_radio_caps_manager *mgr = self->mgr;
- struct ril_sim_settings *settings = self->network->settings;
-
- ril_network_remove_handler(self->network, self->max_pref_mode_event_id);
- ril_radio_remove_handler(self->radio, self->radio_event_id);
- ril_sim_settings_remove_handlers(settings, self->settings_event_id,
- G_N_ELEMENTS(self->settings_event_id));
- ril_sim_card_remove_handlers(self->simcard, self->simcard_event_id,
- G_N_ELEMENTS(self->simcard_event_id));
- grilio_channel_remove_handlers(self->io, self->io_event_id,
- G_N_ELEMENTS(self->io_event_id));
- g_ptr_array_remove(mgr->caps_list, self);
+ ril_radio_remove_all_handlers(self->radio, self->radio_event_id);
+ ril_sim_settings_remove_handlers(self->settings,
+ self->settings_event_id, G_N_ELEMENTS(self->settings_event_id));
+ ril_sim_card_remove_all_handlers(self->simcard, self->simcard_event_id);
+ grilio_channel_remove_all_handlers(self->io, self->io_event_id);
+ ofono_watch_remove_all_handlers(self->watch, self->watch_event_id);
+ ofono_watch_unref(self->watch);
+ ril_radio_caps_manager_remove(mgr, self);
ril_radio_caps_manager_unref(mgr);
grilio_queue_cancel_all(self->q, FALSE);
grilio_queue_unref(self->q);
@@ -436,25 +520,25 @@
ril_data_unref(self->data);
ril_radio_unref(self->radio);
ril_sim_card_unref(self->simcard);
- ril_network_unref(self->network);
+ ril_sim_settings_unref(self->settings);
+ gutil_idle_pool_unref(self->idle_pool);
g_free(self->log_prefix);
- g_slice_free(struct ril_radio_caps, self);
+ G_OBJECT_CLASS(ril_radio_caps_parent_class)->finalize(object);
}
-struct ril_radio_caps *ril_radio_caps_new(struct ril_radio_caps_manager *mgr,
+struct ril_radio_caps *ril_radio_caps_new(RilRadioCapsManager *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)
{
GASSERT(mgr);
if (G_LIKELY(mgr)) {
- struct ril_sim_settings *settings = net->settings;
- struct ril_radio_caps *self =
- g_slice_new0(struct ril_radio_caps);
+ RilRadioCaps *self = g_object_new(RADIO_CAPS_TYPE, 0);
+ struct ril_radio_caps *caps = &self->pub;
- g_atomic_int_set(&self->ref_count, 1);
self->slot = config->slot;
self->log_prefix = (log_prefix && log_prefix[0]) ?
g_strconcat(log_prefix, " ", NULL) : g_strdup("");
@@ -462,11 +546,15 @@
self->q = grilio_queue_new(io);
self->io = grilio_channel_ref(io);
self->data = ril_data_ref(data);
- self->mgr = ril_radio_caps_manager_ref(mgr);
+ caps->mgr = ril_radio_caps_manager_ref(mgr);
self->radio = ril_radio_ref(radio);
- self->radio_event_id = ril_radio_add_state_changed_handler(
- radio, ril_radio_caps_radio_event, self);
+ self->radio_event_id[RADIO_EVENT_STATE] =
+ ril_radio_add_state_changed_handler(radio,
+ ril_radio_caps_radio_event, self);
+ self->radio_event_id[RADIO_EVENT_ONLINE] =
+ ril_radio_add_online_changed_handler(radio,
+ ril_radio_caps_radio_event, self);
self->simcard = ril_sim_card_ref(sim);
self->simcard_event_id[SIM_EVENT_STATE_CHANGED] =
@@ -476,25 +564,24 @@
ril_sim_card_add_sim_io_active_changed_handler(sim,
ril_radio_caps_simcard_event, self);
- self->network = ril_network_ref(net);
+ self->watch = ofono_watch_ref(watch);
+ self->watch_event_id[WATCH_EVENT_IMSI] =
+ ofono_watch_add_imsi_changed_handler(watch,
+ ril_radio_caps_watch_event, self);
+ self->watch_event_id[WATCH_EVENT_MODEM] =
+ ofono_watch_add_modem_changed_handler(watch,
+ ril_radio_caps_watch_event, self);
+
+ self->settings = ril_sim_settings_ref(settings);
self->settings_event_id[SETTINGS_EVENT_PREF_MODE] =
ril_sim_settings_add_pref_mode_changed_handler(
settings, ril_radio_caps_settings_event, self);
- self->settings_event_id[SETTINGS_EVENT_IMSI] =
- ril_sim_settings_add_imsi_changed_handler(
- settings, ril_radio_caps_settings_event, self);
-
- self->max_pref_mode_event_id =
- ril_network_add_max_pref_mode_changed_handler(net,
- ril_radio_caps_network_event, self);
-
- /* Order list elements according to slot numbers */
- g_ptr_array_add(mgr->caps_list, self);
- g_ptr_array_sort(mgr->caps_list, ril_caps_compare_cb);
+ ril_radio_caps_manager_add(mgr, self);
if (cap) {
/* Current capabilities are provided by the caller */
self->cap = *cap;
+ caps->supported_modes = ril_radio_caps_modes(cap);
ril_radio_caps_finish_init(self);
} else {
/* Need to query current capabilities */
@@ -508,54 +595,158 @@
grilio_request_unref(req);
}
- return self;
+ return caps;
}
return NULL;
}
-struct ril_radio_caps *ril_radio_caps_ref(struct ril_radio_caps *self)
+struct ril_radio_caps *ril_radio_caps_ref(struct ril_radio_caps *caps)
{
+ RilRadioCaps *self = ril_radio_caps_cast(caps);
+
if (G_LIKELY(self)) {
- GASSERT(self->ref_count > 0);
- g_atomic_int_inc(&self->ref_count);
+ g_object_ref(self);
+ }
+ return caps;
+}
+
+void ril_radio_caps_unref(struct ril_radio_caps *caps)
+{
+ RilRadioCaps *self = ril_radio_caps_cast(caps);
+
+ if (G_LIKELY(self)) {
+ g_object_unref(self);
}
- return self;
}
-void ril_radio_caps_unref(struct ril_radio_caps *self)
+void ril_radio_caps_drop(struct ril_radio_caps *caps)
{
+ RilRadioCaps *self = ril_radio_caps_cast(caps);
+
if (G_LIKELY(self)) {
- GASSERT(self->ref_count > 0);
- if (g_atomic_int_dec_and_test(&self->ref_count)) {
- ril_radio_caps_free(self);
+ ril_radio_caps_manager_remove(self->pub.mgr, self);
+ g_object_unref(self);
+ }
+}
+
+static void ril_radio_caps_signal_cb(RilRadioCaps *object,
+ RilRadioCapsClosure *closure)
+{
+ closure->cb(&object->pub, closure->user_data);
+}
+
+gulong ril_radio_caps_add_supported_modes_handler(struct ril_radio_caps *caps,
+ ril_radio_caps_cb_t cb, void *arg)
+{
+ RilRadioCaps *self = ril_radio_caps_cast(caps);
+
+ if (G_LIKELY(self) && G_LIKELY(cb)) {
+ RilRadioCapsClosure *closure = ril_radio_caps_closure_new();
+ GCClosure *cc = &closure->cclosure;
+
+ cc->closure.data = closure;
+ cc->callback = G_CALLBACK(ril_radio_caps_signal_cb);
+ closure->cb = cb;
+ closure->user_data = arg;
+
+ return g_signal_connect_closure_by_id(self,
+ ril_radio_caps_signals[CAPS_SIGNAL_MODES_CHANGED],
+ 0, &cc->closure, FALSE);
+ }
+ return 0;
+}
+
+void ril_radio_caps_remove_handler(struct ril_radio_caps *caps, gulong id)
+{
+ if (G_LIKELY(id)) {
+ RilRadioCaps *self = ril_radio_caps_cast(caps);
+
+ if (G_LIKELY(self)) {
+ g_signal_handler_disconnect(self, id);
}
}
}
+static void ril_radio_caps_init(RilRadioCaps *self)
+{
+ self->idle_pool = gutil_idle_pool_ref
+ (gutil_idle_pool_get(&ril_radio_caps_shared_pool));
+}
+
+static void ril_radio_caps_class_init(RilRadioCapsClass *klass)
+{
+ G_OBJECT_CLASS(klass)->finalize = ril_radio_caps_finalize;
+ ril_radio_caps_signals[CAPS_SIGNAL_MODES_CHANGED] =
+ g_signal_new(CAPS_SIGNAL_MODES_CHANGED_NAME,
+ G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
+}
+
/*==========================================================================*
* ril_radio_caps_manager
*==========================================================================*/
-static void ril_radio_caps_manager_foreach(struct ril_radio_caps_manager *self,
- ril_radio_caps_cb_t cb)
+static const char *ril_radio_caps_manager_order_str(RilRadioCapsManager *self,
+ const guint *order)
+{
+ const guint n = self->caps_list->len;
+
+ if (n > 0) {
+ guint i;
+ char *str;
+ GString *buf = g_string_sized_new(2*n + 2 /* roughly */);
+
+ g_string_append_printf(buf, "(%u", order[0]);
+ for (i = 1; i < n; i++) {
+ g_string_append_printf(buf, ",%u", order[i]);
+ }
+ g_string_append_c(buf, ')');
+ str = g_string_free(buf, FALSE);
+ gutil_idle_pool_add(self->idle_pool, str, g_free);
+ return str;
+ } else {
+ return "()";
+ }
+}
+
+static const char *ril_radio_caps_manager_role_str(RilRadioCapsManager *self,
+ enum ril_data_role role)
+{
+ char *str;
+
+ switch (role) {
+ case RIL_DATA_ROLE_NONE:
+ return "none";
+ case RIL_DATA_ROLE_MMS:
+ return "mms";
+ case RIL_DATA_ROLE_INTERNET:
+ return "internet";
+ }
+
+ str = g_strdup_printf("%d", (int)role);
+ gutil_idle_pool_add(self->idle_pool, str, g_free);
+ return str;
+}
+
+static void ril_radio_caps_manager_foreach(RilRadioCapsManager *self,
+ ril_radio_caps_enum_cb_t cb)
{
guint i;
const GPtrArray *list = self->caps_list;
for (i = 0; i < list->len; i++) {
- cb(self, (struct ril_radio_caps *)(list->pdata[i]));
+ cb(self, (RilRadioCaps *)(list->pdata[i]));
}
}
-static void ril_radio_caps_manager_foreach_tx
- (struct ril_radio_caps_manager *self,
- ril_radio_caps_cb_t cb)
+static void ril_radio_caps_manager_foreach_tx(RilRadioCapsManager *self,
+ ril_radio_caps_enum_cb_t cb)
{
guint i;
const GPtrArray *list = self->caps_list;
for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
+ RilRadioCaps *caps = list->pdata[i];
/* Ignore the modems not associated with this transaction */
if (caps->tx_id == self->tx_id) {
@@ -564,14 +755,13 @@
}
}
-static gboolean ril_radio_caps_manager_tx_pending
- (struct ril_radio_caps_manager *self)
+static gboolean ril_radio_caps_manager_tx_pending(RilRadioCapsManager *self)
{
guint i;
const GPtrArray *list = self->caps_list;
for (i = 0; i < list->len; i++) {
- const struct ril_radio_caps *caps = list->pdata[i];
+ RilRadioCaps *caps = list->pdata[i];
/* Ignore the modems not associated with this transaction */
if (caps->tx_id == self->tx_id && caps->tx_pending > 0) {
@@ -587,20 +777,29 @@
* GET_RADIO_CAPABILITY requests have completed) and there's no transaction
* in progress.
*/
-static gboolean ril_radio_caps_manager_can_check
- (struct ril_radio_caps_manager *self)
+static gboolean ril_radio_caps_manager_can_check(RilRadioCapsManager *self)
{
if (self->caps_list && !ril_radio_caps_manager_tx_pending(self)) {
const GPtrArray *list = self->caps_list;
- const struct ril_radio_caps *prev_caps = NULL;
+ const RilRadioCaps *prev_caps = NULL;
gboolean all_modes_equal = TRUE;
guint i;
for (i = 0; i < list->len; i++) {
- const struct ril_radio_caps *caps = list->pdata[i];
-
- if (caps->radio->state == RADIO_STATE_ON &&
- !caps->cap.rat) {
+ const RilRadioCaps *caps = list->pdata[i];
+ const struct ril_radio *radio = caps->radio;
+ const struct ril_sim_card_status *status =
+ caps->simcard->status;
+ const gboolean slot_enabled =
+ (caps->watch->modem != NULL);
+ const gboolean sim_present = status &&
+ (status->card_state == RIL_CARDSTATE_PRESENT);
+
+ if (slot_enabled &&
+ ((radio->online &&
+ (radio->state != RADIO_STATE_ON ||
+ !caps->cap.rat)) || (sim_present &&
+ !caps->settings->imsi))) {
DBG_(caps, "not ready");
return FALSE;
}
@@ -612,152 +811,26 @@
all_modes_equal = FALSE;
}
- DBG_(caps, "radio=%s,sim=%s,imsi=%s,raf=0x%x(%s),"
- "uuid=%s,limit=%s", (caps->radio->state ==
- RADIO_STATE_ON) ? "on" : "off",
- caps->simcard->status ?
- (caps->simcard->status->card_state ==
- RIL_CARDSTATE_PRESENT) ? "yes" : "no" : "?",
- caps->network->settings->imsi ?
- caps->network->settings->imsi : "",
- caps->cap.rat,
- ril_access_mode_to_string
+ DBG_(caps, "enabled=%s,online=%s,sim=%s,imsi=%s,"
+ "raf=0x%x(%s),uuid=%s,req=%s,score=%d",
+ slot_enabled ? "yes" : "no",
+ radio->online ? "yes" : "no", status ?
+ (status->card_state == RIL_CARDSTATE_PRESENT) ?
+ "yes" : "no" : "?", caps->settings->imsi ?
+ caps->settings->imsi : "", caps->cap.rat,
+ ofono_radio_access_mode_to_string
(ril_radio_caps_access_mode(caps)),
caps->cap.logicalModemUuid,
- ril_access_mode_to_string
- (ril_radio_caps_pref_mode_limit(caps)));
+ ofono_radio_access_mode_to_string
+ (caps->requested_modes),
+ ril_radio_caps_score(caps, &caps->cap));
}
return !all_modes_equal;
}
return FALSE;
}
-static int ril_radio_caps_manager_first_mismatch
- (struct ril_radio_caps_manager *self)
-{
- guint i;
- const GPtrArray *list = self->caps_list;
-
- for (i = 0; i < list->len; i++) {
- const struct ril_radio_caps *caps = list->pdata[i];
-
- if (!ril_radio_caps_ok(caps,
- ril_radio_caps_pref_mode_limit(caps))) {
- return i;
- }
- }
-
- return -1;
-}
-
-static int ril_radio_caps_manager_find_mismatch
- (struct ril_radio_caps_manager *self,
- const guint *order, const gboolean *done)
-{
- guint i;
- const GPtrArray *list = self->caps_list;
-
- for (i = 0; i < list->len; i++) {
- if (!done[i] && !ril_radio_caps_ok(list->pdata[order[i]],
- ril_radio_caps_pref_mode_limit(list->pdata[i]))) {
- return i;
- }
- }
-
- return -1;
-}
-
-static int ril_radio_caps_manager_find_match
- (struct ril_radio_caps_manager *self,
- guint from, const guint *order,
- const gboolean *done)
-{
- guint i;
- const GPtrArray *list = self->caps_list;
- const struct ril_radio_caps *src = list->pdata[order[from]];
-
- for (i = 0; i < list->len; i++) {
- if (!done[i] && ril_radio_caps_ok(src,
- ril_radio_caps_pref_mode_limit(list->pdata[i]))) {
- return i;
- }
- }
-
- return -1;
-}
-
-/**
- * Updates the order of capabilities (i.e. which slots should get
- * assigned which capabilities). Returns FALSE if nothing can be
- * done due to impossible constraints. If everything is already
- * fine, we shouldn't even get here - the caller makes sure of that.
- */
-static gboolean ril_radio_caps_manager_update_caps
- (struct ril_radio_caps_manager *self, int mismatch)
-{
- guint i;
- int from, to;
- gboolean ok = TRUE;
- const GPtrArray *list = self->caps_list;
- guint *order = g_new(guint, list->len);
- gboolean *done = g_new(gboolean, list->len);
-
- for (i = 0; i < list->len; i++) {
- const struct ril_radio_caps *caps = list->pdata[i];
-
- /* Not touching powered off modems */
- done[i] = !ril_radio_caps_ready(caps);
- order[i] = i;
- }
-
- /* The first mismatch is already known */
- to = ril_radio_caps_manager_find_match(self, mismatch, order, done);
- if (to < 0) {
- ok = FALSE;
- } else {
- DBG("%d <-> %d", mismatch, to);
- order[mismatch] = to;
- order[to] = mismatch;
- done[to] = TRUE;
- }
-
- /* Handle other mismatched slots (if any) */
- while (ok && (from = ril_radio_caps_manager_find_mismatch(self, order,
- done)) >= 0) {
- to = ril_radio_caps_manager_find_match(self, from, order,
- done);
- if (to < 0) {
- ok = FALSE;
- } else {
- const guint tmp = order[from];
- DBG("%d <-> %d", order[from], order[to]);
- order[from] = order[to];
- order[to] = tmp;
- done[to] = TRUE;
- }
- }
-
- if (ok) {
- for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
- caps->new_cap = caps->old_cap = caps->cap;
- }
-
- /* Update the rafs */
- for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *src = list->pdata[i];
- struct ril_radio_caps *dest = list->pdata[order[i]];
- dest->new_cap = src->cap;
- }
- }
-
- g_free(order);
- g_free(done);
- return ok;
-}
-
-static void ril_radio_caps_manager_issue_requests
- (struct ril_radio_caps_manager *self,
+static void ril_radio_caps_manager_issue_requests(RilRadioCapsManager *self,
const struct ril_radio_caps_request_tx_phase *phase,
GRilIoChannelResponseFunc handler)
{
@@ -766,7 +839,7 @@
DBG("%s transaction %d", phase->name, self->tx_id);
for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
+ RilRadioCaps *caps = list->pdata[i];
/* Ignore the modems not associated with this transaction */
if (caps->tx_id == self->tx_id) {
@@ -797,8 +870,7 @@
}
static void ril_radio_caps_manager_next_transaction_cb
- (struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps)
+ (RilRadioCapsManager *self, RilRadioCaps *caps)
{
grilio_queue_cancel_all(caps->q, FALSE);
grilio_channel_remove_handlers(caps->io, caps->io_event_id +
@@ -809,8 +881,7 @@
SIM_EVENT_IO_ACTIVE_CHANGED, 1);
}
-static void ril_radio_caps_manager_next_transaction
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_next_transaction(RilRadioCapsManager *self)
{
ril_radio_caps_manager_foreach(self,
ril_radio_caps_manager_next_transaction_cb);
@@ -820,36 +891,26 @@
if (self->tx_id <= 0) self->tx_id = 1;
}
-static void ril_radio_caps_manager_cancel_cb
- (struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps)
+static void ril_radio_caps_manager_cancel_cb(RilRadioCapsManager *self,
+ RilRadioCaps *caps)
{
GASSERT(!caps->io_event_id[IO_EVENT_OWNER]);
GASSERT(!caps->io_event_id[IO_EVENT_PENDING]);
grilio_queue_transaction_finish(caps->q);
}
-static void ril_radio_caps_manager_finish_cb
- (struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps)
-{
- ril_radio_caps_manager_cancel_cb(self, caps);
- ril_network_assert_pref_mode(caps->network, FALSE);
-}
-
-static void ril_radio_caps_manager_transaction_done
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_transaction_done(RilRadioCapsManager *self)
{
ril_radio_caps_manager_schedule_check(self);
ril_data_manager_assert_data_on(self->data_manager);
- ril_radio_caps_manager_foreach(self, ril_radio_caps_manager_finish_cb);
+ ril_radio_caps_manager_foreach(self, ril_radio_caps_manager_cancel_cb);
}
static void ril_radio_caps_manager_abort_cb(GRilIoChannel *io,
int ril_status, const void *data, guint len, void *user_data)
{
- struct ril_radio_caps *caps = user_data;
- struct ril_radio_caps_manager *self = caps->mgr;
+ RilRadioCaps *caps = RADIO_CAPS(user_data);
+ RilRadioCapsManager *self = caps->pub.mgr;
GASSERT(caps->tx_pending > 0);
caps->tx_pending--;
@@ -860,8 +921,7 @@
}
}
-static void ril_radio_caps_manager_abort_transaction
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_abort_transaction(RilRadioCapsManager *self)
{
guint i;
const GPtrArray *list = self->caps_list;
@@ -873,7 +933,7 @@
/* Re-associate the modems with the new transaction */
for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
+ RilRadioCaps *caps = list->pdata[i];
if (caps->tx_id == prev_tx_id) {
caps->tx_id = self->tx_id;
@@ -889,22 +949,23 @@
ril_radio_caps_manager_abort_cb);
/* Notify the listeners */
- g_signal_emit(self, ril_radio_caps_manager_signals[SIGNAL_ABORTED], 0);
+ g_signal_emit(self, ril_radio_caps_manager_signals
+ [CAPS_MANAGER_SIGNAL_ABORTED], 0);
}
static void ril_radio_caps_manager_next_phase_cb(GRilIoChannel *io,
int ril_status, const void *data, guint len, void *user_data)
{
- struct ril_radio_caps *caps = user_data;
- struct ril_radio_caps_manager *self = caps->mgr;
+ RilRadioCaps *caps = RADIO_CAPS(user_data);
+ RilRadioCapsManager *self = caps->pub.mgr;
gboolean ok = FALSE;
GASSERT(caps->tx_pending > 0);
if (ril_status == RIL_E_SUCCESS) {
struct ril_radio_capability cap;
+
if (ril_radio_caps_parse(caps->log_prefix, data, len, &cap) &&
- cap.status == RC_STATUS_SUCCESS) {
- caps->cap = cap;
+ cap.status != RC_STATUS_FAIL) {
ok = TRUE;
}
}
@@ -927,16 +988,41 @@
}
}
-static void ril_radio_caps_manager_next_phase
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_next_phase(RilRadioCapsManager *self)
{
/* Note: -1 > 2 if 2 is unsigned (which turns -1 into 4294967295) */
const int max_index = G_N_ELEMENTS(ril_radio_caps_tx_phase) - 1;
GASSERT(!ril_radio_caps_manager_tx_pending(self));
if (self->tx_phase_index >= max_index) {
+ const GPtrArray *list = self->caps_list;
+ GSList *updated_caps = NULL;
+ GSList *l;
+ guint i;
+
DBG("transaction %d is done", self->tx_id);
+
+ /* Update all caps before emitting signals */
+ for (i = 0; i < list->len; i++) {
+ RilRadioCaps *caps = list->pdata[i];
+
+ if (caps->tx_id == self->tx_id) {
+ caps->cap = caps->new_cap;
+ /* Better bump refs to make sure RilRadioCaps
+ * don't get freed by a signal handler */
+ updated_caps = g_slist_append(updated_caps,
+ g_object_ref(caps));
+ }
+ }
+ /* ril_radio_caps_update_modes will emit signals if needed */
+ for (l = updated_caps; l; l = l->next) {
+ ril_radio_caps_update_modes((RilRadioCaps *)l->data);
+ }
ril_radio_caps_manager_transaction_done(self);
+ /* Free temporary RilRadioCaps references */
+ g_slist_free_full(updated_caps, g_object_unref);
+ g_signal_emit(self, ril_radio_caps_manager_signals
+ [CAPS_MANAGER_SIGNAL_TX_DONE], 0);
} else {
const struct ril_radio_caps_request_tx_phase *phase =
ril_radio_caps_tx_phase +
@@ -950,8 +1036,8 @@
static void ril_radio_caps_manager_data_off_done(GRilIoChannel *io,
int status, const void *req_data, guint len, void *user_data)
{
- struct ril_radio_caps *caps = user_data;
- struct ril_radio_caps_manager *self = caps->mgr;
+ RilRadioCaps *caps = RADIO_CAPS(user_data);
+ RilRadioCapsManager *self = caps->pub.mgr;
GASSERT(caps->tx_pending > 0);
if (status != GRILIO_STATUS_OK) {
@@ -966,6 +1052,8 @@
ril_radio_caps_manager_recheck_later(self);
ril_radio_caps_manager_foreach(self,
ril_radio_caps_manager_cancel_cb);
+ g_signal_emit(self, ril_radio_caps_manager_signals
+ [CAPS_MANAGER_SIGNAL_ABORTED], 0);
} else {
DBG("starting transaction");
ril_radio_caps_manager_next_phase(self);
@@ -973,9 +1061,8 @@
}
}
-static void ril_radio_caps_manager_data_off
- (struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps)
+static void ril_radio_caps_manager_data_off(RilRadioCapsManager *self,
+ RilRadioCaps *caps)
{
GRilIoRequest *req = ril_request_allow_data_new(FALSE);
@@ -992,8 +1079,8 @@
static void ril_radio_caps_manager_deactivate_data_call_done(GRilIoChannel *io,
int status, const void *data, guint len, void *user_data)
{
- struct ril_radio_caps *caps = user_data;
- struct ril_radio_caps_manager *self = caps->mgr;
+ RilRadioCaps *caps = RADIO_CAPS(user_data);
+ RilRadioCapsManager *self = caps->pub.mgr;
GASSERT(caps->tx_pending > 0);
if (status != GRILIO_STATUS_OK) {
@@ -1017,8 +1104,7 @@
}
}
-static void ril_radio_caps_deactivate_data_call(struct ril_radio_caps *caps,
- int cid)
+static void ril_radio_caps_deactivate_data_call(RilRadioCaps *caps, int cid)
{
GRilIoRequest *req = ril_request_deactivate_data_call_new(cid);
@@ -1039,22 +1125,23 @@
struct ril_data_call *call = list_data;
if (call->status == PDP_FAIL_NONE) {
- ril_radio_caps_deactivate_data_call(user_data, call->cid);
+ ril_radio_caps_deactivate_data_call(RADIO_CAPS(user_data),
+ call->cid);
}
}
-static void ril_radio_caps_manager_deactivate_all_cb
- (struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps)
+static void ril_radio_caps_manager_deactivate_all_cb(RilRadioCapsManager *self,
+ RilRadioCaps *caps)
{
- if (caps->data->data_calls) {
- g_slist_foreach(caps->data->data_calls->calls,
+ struct ril_data *data = caps->data;
+
+ if (data && data->data_calls) {
+ g_slist_foreach(data->data_calls->calls,
ril_radio_caps_deactivate_data_call_cb, caps);
}
}
-static void ril_radio_caps_manager_deactivate_all
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_deactivate_all(RilRadioCapsManager *self)
{
ril_radio_caps_manager_foreach_tx(self,
ril_radio_caps_manager_deactivate_all_cb);
@@ -1068,8 +1155,8 @@
static void ril_radio_caps_tx_wait_cb(GRilIoChannel *io, void *user_data)
{
- struct ril_radio_caps *caps = user_data;
- struct ril_radio_caps_manager *self = caps->mgr;
+ RilRadioCaps *caps = RADIO_CAPS(user_data);
+ RilRadioCapsManager *self = caps->pub.mgr;
const GPtrArray *list = self->caps_list;
gboolean can_start = TRUE;
guint i;
@@ -1088,7 +1175,7 @@
/* Check if all channels are ours */
for (i = 0; i < list->len && can_start; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
+ const RilRadioCaps *caps = list->pdata[i];
if (caps->tx_id == self->tx_id &&
(grilio_channel_has_pending_requests(caps->io) ||
@@ -1107,7 +1194,7 @@
}
static void ril_radio_caps_manager_lock_io_for_transaction
- (struct ril_radio_caps_manager *self)
+ (RilRadioCapsManager *self)
{
const GPtrArray *list = self->caps_list;
gboolean can_start = TRUE;
@@ -1120,7 +1207,7 @@
* completion of all DEACTIVATE_DATA_CALL and ALLOW_DATA requests.
* Then we can start the capability switch transaction. */
for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
+ RilRadioCaps *caps = list->pdata[i];
GRILIO_TRANSACTION_STATE state;
/* Restart the queue transation to make sure that
@@ -1160,9 +1247,8 @@
}
}
-static void ril_radio_caps_manager_stop_sim_io_watch
- (struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps)
+static void ril_radio_caps_manager_stop_sim_io_watch(RilRadioCapsManager *self,
+ RilRadioCaps *caps)
{
/* ril_sim_card_remove_handlers zeros the id */
ril_sim_card_remove_handlers(caps->simcard, caps->simcard_event_id +
@@ -1170,15 +1256,15 @@
}
static void ril_radio_caps_tx_wait_sim_io_cb(struct ril_sim_card *simcard,
- void *data)
+ void *user_data)
{
- struct ril_radio_caps *caps = data;
- struct ril_radio_caps_manager *self = caps->mgr;
+ RilRadioCaps *src = RADIO_CAPS(user_data);
+ RilRadioCapsManager *self = src->pub.mgr;
const GPtrArray *list = self->caps_list;
guint i;
for (i = 0; i < list->len; i++) {
- const struct ril_radio_caps *caps = list->pdata[i];
+ const RilRadioCaps *caps = list->pdata[i];
if (caps->simcard->sim_io_active) {
DBG_(caps, "still waiting for SIM I/O to calm down");
@@ -1195,17 +1281,15 @@
ril_radio_caps_manager_lock_io_for_transaction(self);
}
-static void ril_radio_caps_manager_start_sim_io_watch
- (struct ril_radio_caps_manager *self,
- struct ril_radio_caps *caps)
+static void ril_radio_caps_manager_start_sim_io_watch(RilRadioCapsManager *self,
+ RilRadioCaps *caps)
{
caps->simcard_event_id[SIM_EVENT_IO_ACTIVE_CHANGED] =
ril_sim_card_add_sim_io_active_changed_handler(caps->simcard,
ril_radio_caps_tx_wait_sim_io_cb, caps);
}
-static void ril_radio_caps_manager_start_transaction
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_start_transaction(RilRadioCapsManager *self)
{
const GPtrArray *list = self->caps_list;
gboolean sim_io_active = FALSE;
@@ -1216,7 +1300,7 @@
DBG("transaction %d", self->tx_id);
for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
+ RilRadioCaps *caps = list->pdata[i];
if (memcmp(&caps->new_cap, &caps->old_cap, sizeof(caps->cap))) {
/* Mark it as taking part in this transaction */
@@ -1244,121 +1328,66 @@
/* And continue with locking RIL I/O for the transaction */
ril_radio_caps_manager_lock_io_for_transaction(self);
}
-
}
-static GSList *ril_radio_caps_manager_upgradable_slots
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_set_order(RilRadioCapsManager *self,
+ const guint *order)
{
- GSList *found = NULL;
const GPtrArray *list = self->caps_list;
guint i;
- for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
-
- if (ril_radio_caps_wants_upgrade(caps)) {
- found = g_slist_append(found, caps);
- }
- }
-
- return found;
-}
-
-static GSList *ril_radio_caps_manager_empty_slots
- (struct ril_radio_caps_manager *self)
-{
- GSList *found = NULL;
- const GPtrArray *list = self->caps_list;
- guint i;
+ DBG("%s => %s", ril_radio_caps_manager_order_str
+ (self, self->order_list->pdata[0]),
+ ril_radio_caps_manager_order_str(self, order));
for (i = 0; i < list->len; i++) {
- struct ril_radio_caps *caps = list->pdata[i];
+ RilRadioCaps *dest = list->pdata[i];
+ const RilRadioCaps *src = list->pdata[order[i]];
- if (ril_radio_caps_ready(caps) &&
- caps->simcard->status->card_state !=
- RIL_CARDSTATE_PRESENT) {
- found = g_slist_append(found, caps);
- }
+ dest->old_cap = dest->cap;
+ dest->new_cap = src->cap;
}
-
- return found;
+ ril_radio_caps_manager_start_transaction(self);
}
-static guint ril_radio_caps_manager_sim_count
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_check(RilRadioCapsManager *self)
{
- const GPtrArray *list = self->caps_list;
- guint i, count = 0;
-
- for (i = 0; i < list->len; i++) {
- const struct ril_radio_caps *caps = list->pdata[i];
-
- if (caps->simcard->status->card_state ==
- RIL_CARDSTATE_PRESENT) {
- count++;
- }
- }
-
- return count;
-}
+ if (ril_radio_caps_manager_can_check(self)) {
+ guint i;
+ const GPtrArray *list = self->caps_list;
+ const GPtrArray *permutations = self->order_list;
+ int highest_score = -INT_MAX, best_index = -1;
-/**
- * There could be no capability mismatch but LTE could be enabled for
- * the slot that has no SIM card in it. That's a waste, fix it.
- */
-static gboolean ril_radio_caps_manager_upgrade_caps
- (struct ril_radio_caps_manager *self)
-{
- gboolean upgrading = FALSE;
- GSList *upgradable = ril_radio_caps_manager_upgradable_slots(self);
+ for (i = 0; i < permutations->len; i++) {
+ const guint *order = permutations->pdata[i];
+ int score = 0;
+ guint k;
+
+ for (k = 0; k < list->len; k++) {
+ const RilRadioCaps *c1 = list->pdata[k];
+ const RilRadioCaps *c2 = list->pdata[order[k]];
- if (upgradable) {
- GSList *empty = ril_radio_caps_manager_empty_slots(self);
+ score += ril_radio_caps_score(c1, &c2->cap);
+ }
- if (empty) {
- struct ril_radio_caps *dest = upgradable->data;
- struct ril_radio_caps *src = empty->data;
-
- if (ril_radio_caps_access_mode(src) >
- ril_radio_caps_access_mode(dest)) {
-
- DBG("%d <-> %d", ril_radio_caps_index(src),
- ril_radio_caps_index(dest));
- src->old_cap = src->cap;
- src->new_cap = dest->cap;
- dest->old_cap = dest->cap;
- dest->new_cap = src->cap;
- ril_radio_caps_manager_start_transaction(self);
- upgrading = TRUE;
+ DBG("%s %d", ril_radio_caps_manager_order_str
+ (self, order), score);
+ if (score > highest_score) {
+ highest_score = score;
+ best_index = i;
}
- g_slist_free(empty);
}
- g_slist_free(upgradable);
- }
-
- return upgrading;
-}
-
-static void ril_radio_caps_manager_check(struct ril_radio_caps_manager *self)
-{
- DBG("");
- if (ril_radio_caps_manager_can_check(self)) {
- const int first = ril_radio_caps_manager_first_mismatch(self);
- if (first >= 0 && ril_radio_caps_manager_sim_count(self) > 1) {
- if (ril_radio_caps_manager_update_caps(self, first)) {
- ril_radio_caps_manager_start_transaction(self);
- }
- } else if (!ril_radio_caps_manager_upgrade_caps(self)) {
- DBG("nothing to do");
+ if (best_index > 0) {
+ ril_radio_caps_manager_set_order(self,
+ permutations->pdata[best_index]);
}
}
}
static gboolean ril_radio_caps_manager_check_cb(gpointer data)
{
- struct ril_radio_caps_manager *self = RADIO_CAPS_MANAGER(data);
+ RilRadioCapsManager *self = RADIO_CAPS_MANAGER(data);
GASSERT(self->check_id);
self->check_id = 0;
@@ -1366,8 +1395,7 @@
return G_SOURCE_REMOVE;
}
-static void ril_radio_caps_manager_recheck_later
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_recheck_later(RilRadioCapsManager *self)
{
if (!ril_radio_caps_manager_tx_pending(self)) {
if (self->check_id) {
@@ -1379,8 +1407,7 @@
}
}
-static void ril_radio_caps_manager_schedule_check
- (struct ril_radio_caps_manager *self)
+static void ril_radio_caps_manager_schedule_check(RilRadioCapsManager *self)
{
if (!self->check_id && !ril_radio_caps_manager_tx_pending(self)) {
self->check_id = g_idle_add(ril_radio_caps_manager_check_cb,
@@ -1388,22 +1415,128 @@
}
}
-gulong ril_radio_caps_manager_add_aborted_handler
- (struct ril_radio_caps_manager *self,
+static gint ril_caps_manager_sort_requests(gconstpointer a, gconstpointer b)
+{
+ const struct ril_radio_caps_request *r1 = *(void**)a;
+ const struct ril_radio_caps_request *r2 = *(void**)b;
+
+ /* MMS requests have higher priority */
+ if (r1->role == RIL_DATA_ROLE_MMS && r2->role != RIL_DATA_ROLE_MMS) {
+ return -1;
+ }
+ if (r1->role != RIL_DATA_ROLE_MMS && r2->role == RIL_DATA_ROLE_MMS) {
+ return 1;
+ }
+ return (int)r2->role - (int)r1->role;
+}
+
+static void ril_radio_caps_manager_consider_requests(RilRadioCapsManager *self)
+{
+ guint i;
+ gboolean changed = FALSE;
+ const GPtrArray *list = self->caps_list;
+ GPtrArray *requests = self->requests;
+
+ if (requests->len) {
+ const struct ril_radio_caps_request *req;
+
+ g_ptr_array_sort(requests, ril_caps_manager_sort_requests);
+ req = self->requests->pdata[0];
+
+ for (i = 0; i < list->len; i++) {
+ RilRadioCaps *caps = list->pdata[i];
+ struct ril_sim_settings *settings = caps->settings;
+ enum ofono_radio_access_mode modes;
+
+ if (req->caps == caps) {
+ modes = (req->mode && settings->pref_mode) ?
+ MIN(req->mode, settings->pref_mode) :
+ req->mode ? req->mode :
+ settings->pref_mode;
+ } else {
+ modes = 0;
+ }
+
+ if (caps->requested_modes != modes) {
+ caps->requested_modes = modes;
+ changed = TRUE;
+ }
+ }
+ } else {
+ for (i = 0; i < list->len; i++) {
+ RilRadioCaps *caps = list->pdata[i];
+
+ if (caps->requested_modes) {
+ caps->requested_modes = 0;
+ changed = TRUE;
+ }
+ }
+ }
+ if (changed) {
+ ril_radio_caps_manager_schedule_check(self);
+ }
+}
+
+static gint ril_caps_manager_sort_caps(gconstpointer a, gconstpointer b)
+{
+ const RilRadioCaps *c1 = *(void**)a;
+ const RilRadioCaps *c2 = *(void**)b;
+
+ return c1->slot < c2->slot ? (-1) : c1->slot > c2->slot ? 1 : 0;
+}
+
+static void ril_radio_caps_manager_list_changed(RilRadioCapsManager *self)
+{
+ /* Order list elements according to slot numbers */
+ g_ptr_array_sort(self->caps_list, ril_caps_manager_sort_caps);
+
+ /* Generate full list of available permutations */
+ ril_radio_caps_generate_permutations(self->order_list,
+ self->caps_list->len);
+}
+
+static void ril_radio_caps_manager_add(RilRadioCapsManager *self,
+ RilRadioCaps *caps)
+{
+ g_ptr_array_add(self->caps_list, caps);
+ ril_radio_caps_manager_list_changed(self);
+}
+
+static void ril_radio_caps_manager_remove(RilRadioCapsManager *self,
+ RilRadioCaps *caps)
+{
+ if (g_ptr_array_remove(self->caps_list, caps)) {
+ ril_radio_caps_manager_list_changed(self);
+ }
+}
+
+gulong ril_radio_caps_manager_add_tx_aborted_handler(RilRadioCapsManager *self,
ril_radio_caps_manager_cb_t cb, void *arg)
{
return (G_LIKELY(self) && G_LIKELY(cb)) ? g_signal_connect(self,
- SIGNAL_ABORTED_NAME, G_CALLBACK(cb), arg) : 0;
+ CAPS_MANAGER_SIGNAL_ABORTED_NAME, G_CALLBACK(cb), arg) : 0;
}
-void ril_radio_caps_manager_remove_handler(struct ril_radio_caps_manager *self,
- gulong id)
+gulong ril_radio_caps_manager_add_tx_done_handler(RilRadioCapsManager *self,
+ ril_radio_caps_manager_cb_t cb, void *arg)
+{
+ return (G_LIKELY(self) && G_LIKELY(cb)) ? g_signal_connect(self,
+ CAPS_MANAGER_SIGNAL_TX_DONE_NAME, G_CALLBACK(cb), arg) : 0;
+}
+
+void ril_radio_caps_manager_remove_handler(RilRadioCapsManager *self, gulong id)
{
if (G_LIKELY(self) && G_LIKELY(id)) {
g_signal_handler_disconnect(self, id);
}
}
+void ril_radio_caps_manager_remove_handlers(RilRadioCapsManager *self,
+ gulong *ids, int count)
+{
+ gutil_disconnect_handlers(self, ids, count);
+}
+
RilRadioCapsManager *ril_radio_caps_manager_ref(RilRadioCapsManager *self)
{
if (G_LIKELY(self)) {
@@ -1415,7 +1548,7 @@
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));
}
}
@@ -1430,7 +1563,11 @@
static void ril_radio_caps_manager_init(RilRadioCapsManager *self)
{
self->caps_list = g_ptr_array_new();
+ self->order_list = g_ptr_array_new();
+ self->requests = g_ptr_array_new();
self->tx_phase_index = -1;
+ self->idle_pool = gutil_idle_pool_ref
+ (gutil_idle_pool_get(&ril_radio_caps_shared_pool));
}
static void ril_radio_caps_manager_finalize(GObject *object)
@@ -1438,21 +1575,75 @@
RilRadioCapsManager *self = RADIO_CAPS_MANAGER(object);
GASSERT(!self->caps_list->len);
+ GASSERT(!self->order_list->len);
+ GASSERT(!self->requests->len);
g_ptr_array_free(self->caps_list, TRUE);
+ g_ptr_array_free(self->order_list, TRUE);
+ g_ptr_array_free(self->requests, TRUE);
if (self->check_id) {
g_source_remove(self->check_id);
}
ril_data_manager_unref(self->data_manager);
+ gutil_idle_pool_unref(self->idle_pool);
G_OBJECT_CLASS(ril_radio_caps_manager_parent_class)->finalize(object);
}
static void ril_radio_caps_manager_class_init(RilRadioCapsManagerClass *klass)
{
G_OBJECT_CLASS(klass)->finalize = ril_radio_caps_manager_finalize;
- ril_radio_caps_manager_signals[SIGNAL_ABORTED] =
- g_signal_new(SIGNAL_ABORTED_NAME,
+ ril_radio_caps_manager_signals[CAPS_MANAGER_SIGNAL_ABORTED] =
+ g_signal_new(CAPS_MANAGER_SIGNAL_ABORTED_NAME,
G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL, G_TYPE_NONE, 0);
+ ril_radio_caps_manager_signals[CAPS_MANAGER_SIGNAL_TX_DONE] =
+ g_signal_new(CAPS_MANAGER_SIGNAL_TX_DONE_NAME,
+ G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
+}
+
+/*==========================================================================*
+ * ril_radio_caps_request
+ *==========================================================================*/
+
+struct ril_radio_caps_request *ril_radio_caps_request_new
+ (struct ril_radio_caps *pub, enum ofono_radio_access_mode mode,
+ enum ril_data_role role)
+{
+ struct ril_radio_caps_request *req = NULL;
+ RilRadioCaps *caps = ril_radio_caps_cast(pub);
+
+ if (caps) {
+ RilRadioCapsManager *mgr = pub->mgr;
+
+ DBG_(caps, "%s (%s)",
+ ril_radio_caps_manager_role_str(pub->mgr, role),
+ ofono_radio_access_mode_to_string(mode));
+ req = g_slice_new(struct ril_radio_caps_request);
+ g_object_ref(req->caps = caps);
+ req->mode = mode;
+ req->role = role;
+ g_ptr_array_add(mgr->requests, req);
+ ril_radio_caps_manager_consider_requests(mgr);
+ }
+ return req;
+}
+
+void ril_radio_caps_request_free(struct ril_radio_caps_request *req)
+{
+ if (req) {
+ /* In case if g_object_unref frees the caps */
+ RilRadioCapsManager *mgr = ril_radio_caps_manager_ref
+ (req->caps->pub.mgr);
+
+ DBG_(req->caps, "%s (%s)",
+ ril_radio_caps_manager_role_str(mgr, req->role),
+ ofono_radio_access_mode_to_string(req->mode));
+ g_ptr_array_remove(mgr->requests, req);
+ g_object_unref(req->caps);
+ g_slice_free1(sizeof(*req), req);
+ ril_radio_caps_manager_consider_requests(mgr);
+ ril_radio_caps_manager_unref(mgr);
+ }
}
/*
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_radio_caps.h
^
|
@@ -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_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 */
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_radio_settings.c
^
|
@@ -15,28 +15,15 @@
#include "ril_plugin.h"
#include "ril_sim_settings.h"
-#include "ril_network.h"
#include "ril_util.h"
#include "ril_log.h"
-#include <gutil_idlequeue.h>
-#include <gutil_ints.h>
-
-enum ril_radio_settings_cb_tag {
- RADIO_SETTINGS_QUERY_AVAILABLE_RATS = 1,
- RADIO_SETTINGS_QUERY_AVAILABLE_MODES,
- RADIO_SETTINGS_QUERY_RAT_MODE,
- RADIO_SETTINGS_SET_RAT_MODE
-};
-
struct ril_radio_settings {
- GUtilIdleQueue *iq;
- GUtilInts *supported_modes;
- GHashTable *legacy_rat_map;
struct ofono_radio_settings *rs;
struct ril_sim_settings *settings;
const char *log_prefix;
char *allocated_log_prefix;
+ guint source_id;
};
struct ril_radio_settings_cbd {
@@ -45,7 +32,6 @@
ofono_radio_settings_rat_mode_set_cb_t rat_mode_set;
ofono_radio_settings_rat_mode_query_cb_t rat_mode_query;
ofono_radio_settings_available_rats_query_cb_t available_rats;
- ofono_radio_settings_available_modes_query_cb_t available_modes;
gpointer ptr;
} cb;
gpointer data;
@@ -59,41 +45,31 @@
return ofono_radio_settings_get_data(rs);
}
-static void ril_radio_settings_cbd_free(gpointer data)
-{
- g_slice_free(struct ril_radio_settings_cbd, data);
-}
-
static void ril_radio_settings_later(struct ril_radio_settings *rsd,
- enum ril_radio_settings_cb_tag tag, GUtilIdleFunc fn,
- void *cb, void *data)
+ GSourceFunc fn, void *cb, void *data)
{
struct ril_radio_settings_cbd *cbd;
- cbd = g_slice_new0(struct ril_radio_settings_cbd);
+ cbd = g_new0(struct ril_radio_settings_cbd, 1);
cbd->rsd = rsd;
cbd->cb.ptr = cb;
cbd->data = data;
- GVERIFY_FALSE(gutil_idle_queue_cancel_tag(rsd->iq, tag));
- gutil_idle_queue_add_tag_full(rsd->iq, tag, fn, cbd,
- ril_radio_settings_cbd_free);
+ GASSERT(!rsd->source_id);
+ rsd->source_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
+ fn, cbd, g_free);
}
-static void ril_radio_settings_set_rat_mode_cb(gpointer user_data)
+static gboolean ril_radio_settings_set_rat_mode_cb(gpointer user_data)
{
- struct ril_radio_settings_cbd *cbd = user_data;
struct ofono_error error;
-
- cbd->cb.rat_mode_set(ril_error_ok(&error), cbd->data);
-}
-
-static void ril_radio_settings_set_rat_mode_error_cb(gpointer user_data)
-{
struct ril_radio_settings_cbd *cbd = user_data;
- struct ofono_error error;
+ struct ril_radio_settings *rsd = cbd->rsd;
- cbd->cb.rat_mode_set(ril_error_failure(&error), cbd->data);
+ GASSERT(rsd->source_id);
+ rsd->source_id = 0;
+ cbd->cb.rat_mode_set(ril_error_ok(&error), cbd->data);
+ return G_SOURCE_REMOVE;
}
static void ril_radio_settings_set_rat_mode(struct ofono_radio_settings *rs,
@@ -101,29 +77,24 @@
ofono_radio_settings_rat_mode_set_cb_t cb, void *data)
{
struct ril_radio_settings *rsd = ril_radio_settings_get_data(rs);
-
- DBG_(rsd, "%s", ril_access_mode_to_string(mode));
- if (mode == OFONO_RADIO_ACCESS_MODE_ANY ||
- gutil_ints_contains(rsd->supported_modes, mode)) {
- ril_sim_settings_set_pref_mode(rsd->settings, mode);
- ril_radio_settings_later(rsd, RADIO_SETTINGS_SET_RAT_MODE,
- ril_radio_settings_set_rat_mode_cb, cb, data);
- } else {
- /* Refuse to accept unsupported modes */
- ril_radio_settings_later(rsd, RADIO_SETTINGS_SET_RAT_MODE,
- ril_radio_settings_set_rat_mode_error_cb, cb, data);
- }
+ DBG_(rsd, "%s", ofono_radio_access_mode_to_string(mode));
+ ril_sim_settings_set_pref_mode(rsd->settings, mode);
+ ril_radio_settings_later(rsd, ril_radio_settings_set_rat_mode_cb,
+ cb, data);
}
-static void ril_radio_settings_query_rat_mode_cb(gpointer user_data)
+static gboolean ril_radio_settings_query_rat_mode_cb(gpointer user_data)
{
struct ril_radio_settings_cbd *cbd = user_data;
struct ril_radio_settings *rsd = cbd->rsd;
enum ofono_radio_access_mode mode = rsd->settings->pref_mode;
struct ofono_error error;
- DBG_(rsd, "rat mode %s", ril_access_mode_to_string(mode));
+ DBG_(rsd, "rat mode %s", ofono_radio_access_mode_to_string(mode));
+ GASSERT(rsd->source_id);
+ rsd->source_id = 0;
cbd->cb.rat_mode_query(ril_error_ok(&error), mode, cbd->data);
+ return G_SOURCE_REMOVE;
}
static void ril_radio_settings_query_rat_mode(struct ofono_radio_settings *rs,
@@ -132,18 +103,21 @@
struct ril_radio_settings *rsd = ril_radio_settings_get_data(rs);
DBG_(rsd, "");
- ril_radio_settings_later(rsd, RADIO_SETTINGS_QUERY_RAT_MODE,
- ril_radio_settings_query_rat_mode_cb, cb, data);
+ ril_radio_settings_later(rsd, ril_radio_settings_query_rat_mode_cb,
+ cb, data);
}
-static void ril_radio_settings_query_available_rats_cb(gpointer data)
+static gboolean ril_radio_settings_query_available_rats_cb(gpointer data)
{
struct ofono_error error;
struct ril_radio_settings_cbd *cbd = data;
struct ril_radio_settings *rsd = cbd->rsd;
+ GASSERT(rsd->source_id);
+ rsd->source_id = 0;
cbd->cb.available_rats(ril_error_ok(&error), rsd->settings->techs,
cbd->data);
+ return G_SOURCE_REMOVE;
}
static void ril_radio_settings_query_available_rats(
@@ -153,56 +127,17 @@
struct ril_radio_settings *rsd = ril_radio_settings_get_data(rs);
DBG_(rsd, "");
- ril_radio_settings_later(rsd, RADIO_SETTINGS_QUERY_AVAILABLE_RATS,
+ ril_radio_settings_later(rsd,
ril_radio_settings_query_available_rats_cb, cb, data);
}
-static void ril_radio_settings_query_available_modes_cb(gpointer data)
-{
- guint i, n;
- struct ofono_error error;
- struct ril_radio_settings_cbd *cbd = data;
- struct ril_radio_settings *rsd = cbd->rsd;
- const int* value = gutil_ints_get_data(rsd->supported_modes, &n);
- enum ofono_radio_access_mode *modes;
-
- /* Copy those, enum doesn't have to have to size of an int */
- modes = g_new(enum ofono_radio_access_mode, n + 1);
- for (i = 0; i < n; i++) {
- modes[i] = value[i];
- }
- modes[i] = 0;
-
- cbd->cb.available_modes(ril_error_ok(&error), modes, cbd->data);
- g_free(modes);
-}
-
-static void ril_radio_settings_query_available_modes(
- struct ofono_radio_settings *rs,
- ofono_radio_settings_available_modes_query_cb_t cb, void *data)
-{
- struct ril_radio_settings *rsd = ril_radio_settings_get_data(rs);
-
- DBG_(rsd, "");
- ril_radio_settings_later(rsd, RADIO_SETTINGS_QUERY_AVAILABLE_MODES,
- ril_radio_settings_query_available_modes_cb, cb, data);
-}
-
-static enum ofono_radio_access_mode ril_radio_settings_map_legacy_rat_mode
- (struct ofono_radio_settings *rs, enum ofono_radio_access_mode rat)
-{
- struct ril_radio_settings *rsd = ril_radio_settings_get_data(rs);
- gpointer mapped = g_hash_table_lookup(rsd->legacy_rat_map,
- GINT_TO_POINTER(rat));
- return (enum ofono_radio_access_mode)GPOINTER_TO_INT(mapped);
-}
-
-static void ril_radio_settings_register(gpointer user_data)
+static gboolean ril_radio_settings_register(gpointer user_data)
{
struct ril_radio_settings *rsd = user_data;
-
- DBG_(rsd, "");
+ GASSERT(rsd->source_id);
+ rsd->source_id = 0;
ofono_radio_settings_register(rsd->rs);
+ return G_SOURCE_REMOVE;
}
static int ril_radio_settings_probe(struct ofono_radio_settings *rs,
@@ -210,16 +145,11 @@
{
struct ril_modem *modem = data;
struct ril_radio_settings *rsd = g_new0(struct ril_radio_settings, 1);
- guint r, n;
- GUtilInts *modes = ril_network_supported_modes(modem->network);
- const int* val = gutil_ints_get_data(modes, &n);
DBG("%s", modem->log_prefix);
rsd->rs = rs;
rsd->settings = ril_sim_settings_ref(modem->sim_settings);
- rsd->supported_modes = gutil_ints_ref(modes);
- rsd->iq = gutil_idle_queue_new();
- gutil_idle_queue_add(rsd->iq, ril_radio_settings_register, rsd);
+ rsd->source_id = g_idle_add(ril_radio_settings_register, rsd);
if (modem->log_prefix && modem->log_prefix[0]) {
rsd->log_prefix = rsd->allocated_log_prefix =
@@ -228,28 +158,6 @@
rsd->log_prefix = "";
}
- /* Fill the legacy access mode map */
- rsd->legacy_rat_map = g_hash_table_new(g_direct_hash, g_direct_equal);
- for (r = 1; r & OFONO_RADIO_ACCESS_MODE_ALL; r <<= 1) {
- guint i, max = 0;
- /* These bits have to be off: */
- const int off = ~((r << 1) - 1);
-
- /* Find the largest (e.g. most functional) mode */
- for (i = 0; i < n; i++) {
- const int m = val[i];
-
- if (!(m & off) && m > max) {
- max = m;
- }
- }
- DBG_(rsd, "%s -> 0x%x", ril_access_mode_to_string(r), max);
- if (max) {
- g_hash_table_insert(rsd->legacy_rat_map,
- GINT_TO_POINTER(r), GINT_TO_POINTER(max));
- }
- }
-
ofono_radio_settings_set_data(rs, rsd);
return 0;
}
@@ -259,25 +167,22 @@
struct ril_radio_settings *rsd = ril_radio_settings_get_data(rs);
DBG_(rsd, "");
- g_hash_table_destroy(rsd->legacy_rat_map);
ofono_radio_settings_set_data(rs, NULL);
- gutil_ints_unref(rsd->supported_modes);
- gutil_idle_queue_cancel_all(rsd->iq);
- gutil_idle_queue_unref(rsd->iq);
+ if (rsd->source_id) {
+ g_source_remove(rsd->source_id);
+ }
ril_sim_settings_unref(rsd->settings);
g_free(rsd->allocated_log_prefix);
g_free(rsd);
}
const struct ofono_radio_settings_driver ril_radio_settings_driver = {
- .name = RILMODEM_DRIVER,
- .probe = ril_radio_settings_probe,
- .remove = ril_radio_settings_remove,
- .query_rat_mode = ril_radio_settings_query_rat_mode,
- .set_rat_mode = ril_radio_settings_set_rat_mode,
- .query_available_rats = ril_radio_settings_query_available_rats,
- .query_available_rat_modes = ril_radio_settings_query_available_modes,
- .map_legacy_rat_mode = ril_radio_settings_map_legacy_rat_mode
+ .name = RILMODEM_DRIVER,
+ .probe = ril_radio_settings_probe,
+ .remove = ril_radio_settings_remove,
+ .query_rat_mode = ril_radio_settings_query_rat_mode,
+ .set_rat_mode = ril_radio_settings_set_rat_mode,
+ .query_available_rats = ril_radio_settings_query_available_rats
};
/*
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_sim_card.c
^
|
@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2015-2018 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
@@ -13,6 +13,8 @@
* GNU General Public License for more details.
*/
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#include "ril_sim_card.h"
#include "ril_radio.h"
#include "ril_util.h"
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_sim_settings.c
^
|
@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
- * Copyright (C) 2016-2019 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
@@ -13,6 +13,8 @@
* GNU General Public License for more details.
*/
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#include "ril_sim_settings.h"
#include "ril_log.h"
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_sim_settings.h
^
|
@@ -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 @@
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 */
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_subscription.conf
^
|
@@ -237,6 +237,13 @@
#
#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
@@ -275,6 +282,16 @@
#
#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.
@@ -302,9 +319,15 @@
#
# ss = Use legacy device state management (RIL_REQUEST_SCREEN_STATE)
# ds = Use newer device state management (RIL_REQUEST_SEND_DEVICE_STATE)
-# auto = Choose one of the above based on the RIL version
+# ur = Use URC filter (RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER)
+# This may be useful on devices with RIL version >= 15 if auto
+# method fails
+# auto = Choose ss or ds based on the RIL version
# none = Disable device state management
#
+# In addition to specifying ss, ds or ur method, one can specify a
+# combination of methods, e.g. ds+ur
+#
# Default auto
#
#deviceStateTracking=auto
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_types.h
^
|
@@ -24,6 +24,7 @@
#include <grilio_types.h>
#include <gutil_macros.h>
+struct ofono_watch;
struct ofono_modem;
struct ofono_sim;
@@ -49,12 +50,19 @@
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;
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;
@@ -64,6 +72,7 @@
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;
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_util.c
^
|
@@ -472,54 +472,6 @@
return FALSE;
}
-const char *ril_access_mode_to_string(enum ofono_radio_access_mode mode)
-{
- static const char *str[] = {
- "any",
- "gsm",
- "umts",
- "umts+gsm",
- "lte",
- "lte+gsm",
- "lte+umts",
- "lte+umts+gsm"
- };
-
- const int i = (mode & OFONO_RADIO_ACCESS_MODE_ALL);
-
- G_STATIC_ASSERT(G_N_ELEMENTS(str) == OFONO_RADIO_ACCESS_MODE_ALL+1);
-
- return (i == (int)mode) ? str[i] : NULL;
-}
-
-gboolean ril_access_mode_from_string(const char *str,
- enum ofono_radio_access_mode *result)
-{
- if (str) {
- enum ofono_radio_access_mode mode;
-
- if (!strcmp(str, "any")) {
- mode = OFONO_RADIO_ACCESS_MODE_ANY;
- } else if (!strcmp(str, "gsm")) {
- mode = OFONO_RADIO_ACCESS_MODE_GSM;
- } else if (!strcmp(str, "umts")) {
- mode = OFONO_RADIO_ACCESS_MODE_UMTS;
- } else if (!strcmp(str, "lte")) {
- mode = OFONO_RADIO_ACCESS_MODE_LTE;
- } else {
- return FALSE;
- }
-
- if (result) {
- *result = mode;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
/*
* Local Variables:
* mode: C
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_util.h
^
|
@@ -31,9 +31,6 @@
enum ril_auth ril_auth_method_from_ofono(enum ofono_gprs_auth_method auth);
int ril_parse_tech(const char *stech, int *ril_tech);
gboolean ril_parse_mcc_mnc(const char *str, struct ofono_network_operator *op);
-const char *ril_access_mode_to_string(enum ofono_radio_access_mode mode);
-gboolean ril_access_mode_from_string(const char *str,
- enum ofono_radio_access_mode *mode);
#define ril_error_init_ok(err) \
((err)->error = 0, (err)->type = OFONO_ERROR_TYPE_NO_ERROR)
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_vendor.h
^
|
@@ -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 @@
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;
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/drivers/ril/ril_vendor_mtk.c
^
|
@@ -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 @@
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,
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/include/dbus-access.h
^
|
@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony
*
- * Copyright (C) 2019 Jolla Ltd.
+ * Copyright (C) 2019-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
@@ -25,7 +26,7 @@
enum ofono_dbus_access {
OFONO_DBUS_ACCESS_DENY, /* Deny access */
OFONO_DBUS_ACCESS_ALLOW, /* Allow access */
- OFONO_DBUS_ACCESS_DONT_CARE, /* No decision */
+ OFONO_DBUS_ACCESS_DONT_CARE /* No decision */
};
enum ofono_dbus_access_intf {
@@ -38,6 +39,8 @@
OFONO_DBUS_ACCESS_INTF_SIMMGR, /* org.ofono.SimManager */
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
};
@@ -116,6 +119,18 @@
OFONO_DBUS_ACCESS_RADIOSETTINGS_METHOD_COUNT
};
+/* OFONO_DBUS_ACCESS_INTF_STK */
+enum ofono_dbus_access_stk_method {
+ OFONO_DBUS_ACCESS_STK_REGISTER_AGENT,
+ 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)
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/include/radio-settings.h
^
|
@@ -35,11 +35,6 @@
OFONO_RADIO_ACCESS_MODE_LTE = 0x4,
};
-#define OFONO_RADIO_ACCESS_MODE_ALL (\
- OFONO_RADIO_ACCESS_MODE_GSM |\
- OFONO_RADIO_ACCESS_MODE_UMTS |\
- OFONO_RADIO_ACCESS_MODE_LTE)
-
enum ofono_radio_band_gsm {
OFONO_RADIO_BAND_GSM_ANY,
OFONO_RADIO_BAND_GSM_850,
@@ -90,11 +85,6 @@
unsigned int available_rats,
void *data);
-typedef void (*ofono_radio_settings_available_modes_query_cb_t)(
- const struct ofono_error *error,
- const enum ofono_radio_access_mode *modes,
- void *data);
-
struct ofono_radio_settings_driver {
const char *name;
int (*probe)(struct ofono_radio_settings *rs, unsigned int vendor,
@@ -125,15 +115,6 @@
void (*query_available_rats)(struct ofono_radio_settings *rs,
ofono_radio_settings_available_rats_query_cb_t cb,
void *data);
- /* query_available_rat_modes and map_legacy_rat_mode are provided
- * by the drivers that support ofono_radio_access_mode mask, i.e.
- * selecting a set of preferred technologies. */
- void (*query_available_rat_modes)(struct ofono_radio_settings *rs,
- ofono_radio_settings_available_modes_query_cb_t cb,
- void *data);
- enum ofono_radio_access_mode (*map_legacy_rat_mode)
- (struct ofono_radio_settings *rs,
- enum ofono_radio_access_mode rat);
};
int ofono_radio_settings_driver_register(
@@ -155,6 +136,10 @@
struct ofono_modem *ofono_radio_settings_get_modem(
struct ofono_radio_settings *rs);
+const char *ofono_radio_access_mode_to_string(enum ofono_radio_access_mode m);
+ofono_bool_t ofono_radio_access_mode_from_string(const char *str,
+ enum ofono_radio_access_mode *mode);
+
#ifdef __cplusplus
}
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/plugins/mbpi.c
^
|
@@ -3,7 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
- * 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
@@ -60,6 +60,7 @@
*/
enum ofono_gprs_proto mbpi_default_internet_proto = OFONO_GPRS_PROTO_IPV4V6;
enum ofono_gprs_proto mbpi_default_mms_proto = OFONO_GPRS_PROTO_IP;
+enum ofono_gprs_proto mbpi_default_ims_proto = OFONO_GPRS_PROTO_IPV4V6;
enum ofono_gprs_proto mbpi_default_proto = OFONO_GPRS_PROTO_IP;
enum ofono_gprs_auth_method mbpi_default_auth_method = OFONO_GPRS_AUTH_METHOD_ANY;
@@ -246,6 +247,9 @@
} else if (strcmp(text, "mms") == 0) {
apn->type = OFONO_GPRS_CONTEXT_TYPE_MMS;
apn->proto = mbpi_default_mms_proto;
+ } else if (strcmp(text, "ims") == 0) {
+ apn->type = OFONO_GPRS_CONTEXT_TYPE_IMS;
+ apn->proto = mbpi_default_ims_proto;
} else if (strcmp(text, "wap") == 0)
apn->type = OFONO_GPRS_CONTEXT_TYPE_WAP;
else
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/plugins/mbpi.h
^
|
@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
+ * 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
@@ -22,6 +23,7 @@
extern const char *mbpi_database;
extern enum ofono_gprs_proto mbpi_default_internet_proto;
extern enum ofono_gprs_proto mbpi_default_mms_proto;
+extern enum ofono_gprs_proto mbpi_default_ims_proto;
extern enum ofono_gprs_proto mbpi_default_proto;
extern enum ofono_gprs_auth_method mbpi_default_auth_method;
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/plugins/sailfish_manager/sailfish_manager.c
^
|
@@ -743,18 +743,32 @@
*/
if (sailfish_manager_all_sims_are_initialized(p)) {
slot = sailfish_manager_find_slot_imsi(p, NULL);
- if (slot && slot->watch->online &&
+ if (slot && slot->watch->imsi && slot->watch->online &&
p->auto_data_sim == SIM_AUTO_SELECT_ONCE) {
+ const char *imsi = slot->watch->imsi;
+
/*
* Data SIM only needs to be auto-selected
* once and it's done. Write that down.
*/
+ DBG("Default data sim set to %s once", imsi);
p->auto_data_sim_done = TRUE;
g_key_file_set_boolean(p->storage,
SF_STORE_GROUP,
SF_STORE_AUTO_DATA_SIM_DONE,
p->auto_data_sim_done);
+
+ g_free(p->default_data_imsi);
+ p->pub.default_data_imsi =
+ p->default_data_imsi = g_strdup(imsi);
+ g_key_file_set_string(p->storage,
+ SF_STORE_GROUP,
+ SF_STORE_DEFAULT_DATA_SIM,
+ imsi);
+
storage_sync(NULL, SF_STORE, p->storage);
+ sailfish_manager_dbus_signal(p->dbus,
+ SAILFISH_MANAGER_SIGNAL_DATA_IMSI);
}
} else {
DBG("Skipping auto-selection of data SIM");
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/plugins/sailfish_manager/sailfish_sim_info.c
^
|
@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony
*
- * Copyright (C) 2017-2019 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
@@ -13,6 +13,8 @@
* GNU General Public License for more details.
*/
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/plugins/sailfish_provision.c
^
|
@@ -2,7 +2,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
- * Copyright (C) 2013-2017 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
@@ -136,38 +136,56 @@
}
}
-/* Returns the list containing exactly one INTERNET and one MMS access point */
+/**
+ * Returns the list containing INTERNET, MMS and IMS access points,
+ * always all three of them and always in this order.
+ */
static GSList *provision_normalize_apn_list(GSList *apns, const char *spn)
{
static const struct provision_ap_defaults internet_defaults =
{ OFONO_GPRS_CONTEXT_TYPE_INTERNET, "Internet", "internet" };
static const struct provision_ap_defaults mms_defaults =
{ OFONO_GPRS_CONTEXT_TYPE_MMS, "MMS", "mms" };
+ static const struct provision_ap_defaults ims_defaults =
+ { OFONO_GPRS_CONTEXT_TYPE_IMS, "IMS", "ims" };
GSList *internet_apns = NULL;
GSList *mms_apns = NULL;
+ GSList *ims_apns = NULL;
- /* Split internet and mms apns, delete all others */
+ /* Build separate apn list for each type */
while (apns) {
GSList *link = apns;
struct ofono_gprs_provision_data *ap = link->data;
apns = g_slist_remove_link(apns, link);
- if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET) {
+ switch (ap->type) {
+ case OFONO_GPRS_CONTEXT_TYPE_INTERNET:
internet_apns = g_slist_concat(internet_apns, link);
- } else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
+ break;
+ case OFONO_GPRS_CONTEXT_TYPE_MMS:
mms_apns = g_slist_concat(mms_apns, link);
- } else {
+ break;
+ case OFONO_GPRS_CONTEXT_TYPE_IMS:
+ ims_apns = g_slist_concat(ims_apns, link);
+ break;
+ default:
g_slist_free_full(link, provision_free_ap);
+ break;
}
}
- /* Pick the best ap of each type and concatenate them */
- return g_slist_concat(
- provision_pick_best_ap(internet_apns, spn,
- mbpi_default_internet_proto, &internet_defaults),
- provision_pick_best_ap(mms_apns, spn,
- mbpi_default_mms_proto, &mms_defaults));
+ /* Pick the best ap of each type */
+ internet_apns = provision_pick_best_ap(internet_apns, spn,
+ mbpi_default_internet_proto, &internet_defaults);
+ mms_apns = provision_pick_best_ap(mms_apns, spn,
+ mbpi_default_mms_proto, &mms_defaults);
+ ims_apns = provision_pick_best_ap(ims_apns, spn,
+ mbpi_default_ims_proto, &ims_defaults);
+
+ /* And concatenate them in the right order */
+ return g_slist_concat(internet_apns, g_slist_concat(mms_apns,
+ ims_apns));
}
int provision_get_settings(const char *mcc, const char *mnc,
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/plugins/smshistory.c
^
|
@@ -4,6 +4,7 @@
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013 Jolla Ltd. All rights reserved.
+ * Copyright (C) 2020 Open Mobile Platform LLŠ”. All rights reserved.
*
* 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
@@ -26,6 +27,7 @@
#include <string.h>
#include <stdio.h>
+#include <errno.h>
#include <glib.h>
#include <gdbus.h>
@@ -40,58 +42,42 @@
#define SMS_HISTORY_INTERFACE "org.ofono.SmsHistory"
-gboolean sms_history_interface_registered = FALSE;
-
static const GDBusSignalTable sms_history_signals[] = {
{ GDBUS_SIGNAL("StatusReport",
GDBUS_ARGS({ "message", "s" }, { "Delivered", "a{b}" })) },
{ }
};
-static void sms_history_cleanup(gpointer user)
+static int sms_history_probe(struct ofono_history_context *context)
{
- struct ofono_modem *modem = user;
- DBG("modem %p", modem);
- ofono_modem_remove_interface(modem, SMS_HISTORY_INTERFACE);
- sms_history_interface_registered = FALSE;
-}
-
-static gboolean sms_history_ensure_interface(
- struct ofono_modem *modem) {
+ DBusConnection *conn = ofono_dbus_get_connection();
+ struct ofono_modem *modem = context->modem;
- if (sms_history_interface_registered)
- return TRUE;
+ ofono_debug("SMS History Probe for modem: %p", modem);
- /* Late initialization of the D-Bus interface */
- DBusConnection *conn = ofono_dbus_get_connection();
- if (conn == NULL)
- return FALSE;
if (!g_dbus_register_interface(conn,
ofono_modem_get_path(modem),
SMS_HISTORY_INTERFACE,
- NULL, sms_history_signals, NULL,
- modem, sms_history_cleanup)) {
+ NULL, sms_history_signals,
+ NULL, NULL, NULL)) {
ofono_error("Could not create %s interface",
SMS_HISTORY_INTERFACE);
- return FALSE;
+ return -EIO;
}
- sms_history_interface_registered = TRUE;
- ofono_modem_add_interface(modem, SMS_HISTORY_INTERFACE);
-
- return TRUE;
-}
-
-static int sms_history_probe(struct ofono_history_context *context)
-{
- ofono_debug("SMS History Probe for modem: %p", context->modem);
- sms_history_ensure_interface(context->modem);
+ ofono_modem_add_interface(modem, SMS_HISTORY_INTERFACE);
return 0;
}
static void sms_history_remove(struct ofono_history_context *context)
{
- ofono_debug("SMS History Remove for modem: %p", context->modem);
+ DBusConnection *conn = ofono_dbus_get_connection();
+ struct ofono_modem *modem = context->modem;
+
+ ofono_debug("SMS History remove for modem: %p", modem);
+ ofono_modem_remove_interface(modem, SMS_HISTORY_INTERFACE);
+ g_dbus_unregister_interface(conn, ofono_modem_get_path(modem),
+ SMS_HISTORY_INTERFACE);
}
static void sms_history_sms_send_status(
@@ -102,9 +88,6 @@
{
DBG("");
- if (!sms_history_ensure_interface(context->modem))
- return;
-
if ((s == OFONO_HISTORY_SMS_STATUS_DELIVERED)
|| (s == OFONO_HISTORY_SMS_STATUS_DELIVER_FAILED)) {
@@ -174,4 +157,3 @@
OFONO_PLUGIN_DEFINE(sms_history, "SMS History Plugin",
VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
sms_history_init, sms_history_exit)
-
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/src/dbus-access.c
^
|
@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony
*
- * Copyright (C) 2019 Jolla Ltd.
+ * Copyright (C) 2019-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
@@ -41,6 +42,10 @@
return OFONO_MODEM_INTERFACE;
case OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS:
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;
}
@@ -165,6 +170,22 @@
break;
}
break;
+ case OFONO_DBUS_ACCESS_INTF_STK:
+ switch ((enum ofono_dbus_access_stk_method)method) {
+ case OFONO_DBUS_ACCESS_STK_REGISTER_AGENT:
+ return "RegisterAgent";
+ case OFONO_DBUS_ACCESS_STK_METHOD_COUNT:
+ 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;
}
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/src/gprs.c
^
|
@@ -3,7 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
- * Copyright (C) 2015-2019 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
@@ -2874,12 +2874,53 @@
return;
}
- for (i = 0; i < count; i++)
- provision_context(&settings[i], gprs);
+ for (i = 0; i < count; i++) {
+ const struct ofono_gprs_provision_data *ap = settings + i;
+
+ if (!ofono_gprs_context_settings_by_type(gprs, ap->type)) {
+ provision_context(ap, gprs);
+ }
+ }
__ofono_gprs_provision_free_settings(settings, count);
}
+static gboolean all_contexts_configured(struct ofono_gprs *gprs)
+{
+ GSList *l;
+
+ for (l = gprs->context_drivers; l; l = l->next) {
+ struct ofono_gprs_context *gc = l->data;
+
+ if (gc->type != OFONO_GPRS_CONTEXT_TYPE_ANY &&
+ !ofono_gprs_context_settings_by_type(gprs, gc->type)) {
+ return FALSE; /* Not yet */
+ }
+ }
+
+ return TRUE;
+}
+
+static void configure_remaining_contexts(struct ofono_gprs *gprs)
+{
+ GSList *l;
+
+ for (l = gprs->context_drivers; l; l = l->next) {
+ struct ofono_gprs_context *gc = l->data;
+
+ if (gc->type != OFONO_GPRS_CONTEXT_TYPE_ANY &&
+ !ofono_gprs_context_settings_by_type(gprs, gc->type)) {
+ add_context(gprs, NULL, gc->type);
+ }
+ }
+
+ /* Make sure internet context is there */
+ if (!ofono_gprs_context_settings_by_type(gprs,
+ OFONO_GPRS_CONTEXT_TYPE_INTERNET)) {
+ add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
+ }
+}
+
static void remove_non_active_context(struct ofono_gprs *gprs,
struct pri_context *ctx, DBusConnection *conn)
{
@@ -2960,8 +3001,7 @@
provision_contexts(gprs, ofono_sim_get_mcc(sim),
ofono_sim_get_mnc(sim), ofono_sim_get_spn(sim));
- if (gprs->contexts == NULL) /* Automatic provisioning failed */
- add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
+ configure_remaining_contexts(gprs);
for (l = gprs->contexts; l; l = l->next) {
struct pri_context *ctx = l->data;
@@ -3832,8 +3872,7 @@
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
const char *path = __ofono_atom_get_path(gprs->atom);
- if (gprs->contexts == NULL) /* Automatic provisioning failed */
- add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
+ configure_remaining_contexts(gprs);
if (!g_dbus_register_interface(conn, path,
OFONO_CONNECTION_MANAGER_INTERFACE,
@@ -3856,56 +3895,14 @@
__ofono_atom_register(gprs->atom, gprs_unregister);
}
-static gboolean mms_context_configured(struct ofono_gprs *gprs)
-{
- GSList *l;
-
- for (l = gprs->contexts; l; l = l->next) {
- struct pri_context *ctx = l->data;
-
- if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void provision_mms_context(struct ofono_gprs *gprs, const char *mcc,
- const char *mnc, const char *spn)
-{
- struct ofono_gprs_provision_data *settings;
- int count;
- int i;
-
- if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
- &settings, &count) == FALSE) {
- ofono_warn("Provisioning failed");
- return;
- }
-
- for (i = 0; i < count; i++) {
- if (settings[i].type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
- provision_context(&settings[i], gprs);
- break;
- }
- }
-
- __ofono_gprs_provision_free_settings(settings, count);
-}
-
static void spn_read_cb(const char *spn, const char *dc, void *data)
{
struct ofono_gprs *gprs = data;
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
- if (gprs->contexts == NULL) {
- provision_contexts(gprs, ofono_sim_get_mcc(sim),
- ofono_sim_get_mnc(sim), spn);
- } else if (!mms_context_configured(gprs)) {
- provision_mms_context(gprs, ofono_sim_get_mcc(sim),
+ provision_contexts(gprs, ofono_sim_get_mcc(sim),
ofono_sim_get_mnc(sim), spn);
- }
ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
@@ -3927,7 +3924,7 @@
gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
- if (mms_context_configured(gprs))
+ if (all_contexts_configured(gprs))
goto finish;
ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/src/ofono.h
^
|
@@ -283,6 +283,10 @@
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>
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/src/radio-settings.c
^
|
@@ -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
@@ -24,7 +25,6 @@
#endif
#include <string.h>
-#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
@@ -46,15 +46,15 @@
struct ofono_radio_settings {
struct ofono_dbus_queue *q;
int flags;
- int mode; /* rat mask or -legacy mode */
+ enum ofono_radio_access_mode mode;
enum ofono_radio_band_gsm band_gsm;
enum ofono_radio_band_umts band_umts;
ofono_bool_t fast_dormancy;
- int pending_mode;
+ enum ofono_radio_access_mode pending_mode;
enum ofono_radio_band_gsm pending_band_gsm;
enum ofono_radio_band_umts pending_band_umts;
ofono_bool_t fast_dormancy_pending;
- enum ofono_radio_access_mode *available_modes;
+ uint32_t available_rats;
GKeyFile *settings;
char *imsi;
const struct ofono_radio_settings_driver *driver;
@@ -62,15 +62,22 @@
struct ofono_atom *atom;
};
-static const enum ofono_radio_access_mode legacy_modes[] = {
- OFONO_RADIO_ACCESS_MODE_GSM,
- OFONO_RADIO_ACCESS_MODE_UMTS,
- OFONO_RADIO_ACCESS_MODE_LTE
-};
+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;
+}
-static const char *radio_legacy_mode_to_string(enum ofono_radio_access_mode m)
+#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:
@@ -82,84 +89,19 @@
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;
}
-
-static const char *radio_access_modes_to_string(enum ofono_radio_access_mode m)
-{
- static const char *mode_string[OFONO_RADIO_ACCESS_MODE_ALL+1] = {
- "any",
- "+gsm",
- "+umts",
- "+umts+gsm",
- "+lte",
- "+lte+gsm",
- "+lte+umts",
- "+lte+umts+gsm"
- };
-
- return mode_string[m & OFONO_RADIO_ACCESS_MODE_ALL];
-}
-
-static const char *radio_access_mode_to_string(int m)
-{
- return m < 0 ? radio_legacy_mode_to_string(-m) :
- radio_access_modes_to_string(m);
-}
-
-static gboolean radio_access_mode_is_supported(struct ofono_radio_settings *rs,
- enum ofono_radio_access_mode mode)
-{
- /* ANY is always supported */
- if (mode == OFONO_RADIO_ACCESS_MODE_ANY)
- return TRUE;
-
- if (rs->available_modes) {
- const enum ofono_radio_access_mode *m = rs->available_modes;
-
- while (*m) {
- if (*m++ == mode) {
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- /*
- * We have no idea what's supported and what's not, let's assume
- * that everything is!
- */
- return TRUE;
-}
-
-static gboolean radio_legacy_rat_driver(struct ofono_radio_settings *rs)
-{
- /*
- * query_available_rat_modes is provided by the drivers that support
- * ofono_radio_access_mode mask, i.e. a set of preferred technologies.
- */
- return !rs->driver->query_available_rat_modes;
-}
-
-static enum ofono_radio_access_mode radio_map_legacy_rat
- (struct ofono_radio_settings *rs,
- enum ofono_radio_access_mode rat)
-{
- if (rat == OFONO_RADIO_ACCESS_MODE_ANY || radio_legacy_rat_driver(rs))
- return rat;
-
- if (rs->driver->map_legacy_rat_mode)
- return rs->driver->map_legacy_rat_mode(rs, rat);
-
- /* rat is supposed to be a single bit */
- return (rat | (rat - 1)) & OFONO_RADIO_ACCESS_MODE_ALL;
-}
-
-static gboolean radio_legacy_mode_from_string(const char *str,
+#define radio_access_mode_from_string ofono_radio_access_mode_from_string
+ofono_bool_t ofono_radio_access_mode_from_string(const char *str,
enum ofono_radio_access_mode *mode)
{
- if (g_str_equal(str, "any")) {
+ if (!str) {
+ return FALSE;
+ } else if (g_str_equal(str, "any")) {
*mode = OFONO_RADIO_ACCESS_MODE_ANY;
return TRUE;
} else if (g_str_equal(str, "gsm")) {
@@ -176,39 +118,6 @@
return FALSE;
}
-static gboolean radio_access_modes_from_string(const char *str,
- enum ofono_radio_access_mode *mask)
-{
- if (str && str[0] == '+') {
- gboolean ok = TRUE, any = FALSE;
- char **modes = g_strsplit (str + 1, "+", -1);
- int i;
-
- *mask = 0;
-
- for (i = 0; modes[i] && ok; i++) {
- enum ofono_radio_access_mode m;
- const char *s = modes[i];
-
- if (radio_legacy_mode_from_string(s, &m)) {
- if (m == OFONO_RADIO_ACCESS_MODE_ANY)
- any = TRUE;
- else
- *mask |= m;
- } else {
- ok = FALSE;
- }
- }
-
- if (any)
- *mask = OFONO_RADIO_ACCESS_MODE_ANY;
-
- g_strfreev(modes);
- return ok;
- }
- return FALSE;
-}
-
static const char *radio_band_gsm_to_string(enum ofono_radio_band_gsm band)
{
switch (band) {
@@ -341,48 +250,25 @@
DBUS_TYPE_BOOLEAN, &value);
}
- if (rs->available_modes) {
- int i = 0, n = 0;
- const char **dbus_rats;
- const enum ofono_radio_access_mode *m;
-
- while (rs->available_modes[n])
- n++;
-
- if (radio_legacy_rat_driver(rs)) {
- dbus_rats = g_new(const char *, n + 1);
- for (m = rs->available_modes; *m; m++) {
- dbus_rats[i++] =
- radio_legacy_mode_to_string(*m);
- }
- } else {
- int k;
-
- /* Add valid legacy modes */
- n += G_N_ELEMENTS(legacy_modes);
- dbus_rats = g_new(const char *, n + 1);
-
- for (k = 0; k < G_N_ELEMENTS(legacy_modes); k++) {
- enum ofono_radio_access_mode l =
- legacy_modes[k];
-
- if (radio_map_legacy_rat(rs, l)) {
- dbus_rats[i++] =
- radio_legacy_mode_to_string(l);
- }
- }
-
- /* and the combinations of modes */
- for (m = rs->available_modes; *m; m++) {
- dbus_rats[i++] =
- radio_access_modes_to_string(*m);
- }
+ if (rs->available_rats) {
+ const char *rats[sizeof(uint32_t) * CHAR_BIT + 1];
+ const char **dbus_rats = rats;
+ int n = 0;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(uint32_t) * CHAR_BIT; i++) {
+ int tech = 1 << i;
+
+ if (!(rs->available_rats & tech))
+ continue;
+
+ rats[n++] = radio_access_mode_to_string(tech);
}
- dbus_rats[i] = NULL;
+ rats[n] = NULL;
+
ofono_dbus_dict_append_array(&dict, "AvailableTechnologies",
DBUS_TYPE_STRING, &dbus_rats);
- g_free(dbus_rats);
}
dbus_message_iter_close_container(&iter, &dict);
@@ -489,7 +375,8 @@
radio_set_band(rs);
}
-static void radio_set_rat_mode(struct ofono_radio_settings *rs, int mode)
+static void radio_set_rat_mode(struct ofono_radio_settings *rs,
+ enum ofono_radio_access_mode mode)
{
DBusConnection *conn = ofono_dbus_get_connection();
const char *path;
@@ -509,8 +396,8 @@
DBUS_TYPE_STRING, &str_mode);
if (rs->settings) {
- g_key_file_set_string(rs->settings, SETTINGS_GROUP,
- "TechnologyPreference", str_mode);
+ g_key_file_set_integer(rs->settings, SETTINGS_GROUP,
+ "TechnologyPreference", rs->mode);
storage_sync(rs->imsi, SETTINGS_STORE, rs->settings);
}
}
@@ -553,47 +440,10 @@
{
struct ofono_radio_settings *rs = data;
- if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
- unsigned int m, n;
-
- /* Count number of bits */
- available_rats &= OFONO_RADIO_ACCESS_MODE_ALL;
- for (m = available_rats, n = 0; m; n++)
- m &= m - 1;
-
- g_free(rs->available_modes);
- rs->available_modes = g_new(enum ofono_radio_access_mode, n+1);
-
- for (m = available_rats, n = 0; m; n++) {
- /* Extract the least significant bit from the mask */
- rs->available_modes[n] = (m & ~(m - 1));
- m &= m - 1;
- }
- rs->available_modes[n] = 0;
- } else {
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
+ rs->available_rats = available_rats & 0x7;
+ else
DBG("Error while querying available rats");
- }
-
- radio_send_properties_reply(rs);
-}
-
-static void radio_available_modes_query_callback(const struct ofono_error *err,
- const enum ofono_radio_access_mode *modes, void *data)
-{
- struct ofono_radio_settings *rs = data;
-
- if (err->type == OFONO_ERROR_TYPE_NO_ERROR) {
- unsigned int n;
-
- for (n = 0; modes[n]; n++);
-
- g_free(rs->available_modes);
- rs->available_modes = g_new(enum ofono_radio_access_mode, n+1);
- rs->available_modes[n] = 0;
- memcpy(rs->available_modes, modes, sizeof(modes[0]) * n);
- } else {
- DBG("Error while querying available modes");
- }
radio_send_properties_reply(rs);
}
@@ -601,17 +451,12 @@
static void radio_query_available_rats(struct ofono_radio_settings *rs)
{
/* Modem technology is not supposed to change, so one query is enough */
- if (rs->available_modes || (!rs->driver->query_available_rats &&
- !rs->driver->query_available_rat_modes)) {
+ if (rs->driver->query_available_rats == NULL || rs->available_rats) {
radio_send_properties_reply(rs);
return;
}
- if (rs->driver->query_available_rat_modes)
- rs->driver->query_available_rat_modes(
- rs, radio_available_modes_query_callback, rs);
- else
- rs->driver->query_available_rats(
+ rs->driver->query_available_rats(
rs, radio_available_rats_query_callback, rs);
}
@@ -676,11 +521,10 @@
}
static void radio_rat_mode_query_callback(const struct ofono_error *error,
- enum ofono_radio_access_mode rat,
+ enum ofono_radio_access_mode mode,
void *data)
{
struct ofono_radio_settings *rs = data;
- int mode = rat;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG("Error during radio access mode query");
@@ -690,22 +534,6 @@
return;
}
- if (radio_legacy_rat_driver(rs)) {
- mode = -mode;
- } else {
- /*
- * If we have previously set a legacy mode, let's check
- * it if still maps to the current (real) mode and
- * if it does, keep the legacy mode. This is necessary
- * for compatibility with legacy UIs that only know
- * about legacy modes.
- */
- if (rs->mode < 0 &&
- radio_map_legacy_rat(rs, -rs->mode) == mode) {
- mode = rs->mode;
- }
- }
-
radio_set_rat_mode(rs, mode);
radio_query_band(rs);
}
@@ -753,8 +581,7 @@
if (g_strcmp0(property, "TechnologyPreference") == 0) {
const char *value;
- int mode;
- enum ofono_radio_access_mode am;
+ enum ofono_radio_access_mode mode;
if (rs->driver->set_rat_mode == NULL)
return __ofono_error_not_implemented(msg);
@@ -763,27 +590,7 @@
return __ofono_error_invalid_args(msg);
dbus_message_iter_get_basic(&var, &value);
- if (radio_legacy_mode_from_string(value, &am)) {
- mode = -(int)am;
-
- if (radio_legacy_rat_driver(rs)) {
- /* Make sure it's supported */
- if (!radio_access_mode_is_supported(rs, am))
- return __ofono_error_not_supported(msg);
- } else if (mode != OFONO_RADIO_ACCESS_MODE_ANY) {
- /* Map a legacy value into the real one */
- am = radio_map_legacy_rat(rs, am);
- if (!am)
- return __ofono_error_not_supported(msg);
- }
- } else if (radio_access_modes_from_string(value, &am)) {
- mode = am;
-
- /* Make sure this combination of modes is supported */
- if (radio_legacy_rat_driver(rs) ||
- !radio_access_mode_is_supported(rs, am))
- return __ofono_error_not_supported(msg);
- } else
+ if (radio_access_mode_from_string(value, &mode) == FALSE)
return __ofono_error_invalid_args(msg);
if (rs->mode == mode)
@@ -791,7 +598,7 @@
rs->pending_mode = mode;
- rs->driver->set_rat_mode(rs, am, radio_mode_set_callback, rs);
+ rs->driver->set_rat_mode(rs, mode, radio_mode_set_callback, rs);
/* will be saved in radiosettng on success response*/
return NULL;
} else if (g_strcmp0(property, "GsmBand") == 0) {
@@ -932,7 +739,6 @@
struct ofono_modem *modem = __ofono_atom_get_modem(rs->atom);
__ofono_dbus_queue_free(rs->q);
- g_free(rs->available_modes);
ofono_modem_remove_interface(modem, OFONO_RADIO_SETTINGS_INTERFACE);
g_dbus_unregister_interface(conn, path, OFONO_RADIO_SETTINGS_INTERFACE);
@@ -975,7 +781,7 @@
if (rs == NULL)
return NULL;
- rs->mode = 0;
+ rs->mode = -1;
rs->q = __ofono_dbus_queue_new();
rs->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_RADIO_SETTINGS,
radio_settings_remove, rs);
@@ -1045,8 +851,6 @@
const char *imsi)
{
GError *error;
- char *str;
- gboolean save_mode = FALSE;
rs->settings = storage_open(imsi, SETTINGS_STORE);
@@ -1097,37 +901,13 @@
rs->pending_band_umts = rs->band_umts;
- rs->mode = 0;
-
- str = g_key_file_get_string(rs->settings, SETTINGS_GROUP,
- "TechnologyPreference", NULL);
+ rs->mode = g_key_file_get_integer(rs->settings, SETTINGS_GROUP,
+ "TechnologyPreference", &error);
- if (str) {
- enum ofono_radio_access_mode am;
-
- if (radio_legacy_mode_from_string(str, &am)) {
- if (radio_legacy_rat_driver(rs) ||
- radio_map_legacy_rat(rs, am)) {
- rs->mode = -(int)am;
- }
- } else if (radio_access_modes_from_string(str, &am)) {
- /* Mask of rats */
- rs->mode = am;
- } else {
- /* Old format (integer) */
- save_mode = TRUE;
- rs->mode = -atoi(str);
- DBG("migrating %s -> %s", str,
- radio_access_mode_to_string(rs->mode));
- }
- g_free(str);
- }
-
- if (save_mode) {
- g_key_file_set_string(rs->settings, SETTINGS_GROUP,
- "TechnologyPreference",
- radio_access_mode_to_string(rs->mode));
- /* No need to save the file right away */
+ if (error || radio_access_mode_to_string(rs->mode) == NULL) {
+ rs->mode = OFONO_RADIO_ACCESS_MODE_ANY;
+ g_key_file_set_integer(rs->settings, SETTINGS_GROUP,
+ "TechnologyPreference", rs->mode);
}
if (error) {
@@ -1135,7 +915,7 @@
error = NULL;
}
- DBG("TechnologyPreference: %s", radio_access_mode_to_string(rs->mode));
+ DBG("TechnologyPreference: %d", rs->mode);
DBG("GsmBand: %d", rs->band_gsm);
DBG("UmtsBand: %d", rs->band_umts);
}
@@ -1161,8 +941,7 @@
* Diff callback used. No need of using DBUS pending concept.
* As its atom registration time - no DBUS clients.
*/
- rs->driver->set_rat_mode(rs, rs->mode < 0 ?
- radio_map_legacy_rat(rs, -rs->mode) : rs->mode,
+ rs->driver->set_rat_mode(rs, rs->mode,
radio_mode_set_callback_at_reg, rs);
return;
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/src/smsutil.c
^
|
@@ -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 @@
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_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 @@
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 @@
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 @@
if (iso639)
bufsize -= 3;
} else {
- bufsize += 82;
+ bufsize += cbs->udlen;
if (iso639)
bufsize -= 2;
@@ -4089,7 +4097,7 @@
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 @@
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 @@
* 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;
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/src/smsutil.h
^
|
@@ -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 @@
guint8 dcs; /* 8 bits */
guint8 max_pages; /* 4 bits */
guint8 page; /* 4 bits */
+ guint8 udlen;
guint8 ud[82];
};
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/src/stk.c
^
|
@@ -3,6 +3,8 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
+ * Copyright (C) 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
@@ -725,6 +727,12 @@
if (!dbus_validate_path(agent_path, NULL))
return __ofono_error_invalid_format(msg);
+ if (!__ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
+ OFONO_DBUS_ACCESS_INTF_STK,
+ OFONO_DBUS_ACCESS_STK_REGISTER_AGENT,
+ agent_path))
+ return __ofono_error_access_denied(msg);
+
stk->default_agent = stk_agent_new(agent_path,
dbus_message_get_sender(msg),
FALSE);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/unit/test-dbus-access.c
^
|
@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony
*
- * Copyright (C) 2019 Jolla Ltd.
+ * Copyright (C) 2019-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
@@ -33,6 +34,12 @@
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",
@@ -50,6 +57,12 @@
.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
*==========================================================================*/
@@ -103,6 +116,12 @@
},{
OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS,
OFONO_DBUS_ACCESS_RADIOSETTINGS_METHOD_COUNT
+ },{
+ OFONO_DBUS_ACCESS_INTF_STK,
+ OFONO_DBUS_ACCESS_STK_METHOD_COUNT
+ },{
+ OFONO_DBUS_ACCESS_INTF_OEMRAW,
+ OFONO_DBUS_ACCESS_OEMRAW_METHOD_COUNT
}
};
@@ -150,6 +169,13 @@
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);
+
+ /* 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 */
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/unit/test-provision.c
^
|
@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony
*
- * Copyright (C) 2014-2017 Jolla. All rights reserved.
+ * Copyright (C) 2014-2020 Jolla. All rights reserved.
*
* 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
@@ -105,21 +105,21 @@
g_assert(actual->type == expected->type);
g_assert(actual->proto == expected->proto);
- g_assert(!g_strcmp0(actual->provider_name,
- expected->provider_name));
- g_assert(!g_strcmp0(actual->name, expected->name));
+ g_assert_cmpstr(actual->provider_name, ==,
+ expected->provider_name);
+ g_assert_cmpstr(actual->name, ==, expected->name);
g_assert(actual->provider_primary ==
expected->provider_primary);
- g_assert(!g_strcmp0(actual->apn, expected->apn));
- g_assert(!g_strcmp0(actual->username,
- expected->username));
- g_assert(!g_strcmp0(actual->password,
- expected->password));
+ g_assert_cmpstr(actual->apn, ==, expected->apn);
+ g_assert_cmpstr(actual->username, ==,
+ expected->username);
+ g_assert_cmpstr(actual->password, ==,
+ expected->password);
g_assert(actual->auth_method == expected->auth_method);
- g_assert(!g_strcmp0(actual->message_proxy,
- expected->message_proxy));
- g_assert(!g_strcmp0(actual->message_center,
- expected->message_center));
+ g_assert_cmpstr(actual->message_proxy, ==,
+ expected->message_proxy);
+ g_assert_cmpstr(actual->message_center, ==,
+ expected->message_center);
}
} else {
g_assert(!__ofono_gprs_provision_get_settings(test->mcc,
@@ -212,6 +212,14 @@
.apn = "mms", \
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE
+/* Default IMS settings */
+#define DEFAULT_IMS_SETTINGS \
+ .type = OFONO_GPRS_CONTEXT_TYPE_IMS, \
+ .proto = OFONO_GPRS_PROTO_IPV4V6, \
+ .name = "IMS", \
+ .apn = "ims", \
+ .auth_method = OFONO_GPRS_AUTH_METHOD_NONE
+
static const struct ofono_gprs_provision_data telia_fi_internet_mms_p[] = {
{
.type = OFONO_GPRS_CONTEXT_TYPE_INTERNET,
@@ -231,7 +239,8 @@
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE,
.message_proxy = telia_fi_message_proxy,
.message_center = telia_fi_message_center
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data telia_fi_internet_mms[] = {
@@ -251,7 +260,8 @@
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE,
.message_proxy = telia_fi_message_proxy,
.message_center = telia_fi_message_center
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data telia_fi_internet[] = {
@@ -263,7 +273,8 @@
.apn = telia_fi_apn_internet,
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE
},
- { DEFAULT_MMS_SETTINGS }
+ { DEFAULT_MMS_SETTINGS },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data telia_fi_mms[] = {
@@ -277,12 +288,14 @@
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE,
.message_proxy = telia_fi_message_proxy,
.message_center = telia_fi_message_center
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data default_settings[] = {
{ DEFAILT_INTERNET_SETTINGS },
- { DEFAULT_MMS_SETTINGS }
+ { DEFAULT_MMS_SETTINGS },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data no_auth_settings[] = {
@@ -300,7 +313,8 @@
.name = "MMS",
.apn = "mms",
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data auth_settings[] = {
@@ -318,7 +332,8 @@
.apn = "mms",
.password = "password",
.auth_method = OFONO_GPRS_AUTH_METHOD_ANY
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data settings_ip[] = {
@@ -329,7 +344,8 @@
.apn = "internet",
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE
},
- { DEFAULT_MMS_SETTINGS }
+ { DEFAULT_MMS_SETTINGS },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data settings_ipv6[] = {
@@ -345,7 +361,8 @@
.name = "MMS",
.apn = "mms",
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
};
static const struct ofono_gprs_provision_data settings_ipv4v6[] = {
@@ -356,7 +373,40 @@
.name = "MMS",
.apn = "mms",
.auth_method = OFONO_GPRS_AUTH_METHOD_NONE
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
+};
+
+static char beeline_provider_name [] = "Beeline";
+static const struct ofono_gprs_provision_data beeline_ims[] = {
+ {
+ .type = OFONO_GPRS_CONTEXT_TYPE_INTERNET,
+ .proto = OFONO_GPRS_PROTO_IPV4V6,
+ .provider_name = beeline_provider_name,
+ .name = "Beeline Internet",
+ .apn = "internet.beeline.ru",
+ .username = "beeline",
+ .password = "beeline",
+ .auth_method = OFONO_GPRS_AUTH_METHOD_ANY
+ }, {
+ .type = OFONO_GPRS_CONTEXT_TYPE_MMS,
+ .proto = OFONO_GPRS_PROTO_IP,
+ .provider_name = beeline_provider_name,
+ .name = "Beeline MMS",
+ .apn = "mms.beeline.ru",
+ .username = "beeline",
+ .password = "beeline",
+ .auth_method = OFONO_GPRS_AUTH_METHOD_PAP,
+ .message_proxy = "192.168.94.23:8080",
+ .message_center = "http://mms/"
+ }, {
+ .type = OFONO_GPRS_CONTEXT_TYPE_IMS,
+ .proto = OFONO_GPRS_PROTO_IPV4V6,
+ .provider_name = beeline_provider_name,
+ .name = "Beeline IMS",
+ .apn = "ims.beeline.ru",
+ .auth_method = OFONO_GPRS_AUTH_METHOD_NONE
+ }
};
static char test_provider_name[] = "Test provider";
@@ -382,7 +432,8 @@
.auth_method = OFONO_GPRS_AUTH_METHOD_CHAP,
.message_proxy = test_message_proxy,
.message_center = test_message_center
- }
+ },
+ { DEFAULT_IMS_SETTINGS }
};
static const char telia_fi_internet_xml[] =
@@ -807,6 +858,42 @@
.settings = telia_fi_mms,
.count = G_N_ELEMENTS(telia_fi_mms)
},{
+ .name = TEST_SUITE "ims",
+ .xml =
+"<serviceproviders format=\"2.0\">\n\
+<country code=\"ru\">\n\
+ <provider>\n\
+ <name>Beeline</name>\n\
+ <gsm>\n\
+ <network-id mcc=\"250\" mnc=\"99\"/>\n\
+ <apn value=\"internet.beeline.ru\">\n\
+ <usage type=\"internet\"/>\n\
+ <name>Beeline Internet</name>\n\
+ <username>beeline</username>\n\
+ <password>beeline</password>\n\
+ </apn>\n\
+ <apn value=\"mms.beeline.ru\">\n\
+ <usage type=\"mms\"/>\n\
+ <name>Beeline MMS</name>\n\
+ <authentication method=\"pap\"/>\n\
+ <username>beeline</username>\n\
+ <password>beeline</password>\n\
+ <mmsc>http://mms/</mmsc>\n\
+ <mmsproxy>192.168.94.23:8080</mmsproxy>\n\
+ </apn>\n\
+ <apn value=\"ims.beeline.ru\">\n\
+ <usage type=\"ims\"/>\n\
+ <name>Beeline IMS</name>\n\
+ </apn>\n\
+ </gsm>\n\
+ </provider>\n\
+</country>\n\
+</serviceproviders>\n",
+ .mcc = "250",
+ .mnc = "99",
+ .settings = beeline_ims,
+ .count = G_N_ELEMENTS(beeline_ims)
+ },{
.name = TEST_SUITE "not_found_mcc",
.xml = telia_fi_internet_xml,
.mcc = "245", /* Wrong MCC */
@@ -1297,3 +1384,11 @@
}
return g_test_run();
}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-basic-offset: 8
+ * indent-tabs-mode: t
+ * End:
+ */
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/unit/test-ril_config.c
^
|
@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony
*
- * Copyright (C) 2018-2019 Jolla Ltd.
- * Copyright (C) 2019 Open Mobile Platform LLC.
+ * Copyright (C) 2018-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
@@ -377,6 +377,39 @@
test_get_value(conf, test_get_enum_cb);
}
+/* ==== get_mask ==== */
+
+static void test_get_mask_cb(GKeyFile *k)
+{
+ int v = 0;
+
+ g_assert(!ril_config_get_mask(k, "g1", "k", NULL, "x",1, "y",2, NULL));
+ g_assert(!ril_config_get_mask(k, "g1", "k", &v, "x",1, "y",2, NULL));
+ g_assert_cmpint(v, ==, 0);
+
+ g_assert(ril_config_get_mask(k, "g", "k", NULL, "x",1, "y",2, NULL));
+ g_assert(ril_config_get_mask(k, "g", "k", &v, "x",1, "y",2, NULL));
+ g_assert_cmpint(v, ==, 1);
+
+ g_assert(ril_config_get_mask(k, "g", "k1", NULL, "x",1, "y",2, NULL));
+ g_assert(ril_config_get_mask(k, "g", "k1", &v, "x",1, "y",2, NULL));
+ g_assert_cmpint(v, ==, 3);
+
+ g_assert(!ril_config_get_mask(k, "g", "k2", NULL, "x",1, "y",2, NULL));
+ g_assert(!ril_config_get_mask(k, "g", "k2", &v, "x",1, "y",2, NULL));
+ g_assert_cmpint(v, ==, 0);
+}
+
+static void test_get_mask(void)
+{
+ static const char conf [] = "[g]\n"
+ "k = x# comment\n"
+ "k1 = x+y\n"
+ "k2 = x+z+y\n";
+
+ test_get_value(conf, test_get_mask_cb);
+}
+
/* ==== get_ints ==== */
static void test_get_ints_cb(GKeyFile *k)
@@ -451,6 +484,7 @@
g_test_add_func(TEST_("get_boolean3"), test_get_boolean3);
g_test_add_func(TEST_("get_flag"), test_get_flag);
g_test_add_func(TEST_("get_enum"), test_get_enum);
+ g_test_add_func(TEST_("get_mask"), test_get_mask);
g_test_add_func(TEST_("get_ints"), test_get_ints);
g_test_add_func(TEST_("ints_to_string"), test_ints_to_string);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.23+git16.tar.bz2/ofono/unit/test-ril_util.c
^
|
@@ -137,46 +137,6 @@
"2147483647 (?)"));
}
-void test_access_mode(void)
-{
- static const struct access_mode_map {
- const char *str;
- enum ofono_radio_access_mode value;
- } modes [] = {
- { "any", OFONO_RADIO_ACCESS_MODE_ANY },
- { "gsm", OFONO_RADIO_ACCESS_MODE_GSM },
- { "umts", OFONO_RADIO_ACCESS_MODE_UMTS },
- { "lte", OFONO_RADIO_ACCESS_MODE_LTE }
- };
-
- int i;
-
- for (i = 0; i < G_N_ELEMENTS(modes); i++) {
- g_assert(!g_strcmp0(ril_access_mode_to_string(modes[i].value),
- modes[i].str));
- }
- g_assert(!g_strcmp0(ril_access_mode_to_string
- (OFONO_RADIO_ACCESS_MODE_GSM |
- OFONO_RADIO_ACCESS_MODE_UMTS), "umts+gsm"));
- g_assert(!g_strcmp0(ril_access_mode_to_string
- (OFONO_RADIO_ACCESS_MODE_GSM |
- OFONO_RADIO_ACCESS_MODE_LTE), "lte+gsm"));
- g_assert(!ril_access_mode_to_string(-1));
-
- g_assert(!ril_access_mode_from_string(NULL, NULL));
- g_assert(!ril_access_mode_from_string("", NULL));
- g_assert(!ril_access_mode_from_string("invalid", NULL));
- g_assert(!ril_access_mode_from_string("lte+gsm", NULL));
-
- for (i = 0; i < G_N_ELEMENTS(modes); i++) {
- const struct access_mode_map *map = modes + i;
- enum ofono_radio_access_mode am = OFONO_RADIO_ACCESS_MODE_ANY;
- g_assert(ril_access_mode_from_string(map->str, NULL));
- g_assert(ril_access_mode_from_string(map->str, &am));
- g_assert(am == map->value);
- }
-}
-
#define TEST_(name) "/ril_util/" name
int main(int argc, char *argv[])
@@ -193,7 +153,6 @@
g_test_add_func(TEST_("protocol_to_ofono"), test_protocol_to_ofono);
g_test_add_func(TEST_("auth_method"), test_auth_method);
g_test_add_func(TEST_("strings"), test_strings);
- g_test_add_func(TEST_("access_mode"), test_access_mode);
return g_test_run();
}
|