Compare commits

..

12 Commits

Author SHA1 Message Date
Denis Grigorev
3e82beca36 [ril] Provide SmsHistory interface for all modems. JB#49955
The SmsHistory plugin uses a global variable to determine if it is already
registered. Because of that, Ofono provides org.ofono.SmsHistory only for
the first modem, and SMS delivery notifications do not work on the others.
After this commit is applied, the plugin will be registered for each modem.
2020-05-20 17:21:06 +03:00
Slava Monich
d3ddce9661 [ril] Stop repeating requests on RADIO_NOT_AVAILABLE. JB#49471
If the modem is powered off, this error is repeated indefinitely,
causing unnecessary wakeups.
2020-04-01 19:44:54 +03:00
Slava Monich
54ef7e78a3 [ril] Tweaked power state confirmation logic. JB#49471
Changed ril_radio_confirm_power_on() to send RADIO_POWER request even if
we think that modem is powered on. Some RILs change power state without
letting us know and that's what this function is for - to make sure that
power is on when we think that it's on.
2020-04-01 19:43:57 +03:00
Slava Monich
a54b74cbe6 [ril] Take modem offline when ril_modem is deleted. JB#49471
Also, mobile data need to be disallowed before deleting the modem
object, so that power keep-on request could be submitted before
bringing the modem offline, to keep power on while data call is
being deactivated (if there was one).
2020-04-01 19:43:57 +03:00
Slava Monich
b136997e5c [ril] Fixed ref vs unref mixup.
RilRadioCapsManager was never freed :/

That was leaving 472 bytes in 8 blocks still reachable on exit.
2020-04-01 19:43:57 +03:00
Denis Grigorev
af29f9a9f9 [ril] Do not trigger automatic PLMN selection if not needed. JB#49322
On some devices SET_NETWORK_SELECTION_AUTOMATIC takes significant time,
because it triggers a complete scan of available PLMNs. If applied, this
commit will make ofono to issue QUERY_NETWORK_SELECTION_MODE first and
check whether the mode actually needs to be changed.
2020-03-16 21:26:40 +02:00
Denis Grigorev
59e8853c77 [ril] Add networkSelectionTimeout config option. JB#49322
On some devices (such as BQ Aquarius NS208) SET_NETWORK_SELECTION_AUTOMATIC
takes a long time and ofono fails with timeout. If applied, this commit
will make network selection timeout configurable.
2020-03-16 21:26:17 +02:00
Slava Monich
c03a508622 [ril] Support combinations of device state tracking methods. JB#49175
In addition to specifying ss, ds or ur method, one can specify a
combination of methods, e.g. ds+ur
2020-03-10 15:35:08 +02:00
Slava Monich
1fd2f955ec [ril] Added ril_config_get_mask. JB#49175 2020-03-10 15:35:08 +02:00
Denis Grigorev
124a3bf982 [ril] Add a new device state management method. JB#49175
If applied, this commit will add a new ril_devmon implementation which
controls network state updates by sending SET_UNSOLICITED_RESPONSE_FILTER.
This is useful for devices with RIL version >= 15 if they ignore
both SEND_DEVICE_STATE and SEND_SCREEN_STATE requests as some Qualcomm-
based devices do.
2020-03-06 15:41:59 +02:00
Slava Monich
4ed6bf1d51 [ofono] Access control for SIM Toolkit agent. Fixes JB#49163
Non-privileged process will get org.ofono.Error.AccessDenied from
RegisterAgent. Other methods already check that D-Bus call is coming
from a registered agent.
2020-03-04 15:33:25 +02:00
Slava Monich
7c07139439 [ofono] Store one-time data SIM selection. JB#48462
This way, automatic choice survives a reboot.
2020-02-13 20:11:38 +03:00
43 changed files with 735 additions and 823 deletions

View File

@@ -1,8 +1,3 @@
ver 1.23:
Fix issue with handling SIM AID sessions.
Add support for QMI LTE bearer handling.
Add support for memory location dialing.
ver 1.22:
Fix issue with GPIO handling and Nokia modems.
Fix issue with SIM state callback and AT modems.

View File

@@ -151,8 +151,10 @@ builtin_sources += drivers/ril/ril_call_barring.c \
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 \
@@ -305,7 +307,6 @@ builtin_sources += $(qmi_sources) \
drivers/qmimodem/ussd.c \
drivers/qmimodem/gprs.c \
drivers/qmimodem/gprs-context.c \
drivers/qmimodem/lte.c \
drivers/qmimodem/radio-settings.c \
drivers/qmimodem/location-reporting.c \
drivers/qmimodem/netmon.c

View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.60)
AC_INIT(ofono, 1.23)
AC_INIT(ofono, 1.22)
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
AC_CONFIG_HEADERS(config.h)

View File

@@ -95,13 +95,6 @@ Properties boolean Powered [readwrite]
String representing the software version number of the
modem device.
string SystemPath [readonly, optional]
String representing the system path for the modem
device.
For modems detected by udev events, this corresponds to
the modem sysfs path.
array{string} Features [readonly]
List of currently enabled features. It uses simple

View File

@@ -69,17 +69,6 @@ Methods dict GetProperties()
[service].Error.NotImplemented
[service].Error.Failed
object DialMemory(string memory position, string hide_callerid)
Initiates a new outgoing call to the number in the given memory
position/favourite. For callerid see the Dial method.
Possible Errors: [service].Error.InProgress
[service].Error.InvalidArguments
[service].Error.InvalidFormat
[service].Error.NotImplemented
[service].Error.Failed
void Transfer()
Joins the currently Active (or Outgoing, depending

View File

@@ -422,28 +422,6 @@ static void hfp_dial_last(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb,
CALLBACK_WITH_FAILURE(cb, data);
}
static void hfp_dial_memory(struct ofono_voicecall *vc,
unsigned int memory_location,
ofono_voicecall_cb_t cb, void *data)
{
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
struct cb_data *cbd = cb_data_new(cb, data);
char buf[256];
cbd->user = vc;
DBG("Calling memory location %d\n", memory_location);
snprintf(buf, sizeof(buf), "ATD>%d;", memory_location);
if (g_at_chat_send(vd->chat, buf, none_prefix,
atd_cb, cbd, g_free) > 0)
return;
g_free(cbd);
DBG("at_chat_failed");
CALLBACK_WITH_FAILURE(cb, data);
}
static void hfp_template(const char *cmd, struct ofono_voicecall *vc,
GAtResultFunc result_cb, unsigned int affected_types,
ofono_voicecall_cb_t cb, void *data)
@@ -1309,7 +1287,6 @@ static struct ofono_voicecall_driver driver = {
.remove = hfp_voicecall_remove,
.dial = hfp_dial,
.dial_last = hfp_dial_last,
.dial_memory = hfp_dial_memory,
.answer = hfp_answer,
.hangup_active = hfp_hangup,
.hold_all_active = hfp_hold_all_active,

View File

@@ -29,16 +29,12 @@
#include "qmi.h"
#include "nas.h"
#include "wds.h"
#include "src/common.h"
#include "qmimodem.h"
struct gprs_data {
struct qmi_device *dev;
struct qmi_service *nas;
struct qmi_service *wds;
unsigned int last_auto_context_id;
};
static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
@@ -68,124 +64,8 @@ static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
return true;
}
static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
{
struct ofono_gprs *gprs = user_data;
struct gprs_data *data = ofono_gprs_get_data(gprs);
char *apn = NULL;
uint16_t error;
uint8_t iptype;
DBG("");
if (qmi_result_set_error(result, &error)) {
ofono_error("Failed to query LTE attach params: %hd", error);
goto noapn;
}
/* APN */
apn = qmi_result_get_string(result, 0x10);
if (!apn) {
DBG("Default profile has no APN setting");
goto noapn;
}
if (qmi_result_get_uint8(result, 0x11, &iptype))
ofono_info("LTE attach IP type: %hhd", iptype);
ofono_gprs_cid_activated(gprs, data->last_auto_context_id, apn);
g_free(apn);
return;
noapn:
data->last_auto_context_id = 0;
ofono_error("LTE bearer established but APN not set");
}
static void get_default_profile_cb(struct qmi_result *result, void *user_data)
{
struct ofono_gprs* gprs = user_data;
struct gprs_data *data = ofono_gprs_get_data(gprs);
uint16_t error;
uint8_t index;
DBG("");
if (qmi_result_set_error(result, &error)) {
ofono_error("Get default profile error: %hd", error);
goto error;
}
/* Profile index */
if (!qmi_result_get_uint8(result, 0x01, &index)) {
ofono_error("Failed query default profile");
goto error;
}
DBG("Default profile index: %hhd", index);
data->last_auto_context_id = index;
/* Get LTE Attach Parameters */
if (qmi_service_send(data->wds, 0x85, NULL,
get_lte_attach_param_cb, gprs, NULL) > 0)
return;
error:
data->last_auto_context_id = 0;
ofono_error("LTE bearer established but APN not set");
}
/*
* Query the settings in effect on the default bearer. These may be
* implicit or may even be something other than requested as the gateway
* is allowed to override whatever was requested by the user.
*/
static void get_lte_attach_params(struct ofono_gprs* gprs)
{
struct gprs_data *data = ofono_gprs_get_data(gprs);
struct {
uint8_t type;
uint8_t family;
} __attribute((packed)) p = {
.type = 0, /* 3GPP */
.family = 0, /* embedded */
};
struct qmi_param *param;
DBG("");
if (data->last_auto_context_id != 0)
return; /* Established or in progress */
/* Set query in progress */
data->last_auto_context_id = -1;
/* First we query the default profile in order to find out which
* context the modem has activated.
*/
param = qmi_param_new();
if (!param)
goto error;
/* Profile type */
qmi_param_append(param, 0x1, sizeof(p), &p);
/* Get default profile */
if (qmi_service_send(data->wds, 0x49, param,
get_default_profile_cb, gprs, NULL) > 0)
return;
qmi_param_free(param);
error:
ofono_warn("Unable to query LTE APN... will not activate context");
}
static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
{
struct gprs_data *data = ofono_gprs_get_data(gprs);
int status;
int tech;
@@ -194,19 +74,16 @@ static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
if (!extract_ss_info(result, &status, &tech))
return -1;
if (status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
if (status == NETWORK_REGISTRATION_STATUS_REGISTERED)
if (tech == ACCESS_TECHNOLOGY_EUTRAN) {
/* On LTE we are effectively always attached; and
* the default bearer is established as soon as the
* network is joined. We just need to query the
* parameters in effect on the default bearer and
* let the ofono core know about the activated
* context.
* network is joined.
*/
get_lte_attach_params(gprs);
}
} else {
data->last_auto_context_id = 0;
/* FIXME: query default profile number and APN
* instead of assuming profile 1 and ""
*/
ofono_gprs_cid_activated(gprs, 1 , "automatic");
}
return status;
@@ -321,7 +198,7 @@ static void qmi_attached_status(struct ofono_gprs *gprs,
g_free(cbd);
}
static void create_wds_cb(struct qmi_service *service, void *user_data)
static void create_nas_cb(struct qmi_service *service, void *user_data)
{
struct ofono_gprs *gprs = user_data;
struct gprs_data *data = ofono_gprs_get_data(gprs);
@@ -329,12 +206,12 @@ static void create_wds_cb(struct qmi_service *service, void *user_data)
DBG("");
if (!service) {
ofono_error("Failed to request WDS service");
ofono_error("Failed to request NAS service");
ofono_gprs_remove(gprs);
return;
}
data->wds = qmi_service_ref(service);
data->nas = qmi_service_ref(service);
/*
* First get the SS info - the modem may already be connected,
@@ -351,25 +228,6 @@ static void create_wds_cb(struct qmi_service *service, void *user_data)
ofono_gprs_register(gprs);
}
static void create_nas_cb(struct qmi_service *service, void *user_data)
{
struct ofono_gprs *gprs = user_data;
struct gprs_data *data = ofono_gprs_get_data(gprs);
DBG("");
if (!service) {
ofono_error("Failed to request NAS service");
ofono_gprs_remove(gprs);
return;
}
data->nas = qmi_service_ref(service);
qmi_service_create_shared(data->dev, QMI_SERVICE_WDS,
create_wds_cb, gprs, NULL);
}
static int qmi_gprs_probe(struct ofono_gprs *gprs,
unsigned int vendor, void *user_data)
{
@@ -382,8 +240,6 @@ static int qmi_gprs_probe(struct ofono_gprs *gprs,
ofono_gprs_set_data(gprs, data);
data->dev = device;
qmi_service_create_shared(device, QMI_SERVICE_NAS,
create_nas_cb, gprs, NULL);
@@ -398,9 +254,6 @@ static void qmi_gprs_remove(struct ofono_gprs *gprs)
ofono_gprs_set_data(gprs, NULL);
qmi_service_unregister_all(data->wds);
qmi_service_unref(data->wds);
qmi_service_unregister_all(data->nas);
qmi_service_unref(data->nas);

View File

@@ -1,264 +0,0 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2018 Jonas Bonn. All rights reserved.
* Copyright (C) 2018 Norrbonn AB. All rights reserved.
* Copyright (C) 2018 Data Respons ASA. 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
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include <ofono/modem.h>
#include <ofono/gprs-context.h>
#include <ofono/log.h>
#include <ofono/lte.h>
#include "qmi.h"
#include "wds.h"
#include "qmimodem.h"
struct lte_data {
struct qmi_service *wds;
uint8_t default_profile;
};
static void modify_profile_cb(struct qmi_result *result, void *user_data)
{
struct cb_data *cbd = user_data;
ofono_lte_cb_t cb = cbd->cb;
uint16_t error;
DBG("");
if (qmi_result_set_error(result, &error)) {
DBG("Failed to modify profile: %d", error);
CALLBACK_WITH_FAILURE(cb, cbd->data);
return;
}
CALLBACK_WITH_SUCCESS(cb, cbd->data);
}
static void qmimodem_lte_set_default_attach_info(const struct ofono_lte *lte,
const struct ofono_lte_default_attach_info *info,
ofono_lte_cb_t cb, void *data)
{
struct lte_data *ldd = ofono_lte_get_data(lte);
struct cb_data *cbd = cb_data_new(cb, data);
struct qmi_param* param;
struct {
uint8_t type;
uint8_t index;
} __attribute__((packed)) p = {
.type = 0, /* 3GPP */
};
DBG("");
p.index = ldd->default_profile;
param = qmi_param_new();
if (!param)
goto error;
/* Profile selector */
qmi_param_append(param, 0x01, sizeof(p), &p);
/* WDS APN Name */
qmi_param_append(param, QMI_WDS_PARAM_APN,
strlen(info->apn), info->apn);
/* Modify profile */
if (qmi_service_send(ldd->wds, 0x28, param,
modify_profile_cb, cbd, g_free) > 0)
return;
qmi_param_free(param);
error:
CALLBACK_WITH_FAILURE(cb, cbd->data);
}
static void reset_profile_cb(struct qmi_result *result, void *user_data)
{
struct ofono_lte *lte = user_data;
uint16_t error;
DBG("");
if (qmi_result_set_error(result, &error))
ofono_error("Reset profile error: %hd", error);
ofono_lte_register(lte);
}
static void get_default_profile_cb(struct qmi_result *result, void *user_data)
{
struct ofono_lte *lte = user_data;
struct lte_data *ldd = ofono_lte_get_data(lte);
uint16_t error;
uint8_t index;
struct qmi_param *param;
struct {
uint8_t type;
uint8_t index;
} __attribute__((packed)) p = {
.type = 0, /* 3GPP */
};
DBG("");
if (qmi_result_set_error(result, &error)) {
ofono_error("Get default profile error: %hd", error);
goto error;
}
/* Profile index */
if (!qmi_result_get_uint8(result, 0x01, &index)) {
ofono_error("Failed query default profile");
goto error;
}
DBG("Default profile index: %hhd", index);
ldd->default_profile = index;
p.index = index;
param = qmi_param_new();
if (!param)
goto error;
/* Profile selector */
qmi_param_append(param, 0x01, sizeof(p), &p);
/* Reset profile */
if (qmi_service_send(ldd->wds, 0x4b, param,
reset_profile_cb, lte, NULL) > 0)
return;
qmi_param_free(param);
error:
ofono_error("Failed to reset profile %hhd", index);
ofono_lte_remove(lte);
}
static void create_wds_cb(struct qmi_service *service, void *user_data)
{
struct ofono_lte *lte = user_data;
struct lte_data *ldd = ofono_lte_get_data(lte);
struct qmi_param *param;
struct {
uint8_t type;
uint8_t family;
} __attribute((packed)) p = {
.type = 0, /* 3GPP */
.family = 0, /* embedded */
};
DBG("");
if (!service) {
ofono_error("Failed to request WDS service");
ofono_lte_remove(lte);
return;
}
ldd->wds = qmi_service_ref(service);
/* Query the default profile */
param = qmi_param_new();
if (!param)
goto error;
/* Profile type */
qmi_param_append(param, 0x1, sizeof(p), &p);
/* Get default profile */
if (qmi_service_send(ldd->wds, 0x49, param,
get_default_profile_cb, lte, NULL) > 0)
return;
qmi_param_free(param);
error:
ofono_error("Failed to query default profile");
ofono_lte_register(lte);
}
static int qmimodem_lte_probe(struct ofono_lte *lte, void *data)
{
struct qmi_device *device = data;
struct lte_data *ldd;
DBG("qmimodem lte probe");
ldd = g_try_new0(struct lte_data, 1);
if (!ldd)
return -ENOMEM;
ofono_lte_set_data(lte, ldd);
qmi_service_create_shared(device, QMI_SERVICE_WDS,
create_wds_cb, lte, NULL);
return 0;
}
static void qmimodem_lte_remove(struct ofono_lte *lte)
{
struct lte_data *ldd = ofono_lte_get_data(lte);
DBG("");
ofono_lte_set_data(lte, NULL);
qmi_service_unregister_all(ldd->wds);
qmi_service_unref(ldd->wds);
g_free(ldd);
}
static struct ofono_lte_driver driver = {
.name = "qmimodem",
.probe = qmimodem_lte_probe,
.remove = qmimodem_lte_remove,
.set_default_attach_info = qmimodem_lte_set_default_attach_info,
};
void qmi_lte_init(void)
{
ofono_lte_driver_register(&driver);
}
void qmi_lte_exit(void)
{
ofono_lte_driver_unregister(&driver);
}

View File

@@ -39,7 +39,6 @@ static int qmimodem_init(void)
qmi_ussd_init();
qmi_gprs_init();
qmi_gprs_context_init();
qmi_lte_init();
qmi_radio_settings_init();
qmi_location_reporting_init();
qmi_netmon_init();
@@ -52,7 +51,6 @@ static void qmimodem_exit(void)
qmi_netmon_exit();
qmi_location_reporting_exit();
qmi_radio_settings_exit();
qmi_lte_exit();
qmi_gprs_context_exit();
qmi_gprs_exit();
qmi_ussd_exit();

View File

@@ -48,9 +48,6 @@ extern void qmi_gprs_exit(void);
extern void qmi_gprs_context_init(void);
extern void qmi_gprs_context_exit(void);
extern void qmi_lte_init(void);
extern void qmi_lte_exit(void);
extern void qmi_radio_settings_init(void);
extern void qmi_radio_settings_exit(void);

View File

@@ -277,9 +277,6 @@ static void qmi_radio_settings_remove(struct ofono_radio_settings *rs)
ofono_radio_settings_set_data(rs, NULL);
qmi_service_unregister_all(data->dms);
qmi_service_unref(data->dms);
qmi_service_unregister_all(data->nas);
qmi_service_unref(data->nas);

View File

@@ -1,7 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2016-2020 Jolla Ltd.
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -344,11 +345,24 @@ static void ril_cell_info_set_rate_cb(GRilIoChannel *io, int status,
self->set_rate_id = 0;
}
static gboolean ril_cell_info_retry(GRilIoRequest* request, int ril_status,
const void* response_data, guint response_len, void* user_data)
{
switch (ril_status) {
case RIL_E_SUCCESS:
case RIL_E_RADIO_NOT_AVAILABLE:
return FALSE;
default:
return TRUE;
}
}
static void ril_cell_info_query(struct ril_cell_info *self)
{
GRilIoRequest *req = grilio_request_new();
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
grilio_request_set_retry_func(req, ril_cell_info_retry);
grilio_channel_cancel_request(self->io, self->query_id, FALSE);
self->query_id = grilio_channel_send_request_full(self->io, req,
RIL_REQUEST_GET_CELL_INFO_LIST, ril_cell_info_list_cb,
@@ -362,6 +376,7 @@ static void ril_cell_info_set_rate(struct ril_cell_info *self)
(self->update_rate_ms > 0) ? self->update_rate_ms : INT_MAX);
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
grilio_request_set_retry_func(req, ril_cell_info_retry);
grilio_channel_cancel_request(self->io, self->set_rate_id, FALSE);
self->set_rate_id = grilio_channel_send_request_full(self->io, req,
RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE,

View File

@@ -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 @@ gboolean ril_config_get_enum(GKeyFile *file, const char *group,
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)
{

View File

@@ -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 @@ gboolean ril_config_get_flag(GKeyFile *file, const char *group,
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);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2013 Canonical Ltd.
* Copyright (C) 2013-2020 Jolla Ltd.
* Copyright (C) 2013-2019 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,44 +205,10 @@ enum ril_data_call_fail_cause {
PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
PDP_FAIL_NSAPI_IN_USE = 0x23,
PDP_FAIL_REGULAR_DEACTIVATION = 0x24,
PDP_FAIL_QOS_NOT_ACCEPTED = 0x25,
PDP_FAIL_NETWORK_FAILURE = 0x26,
PDP_FAIL_UMTS_REACTIVATION_REQ = 0x27,
PDP_FAIL_FEATURE_NOT_SUPP = 0x28,
PDP_FAIL_TFT_SEMANTIC_ERROR = 0x29,
PDP_FAIL_TFT_SYTAX_ERROR = 0x2A,
PDP_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B,
PDP_FAIL_FILTER_SEMANTIC_ERROR = 0x2C,
PDP_FAIL_FILTER_SYTAX_ERROR = 0x2D,
PDP_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E,
PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32,
PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33,
PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
PDP_FAIL_ESM_INFO_NOT_RECEIVED = 0x35,
PDP_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36,
PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
PDP_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
PDP_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
PDP_FAIL_INVALID_TRANSACTION_ID = 0x51,
PDP_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F,
PDP_FAIL_INVALID_MANDATORY_INFO = 0x60,
PDP_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61,
PDP_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
PDP_FAIL_UNKNOWN_INFO_ELEMENT = 0x63,
PDP_FAIL_CONDITIONAL_IE_ERROR = 0x64,
PDP_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
PDP_FAIL_PROTOCOL_ERRORS = 0x6F,
PDP_FAIL_APN_TYPE_CONFLICT = 0x70,
PDP_FAIL_INVALID_PCSCF_ADDR = 0x71,
PDP_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
PDP_FAIL_EMM_ACCESS_BARRED = 0x73,
PDP_FAIL_EMERGENCY_IFACE_ONLY = 0x74,
PDP_FAIL_IFACE_MISMATCH = 0x75,
PDP_FAIL_COMPANION_IFACE_IN_USE = 0x76,
PDP_FAIL_IP_ADDRESS_MISMATCH = 0x77,
PDP_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
PDP_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
PDP_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
PDP_FAIL_DATA_REGISTRATION_FAIL = -2,
PDP_FAIL_SIGNAL_LOST = -3,
@@ -375,6 +341,19 @@ enum ril_restricted_state {
#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 */
/*

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2020 Jolla Ltd.
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
@@ -14,8 +14,6 @@
* GNU General Public License for more details.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "ril_data.h"
#include "ril_radio.h"
#include "ril_network.h"
@@ -31,8 +29,6 @@
#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 */
@@ -119,7 +115,6 @@ struct ril_data_priv {
gulong io_event_id[IO_EVENT_COUNT];
gulong settings_event_id[SETTINGS_EVENT_COUNT];
GHashTable* grab;
gboolean downgraded_tech; /* Status 55 workaround */
};
enum ril_data_signal {
@@ -820,31 +815,6 @@ static gboolean ril_data_call_setup_retry(void *user_data)
return G_SOURCE_REMOVE;
}
static gboolean ril_data_call_retry(struct ril_data_request_setup *setup)
{
struct ril_data_request *req = &setup->req;
const struct ril_data_options *options = &req->data->priv->options;
if (setup->retry_count < options->data_call_retry_limit) {
req->pending_id = 0;
GASSERT(!setup->retry_delay_id);
if (!setup->retry_count) {
/* No delay first time */
setup->retry_count++;
DBG("silent retry %u out of %u", setup->retry_count,
options->data_call_retry_limit);
req->submit(req);
} else {
const guint ms = options->data_call_retry_delay_ms;
DBG("silent retry scheduled in %u ms", ms);
setup->retry_delay_id = g_timeout_add(ms,
ril_data_call_setup_retry, setup);
}
return TRUE;
}
return FALSE;
}
static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
const void *data, guint len, void *user_data)
{
@@ -869,49 +839,33 @@ static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
}
}
if (call) {
switch (call->status) {
if (call && call->status == PDP_FAIL_ERROR_UNSPECIFIED &&
setup->retry_count < priv->options.data_call_retry_limit) {
/*
* According to the comment from ril.h we should silently
* retry. First time we retry immediately and if that doesn't
* retry. First time we retry immediately and if that doedsn't
* work, then after certain delay.
*/
case PDP_FAIL_ERROR_UNSPECIFIED:
if (ril_data_call_retry(setup)) {
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);
}
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_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);
@@ -1197,11 +1151,6 @@ static struct ril_data_request *ril_data_allow_new(struct ril_data *data,
/*==========================================================================*
* ril_data
*==========================================================================*/
static enum ofono_radio_access_mode ril_data_max_mode(struct ril_data *self)
{
return self->priv->downgraded_tech ? OFONO_RADIO_ACCESS_MODE_UMTS :
OFONO_RADIO_ACCESS_MODE_ANY;
}
gulong ril_data_add_allow_changed_handler(struct ril_data *self,
ril_data_cb_t cb, void *arg)
@@ -1735,7 +1684,7 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)
ril_network_set_max_pref_mode(network,
(network == lte_network) ?
ril_data_max_mode(data) :
OFONO_RADIO_ACCESS_MODE_ANY :
OFONO_RADIO_ACCESS_MODE_GSM,
FALSE);
}
@@ -1745,7 +1694,7 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)
for (l= self->data_list; l; l = l->next) {
struct ril_data *data = l->data;
ril_network_set_max_pref_mode(data->priv->network,
ril_data_max_mode(data), FALSE);
OFONO_RADIO_ACCESS_MODE_ANY, FALSE);
}
}
}
@@ -1774,7 +1723,7 @@ static void ril_data_manager_switch_data_on(struct ril_data_manager *self,
if (ril_data_manager_handover(self)) {
ril_network_set_max_pref_mode(priv->network,
ril_data_max_mode(data), TRUE);
OFONO_RADIO_ACCESS_MODE_ANY, TRUE);
}
if (priv->options.allow_data == RIL_ALLOW_DATA_ENABLED) {

View File

@@ -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
@@ -50,11 +51,22 @@ struct ril_devmon *ril_devmon_ss_new(void);
*/
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);

View File

@@ -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:
*/

View File

@@ -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:
*/

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2020 Jolla Ltd.
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
@@ -14,8 +14,6 @@
* GNU General Public License for more details.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "ril_ecclist.h"
#include "ril_log.h"

View File

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

View File

@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2019 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
@@ -23,7 +23,6 @@
#include "common.h"
#include "simutil.h"
#define REGISTRATION_TIMEOUT (100*1000) /* ms */
#define REGISTRATION_MAX_RETRIES (2)
enum ril_netreg_events {
@@ -42,8 +41,6 @@ struct ril_netreg {
GRilIoChannel *io;
GRilIoQueue *q;
gboolean network_selection_manual_0;
int signal_strength_dbm_weak;
int signal_strength_dbm_strong;
struct ofono_netreg *netreg;
struct ril_network *network;
struct ril_vendor *vendor;
@@ -53,6 +50,7 @@ struct ril_netreg {
guint current_operator_id;
gulong ril_event_id[NETREG_RIL_EVENT_COUNT];
gulong network_event_id[NETREG_NETWORK_EVENT_COUNT];
int network_selection_timeout;
};
struct ril_netreg_cbd {
@@ -301,18 +299,55 @@ static void ril_netreg_register_cb(GRilIoChannel *io, int status,
}
}
static void ril_netreg_set_register_auto(struct ril_netreg *nd,
ofono_netreg_register_cb_t cb, void *data)
{
GRilIoRequest *req = grilio_request_new();
ofono_info("nw select automatic");
grilio_request_set_timeout(req, nd->network_selection_timeout);
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
grilio_queue_send_request_full(nd->q, req,
RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
ril_netreg_register_cb, ril_netreg_cbd_free,
ril_netreg_cbd_new(nd, cb, data));
grilio_request_unref(req);
}
static void ril_netreg_query_register_auto_cb(GRilIoChannel *io, int status,
const void *data, guint len,
void *user_data)
{
struct ril_netreg_cbd *cbd = user_data;
ofono_netreg_register_cb_t cb = cbd->cb.reg;
if (status == RIL_E_SUCCESS) {
GRilIoParser rilp;
gint32 net_mode;
grilio_parser_init(&rilp, data, len);
if (grilio_parser_get_int32(&rilp, NULL) /* Array length */ &&
grilio_parser_get_int32(&rilp, &net_mode) &&
net_mode == RIL_NETWORK_SELECTION_MODE_AUTO) {
struct ofono_error error;
ofono_info("nw selection is already auto");
cb(ril_error_ok(&error), cbd->data);
return;
}
}
ril_netreg_set_register_auto(cbd->nd, cb, cbd->data);
}
static void ril_netreg_register_auto(struct ofono_netreg *netreg,
ofono_netreg_register_cb_t cb, void *data)
{
struct ril_netreg *nd = ril_netreg_get_data(netreg);
GRilIoRequest *req = grilio_request_new();
ofono_info("nw select automatic");
grilio_request_set_timeout(req, REGISTRATION_TIMEOUT);
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
grilio_queue_send_request_full(nd->q, req,
RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
ril_netreg_register_cb, ril_netreg_cbd_free,
RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE,
ril_netreg_query_register_auto_cb, ril_netreg_cbd_free,
ril_netreg_cbd_new(nd, cb, data));
grilio_request_unref(req);
}
@@ -327,7 +362,7 @@ static void ril_netreg_register_manual(struct ofono_netreg *netreg,
ofono_info("nw select manual: %s%s%s", mcc, mnc, suffix);
grilio_request_append_format(req, "%s%s%s", mcc, mnc, suffix);
grilio_request_set_timeout(req, REGISTRATION_TIMEOUT);
grilio_request_set_timeout(req, nd->network_selection_timeout);
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
grilio_queue_send_request_full(nd->q, req,
RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
@@ -336,17 +371,17 @@ static void ril_netreg_register_manual(struct ofono_netreg *netreg,
grilio_request_unref(req);
}
static int ril_netreg_qdbm_to_percentage(struct ril_netreg *nd, int qdbm)
static int ril_netreg_qdbm_to_percentage(int qdbm /* 4*dBm */)
{
const int min_qdbm = 4 * nd->signal_strength_dbm_weak; /* 4*dBm */
const int max_qdbm = 4 * nd->signal_strength_dbm_strong; /* 4*dBm */
const int min_qdbm = -4*100; /* very weak signal, 0.0000000001 mW */
const int max_qdbm = -4*60; /* strong signal, 0.000001 mW */
return (qdbm <= min_qdbm) ? 1 :
(qdbm >= max_qdbm) ? 100 :
(100 * (qdbm - min_qdbm) / (max_qdbm - min_qdbm));
}
static int ril_netreg_get_signal_strength(struct ril_netreg *nd,
static int ril_netreg_get_signal_strength(struct ril_vendor *vendor,
const void *data, guint len)
{
GRilIoParser rilp;
@@ -357,7 +392,7 @@ static int ril_netreg_get_signal_strength(struct ril_netreg *nd,
signal.lte = INT_MAX;
signal.qdbm = 0;
if (!ril_vendor_signal_strength_parse(nd->vendor, &signal, &rilp)) {
if (!ril_vendor_signal_strength_parse(vendor, &signal, &rilp)) {
gint32 rsrp = 0, tdscdma_dbm = 0;
/* Apply default parsing algorithm */
@@ -416,7 +451,7 @@ static int ril_netreg_get_signal_strength(struct ril_netreg *nd,
}
if (signal.qdbm < 0) {
return ril_netreg_qdbm_to_percentage(nd, signal.qdbm);
return ril_netreg_qdbm_to_percentage(signal.qdbm);
} else if (signal.gsm == 0) {
return 0;
} else {
@@ -431,7 +466,7 @@ static void ril_netreg_strength_notify(GRilIoChannel *io, guint ril_event,
int strength;
GASSERT(ril_event == RIL_UNSOL_SIGNAL_STRENGTH);
strength = ril_netreg_get_signal_strength(nd, data, len);
strength = ril_netreg_get_signal_strength(nd->vendor, data, len);
DBG_(nd, "%d", strength);
if (strength >= 0) {
ofono_netreg_strength_notify(nd->netreg, strength);
@@ -447,7 +482,7 @@ static void ril_netreg_strength_cb(GRilIoChannel *io, int status,
if (status == RIL_E_SUCCESS) {
cb(ril_error_ok(&error), ril_netreg_get_signal_strength
(cbd->nd, data, len), cbd->data);
(cbd->nd->vendor, data, len), cbd->data);
} else {
ofono_error("Failed to retrive the signal strength: %s",
ril_error_to_string(status));
@@ -561,8 +596,7 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
nd->network = ril_network_ref(modem->network);
nd->netreg = netreg;
nd->network_selection_manual_0 = config->network_selection_manual_0;
nd->signal_strength_dbm_weak = config->signal_strength_dbm_weak;
nd->signal_strength_dbm_strong = config->signal_strength_dbm_strong;
nd->network_selection_timeout = config->network_selection_timeout;
ofono_netreg_set_data(netreg, nd);
nd->timer_id = g_idle_add(ril_netreg_register, nd);

View File

@@ -2,7 +2,7 @@
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,8 +14,6 @@
* GNU General Public License for more details.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "ril_network.h"
#include "ril_radio.h"
#include "ril_sim_card.h"
@@ -419,6 +417,18 @@ static void ril_network_poll_data_state_cb(GRilIoChannel *io, int req_status,
}
}
static gboolean ril_network_retry(GRilIoRequest* request, int ril_status,
const void* response_data, guint response_len, void* user_data)
{
switch (ril_status) {
case RIL_E_SUCCESS:
case RIL_E_RADIO_NOT_AVAILABLE:
return FALSE;
default:
return TRUE;
}
}
static guint ril_network_poll_and_retry(struct ril_network *self, guint id,
int code, GRilIoChannelResponseFunc fn)
{
@@ -431,6 +441,7 @@ static guint ril_network_poll_and_retry(struct ril_network *self, guint id,
GRilIoRequest *req = grilio_request_new();
grilio_request_set_retry(req, RIL_RETRY_SECS*1000, -1);
grilio_request_set_retry_func(req, ril_network_retry);
id = grilio_queue_send_request_full(priv->q, req, code, fn,
NULL, self);
grilio_request_unref(req);
@@ -998,11 +1009,10 @@ static void ril_network_query_pref_mode_cb(GRilIoChannel *io, int status,
struct ril_network_priv *priv = self->priv;
const enum ofono_radio_access_mode pref_mode = self->pref_mode;
/* This request never fails because in case of error it gets retried */
GASSERT(status == RIL_E_SUCCESS);
GASSERT(priv->query_rat_id);
priv->query_rat_id = 0;
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,
@@ -1015,6 +1025,7 @@ static void ril_network_query_pref_mode_cb(GRilIoChannel *io, int status,
if (ril_network_can_set_pref_mode(self)) {
ril_network_check_pref_mode(self, FALSE);
}
}
}
static void ril_network_query_pref_mode(struct ril_network *self)
@@ -1023,6 +1034,7 @@ static void ril_network_query_pref_mode(struct ril_network *self)
GRilIoRequest *req = grilio_request_new();
grilio_request_set_retry(req, RIL_RETRY_SECS*1000, -1);
grilio_request_set_retry_func(req, ril_network_retry);
grilio_queue_cancel_request(priv->q, priv->query_rat_id, FALSE);
priv->query_rat_id = grilio_queue_send_request_full(priv->q, req,
RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE,

View File

@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2019 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
@@ -73,8 +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_DBM_WEAK (-100) /* very weak, 0.0000000001 mW */
#define RILMODEM_DEFAULT_DBM_STRONG (-60) /* strong signal, 0.000001 mW */
#define RILMODEM_DEFAULT_NETWORK_SELECTION_TIMEOUT (100*1000) /* ms */
#define RILMODEM_DEFAULT_ENABLE_VOICECALL TRUE
#define RILMODEM_DEFAULT_ENABLE_CBS TRUE
#define RILMODEM_DEFAULT_ENABLE_STK TRUE
@@ -134,7 +133,7 @@
#define RILCONF_LTE_MODE "lteNetworkMode"
#define RILCONF_UMTS_MODE "umtsNetworkMode"
#define RILCONF_NETWORK_MODE_TIMEOUT "networkModeTimeout"
#define RILCONF_SIGNAL_STRENGTH_RANGE "signalStrengthRange"
#define RILCONF_NETWORK_SELECTION_TIMEOUT "networkSelectionTimeout"
#define RILCONF_UICC_WORKAROUND "uiccWorkaround"
#define RILCONF_ECCLIST_FILE "ecclistFile"
#define RILCONF_ALLOW_DATA_REQ "allowDataReq"
@@ -179,10 +178,9 @@ enum ril_set_radio_cap_opt {
};
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 {
@@ -363,6 +361,7 @@ static void ril_plugin_remove_slot_handler(ril_slot *slot, int id)
static void ril_plugin_shutdown_slot(ril_slot *slot, gboolean kill_io)
{
if (slot->modem) {
ril_data_allow(slot->data, RIL_DATA_ROLE_NONE);
ril_modem_delete(slot->modem);
/* The above call is expected to result in
* ril_plugin_modem_removed getting called
@@ -1194,8 +1193,8 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
config->lte_network_mode = RILMODEM_DEFAULT_LTE_MODE;
config->umts_network_mode = RILMODEM_DEFAULT_UMTS_MODE;
config->network_mode_timeout = RILMODEM_DEFAULT_NETWORK_MODE_TIMEOUT;
config->signal_strength_dbm_weak = RILMODEM_DEFAULT_DBM_WEAK;
config->signal_strength_dbm_strong = RILMODEM_DEFAULT_DBM_STRONG;
config->network_selection_timeout =
RILMODEM_DEFAULT_NETWORK_SELECTION_TIMEOUT;
config->empty_pin_query = RILMODEM_DEFAULT_EMPTY_PIN_QUERY;
config->radio_power_cycle = RILMODEM_DEFAULT_RADIO_POWER_CYCLE;
config->confirm_radio_power_on =
@@ -1368,7 +1367,6 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
char *sval;
char **strv;
char *modem;
GUtilInts *ints;
GHashTable *transport_params = g_hash_table_new_full(g_str_hash,
g_str_equal, g_free, g_free);
char *transport = NULL;
@@ -1566,20 +1564,13 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
config->network_mode_timeout);
}
/* signalStrengthRange */
ints = ril_config_get_ints(file, group, RILCONF_SIGNAL_STRENGTH_RANGE);
if (gutil_ints_get_count(ints) == 2) {
const int* dbms = gutil_ints_get_data(ints, NULL);
/* MIN,MAX */
if (dbms[0] < dbms[1]) {
DBG("%s: " RILCONF_SIGNAL_STRENGTH_RANGE " [%d,%d]",
group, dbms[0], dbms[1]);
config->signal_strength_dbm_weak = dbms[0];
config->signal_strength_dbm_strong = dbms[1];
/* 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);
}
}
gutil_ints_unref(ints);
/* enable4G (deprecated but still supported) */
ival = config->techs;
@@ -1706,23 +1697,32 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
}
/* 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 */
"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 =
(ival == RIL_DEVMON_DS ? ril_devmon_ds_new() :
ival == RIL_DEVMON_SS ? ril_devmon_ss_new() :
NULL);
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);
}
}

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2019 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,8 +13,6 @@
* GNU General Public License for more details.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "ril_radio.h"
#include "ril_util.h"
#include "ril_log.h"
@@ -241,7 +239,19 @@ static void ril_radio_power_request(struct ril_radio *self, gboolean on,
void ril_radio_confirm_power_on(struct ril_radio *self)
{
if (G_LIKELY(self) && ril_radio_power_should_be_on(self)) {
ril_radio_power_request(self, TRUE, TRUE);
struct ril_radio_priv *priv = self->priv;
if (priv->pending_id) {
if (!priv->next_state) {
/* Wait for the pending request to complete */
priv->next_state_valid = TRUE;
priv->next_state = TRUE;
DBG_(self, "on (queued)");
}
} else {
DBG_(self, "on");
ril_radio_submit_power_request(self, TRUE);
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2017-2018 Jolla Ltd.
* Copyright (C) 2017-2020 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -1414,7 +1414,7 @@ RilRadioCapsManager *ril_radio_caps_manager_ref(RilRadioCapsManager *self)
void ril_radio_caps_manager_unref(RilRadioCapsManager *self)
{
if (G_LIKELY(self)) {
g_object_ref(RADIO_CAPS_MANAGER(self));
g_object_unref(RADIO_CAPS_MANAGER(self));
}
}

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2018 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,8 +13,6 @@
* 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"

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2020 Jolla Ltd.
* Copyright (C) 2016-2019 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,8 +13,6 @@
* GNU General Public License for more details.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "ril_sim_settings.h"
#include "ril_log.h"

View File

@@ -237,16 +237,12 @@ socket=/dev/socket/rild
#
#networkModeTimeout=20000
# Comma-separated signal strength range, in dBm.
# Timeout for RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC and
# RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, in milliseconds.
#
# These values are used for translating dBm values returned by the modem in
# LTE mode into signal strength percentage. If you are getting significantly
# different signal strength readings in GSM and LTE modes, you may need to
# tweak those.
# Default 100000 (100 seconds)
#
# Default -100,-60
#
#signalStrengthRange=-100,-60
#networkSelectionTimeout=100000
# Cycle radio power at startup.
#
@@ -302,9 +298,15 @@ socket=/dev/socket/rild
#
# 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

View File

@@ -1,8 +1,8 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2019 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
@@ -55,8 +55,7 @@ struct ril_slot_config {
enum ril_pref_net_type lte_network_mode;
enum ril_pref_net_type umts_network_mode;
int network_mode_timeout;
int signal_strength_dbm_weak;
int signal_strength_dbm_strong;
int network_selection_timeout;
gboolean query_available_band_mode;
gboolean empty_pin_query;
gboolean radio_power_cycle;

0
ofono/drivers/xmm7modem/ims.c Normal file → Executable file
View File

View File

@@ -139,12 +139,7 @@ struct ofono_voicecall_driver {
/* Dials the last number again, this handles the hfp profile last number
* dialing with the +BLDN AT command
*/
void (*dial_last)(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb,
void *data);
/* dials a number at a given memory location */
void (*dial_memory)(struct ofono_voicecall *vc,
unsigned int memory_location, ofono_voicecall_cb_t cb,
void *data);
void (*dial_last)(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb, void *data);
};
void ofono_voicecall_en_list_notify(struct ofono_voicecall *vc,

View File

@@ -43,7 +43,6 @@
#include <ofono/ussd.h>
#include <ofono/gprs.h>
#include <ofono/gprs-context.h>
#include <ofono/lte.h>
#include <ofono/radio-settings.h>
#include <ofono/location-reporting.h>
#include <ofono/log.h>
@@ -484,8 +483,6 @@ static void gobi_post_sim(struct ofono_modem *modem)
DBG("%p", modem);
ofono_lte_create(modem, "qmimodem", data->device);
if (data->features & GOBI_CAT)
ofono_stk_create(modem, 0, "qmimodem", data->device);
else if (data->features & GOBI_CAT_OLD)

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2017-2020 Jolla Ltd.
* Copyright (C) 2017-2019 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,8 +13,6 @@
* GNU General Public License for more details.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

View File

@@ -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) {
if (sms_history_interface_registered)
return TRUE;
/* Late initialization of the D-Bus interface */
DBusConnection *conn = ofono_dbus_get_connection();
if (conn == NULL)
return FALSE;
struct ofono_modem *modem = context->modem;
ofono_debug("SMS History Probe for modem: %p", modem);
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);
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 @@ static void sms_history_sms_send_status(
{
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 @@ static void sms_history_exit(void)
OFONO_PLUGIN_DEFINE(sms_history, "SMS History Plugin",
VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
sms_history_init, sms_history_exit)

View File

@@ -1731,8 +1731,6 @@ static gboolean create_modem(gpointer key, gpointer value, gpointer user_data)
continue;
if (driver_list[i].setup(modem) == TRUE) {
ofono_modem_set_string(modem->modem, "SystemPath",
syspath);
ofono_modem_register(modem->modem);
return FALSE;
}

View File

@@ -805,7 +805,6 @@ void __ofono_modem_append_properties(struct ofono_modem *modem,
struct ofono_devinfo *info;
dbus_bool_t emergency = ofono_modem_get_emergency_mode(modem);
const char *strtype;
const char *system_path;
ofono_dbus_dict_append(dict, "Online", DBUS_TYPE_BOOLEAN,
&modem->online);
@@ -846,11 +845,6 @@ void __ofono_modem_append_properties(struct ofono_modem *modem,
&info->svn);
}
system_path = ofono_modem_get_string(modem, "SystemPath");
if (system_path)
ofono_dbus_dict_append(dict, "SystemPath", DBUS_TYPE_STRING,
&system_path);
interfaces = g_new0(char *, g_slist_length(modem->interface_list) + 1);
for (i = 0, l = modem->interface_list; l; l = l->next, i++)
interfaces[i] = l->data;

View File

@@ -139,17 +139,8 @@ static void sim_auth_unregister(struct ofono_atom *atom)
struct ofono_sim_auth *sa = __ofono_atom_get_data(atom);
free_apps(sa);
g_free(sa->nai);
if (sa->pending) {
__ofono_dbus_pending_reply(&sa->pending->msg,
__ofono_error_sim_not_ready(sa->pending->msg));
__ofono_sim_remove_session_watch(sa->pending->session,
sa->pending->watch_id);
g_free(sa->pending);
sa->pending = NULL;
}
}
static void sim_auth_remove(struct ofono_atom *atom)

View File

@@ -1798,7 +1798,7 @@ static DBusMessage *manager_dial(DBusConnection *conn,
return __ofono_error_failed(msg);
}
static void manager_dial_hfp_callback(const struct ofono_error *error,
static void manager_dial_last_callback(const struct ofono_error *error,
void *data)
{
struct ofono_voicecall *vc = data;
@@ -1827,7 +1827,7 @@ error:
__ofono_error_failed(vc->pending));
}
static int voicecall_dial_hfp(struct ofono_voicecall *vc, unsigned int position,
static int voicecall_dial_last(struct ofono_voicecall *vc,
ofono_voicecall_cb_t cb, void *data)
{
struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom);
@@ -1838,6 +1838,9 @@ static int voicecall_dial_hfp(struct ofono_voicecall *vc, unsigned int position,
if (ofono_modem_get_online(modem) == FALSE)
return -ENETDOWN;
if (vc->driver->dial_last == NULL)
return -ENOTSUP;
if (voicecalls_have_incoming(vc))
return -EBUSY;
@@ -1848,18 +1851,7 @@ static int voicecall_dial_hfp(struct ofono_voicecall *vc, unsigned int position,
if (voicecalls_have_active(vc) && voicecalls_have_held(vc))
return -EBUSY;
/* when position is not given we dial the last called number */
if (position == 0) {
if (vc->driver->dial_last == NULL)
return -ENOTSUP;
vc->driver->dial_last(vc, cb, vc);
} else {
if (vc->driver->dial_memory == NULL )
return -ENOTSUP;
vc->driver->dial_memory(vc, position, cb, vc);
}
return 0;
}
@@ -1875,7 +1867,7 @@ static DBusMessage *manager_dial_last(DBusConnection *conn,
vc->pending = dbus_message_ref(msg);
err = voicecall_dial_hfp(vc, 0, manager_dial_hfp_callback, vc);
err = voicecall_dial_last(vc, manager_dial_last_callback, vc);
if (err >= 0)
return NULL;
@@ -1897,44 +1889,6 @@ static DBusMessage *manager_dial_last(DBusConnection *conn,
return __ofono_error_failed(msg);
}
static DBusMessage *manager_dial_memory(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_voicecall *vc = data;
int memory_location;
int err;
if (vc->pending || vc->dial_req || vc->pending_em)
return __ofono_error_busy(msg);
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &memory_location,
DBUS_TYPE_INVALID) == FALSE)
return __ofono_error_invalid_args(msg);
vc->pending = dbus_message_ref(msg);
err = voicecall_dial_hfp(vc, memory_location,
manager_dial_hfp_callback, vc);
if (err >= 0)
return NULL;
vc->pending = NULL;
dbus_message_unref(msg);
switch (err) {
case -EINVAL:
return __ofono_error_invalid_format(msg);
case -ENETDOWN:
return __ofono_error_not_available(msg);
case -ENOTSUP:
return __ofono_error_not_implemented(msg);
}
return __ofono_error_failed(msg);
}
static DBusMessage *manager_transfer(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -2598,9 +2552,6 @@ static const GDBusMethodTable manager_methods[] = {
GDBUS_ARGS({ "path", "o" }),
manager_dial) },
{ GDBUS_ASYNC_METHOD("DialLast", NULL, NULL, manager_dial_last)},
{ GDBUS_ASYNC_METHOD("DialMemory",
GDBUS_ARGS({"memory_location", "u" }), NULL,
manager_dial_memory) },
{ GDBUS_ASYNC_METHOD("Transfer", NULL, NULL, manager_transfer) },
{ GDBUS_ASYNC_METHOD("SwapCalls", NULL, NULL, manager_swap_calls) },
{ GDBUS_ASYNC_METHOD("ReleaseAndAnswer", NULL, NULL,

View File

@@ -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 @@ static void test_get_enum(void)
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 @@ int main(int argc, char *argv[])
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);

View File

@@ -500,8 +500,8 @@ static void test_application_entry_decode(void)
g_assert(app[1]->label != NULL);
g_assert(!strcmp(app[1]->label, "MIDPfiles"));
g_slist_free_full(entries, (GDestroyNotify) sim_app_record_free);
g_free(ef_dir);
g_slist_free_full(entries, (GDestroyNotify) sim_app_record_free);
}
static void test_get_3g_path(void)

View File

@@ -1,6 +1,6 @@
Name: ofono
Summary: Open Source Telephony
Version: 1.23
Version: 1.22
Release: 1
Group: Communications/Connectivity Adaptation
License: GPLv2