Compare commits

...

26 Commits

Author SHA1 Message Date
Slava Monich
9331cc1ecb Merge branch 'online' into 'master'
Never fail online requests

See merge request mer-core/ofono!232
2019-09-17 11:59:46 +00:00
Slava Monich
7c8da34a38 [ril] Never fail online requests. JB#46974
If we do so, the core will think that modem's online state
hasn't changed when in fact it does eventually change.
2019-09-17 02:13:21 +03:00
Slava Monich
a05523974e Merge branch 'device_state' into 'master'
Improve device state management

See merge request mer-core/ofono!228
2019-08-29 21:44:58 +00:00
Slava Monich
71ef390b4a [ril] Improved device state management. JB#46836
Use RIL_REQUEST_SEND_DEVICE_STATE on newer devices, take charger
and battery state into account.
2019-08-28 19:07:17 +03:00
Slava Monich
717f6452aa Merge branch 'master' into 'master'
[build] Always require libglibutil and dbus-glib-1. JB#42254

See merge request mer-core/ofono!230
2019-08-28 10:19:53 +00:00
Herrie
0803c21840 configure.ac: always require libglibutil and dbus-glib-1
There are tests that are compiled even when not using sailfish_rilmodem, which still require libglibutil and dbus-glib-1. Without it, tests would fail to build.

Signed-off-by: Christophe Chapuis <chris.chapuis@gmail.com>
Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
2019-08-27 22:26:45 +02:00
Slava Monich
095060b001 Housekeeping
Indentation fixes
2019-08-23 19:57:35 +03:00
Slava Monich
c2971da092 [ril] Defined more RIL command codes. JB#46836 2019-08-15 18:48:21 +03:00
Slava Monich
f07424f0aa Merge branch 'sim_reset' into 'master'
Disable STK after SIM reset

See merge request mer-core/ofono!227
2019-07-28 13:40:23 +00:00
Slava Monich
266a52a40a [ril] Disable STK after SIM reset. JB#42589
As a workaround for STK reset loop.
2019-07-27 16:51:32 +03:00
Slava Monich
eeea5476d1 Merge branch 'fix_make' into 'master'
Fix RIL-less build

See merge request mer-core/ofono!226
2019-07-25 11:46:49 +00:00
Sergey Chupligin
e38a63d179 [packaging] Fixup build without rild. Fixed JB#46736 2019-07-25 13:16:17 +03:00
Slava Monich
0ff8608ac3 Merge branch 'mo_ssn' into 'master'
Hook up MO intermediate SSN (+CSSI)

See merge request mer-core/ofono!225
2019-07-11 11:23:24 +00:00
Slava Monich
5a330b9852 [ril] Hook up MO intermediate SSN (+CSSI). Fixes JB#46578 2019-07-11 14:21:37 +03:00
Slava Monich
78a9323619 Merge branch 'power_off' into 'master'
Send power off request at startup

See merge request mer-core/ofono!224
2019-07-10 11:55:22 +00:00
Slava Monich
8267e206eb [ril] Send power off request at startup. JB#46294
Some RILs like to receive power off request at startup even if radio
is already off.
2019-07-06 00:53:02 +03:00
Slava Monich
fac7684958 [ofono] Bumped libgrilio version requirement 2019-07-02 14:03:15 +03:00
Slava Monich
6ba3170ce2 Merge branch 'enabled' into 'master'
Pass enabled/disabled attribite to GRilIoChannel

See merge request mer-core/ofono!223
2019-07-02 11:01:47 +00:00
Slava Monich
b29730b268 [ril] Pass enabled/disabled attribite to GRilIoChannel. JB#46324 2019-06-28 16:57:25 +03:00
Slava Monich
e095636c97 Merge branch 'get_set_pref_mode' into 'master'
Avoid GET/SET_PREFERRED_NETWORK_TYPE loop

See merge request mer-core/ofono!222
2019-06-21 11:39:51 +00:00
Slava Monich
6fef5444fb [ril] Avoid GET/SET_PREFERRED_NETWORK_TYPE loop. JB#45343
Some RILs accept one RAT in SET_PREFERRED_NETWORK_TYPE but return
a different one in response to GET_PREFERRED_NETWORK_TYPE. If both
RATs belong to the same family (2G, 3G or LTE), just leave it as is,
there's no need to repeat SET_PREFERRED_NETWORK_TYPE request.
2019-06-20 18:34:56 +03:00
Slava Monich
0e62e613e8 Merge branch 'mms-settings' into 'master'
Report full IP settings for MMS context

See merge request mer-core/ofono!221
2019-06-13 10:03:54 +00:00
Slava Monich
c08be69130 Merge branch 'profiles' into 'master'
Support for data profiles

See merge request mer-core/ofono!220
2019-06-13 09:59:10 +00:00
Slava Monich
419caedc2c [ofono] Report full IP settings for MMS context. MER#903
"If we have a Proxy, no other settings are relevant" was a wrong assumption.
Proxy host name may require DNS resolution, which in turn requires at least
addresses of DNS servers.
2019-06-12 01:57:21 +03:00
Slava Monich
ee6a307804 [ril] Use data profiles is needed. JB#45344
By default, data profiles are off because in most cases everything
works without them. In those cases when they are needed, they can
be turned on with the following options in the config file:

  useDataProfiles
  mmsDataProfileId
2019-06-11 17:12:01 +03:00
Slava Monich
412d8c3d4d [ofono] Added __ofono_gprs_context_get_assigned_type(). JB#45344
Note that it's different from ofono_gprs_context_get_type() which
typically returns OFONO_GPRS_CONTEXT_TYPE_ANY no matter what's the
current usage of the context.
2019-06-11 16:04:49 +03:00
35 changed files with 2335 additions and 441 deletions

View File

@@ -150,9 +150,14 @@ builtin_sources += drivers/ril/ril_call_barring.c \
drivers/ril/ril_call_volume.c \
drivers/ril/ril_cell_info.c \
drivers/ril/ril_config.c \
drivers/ril/ril_connman.c \
drivers/ril/ril_cbs.c \
drivers/ril/ril_data.c \
drivers/ril/ril_devinfo.c \
drivers/ril/ril_devmon.c \
drivers/ril/ril_devmon_auto.c \
drivers/ril/ril_devmon_ds.c \
drivers/ril/ril_devmon_ss.c \
drivers/ril/ril_ecclist.c \
drivers/ril/ril_gprs.c \
drivers/ril/ril_gprs_context.c \
@@ -569,9 +574,6 @@ builtin_sources += plugins/samsung.c
builtin_modules += sim900
builtin_sources += plugins/sim900.c
builtin_modules += connman
builtin_sources += plugins/connman.c
builtin_modules += telit
builtin_sources += plugins/telit.c

View File

@@ -183,17 +183,19 @@ AC_ARG_ENABLE(sailfish-rilmodem, AC_HELP_STRING([--enable-sailfish-rilmodem],
[enable_sailfish_rilmodem="no"])
AM_CONDITIONAL(SAILFISH_RILMODEM, test "${enable_sailfish_rilmodem}" != "no")
PKG_CHECK_MODULES(GLIBUTIL, libglibutil >= 1.0.35, dummy=yes,
AC_MSG_ERROR(libglibutil >= 1.0.35 is required))
CFLAGS="$CFLAGS $GLIBUTIL_CFLAGS"
LIBS="$LIBS $GLIBUTIL_LIBS"
if (test "${enable_sailfish_rilmodem}" = "yes"); then
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.25, dummy=yes,
AC_MSG_ERROR(libgrilio >= 1.0.25 is required))
PKG_CHECK_MODULES(GLIBUTIL, libglibutil >= 1.0.30, dummy=yes,
AC_MSG_ERROR(libglibutil >= 1.0.30 is required))
PKG_CHECK_MODULES(LIBMCE, libmce-glib >= 1.0.5, dummy=yes,
AC_MSG_ERROR(libmce-glib >= 1.0.5 is required))
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.35, dummy=yes,
AC_MSG_ERROR(libgrilio >= 1.0.35 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"
LIBS="$LIBS $GRILIO_LIBS $LIBMCE_LIBS"
enable_sailfish_manager=yes
need_glibutil=yes
fi
AC_ARG_ENABLE(sailfish-manager,
@@ -202,12 +204,10 @@ AC_ARG_ENABLE(sailfish-manager,
[enable_sailfish_manager=${enableval}])
AM_CONDITIONAL(SAILFISH_MANAGER, test "${enable_sailfish_manager}" = "yes")
if (test "${enable_sailfish_manager}" = "yes"); then
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1, dummy=yes,
AC_MSG_ERROR(dbus-glib is required by unit tests))
AC_SUBST(DBUS_GLIB_CFLAGS)
AC_SUBST(DBUS_GLIB_LIBS)
fi
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1, dummy=yes,
AC_MSG_ERROR(dbus-glib is required by unit tests))
AC_SUBST(DBUS_GLIB_CFLAGS)
AC_SUBST(DBUS_GLIB_LIBS)
AC_ARG_ENABLE(add-remove-context, AC_HELP_STRING([--disable-add-remove-context],
[don't allow to add or remove connection context over D-Bus]), [
@@ -303,13 +303,10 @@ AC_ARG_ENABLE(sailfish-pushforwarder, AC_HELP_STRING([--enable-sailfish-pushforw
[enable_sailfish_pushforwarder="no"])
AM_CONDITIONAL(SAILFISH_PUSHFORWARDER, test "${enable_sailfish_pushforwarder}" != "no")
if (test "${enable_sailfish_pushforwarder}" != "no"); then
PKG_CHECK_MODULES(GLIBUTIL, libglibutil >= 1.0.15, dummy=yes,
AC_MSG_ERROR(libglibutil >= 1.0.15 is required))
PKG_CHECK_MODULES(WSPCODEC, libwspcodec >= 2.0, dummy=yes,
AC_MSG_ERROR(WSP decoder is required))
CFLAGS="$CFLAGS $WSPCODEC_CFLAGS"
LIBS="$LIBS $WSPCODEC_LIBS"
need_glibutil=yes
fi
AC_ARG_ENABLE(sailfish-access, AC_HELP_STRING([--enable-sailfish-access],
@@ -337,11 +334,6 @@ if (test "${enable_sailfish_debuglog}" = "yes"); then
LIBS="$LIBS $DBUSLOG_LIBS"
fi
if (test "${need_glibutil}" = "yes"); then
CFLAGS="$CFLAGS $GLIBUTIL_CFLAGS"
LIBS="$LIBS $GLIBUTIL_LIBS"
fi
if (test "${prefix}" = "NONE"); then
dnl no prefix and no localstatedir, so default to /var
if (test "$localstatedir" = '${prefix}/var'); then

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2018 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
@@ -26,8 +26,7 @@
#include <gutil_idlepool.h>
#include <gutil_misc.h>
#define DISPLAY_ON_UPDATE_RATE (1000) /* 1 sec */
#define DISPLAY_OFF_UPDATE_RATE (60000) /* 1 min */
#define DEFAULT_UPDATE_RATE_MS (10000) /* 10 sec */
#define MAX_RETRIES (5)
typedef GObjectClass RilCellInfoClass;
@@ -37,13 +36,12 @@ struct ril_cell_info {
GObject object;
struct sailfish_cell_info info;
GRilIoChannel *io;
MceDisplay *display;
struct ril_radio *radio;
struct ril_sim_card *sim_card;
gulong display_state_event_id;
gulong radio_state_event_id;
gulong sim_status_event_id;
gboolean sim_card_ready;
int update_rate_ms;
char *log_prefix;
gulong event_id;
guint query_id;
@@ -358,12 +356,11 @@ static void ril_cell_info_query(struct ril_cell_info *self)
grilio_request_unref(req);
}
static void ril_cell_info_set_rate(struct ril_cell_info *self, int ms)
static void ril_cell_info_set_rate(struct ril_cell_info *self)
{
GRilIoRequest *req = grilio_request_sized_new(8);
GRilIoRequest *req = grilio_request_array_int32_new(1,
(self->update_rate_ms > 0) ? self->update_rate_ms : INT_MAX);
grilio_request_append_int32(req, 1);
grilio_request_append_int32(req, ms);
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
grilio_channel_cancel_request(self->io, self->set_rate_id, FALSE);
self->set_rate_id = grilio_channel_send_request_full(self->io, req,
@@ -372,20 +369,6 @@ static void ril_cell_info_set_rate(struct ril_cell_info *self, int ms)
grilio_request_unref(req);
}
static void ril_cell_info_update_rate(struct ril_cell_info *self)
{
if (self->sim_card_ready) {
ril_cell_info_set_rate(self,
(self->display->state == MCE_DISPLAY_STATE_OFF) ?
DISPLAY_OFF_UPDATE_RATE : DISPLAY_ON_UPDATE_RATE);
}
}
static void ril_cell_info_display_state_cb(MceDisplay *display, void *arg)
{
ril_cell_info_update_rate(RIL_CELL_INFO(arg));
}
static void ril_cell_info_refresh(struct ril_cell_info *self)
{
/* RIL_REQUEST_GET_CELL_INFO_LIST fails without SIM card */
@@ -411,12 +394,15 @@ static void ril_cell_info_sim_status_cb(struct ril_sim_card *sim, void *arg)
self->sim_card_ready = ril_sim_card_ready(sim);
DBG_(self, "%sready", self->sim_card_ready ? "" : "not ");
ril_cell_info_refresh(self);
ril_cell_info_update_rate(self);
if (self->sim_card_ready) {
ril_cell_info_set_rate(self);
}
}
/* sailfish_cell_info interface callbacks */
struct ril_cell_info_signal_data {
struct ril_cell_info_closure {
GCClosure cclosure;
sailfish_cell_info_cb_t cb;
void *arg;
};
@@ -438,17 +424,9 @@ static void ril_cell_info_unref_proc(struct sailfish_cell_info *info)
}
static void ril_cell_info_cells_changed_cb(struct ril_cell_info *self,
void *user_data)
struct ril_cell_info_closure *closure)
{
struct ril_cell_info_signal_data *data = user_data;
data->cb(&self->info, data->arg);
}
static void ril_cell_info_cells_disconnect_notify(gpointer data,
GClosure *closure)
{
g_slice_free1(sizeof(struct ril_cell_info_signal_data), data);
closure->cb(&self->info, closure->arg);
}
static gulong ril_cell_info_add_cells_changed_handler_proc
@@ -456,16 +434,18 @@ static gulong ril_cell_info_add_cells_changed_handler_proc
sailfish_cell_info_cb_t cb, void *arg)
{
if (cb) {
struct ril_cell_info_signal_data *data =
g_slice_new(struct ril_cell_info_signal_data);
struct ril_cell_info_closure *closure =
(struct ril_cell_info_closure *) g_closure_new_simple
(sizeof(struct ril_cell_info_closure), NULL);
GCClosure* cc = &closure->cclosure;
data->cb = cb;
data->arg = arg;
return g_signal_connect_data(ril_cell_info_cast(info),
SIGNAL_CELLS_CHANGED_NAME,
G_CALLBACK(ril_cell_info_cells_changed_cb),
data, ril_cell_info_cells_disconnect_notify,
G_CONNECT_AFTER);
cc->closure.data = closure;
cc->callback = G_CALLBACK(ril_cell_info_cells_changed_cb);
closure->cb = cb;
closure->arg = arg;
return g_signal_connect_closure_by_id(ril_cell_info_cast(info),
ril_cell_info_signals[SIGNAL_CELLS_CHANGED], 0,
&cc->closure, FALSE);
} else {
return 0;
}
@@ -479,22 +459,36 @@ static void ril_cell_info_remove_handler_proc(struct sailfish_cell_info *info,
}
}
static void ril_cell_info_set_update_interval_proc
(struct sailfish_cell_info *info, int ms)
{
struct ril_cell_info *self = ril_cell_info_cast(info);
if (self->update_rate_ms != ms) {
self->update_rate_ms = ms;
DBG_(self, "%d ms", ms);
if (self->sim_card_ready) {
ril_cell_info_set_rate(self);
}
}
}
struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
const char *log_prefix, MceDisplay *display,
struct ril_radio *radio, struct ril_sim_card *sim_card)
const char *log_prefix, struct ril_radio *radio,
struct ril_sim_card *sim_card)
{
static const struct sailfish_cell_info_proc ril_cell_info_proc = {
ril_cell_info_ref_proc,
ril_cell_info_unref_proc,
ril_cell_info_add_cells_changed_handler_proc,
ril_cell_info_remove_handler_proc
ril_cell_info_remove_handler_proc,
ril_cell_info_set_update_interval_proc
};
struct ril_cell_info *self = g_object_new(RIL_CELL_INFO_TYPE, 0);
self->info.proc = &ril_cell_info_proc;
self->io = grilio_channel_ref(io);
self->display = mce_display_ref(display);
self->radio = ril_radio_ref(radio);
self->sim_card = ril_sim_card_ref(sim_card);
self->log_prefix = (log_prefix && log_prefix[0]) ?
@@ -502,9 +496,6 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
DBG_(self, "");
self->event_id = grilio_channel_add_unsol_event_handler(self->io,
ril_cell_info_list_changed_cb, RIL_UNSOL_CELL_INFO_LIST, self);
self->display_state_event_id =
mce_display_add_state_changed_handler(display,
ril_cell_info_display_state_cb, self);
self->radio_state_event_id =
ril_radio_add_state_changed_handler(radio,
ril_cell_info_radio_state_cb, self);
@@ -513,12 +504,15 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
ril_cell_info_sim_status_cb, self);
self->sim_card_ready = ril_sim_card_ready(sim_card);
ril_cell_info_refresh(self);
ril_cell_info_update_rate(self);
if (self->sim_card_ready) {
ril_cell_info_set_rate(self);
}
return &self->info;
}
static void ril_cell_info_init(struct ril_cell_info *self)
{
self->update_rate_ms = DEFAULT_UPDATE_RATE_MS;
}
static void ril_cell_info_dispose(GObject *object)
@@ -535,8 +529,6 @@ static void ril_cell_info_dispose(GObject *object)
FALSE);
self->set_rate_id = 0;
}
gutil_disconnect_handlers(self->display,
&self->display_state_event_id, 1);
ril_radio_remove_handlers(self->radio, &self->radio_state_event_id, 1);
ril_sim_card_remove_handlers(self->sim_card,
&self->sim_status_event_id, 1);
@@ -550,7 +542,6 @@ static void ril_cell_info_finalize(GObject *object)
DBG_(self, "");
g_free(self->log_prefix);
grilio_channel_unref(self->io);
mce_display_unref(self->display);
ril_radio_unref(self->radio);
ril_sim_card_unref(self->sim_card);
g_slist_free_full(self->info.cells, ril_cell_free1);

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2016-2017 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
@@ -17,12 +17,12 @@
#define RIL_CELL_INFO_H
#include "ril_types.h"
#include <mce_display.h>
#include <sailfish_cell_info.h>
struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
const char *log_prefix, MceDisplay *display,
struct ril_radio *radio, struct ril_sim_card *sim_card);
const char *log_prefix, struct ril_radio *radio,
struct ril_sim_card *sim_card);
#endif /* RIL_CELL_INFO_H */

View File

@@ -0,0 +1,622 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 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
* 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_connman.h"
#include <ofono/log.h>
#include <gdbus.h>
#include <gutil_macros.h>
#include <gutil_misc.h>
#include <glib-object.h>
#define CONNMAN_BUS DBUS_BUS_SYSTEM
#define CONNMAN_SERVICE "net.connman"
#define CONNMAN_PATH "/"
#define CONNMAN_GET_PROPERTIES "GetProperties"
#define CONNMAN_GET_TECHNOLOGIES "GetTechnologies"
#define CONNMAN_PROPERTY_CHANGED "PropertyChanged"
#define CONNMAN_TECH_CONNECTED "Connected"
#define CONNMAN_TECH_TETHERING "Tethering"
#define CONNMAN_INTERFACE_(name) "net.connman." name
#define CONNMAN_MANAGER_INTERFACE CONNMAN_INTERFACE_("Manager")
#define CONNMAN_TECH_INTERFACE CONNMAN_INTERFACE_("Technology")
#define CONNMAN_TECH_PATH_(name) "/net/connman/technology/" name
#define CONNMAN_TECH_PATH_WIFI CONNMAN_TECH_PATH_("wifi")
#define CONNMAN_TECH_CONNECTED_BIT (0x01)
#define CONNMAN_TECH_TETHERING_BIT (0x02)
#define CONNMAN_TECH_ALL_PROPERTY_BITS (\
CONNMAN_TECH_CONNECTED_BIT | \
CONNMAN_TECH_TETHERING_BIT)
typedef GObjectClass ConnManObjectClass;
typedef struct connman_tech ConnManTech;
typedef struct connman_object {
GObject object;
struct ril_connman pub;
guint32 pending_signals;
DBusConnection *connection;
DBusPendingCall *call;
guint service_watch;
guint signal_watch;
GHashTable *techs;
ConnManTech *wifi;
} ConnManObject;
G_DEFINE_TYPE(ConnManObject, connman_object, G_TYPE_OBJECT)
#define CONNMAN_OBJECT_TYPE (connman_object_get_type())
#define CONNMAN_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
CONNMAN_OBJECT_TYPE, ConnManObject))
struct connman_tech {
ConnManObject *obj;
const char *path;
gboolean connected;
gboolean tethering;
};
typedef struct connman_closure {
GCClosure cclosure;
ril_connman_property_cb_t callback;
gpointer user_data;
} ConnManClosure;
#define connman_closure_new() ((ConnManClosure *) \
g_closure_new_simple(sizeof(ConnManClosure), NULL))
#define SIGNAL_PROPERTY_CHANGED_NAME "ril-connman-property-changed"
#define SIGNAL_PROPERTY_DETAIL "%x"
#define SIGNAL_PROPERTY_DETAIL_MAX_LEN (8)
#define SIGNAL_BIT(property) (1 << (property - 1))
#define SIGNAL_BIT_(name) SIGNAL_BIT(RIL_CONNMAN_PROPERTY_##name)
enum connman_object_signal {
SIGNAL_PROPERTY_CHANGED,
SIGNAL_COUNT
};
static guint connman_object_signals[SIGNAL_COUNT];
static GQuark connman_object_property_quarks[RIL_CONNMAN_PROPERTY_COUNT - 1];
static inline ConnManObject *connman_object_cast(struct ril_connman *connman)
{
return G_LIKELY(connman) ?
CONNMAN_OBJECT(G_CAST(connman, ConnManObject, pub)) :
NULL;
}
static inline const char *connman_iter_get_string(DBusMessageIter *it)
{
const char *str = NULL;
dbus_message_iter_get_basic(it, &str);
return str;
}
static GQuark connman_object_property_quark(enum ril_connman_property p)
{
/* For ANY property this function is expected to return zero */
if (p > RIL_CONNMAN_PROPERTY_ANY && p < RIL_CONNMAN_PROPERTY_COUNT) {
const int i = p - 1;
if (G_UNLIKELY(!connman_object_property_quarks[i])) {
char buf[SIGNAL_PROPERTY_DETAIL_MAX_LEN + 1];
snprintf(buf, sizeof(buf), SIGNAL_PROPERTY_DETAIL, p);
buf[sizeof(buf) - 1] = 0;
connman_object_property_quarks[i] =
g_quark_from_string(buf);
}
return connman_object_property_quarks[i];
}
return 0;
}
static void connman_object_property_changed(ConnManObject *self,
enum ril_connman_property property, ConnManClosure *closure)
{
closure->callback(&self->pub, property, closure->user_data);
}
static void connman_object_emit_property_change(ConnManObject *self,
enum ril_connman_property p)
{
self->pending_signals &= ~SIGNAL_BIT(p);
g_signal_emit(self, connman_object_signals[SIGNAL_PROPERTY_CHANGED],
connman_object_property_quark(p), p);
}
static void connman_object_emit_pending_signals(ConnManObject *self)
{
struct ril_connman *connman = &self->pub;
gboolean valid_changed, present_changed;
enum ril_connman_property p;
/* Handlers could drop their references to us */
g_object_ref(self);
/*
* PRESENT and VALID are the last signals to be emitted if the object
* BECOMES present and/or valid.
*/
if ((self->pending_signals & SIGNAL_BIT_(VALID)) &&
connman->valid) {
self->pending_signals &= ~SIGNAL_BIT_(VALID);
valid_changed = TRUE;
} else {
valid_changed = FALSE;
}
if ((self->pending_signals & SIGNAL_BIT_(PRESENT)) &&
connman->present) {
self->pending_signals &= ~SIGNAL_BIT_(PRESENT);
present_changed = TRUE;
} else {
present_changed = FALSE;
}
/*
* Emit the signals. Not that in case if valid has become FALSE,
* then VALID is emitted first, otherwise it's emitted last.
* Same thing with PRESENT.
*/
for (p = RIL_CONNMAN_PROPERTY_ANY + 1;
p < RIL_CONNMAN_PROPERTY_COUNT && self->pending_signals;
p++) {
if (self->pending_signals & SIGNAL_BIT(p)) {
connman_object_emit_property_change(self, p);
}
}
/* Then emit PRESENT and VALID if necessary */
if (present_changed) {
connman_object_emit_property_change(self,
RIL_CONNMAN_PROPERTY_PRESENT);
}
if (valid_changed) {
connman_object_emit_property_change(self,
RIL_CONNMAN_PROPERTY_VALID);
}
/* And release the temporary reference */
g_object_unref(self);
}
static void connman_cancel_call(ConnManObject *self)
{
if (self->call) {
dbus_pending_call_cancel(self->call);
dbus_pending_call_unref(self->call);
self->call = NULL;
}
}
static ConnManTech *connman_tech_new(ConnManObject *self, const char *path)
{
ConnManTech *tech = g_new0(ConnManTech, 1);
char *key = g_strdup(path);
tech->obj = self;
tech->path = key;
g_hash_table_replace(self->techs, key, tech);
return tech;
}
static void connman_invalidate(ConnManObject *self)
{
struct ril_connman *connman = &self->pub;
if (connman->valid) {
connman->valid = FALSE;
self->pending_signals |= SIGNAL_BIT_(VALID);
}
}
static void connman_update_valid(ConnManObject *self)
{
struct ril_connman *connman = &self->pub;
const gboolean valid = (connman->present && !self->call);
if (connman->valid != valid) {
connman->valid = valid;
self->pending_signals |= SIGNAL_BIT_(VALID);
}
}
static gboolean connman_update_tethering(ConnManObject *self)
{
struct ril_connman *connman = &self->pub;
gboolean tethering = FALSE;
GHashTableIter it;
gpointer value;
g_hash_table_iter_init(&it, self->techs);
while (g_hash_table_iter_next(&it, NULL, &value)) {
const ConnManTech *tech = value;
if (tech->tethering) {
tethering = TRUE;
break;
}
}
if (connman->tethering != tethering) {
connman->tethering = tethering;
self->pending_signals |= SIGNAL_BIT_(TETHERING);
return TRUE;
} else {
return FALSE;
}
}
static void connman_set_tech_tethering(ConnManTech *tech, gboolean tethering)
{
if (tech->tethering != tethering) {
ConnManObject *self = tech->obj;
tech->tethering = tethering;
DBG(CONNMAN_TECH_TETHERING " %s for %s",
tethering ? "on" : "off", tech->path);
if (tethering) {
struct ril_connman *connman = &self->pub;
if (G_LIKELY(!connman->tethering)) {
/* Definitely tethering now */
connman->tethering = TRUE;
self->pending_signals |= SIGNAL_BIT_(TETHERING);
DBG("Tethering on");
}
} else if (connman_update_tethering(self)) {
/* Not tethering anymore */
DBG("Tethering off");
}
}
}
static void connman_set_tech_connected(ConnManTech *tech, gboolean connected)
{
if (tech->connected != connected) {
ConnManObject *self = tech->obj;
tech->connected = connected;
DBG(CONNMAN_TECH_CONNECTED " %s for %s",
connected ? "on" : "off", tech->path);
if (tech == self->wifi) {
struct ril_connman *connman = &self->pub;
connman->wifi_connected = connected;
self->pending_signals |= SIGNAL_BIT_(WIFI_CONNECTED);
DBG("WiFi %sconnected", connected ? "" : "dis");
}
}
}
static int connman_tech_set_property(ConnManTech *tech, DBusMessageIter *it)
{
DBusMessageIter var;
DBusBasicValue value;
const char *key = connman_iter_get_string(it);
dbus_message_iter_next(it);
dbus_message_iter_recurse(it, &var);
dbus_message_iter_get_basic(&var, &value);
if (!g_ascii_strcasecmp(key, CONNMAN_TECH_CONNECTED)) {
if (dbus_message_iter_get_arg_type(&var) == DBUS_TYPE_BOOLEAN) {
connman_set_tech_connected(tech, value.bool_val);
return CONNMAN_TECH_CONNECTED_BIT;
}
} else if (!g_ascii_strcasecmp(key, CONNMAN_TECH_TETHERING)) {
if (dbus_message_iter_get_arg_type(&var) == DBUS_TYPE_BOOLEAN) {
connman_set_tech_tethering(tech, value.bool_val);
return CONNMAN_TECH_TETHERING_BIT;
}
}
return 0;
}
static void connman_tech_set_properties(ConnManTech *tech, DBusMessageIter *it)
{
DBusMessageIter dict;
int handled = 0;
dbus_message_iter_recurse(it, &dict);
while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter entry;
dbus_message_iter_recurse(&dict, &entry);
handled |= connman_tech_set_property(tech, &entry);
if (handled == CONNMAN_TECH_ALL_PROPERTY_BITS) {
/* Ignore the rest */
break;
}
dbus_message_iter_next(&dict);
}
}
static gboolean connman_tech_property_changed(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
const char *path = dbus_message_get_path(msg);
ConnManObject *self = CONNMAN_OBJECT(user_data);
ConnManTech *tech = g_hash_table_lookup(self->techs, path);
DBusMessageIter it;
if (tech && dbus_message_has_signature(msg, "sv") &&
dbus_message_iter_init(msg, &it)) {
const char* name = connman_iter_get_string(&it);
if (!connman_tech_set_property(tech, &it)) {
DBG("%s changed for %s", name, path);
}
connman_object_emit_pending_signals(self);
}
return TRUE;
}
static void connman_set_techs(ConnManObject *self, DBusMessageIter *it)
{
DBusMessageIter list;
dbus_message_iter_recurse(it, &list);
while (dbus_message_iter_get_arg_type(&list) == DBUS_TYPE_STRUCT) {
DBusMessageIter entry;
const char *path;
ConnManTech *tech;
dbus_message_iter_recurse(&list, &entry);
path = connman_iter_get_string(&entry);
tech = connman_tech_new(self, path);
DBG("%s", path);
if (!g_strcmp0(path, CONNMAN_TECH_PATH_WIFI)) {
/* WiFi is a special case */
self->wifi = tech;
}
dbus_message_iter_next(&entry);
connman_tech_set_properties(tech, &entry);
dbus_message_iter_next(&list);
}
}
static void connman_techs_reply(DBusPendingCall *call, void *user_data)
{
ConnManObject *self = CONNMAN_OBJECT(user_data);
DBusMessage *reply = dbus_pending_call_steal_reply(call);
DBusError error;
DBusMessageIter array;
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, reply)) {
DBG("Failed to get technologies: %s", error.message);
dbus_error_free(&error);
} else if (dbus_message_has_signature(reply, "a(oa{sv})") &&
dbus_message_iter_init(reply, &array)) {
connman_set_techs(self, &array);
}
dbus_message_unref(reply);
dbus_pending_call_unref(self->call);
self->call = NULL;
connman_update_valid(self);
connman_object_emit_pending_signals(self);
}
static void connman_get_techs(ConnManObject *self)
{
DBusMessage *msg = dbus_message_new_method_call(CONNMAN_SERVICE,
CONNMAN_PATH, CONNMAN_MANAGER_INTERFACE,
CONNMAN_GET_TECHNOLOGIES);
connman_cancel_call(self);
if (g_dbus_send_message_with_reply(self->connection, msg,
&self->call, DBUS_TIMEOUT_INFINITE)) {
/* Not valid while any request is pending */
connman_invalidate(self);
dbus_pending_call_set_notify(self->call, connman_techs_reply,
self, NULL);
}
dbus_message_unref(msg);
}
static void connman_appeared(DBusConnection *conn, void *user_data)
{
ConnManObject *self = CONNMAN_OBJECT(user_data);
struct ril_connman *connman = &self->pub;
if (!connman->present) {
DBG("connman is there");
connman->present = TRUE;
self->pending_signals |= SIGNAL_BIT_(PRESENT);
connman_get_techs(self);
connman_object_emit_pending_signals(self);
}
}
static void connman_vanished(DBusConnection *conn, void *user_data)
{
ConnManObject *self = CONNMAN_OBJECT(user_data);
struct ril_connman *connman = &self->pub;
if (connman->present) {
DBG("connman has disappeared");
g_hash_table_remove_all(self->techs);
self->wifi = NULL;
connman->present = FALSE;
self->pending_signals |= SIGNAL_BIT_(PRESENT);
if (connman->wifi_connected) {
connman->wifi_connected = FALSE;
self->pending_signals |= SIGNAL_BIT_(WIFI_CONNECTED);
}
if (connman->tethering) {
connman->tethering = FALSE;
self->pending_signals |= SIGNAL_BIT_(TETHERING);
}
connman_object_emit_pending_signals(self);
}
}
static void connman_init(ConnManObject *self, DBusConnection *connection)
{
self->connection = dbus_connection_ref(connection);
self->service_watch = g_dbus_add_service_watch(self->connection,
CONNMAN_SERVICE, connman_appeared, connman_vanished,
self, NULL);
self->signal_watch = g_dbus_add_signal_watch(self->connection,
CONNMAN_SERVICE, NULL, CONNMAN_TECH_INTERFACE,
CONNMAN_PROPERTY_CHANGED, connman_tech_property_changed,
self, NULL);
}
struct ril_connman *ril_connman_new()
{
static ConnManObject *instance = NULL;
if (instance) {
g_object_ref(instance);
return &instance->pub;
} else {
DBusError error;
DBusConnection *connection;
dbus_error_init(&error);
connection = dbus_bus_get(CONNMAN_BUS, NULL);
if (connection) {
instance = g_object_new(CONNMAN_OBJECT_TYPE, NULL);
connman_init(instance, connection);
dbus_connection_unref(connection);
g_object_add_weak_pointer(G_OBJECT(instance),
(gpointer*)(&instance));
return &instance->pub;
} else {
ofono_error("Unable to attach to connman bus: %s",
error.message);
dbus_error_free(&error);
return NULL;
}
}
}
struct ril_connman *ril_connman_ref(struct ril_connman *connman)
{
ConnManObject *self = connman_object_cast(connman);
if (G_LIKELY(self)) {
g_object_ref(self);
return connman;
} else {
return NULL;
}
}
void ril_connman_unref(struct ril_connman *connman)
{
ConnManObject *self = connman_object_cast(connman);
if (G_LIKELY(self)) {
g_object_unref(self);
}
}
gulong ril_connman_add_property_changed_handler(struct ril_connman *connman,
enum ril_connman_property p, ril_connman_property_cb_t cb, void *arg)
{
ConnManObject *self = connman_object_cast(connman);
if (G_LIKELY(self) && G_LIKELY(cb)) {
/*
* We can't directly connect the provided callback because
* it expects the first parameter to point to public part
* of the object but glib will call it with ConnManObject
* as the first parameter. connman_object_property_changed()
* will do the conversion.
*/
ConnManClosure *closure = connman_closure_new();
GCClosure *cc = &closure->cclosure;
cc->closure.data = closure;
cc->callback = G_CALLBACK(connman_object_property_changed);
closure->callback = cb;
closure->user_data = arg;
return g_signal_connect_closure_by_id(self,
connman_object_signals[SIGNAL_PROPERTY_CHANGED],
connman_object_property_quark(p), &cc->closure, FALSE);
}
return 0;
}
void ril_connman_remove_handler(struct ril_connman *connman, gulong id)
{
if (G_LIKELY(id)) {
ConnManObject *self = connman_object_cast(connman);
if (G_LIKELY(self)) {
g_signal_handler_disconnect(self, id);
}
}
}
void ril_connman_remove_handlers(struct ril_connman *connman, gulong *ids,
int n)
{
gutil_disconnect_handlers(connman_object_cast(connman), ids, n);
}
static void connman_object_init(ConnManObject *self)
{
self->techs = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
}
static void connman_object_finalize(GObject *object)
{
ConnManObject *self = CONNMAN_OBJECT(object);
connman_cancel_call(self);
g_hash_table_destroy(self->techs);
g_dbus_remove_watch(self->connection, self->service_watch);
g_dbus_remove_watch(self->connection, self->signal_watch);
dbus_connection_unref(self->connection);
G_OBJECT_CLASS(connman_object_parent_class)->finalize(object);
}
static void connman_object_class_init(ConnManObjectClass *klass)
{
G_OBJECT_CLASS(klass)->finalize = connman_object_finalize;
connman_object_signals[SIGNAL_PROPERTY_CHANGED] =
g_signal_new(SIGNAL_PROPERTY_CHANGED_NAME,
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT);
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -0,0 +1,61 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 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
* 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.
*/
#ifndef RIL_CONNMAN_H
#define RIL_CONNMAN_H
#include <gutil_misc.h>
struct ril_connman {
gboolean valid; /* TRUE if other fields are valid */
gboolean present; /* ConnMan is present on D-Bus */
gboolean tethering; /* At least one technology is tethering */
gboolean wifi_connected; /* WiFi network is connected */
};
enum ril_connman_property {
RIL_CONNMAN_PROPERTY_ANY,
RIL_CONNMAN_PROPERTY_VALID,
RIL_CONNMAN_PROPERTY_PRESENT,
RIL_CONNMAN_PROPERTY_TETHERING,
RIL_CONNMAN_PROPERTY_WIFI_CONNECTED,
RIL_CONNMAN_PROPERTY_COUNT
};
typedef void (*ril_connman_property_cb_t)(struct ril_connman *connman,
enum ril_connman_property property, void *arg);
struct ril_connman *ril_connman_new(void);
struct ril_connman *ril_connman_ref(struct ril_connman *connman);
void ril_connman_unref(struct ril_connman *connman);
gulong ril_connman_add_property_changed_handler(struct ril_connman *connman,
enum ril_connman_property p, ril_connman_property_cb_t cb, void *arg);
void ril_connman_remove_handler(struct ril_connman *connman, gulong id);
void ril_connman_remove_handlers(struct ril_connman *connman, gulong *ids,
int n);
#define ril_connman_remove_all_handlers(connman, ids) \
ril_connman_remove_handlers(connman, ids, G_N_ELEMENTS(ids))
#endif /* RIL_CONNMAN_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -233,6 +233,12 @@ enum ril_data_profile {
RIL_DATA_PROFILE_INVALID = 0xFFFFFFFF
};
enum ril_profile_type {
RIL_PROFILE_COMMON = 0,
RIL_PROFILE_3GPP = 1,
RIL_PROFILE_3GPP2 = 2
};
enum ril_auth {
RIL_AUTH_NONE = 0,
RIL_AUTH_PAP = 1,
@@ -328,8 +334,6 @@ enum ril_restricted_state {
RIL_RESTRICTED_STATE_PS_ALL = 0x10
};
#define DATA_PROFILE_DEFAULT_STR "0"
/* Suplementary services Service class*/
#define SERVICE_CLASS_NONE 0

View File

@@ -106,6 +106,8 @@ struct ril_data_priv {
struct ril_data_request *pending_req;
struct ril_data_options options;
gboolean use_data_profiles;
guint mms_data_profile_id;
guint slot;
char *log_prefix;
guint query_id;
@@ -162,6 +164,7 @@ struct ril_data_request {
struct ril_data_request_setup {
struct ril_data_request req;
guint profile_id;
char *apn;
char *username;
char *password;
@@ -917,7 +920,7 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
/* Give vendor code a chance to build a vendor specific packet */
ioreq = ril_vendor_data_call_req(priv->vendor, tech,
DATA_PROFILE_DEFAULT_STR, setup->apn, setup->username,
setup->profile_id, setup->apn, setup->username,
setup->password, auth, proto_str);
if (!ioreq) {
@@ -925,7 +928,7 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
ioreq = grilio_request_new();
grilio_request_append_int32(ioreq, 7 /* Parameter count */);
grilio_request_append_format(ioreq, "%d", tech);
grilio_request_append_utf8(ioreq, DATA_PROFILE_DEFAULT_STR);
grilio_request_append_format(ioreq, "%d", setup->profile_id);
grilio_request_append_utf8(ioreq, setup->apn);
grilio_request_append_utf8(ioreq, setup->username);
grilio_request_append_utf8(ioreq, setup->password);
@@ -955,12 +958,18 @@ static void ril_data_call_setup_free(struct ril_data_request *req)
static struct ril_data_request *ril_data_call_setup_new(struct ril_data *data,
const struct ofono_gprs_primary_context *ctx,
enum ofono_gprs_context_type context_type,
ril_data_call_setup_cb_t cb, void *arg)
{
struct ril_data_priv *priv = data->priv;
struct ril_data_request_setup *setup =
g_new0(struct ril_data_request_setup, 1);
struct ril_data_request *req = &setup->req;
setup->profile_id = (priv->use_data_profiles &&
context_type == OFONO_GPRS_CONTEXT_TYPE_MMS) ?
priv->mms_data_profile_id :
RIL_DATA_PROFILE_DEFAULT;
setup->apn = g_strdup(ctx->apn);
setup->username = g_strdup(ctx->username);
setup->password = g_strdup(ctx->password);
@@ -1211,6 +1220,8 @@ struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
priv->log_prefix = (name && name[0]) ?
g_strconcat(name, " ", NULL) : g_strdup("");
priv->use_data_profiles = config->use_data_profiles;
priv->mms_data_profile_id = config->mms_data_profile_id;
priv->slot = config->slot;
priv->q = grilio_queue_new(io);
priv->io = grilio_channel_ref(io);
@@ -1464,10 +1475,11 @@ void ril_data_allow(struct ril_data *self, enum ril_data_role role)
struct ril_data_request *ril_data_call_setup(struct ril_data *self,
const struct ofono_gprs_primary_context *ctx,
enum ofono_gprs_context_type context_type,
ril_data_call_setup_cb_t cb, void *arg)
{
struct ril_data_request *req =
ril_data_call_setup_new(self, ctx, cb, arg);
ril_data_call_setup_new(self, ctx, context_type, cb, arg);
ril_data_request_queue(req);
return req;

View File

@@ -117,6 +117,7 @@ void ril_data_allow(struct ril_data *data, enum ril_data_role role);
struct ril_data_request;
struct ril_data_request *ril_data_call_setup(struct ril_data *data,
const struct ofono_gprs_primary_context *ctx,
enum ofono_gprs_context_type context_type,
ril_data_call_setup_cb_t cb, void *arg);
struct ril_data_request *ril_data_call_deactivate(struct ril_data *data,
int cid, ril_data_call_deactivate_cb_t cb, void *arg);

View File

@@ -0,0 +1,44 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 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
* 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"
struct ril_devmon_io *ril_devmon_start_io(struct ril_devmon *devmon,
GRilIoChannel *channel, struct sailfish_cell_info *cell_info)
{
return devmon ? devmon->start_io(devmon, channel, cell_info) : NULL;
}
void ril_devmon_io_free(struct ril_devmon_io *devmon_io)
{
if (devmon_io) {
devmon_io->free(devmon_io);
}
}
void ril_devmon_free(struct ril_devmon *devmon)
{
if (devmon) {
devmon->free(devmon);
}
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -0,0 +1,72 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 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
* 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.
*/
#ifndef RIL_DEVMON_H
#define RIL_DEVMON_H
#include "ril_cell_info.h"
/*
* Separate instance of ril_devmon is created for each modem.
* Device monitor is started after RIL has been connected.
*/
struct ril_devmon_io {
void (*free)(struct ril_devmon_io *devmon_io);
};
struct ril_devmon {
void (*free)(struct ril_devmon *devmon);
struct ril_devmon_io *(*start_io)(struct ril_devmon *devmon,
GRilIoChannel *channel, struct sailfish_cell_info *cell_info);
};
/* Cell info update intervals */
#define RIL_CELL_INFO_INTERVAL_SHORT_MS (2000) /* 2 sec */
#define RIL_CELL_INFO_INTERVAL_LONG_MS (30000) /* 30 sec */
/*
* Legacy Device Monitor uses RIL_REQUEST_SCREEN_STATE to tell
* the modem when screen turns on and off.
*/
struct ril_devmon *ril_devmon_ss_new(void);
/*
* This Device Monitor uses RIL_REQUEST_SEND_DEVICE_STATE to let
* the modem choose the right power saving strategy. It basically
* mirrors the logic of Android's DeviceStateMonitor class.
*/
struct ril_devmon *ril_devmon_ds_new(void);
/*
* This one selects the type based on the RIL version.
*/
struct ril_devmon *ril_devmon_auto_new(void);
/* Utilities (NULL tolerant) */
struct ril_devmon_io *ril_devmon_start_io(struct ril_devmon *devmon,
GRilIoChannel *channel, struct sailfish_cell_info *cell_info);
void ril_devmon_io_free(struct ril_devmon_io *devmon_io);
void ril_devmon_free(struct ril_devmon *devmon);
#endif /* RIL_CONNMAN_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -0,0 +1,92 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 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
* 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 <grilio_channel.h>
typedef struct ril_devmon_ds {
struct ril_devmon pub;
struct ril_devmon *ss;
struct ril_devmon *ds;
} DevMon;
static inline DevMon *ril_devmon_auto_cast(struct ril_devmon *pub)
{
return G_CAST(pub, DevMon, pub);
}
static struct ril_devmon_io *ril_devmon_auto_start_io(struct ril_devmon *devmon,
GRilIoChannel *io, struct sailfish_cell_info *cell_info)
{
DevMon *self = ril_devmon_auto_cast(devmon);
if (!self->ss) {
/* We have already chosen SEND_DEVICE_STATE method */
return ril_devmon_start_io(self->ds, io, cell_info);
} else if (!self->ds) {
/* We have already chosen SCREEN_STATE method */
return ril_devmon_start_io(self->ss, io, cell_info);
} else if (io->ril_version > 14 /* Covers binder implementation */) {
/* Choose SEND_DEVICE_STATE method */
DBG("%s: Will use SEND_DEVICE_STATE method", io->name);
ril_devmon_free(self->ss);
self->ss = NULL;
return ril_devmon_start_io(self->ds, io, cell_info);
} else {
/* Choose legacy SCREEN_STATE method */
DBG("%s: Will use SCREEN_STATE method", io->name);
ril_devmon_free(self->ds);
self->ds = NULL;
return ril_devmon_start_io(self->ss, io, cell_info);
}
}
static void ril_devmon_auto_free(struct ril_devmon *devmon)
{
DevMon *self = ril_devmon_auto_cast(devmon);
ril_devmon_free(self->ss);
ril_devmon_free(self->ds);
g_free(self);
}
struct ril_devmon *ril_devmon_auto_new()
{
DevMon *self = g_new0(DevMon, 1);
/*
* Allocate both implementations at startup. We need to do that
* early so that connections to D-Bus daemon and services are
* established before we drop privileges. This isn't much of
* an overhead because those implementation don't do much until
* we actually start the I/O (at which point we drop one of those).
*/
self->pub.free = ril_devmon_auto_free;
self->pub.start_io = ril_devmon_auto_start_io;
self->ss = ril_devmon_ss_new();
self->ds = ril_devmon_ds_new();
return &self->pub;
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -0,0 +1,342 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 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
* 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 "ril_connman.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>
enum device_state_type {
/* Mirrors RIL_DeviceStateType from ril.h */
POWER_SAVE_MODE,
CHARGING_STATE,
LOW_DATA_EXPECTED
};
enum ril_devmon_ds_battery_event {
BATTERY_EVENT_VALID,
BATTERY_EVENT_STATUS,
BATTERY_EVENT_COUNT
};
enum ril_devmon_ds_charger_event {
CHARGER_EVENT_VALID,
CHARGER_EVENT_STATE,
CHARGER_EVENT_COUNT
};
enum ril_devmon_ds_display_event {
DISPLAY_EVENT_VALID,
DISPLAY_EVENT_STATE,
DISPLAY_EVENT_COUNT
};
enum ril_devmon_ds_connman_event {
CONNMAN_EVENT_VALID,
CONNMAN_EVENT_TETHERING,
CONNMAN_EVENT_COUNT
};
typedef struct ril_devmon_ds {
struct ril_devmon pub;
struct ril_connman *connman;
MceBattery *battery;
MceCharger *charger;
MceDisplay *display;
} DevMon;
typedef struct ril_devmon_ds_io {
struct ril_devmon_io pub;
struct ril_connman *connman;
struct sailfish_cell_info *cell_info;
MceBattery *battery;
MceCharger *charger;
MceDisplay *display;
GRilIoChannel *io;
guint low_data_req_id;
guint charging_req_id;
gboolean low_data;
gboolean charging;
gboolean low_data_supported;
gboolean charging_supported;
gulong connman_event_id[CONNMAN_EVENT_COUNT];
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)
static inline DevMon *ril_devmon_ds_cast(struct ril_devmon *pub)
{
return G_CAST(pub, DevMon, pub);
}
static inline DevMonIo *ril_devmon_ds_io_cast(struct ril_devmon_io *pub)
{
return G_CAST(pub, DevMonIo, pub);
}
static inline gboolean ril_devmon_ds_tethering_on(struct ril_connman *connman)
{
return connman->valid && connman->tethering;
}
static inline gboolean ril_devmon_ds_battery_ok(MceBattery *battery)
{
return battery->valid && battery->status >= MCE_BATTERY_OK;
}
static inline gboolean ril_devmon_ds_charging(MceCharger *charger)
{
return charger->valid && charger->state == MCE_CHARGER_ON;
}
static inline gboolean ril_devmon_ds_display_on(MceDisplay *display)
{
return display->valid && display->state != MCE_DISPLAY_STATE_OFF;
}
static guint ril_devmon_ds_io_send_device_state(DevMonIo *self,
enum device_state_type type, gboolean state,
GRilIoChannelResponseFunc callback)
{
GRilIoRequest *req = grilio_request_array_int32_new(2, type, state);
const guint id = grilio_channel_send_request_full(self->io, req,
RIL_REQUEST_SEND_DEVICE_STATE, callback, NULL, self);
grilio_request_unref(req);
return id;
}
static void ril_devmon_ds_io_low_data_state_sent(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
DevMonIo *self = user_data;
self->low_data_req_id = 0;
if (status == RIL_E_REQUEST_NOT_SUPPORTED) {
DBG_(self, "LOW_DATA_EXPECTED state is not supported");
self->low_data_supported = FALSE;
}
}
static void ril_devmon_ds_io_charging_state_sent(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
DevMonIo *self = user_data;
self->charging_req_id = 0;
if (status == RIL_E_REQUEST_NOT_SUPPORTED) {
DBG_(self, "CHARGING state is not supported");
self->charging_supported = FALSE;
}
}
static void ril_devmon_ds_io_update_charging(DevMonIo *self)
{
const gboolean charging = ril_devmon_ds_charging(self->charger);
if (self->charging != charging) {
self->charging = charging;
DBG_(self, "Charging %s", charging ? "on" : "off");
if (self->charging_supported) {
grilio_channel_cancel_request(self->io,
self->charging_req_id, FALSE);
self->charging_req_id =
ril_devmon_ds_io_send_device_state(self,
CHARGING_STATE, charging,
ril_devmon_ds_io_charging_state_sent);
}
}
}
static void ril_devmon_ds_io_update_low_data(DevMonIo *self)
{
const gboolean low_data =
!ril_devmon_ds_tethering_on(self->connman) &&
!ril_devmon_ds_charging(self->charger) &&
!ril_devmon_ds_display_on(self->display);
if (self->low_data != low_data) {
self->low_data = low_data;
DBG_(self, "Low data is%s expected", low_data ? "" : " not");
if (self->low_data_supported) {
grilio_channel_cancel_request(self->io,
self->low_data_req_id, FALSE);
self->low_data_req_id =
ril_devmon_ds_io_send_device_state(self,
LOW_DATA_EXPECTED, low_data,
ril_devmon_ds_io_low_data_state_sent);
}
}
}
static void ril_devmon_ds_io_set_cell_info_update_interval(DevMonIo *self)
{
sailfish_cell_info_set_update_interval(self->cell_info,
(ril_devmon_ds_display_on(self->display) &&
(ril_devmon_ds_charging(self->charger) ||
ril_devmon_ds_battery_ok(self->battery))) ?
RIL_CELL_INFO_INTERVAL_SHORT_MS :
RIL_CELL_INFO_INTERVAL_LONG_MS);
}
static void ril_devmon_ds_io_connman_cb(struct ril_connman *connman,
enum ril_connman_property property, void *user_data)
{
ril_devmon_ds_io_update_low_data((DevMonIo *)user_data);
}
static void ril_devmon_ds_io_battery_cb(MceBattery *battery, void *user_data)
{
ril_devmon_ds_io_set_cell_info_update_interval(user_data);
}
static void ril_devmon_ds_io_display_cb(MceDisplay *display, void *user_data)
{
DevMonIo *self = user_data;
ril_devmon_ds_io_update_low_data(self);
ril_devmon_ds_io_set_cell_info_update_interval(self);
}
static void ril_devmon_ds_io_charger_cb(MceCharger *charger, void *user_data)
{
DevMonIo *self = user_data;
ril_devmon_ds_io_update_low_data(self);
ril_devmon_ds_io_update_charging(self);
ril_devmon_ds_io_set_cell_info_update_interval(self);
}
static void ril_devmon_ds_io_free(struct ril_devmon_io *devmon_io)
{
DevMonIo *self = ril_devmon_ds_io_cast(devmon_io);
ril_connman_remove_all_handlers(self->connman, self->connman_event_id);
ril_connman_unref(self->connman);
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->low_data_req_id, FALSE);
grilio_channel_cancel_request(self->io, self->charging_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_ds_start_io(struct ril_devmon *devmon,
GRilIoChannel *io, struct sailfish_cell_info *cell_info)
{
DevMon *ds = ril_devmon_ds_cast(devmon);
DevMonIo *self = g_new0(DevMonIo, 1);
self->pub.free = ril_devmon_ds_io_free;
self->low_data_supported = TRUE;
self->charging_supported = TRUE;
self->io = grilio_channel_ref(io);
self->cell_info = sailfish_cell_info_ref(cell_info);
self->connman = ril_connman_ref(ds->connman);
self->connman_event_id[CONNMAN_EVENT_VALID] =
ril_connman_add_property_changed_handler(self->connman,
RIL_CONNMAN_PROPERTY_VALID,
ril_devmon_ds_io_connman_cb, self);
self->connman_event_id[CONNMAN_EVENT_TETHERING] =
ril_connman_add_property_changed_handler(self->connman,
RIL_CONNMAN_PROPERTY_TETHERING,
ril_devmon_ds_io_connman_cb, self);
self->battery = mce_battery_ref(ds->battery);
self->battery_event_id[BATTERY_EVENT_VALID] =
mce_battery_add_valid_changed_handler(self->battery,
ril_devmon_ds_io_battery_cb, self);
self->battery_event_id[BATTERY_EVENT_STATUS] =
mce_battery_add_status_changed_handler(self->battery,
ril_devmon_ds_io_battery_cb, self);
self->charger = mce_charger_ref(ds->charger);
self->charger_event_id[CHARGER_EVENT_VALID] =
mce_charger_add_valid_changed_handler(self->charger,
ril_devmon_ds_io_charger_cb, self);
self->charger_event_id[CHARGER_EVENT_STATE] =
mce_charger_add_state_changed_handler(self->charger,
ril_devmon_ds_io_charger_cb, self);
self->display = mce_display_ref(ds->display);
self->display_event_id[DISPLAY_EVENT_VALID] =
mce_display_add_valid_changed_handler(self->display,
ril_devmon_ds_io_display_cb, self);
self->display_event_id[DISPLAY_EVENT_STATE] =
mce_display_add_state_changed_handler(self->display,
ril_devmon_ds_io_display_cb, self);
ril_devmon_ds_io_update_low_data(self);
ril_devmon_ds_io_update_charging(self);
ril_devmon_ds_io_set_cell_info_update_interval(self);
return &self->pub;
}
static void ril_devmon_ds_free(struct ril_devmon *devmon)
{
DevMon *self = ril_devmon_ds_cast(devmon);
ril_connman_unref(self->connman);
mce_battery_unref(self->battery);
mce_charger_unref(self->charger);
mce_display_unref(self->display);
g_free(self);
}
struct ril_devmon *ril_devmon_ds_new()
{
DevMon *self = g_new0(DevMon, 1);
self->pub.free = ril_devmon_ds_free;
self->pub.start_io = ril_devmon_ds_start_io;
self->connman = ril_connman_new();
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

@@ -0,0 +1,248 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 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
* 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>
enum ril_devmon_ss_battery_event {
BATTERY_EVENT_VALID,
BATTERY_EVENT_STATUS,
BATTERY_EVENT_COUNT
};
enum ril_devmon_ss_charger_event {
CHARGER_EVENT_VALID,
CHARGER_EVENT_STATE,
CHARGER_EVENT_COUNT
};
enum ril_devmon_ss_display_event {
DISPLAY_EVENT_VALID,
DISPLAY_EVENT_STATE,
DISPLAY_EVENT_COUNT
};
typedef struct ril_devmon_ss {
struct ril_devmon pub;
MceBattery *battery;
MceCharger *charger;
MceDisplay *display;
} DevMon;
typedef struct ril_devmon_ss_io {
struct ril_devmon_io pub;
struct sailfish_cell_info *cell_info;
MceBattery *battery;
MceCharger *charger;
MceDisplay *display;
GRilIoChannel *io;
gboolean display_on;
gboolean screen_state_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;
inline static DevMon *ril_devmon_ss_cast(struct ril_devmon *pub)
{
return G_CAST(pub, DevMon, pub);
}
inline static DevMonIo *ril_devmon_ss_io_cast(struct ril_devmon_io *pub)
{
return G_CAST(pub, DevMonIo, pub);
}
static inline gboolean ril_devmon_ss_battery_ok(MceBattery *battery)
{
return battery->valid && battery->status >= MCE_BATTERY_OK;
}
static inline gboolean ril_devmon_ss_charging(MceCharger *charger)
{
return charger->valid && charger->state == MCE_CHARGER_ON;
}
static gboolean ril_devmon_ss_display_on(MceDisplay *display)
{
return display->valid && display->state != MCE_DISPLAY_STATE_OFF;
}
static void ril_devmon_ss_io_state_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("RIL_REQUEST_SCREEN_STATE is not supported");
self->screen_state_supported = FALSE;
}
}
static void ril_devmon_ss_io_send_screen_state(DevMonIo *self)
{
/*
* RIL_REQUEST_SCREEN_STATE (deprecated on 2017-01-10)
*
* ((int *)data)[0] is == 1 for "Screen On"
* ((int *)data)[0] is == 0 for "Screen Off"
*/
if (self->screen_state_supported) {
GRilIoRequest *req = grilio_request_array_int32_new(1,
self->display_on);
grilio_channel_cancel_request(self->io, self->req_id, FALSE);
self->req_id = grilio_channel_send_request_full(self->io, req,
RIL_REQUEST_SCREEN_STATE, ril_devmon_ss_io_state_sent,
NULL, self);
grilio_request_unref(req);
}
}
static void ril_devmon_ss_io_set_cell_info_update_interval(DevMonIo *self)
{
sailfish_cell_info_set_update_interval(self->cell_info,
(self->display_on && (ril_devmon_ss_charging(self->charger) ||
ril_devmon_ss_battery_ok(self->battery))) ?
RIL_CELL_INFO_INTERVAL_SHORT_MS :
RIL_CELL_INFO_INTERVAL_LONG_MS);
}
static void ril_devmon_ss_io_battery_cb(MceBattery *battery, void *user_data)
{
ril_devmon_ss_io_set_cell_info_update_interval(user_data);
}
static void ril_devmon_ss_io_charger_cb(MceCharger *charger, void *user_data)
{
ril_devmon_ss_io_set_cell_info_update_interval(user_data);
}
static void ril_devmon_ss_io_display_cb(MceDisplay *display, void *user_data)
{
DevMonIo *self = user_data;
const gboolean display_on = ril_devmon_ss_display_on(display);
if (self->display_on != display_on) {
self->display_on = display_on;
ril_devmon_ss_io_send_screen_state(self);
ril_devmon_ss_io_set_cell_info_update_interval(self);
}
}
static void ril_devmon_ss_io_free(struct ril_devmon_io *devmon_io)
{
DevMonIo *self = ril_devmon_ss_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_ss_start_io(struct ril_devmon *devmon,
GRilIoChannel *io, struct sailfish_cell_info *cell_info)
{
DevMon *ss = ril_devmon_ss_cast(devmon);
DevMonIo *self = g_new0(DevMonIo, 1);
self->pub.free = ril_devmon_ss_io_free;
self->screen_state_supported = TRUE;
self->io = grilio_channel_ref(io);
self->cell_info = sailfish_cell_info_ref(cell_info);
self->battery = mce_battery_ref(ss->battery);
self->battery_event_id[BATTERY_EVENT_VALID] =
mce_battery_add_valid_changed_handler(self->battery,
ril_devmon_ss_io_battery_cb, self);
self->battery_event_id[BATTERY_EVENT_STATUS] =
mce_battery_add_status_changed_handler(self->battery,
ril_devmon_ss_io_battery_cb, self);
self->charger = mce_charger_ref(ss->charger);
self->charger_event_id[CHARGER_EVENT_VALID] =
mce_charger_add_valid_changed_handler(self->charger,
ril_devmon_ss_io_charger_cb, self);
self->charger_event_id[CHARGER_EVENT_STATE] =
mce_charger_add_state_changed_handler(self->charger,
ril_devmon_ss_io_charger_cb, self);
self->display = mce_display_ref(ss->display);
self->display_on = ril_devmon_ss_display_on(self->display);
self->display_event_id[DISPLAY_EVENT_VALID] =
mce_display_add_valid_changed_handler(self->display,
ril_devmon_ss_io_display_cb, self);
self->display_event_id[DISPLAY_EVENT_STATE] =
mce_display_add_state_changed_handler(self->display,
ril_devmon_ss_io_display_cb, self);
ril_devmon_ss_io_send_screen_state(self);
ril_devmon_ss_io_set_cell_info_update_interval(self);
return &self->pub;
}
static void ril_devmon_ss_free(struct ril_devmon *devmon)
{
DevMon *self = ril_devmon_ss_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_ss_new()
{
DevMon *self = g_new0(DevMon, 1);
self->pub.free = ril_devmon_ss_free;
self->pub.start_io = ril_devmon_ss_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) 2015-2018 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
@@ -468,6 +468,7 @@ static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
gcd->activate.cb = cb;
gcd->activate.data = data;
gcd->activate.req = ril_data_call_setup(gcd->data, ctx,
__ofono_gprs_context_get_assigned_type(gc),
ril_gprs_context_activate_primary_cb, gcd);
}

View File

@@ -2,6 +2,7 @@
* oFono - Open Source Telephony - RIL-based devices
*
* 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
@@ -43,7 +44,15 @@ enum ril_modem_online_state {
GOING_OFFLINE
};
enum ril_modem_watch_event {
WATCH_IMSI,
WATCH_ICCID,
WATCH_SIM_STATE,
WATCH_EVENT_COUNT
};
struct ril_modem_online_request {
const char *name;
ofono_modem_online_cb_t cb;
struct ril_modem_data *md;
void *data;
@@ -58,7 +67,10 @@ struct ril_modem_data {
char *imeisv;
char *imei;
char *ecclist_file;
gulong imsi_event_id;
gulong watch_event_id[WATCH_EVENT_COUNT];
char* last_known_iccid;
char* reset_iccid;
guint online_check_id;
enum ril_modem_power_state power_state;
@@ -122,13 +134,8 @@ void ril_modem_delete(struct ril_modem *md)
}
}
static void ril_modem_online_request_ok(struct ril_modem_online_request *req)
static void ril_modem_online_request_done(struct ril_modem_online_request *req)
{
if (req->timeout_id) {
g_source_remove(req->timeout_id);
req->timeout_id = 0;
}
if (req->cb) {
struct ofono_error error;
ofono_modem_online_cb_t cb = req->cb;
@@ -136,21 +143,32 @@ static void ril_modem_online_request_ok(struct ril_modem_online_request *req)
req->cb = NULL;
req->data = NULL;
DBG_(req->md, "%s", req->name);
cb(ril_error_ok(&error), data);
}
}
static void ril_modem_online_request_ok(struct ril_modem_online_request *req)
{
if (req->timeout_id) {
g_source_remove(req->timeout_id);
req->timeout_id = 0;
}
ril_modem_online_request_done(req);
}
static void ril_modem_update_online_state(struct ril_modem_data *md)
{
switch (md->modem.radio->state) {
case RADIO_STATE_ON:
DBG("online");
DBG_(md, "online");
ril_modem_online_request_ok(&md->set_online);
break;
case RADIO_STATE_OFF:
case RADIO_STATE_UNAVAILABLE:
DBG("offline");
DBG_(md, "offline");
ril_modem_online_request_ok(&md->set_offline);
break;
@@ -170,17 +188,11 @@ static void ril_modem_update_online_state(struct ril_modem_data *md)
static gboolean ril_modem_online_request_timeout(gpointer data)
{
struct ril_modem_online_request *req = data;
struct ofono_error error;
ofono_modem_online_cb_t cb = req->cb;
void *cb_data = req->data;
GASSERT(req->timeout_id);
GASSERT(cb);
req->timeout_id = 0;
req->cb = NULL;
req->data = NULL;
cb(ril_error_failure(&error), cb_data);
DBG_(req->md, "%s", req->name);
ril_modem_online_request_done(req);
ril_modem_update_online_state(req->md);
return G_SOURCE_REMOVE;
@@ -242,6 +254,32 @@ static void ril_modem_imsi_cb(struct ofono_watch *watch, void *data)
ril_modem_update_radio_settings(md);
}
static void ril_modem_iccid_cb(struct ofono_watch *watch, void *data)
{
struct ril_modem_data *md = data;
GASSERT(md->watch == watch);
if (watch->iccid) {
g_free(md->last_known_iccid);
md->last_known_iccid = g_strdup(watch->iccid);
DBG_(md, "%s", md->last_known_iccid);
}
}
static void ril_modem_sim_state_cb(struct ofono_watch *watch, void *data)
{
struct ril_modem_data *md = data;
const enum ofono_sim_state state = ofono_sim_get_state(watch->sim);
GASSERT(md->watch == watch);
if (state == OFONO_SIM_STATE_RESETTING) {
g_free(md->reset_iccid);
md->reset_iccid = md->last_known_iccid;
md->last_known_iccid = NULL;
DBG_(md, "%s is resetting", md->reset_iccid);
}
}
static void ril_modem_pre_sim(struct ofono_modem *modem)
{
struct ril_modem_data *md = ril_modem_data_from_ofono(modem);
@@ -286,7 +324,13 @@ static void ril_modem_post_sim(struct ofono_modem *modem)
ofono_call_barring_create(modem, 0, RILMODEM_DRIVER, md);
ofono_message_waiting_register(ofono_message_waiting_create(modem));
if (md->modem.config.enable_stk) {
ofono_stk_create(modem, 0, RILMODEM_DRIVER, md);
if (!md->reset_iccid ||
g_strcmp0(md->reset_iccid, md->watch->iccid)) {
/* This SIM was never reset */
ofono_stk_create(modem, 0, RILMODEM_DRIVER, md);
} else {
ofono_warn("Disabling STK after SIM reset");
}
}
if (md->modem.config.enable_cbs) {
ofono_cbs_create(modem, 0, RILMODEM_DRIVER, md);
@@ -376,7 +420,7 @@ static void ril_modem_remove(struct ofono_modem *ofono)
ril_radio_unref(modem->radio);
ril_sim_settings_unref(modem->sim_settings);
ofono_watch_remove_handler(md->watch, md->imsi_event_id);
ofono_watch_remove_all_handlers(md->watch, md->watch_event_id);
ofono_watch_unref(md->watch);
if (md->online_check_id) {
@@ -398,6 +442,8 @@ static void ril_modem_remove(struct ofono_modem *ofono)
grilio_channel_unref(modem->io);
grilio_queue_cancel_all(md->q, FALSE);
grilio_queue_unref(md->q);
g_free(md->last_known_iccid);
g_free(md->reset_iccid);
g_free(md->ecclist_file);
g_free(md->log_prefix);
g_free(md->imeisv);
@@ -446,12 +492,21 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
modem->io = grilio_channel_ref(io);
md->q = grilio_queue_new(io);
md->watch = ofono_watch_new(path);
md->last_known_iccid = g_strdup(md->watch->iccid);
md->imsi_event_id =
md->watch_event_id[WATCH_IMSI] =
ofono_watch_add_imsi_changed_handler(md->watch,
ril_modem_imsi_cb, md);
md->watch_event_id[WATCH_ICCID] =
ofono_watch_add_iccid_changed_handler(md->watch,
ril_modem_iccid_cb, md);
md->watch_event_id[WATCH_SIM_STATE] =
ofono_watch_add_sim_state_changed_handler(md->watch,
ril_modem_sim_state_cb, md);
md->set_online.name = "online";
md->set_online.md = md;
md->set_offline.name = "offline";
md->set_offline.md = md;
ofono_modem_set_data(ofono, md);
err = ofono_modem_register(ofono);

View File

@@ -26,6 +26,7 @@
#include <grilio_parser.h>
#include <gutil_misc.h>
#include <gutil_macros.h>
#include <ofono/netreg.h>
#include <ofono/watch.h>
@@ -68,6 +69,20 @@ enum ril_network_watch_event {
WATCH_EVENT_COUNT
};
struct ril_network_data_profile {
enum ril_data_profile profile_id;
enum ril_profile_type type;
const char *apn;
const char *user;
const char *password;
enum ofono_gprs_auth_method auth_method;
enum ofono_gprs_proto proto;
int max_conns_time;
int max_conns;
int wait_time;
gboolean enabled;
};
struct ril_network_priv {
GRilIoChannel *io;
GRilIoQueue *q;
@@ -95,6 +110,10 @@ struct ril_network_priv {
gboolean set_initial_attach_apn;
struct ofono_network_operator operator;
gboolean assert_rat;
gboolean use_data_profiles;
int mms_data_profile_id;
GSList *data_profiles;
guint set_data_profiles_id;
};
enum ril_network_signal {
@@ -557,8 +576,7 @@ static void ril_network_set_initial_attach_apn(struct ril_network *self,
password = "";
}
req = ril_vendor_set_attach_apn_req(priv->vendor,
DATA_PROFILE_DEFAULT_STR, ctx->apn,
req = ril_vendor_set_attach_apn_req(priv->vendor,ctx->apn,
username, password, auth, proto);
if (!req) {
@@ -610,6 +628,191 @@ static void ril_network_check_initial_attach_apn(struct ril_network *self)
ril_network_try_set_initial_attach_apn(self);
}
struct ril_network_data_profile *ril_network_data_profile_new
(const struct ofono_gprs_primary_context* context,
enum ril_data_profile profile_id)
{
/* Allocate the whole thing as a single memory block */
struct ril_network_data_profile *profile;
const enum ofono_gprs_auth_method auth_method =
(context->username[0] || context->password[0]) ?
context->auth_method : OFONO_GPRS_AUTH_METHOD_NONE;
const gsize apn_size = strlen(context->apn) + 1;
gsize username_size = 0;
gsize password_size = 0;
gsize size = G_ALIGN8(sizeof(*profile)) + G_ALIGN8(apn_size);
char* ptr;
if (auth_method != OFONO_GPRS_AUTH_METHOD_NONE) {
username_size = strlen(context->username) + 1;
password_size = strlen(context->password) + 1;
size += G_ALIGN8(username_size) + G_ALIGN8(password_size);
}
ptr = g_malloc0(size);
profile = (struct ril_network_data_profile*)ptr;
ptr += G_ALIGN8(sizeof(*profile));
profile->profile_id = profile_id;
profile->type = RIL_PROFILE_3GPP;
profile->auth_method = auth_method;
profile->proto = context->proto;
profile->enabled = TRUE;
/* Copy strings */
profile->apn = ptr;
memcpy(ptr, context->apn, apn_size - 1);
ptr += G_ALIGN8(apn_size);
if (auth_method == OFONO_GPRS_AUTH_METHOD_NONE) {
profile->user = "";
profile->password = "";
} else {
profile->user = ptr;
memcpy(ptr, context->username, username_size - 1);
ptr += G_ALIGN8(username_size);
profile->password = ptr;
memcpy(ptr, context->password, password_size - 1);
}
return profile;
}
static gboolean ril_network_data_profile_equal
(const struct ril_network_data_profile *profile1,
const struct ril_network_data_profile *profile2)
{
if (profile1 == profile2) {
return TRUE;
} else if (!profile1 || !profile2) {
return FALSE;
} else {
return profile1->profile_id == profile2->profile_id &&
profile1->type == profile2->type &&
profile1->auth_method == profile2->auth_method &&
profile1->proto == profile2->proto &&
profile1->enabled == profile2->enabled &&
!g_strcmp0(profile1->apn, profile2->apn) &&
!g_strcmp0(profile1->user, profile2->user) &&
!g_strcmp0(profile1->password, profile2->password);
}
}
static gboolean ril_network_data_profiles_equal(GSList *list1, GSList *list2)
{
if (g_slist_length(list1) != g_slist_length(list2)) {
return FALSE;
} else {
GSList *l1 = list1;
GSList *l2 = list2;
while (l1 && l2) {
const struct ril_network_data_profile *p1 = l1->data;
const struct ril_network_data_profile *p2 = l2->data;
if (!ril_network_data_profile_equal(p1, p2)) {
return FALSE;
}
l1 = l1->next;
l2 = l2->next;
}
return TRUE;
}
}
static inline void ril_network_data_profiles_free(GSList *list)
{
/* Profiles are allocated as single memory blocks */
g_slist_free_full(list, g_free);
}
static void ril_network_set_data_profiles_done(GRilIoChannel *channel,
int status, const void *data, guint len, void *user_data)
{
struct ril_network *self = RIL_NETWORK(user_data);
struct ril_network_priv *priv = self->priv;
GASSERT(priv->set_data_profiles_id);
priv->set_data_profiles_id = 0;
}
static void ril_network_set_data_profiles(struct ril_network *self)
{
struct ril_network_priv *priv = self->priv;
GRilIoRequest *req = grilio_request_new();
GSList *l = priv->data_profiles;
grilio_request_append_int32(req, g_slist_length(l));
while (l) {
const struct ril_network_data_profile *p = l->data;
grilio_request_append_int32(req, p->profile_id);
grilio_request_append_utf8(req, p->apn);
grilio_request_append_utf8(req, ril_protocol_from_ofono
(p->proto));
grilio_request_append_int32(req, ril_auth_method_from_ofono
(p->auth_method));
grilio_request_append_utf8(req, p->user);
grilio_request_append_utf8(req, p->password);
grilio_request_append_int32(req, p->type);
grilio_request_append_int32(req, p->max_conns_time);
grilio_request_append_int32(req, p->max_conns);
grilio_request_append_int32(req, p->wait_time);
grilio_request_append_int32(req, p->enabled);
l = l->next;
}
grilio_queue_cancel_request(priv->q, priv->set_data_profiles_id, FALSE);
priv->set_data_profiles_id = grilio_queue_send_request_full(priv->q,
req, RIL_REQUEST_SET_DATA_PROFILE,
ril_network_set_data_profiles_done,
NULL, self);
grilio_request_unref(req);
}
static void ril_network_check_data_profiles(struct ril_network *self)
{
struct ril_network_priv *priv = self->priv;
struct ofono_gprs *gprs = priv->watch->gprs;
if (gprs) {
const struct ofono_gprs_primary_context* internet =
ofono_gprs_context_settings_by_type(gprs,
OFONO_GPRS_CONTEXT_TYPE_INTERNET);
const struct ofono_gprs_primary_context* mms =
ofono_gprs_context_settings_by_type(gprs,
OFONO_GPRS_CONTEXT_TYPE_MMS);
GSList *l = NULL;
if (internet) {
DBG_(self, "internet apn \"%s\"", internet->apn);
l = g_slist_append(l,
ril_network_data_profile_new(internet,
RIL_DATA_PROFILE_DEFAULT));
}
if (mms) {
DBG_(self, "mms apn \"%s\"", mms->apn);
l = g_slist_append(l,
ril_network_data_profile_new(mms,
priv->mms_data_profile_id));
}
if (ril_network_data_profiles_equal(priv->data_profiles, l)) {
ril_network_data_profiles_free(l);
} else {
ril_network_data_profiles_free(priv->data_profiles);
priv->data_profiles = l;
ril_network_set_data_profiles(self);
}
} else {
ril_network_data_profiles_free(priv->data_profiles);
priv->data_profiles = NULL;
}
}
static gboolean ril_network_can_set_pref_mode(struct ril_network *self)
{
struct ril_network_priv *priv = self->priv;
@@ -699,8 +902,10 @@ static void ril_network_check_pref_mode(struct ril_network *self,
gboolean immediate)
{
struct ril_network_priv *priv = self->priv;
const int rat = ril_network_mode_to_rat
(self, ril_network_actual_pref_mode(self));
const enum ofono_radio_access_mode expected_mode =
ril_network_actual_pref_mode(self);
const enum ofono_radio_access_mode current_mode =
ril_network_rat_to_mode(priv->rat);
if (priv->timer[TIMER_FORCE_CHECK_PREF_MODE]) {
ril_network_stop_timer(self, TIMER_FORCE_CHECK_PREF_MODE);
@@ -712,15 +917,19 @@ static void ril_network_check_pref_mode(struct ril_network *self,
immediate = TRUE;
}
if (priv->rat != rat) {
DBG_(self, "rat mode %d, expected %d", priv->rat, rat);
if (priv->rat >= 0 && current_mode != expected_mode) {
DBG_(self, "rat %d (%s), expected %s", priv->rat,
ofono_radio_access_mode_to_string(current_mode),
ofono_radio_access_mode_to_string(expected_mode));
}
if (immediate) {
ril_network_stop_timer(self, TIMER_SET_RAT_HOLDOFF);
}
if (priv->rat != rat || priv->assert_rat) {
if (current_mode != expected_mode || priv->assert_rat) {
const int rat = ril_network_mode_to_rat(self, expected_mode);
if (!priv->timer[TIMER_SET_RAT_HOLDOFF]) {
ril_network_set_pref_mode(self, rat);
} else {
@@ -968,6 +1177,9 @@ static void ril_network_watch_gprs_cb(struct ofono_watch *watch,
DBG_(self, "gprs %s", watch->gprs ? "appeared" : "is gone");
priv->set_initial_attach_apn = TRUE;
if (priv->use_data_profiles) {
ril_network_check_data_profiles(self);
}
ril_network_check_initial_attach_apn(self);
}
@@ -976,8 +1188,14 @@ static void ril_network_watch_gprs_settings_cb(struct ofono_watch *watch,
const struct ofono_gprs_primary_context *settings,
void *user_data)
{
struct ril_network *self = RIL_NETWORK(user_data);
struct ril_network_priv *priv = self->priv;
if (priv->use_data_profiles) {
ril_network_check_data_profiles(self);
}
if (type == OFONO_GPRS_CONTEXT_TYPE_INTERNET) {
struct ril_network *self = RIL_NETWORK(user_data);
struct ril_network_priv *priv = self->priv;
priv->set_initial_attach_apn = TRUE;
@@ -985,7 +1203,6 @@ static void ril_network_watch_gprs_settings_cb(struct ofono_watch *watch,
}
}
struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
const char *log_prefix, struct ril_radio *radio,
struct ril_sim_card *simcard,
@@ -1011,6 +1228,8 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
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->use_data_profiles = config->use_data_profiles;
priv->mms_data_profile_id = config->mms_data_profile_id;
/* Register listeners */
priv->unsol_event_id[UNSOL_EVENT_NETWORK_STATE] =
@@ -1062,6 +1281,9 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
ril_network_need_initial_attach_apn(self);
ril_vendor_set_network(vendor, self);
if (priv->use_data_profiles) {
ril_network_check_data_profiles(self);
}
ril_network_try_set_initial_attach_apn(self);
return self;
}
@@ -1120,6 +1342,7 @@ static void ril_network_finalize(GObject *object)
priv->settings_event_id);
ril_sim_settings_unref(self->settings);
ril_vendor_unref(priv->vendor);
g_slist_free_full(priv->data_profiles, g_free);
g_free(priv->log_prefix);
G_OBJECT_CLASS(ril_network_parent_class)->finalize(object);
}

View File

@@ -24,6 +24,7 @@
#include "ril_data.h"
#include "ril_util.h"
#include "ril_vendor.h"
#include "ril_devmon.h"
#include "ril_log.h"
#include <ofono/sailfish_manager.h>
@@ -35,7 +36,6 @@
#include <gutil_macros.h>
#include <gutil_misc.h>
#include <mce_display.h>
#include <mce_log.h>
#include <linux/capability.h>
@@ -87,6 +87,8 @@
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
#define RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0 TRUE
#define RILMODEM_DEFAULT_USE_DATA_PROFILES FALSE
#define RILMODEM_DEFAULT_MMS_DATA_PROFILE_ID RIL_DATA_PROFILE_IMS
#define RILMODEM_DEFAULT_SLOT_FLAGS SAILFISH_SLOT_NO_FLAGS
/* RIL socket transport name and parameters */
@@ -138,6 +140,9 @@
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
#define RILCONF_SINGLE_DATA_CONTEXT "singleDataContext"
#define RILCONF_NETWORK_SELECTION_MANUAL_0 "networkSelectionManual0"
#define RILCONF_USE_DATA_PROFILES "useDataProfiles"
#define RILCONF_MMS_DATA_PROFILE_ID "mmsDataProfileId"
#define RILCONF_DEVMON "deviceStateTracking"
/* Modem error ids */
#define RIL_ERROR_ID_RILD_RESTART "rild-restart"
@@ -151,12 +156,6 @@ enum ril_plugin_io_events {
IO_EVENT_COUNT
};
enum ril_plugin_display_events {
DISPLAY_EVENT_VALID,
DISPLAY_EVENT_STATE,
DISPLAY_EVENT_COUNT
};
enum ril_plugin_watch_events {
WATCH_EVENT_MODEM,
WATCH_EVENT_COUNT
@@ -168,6 +167,13 @@ enum ril_set_radio_cap_opt {
RIL_SET_RADIO_CAP_DISABLED
};
enum ril_devmon_opt {
RIL_DEVMON_NONE,
RIL_DEVMON_AUTO,
RIL_DEVMON_SS,
RIL_DEVMON_DS
};
struct ril_plugin_identity {
uid_t uid;
gid_t gid;
@@ -186,7 +192,6 @@ typedef struct sailfish_slot_manager_impl {
struct ril_plugin_settings settings;
gulong caps_manager_event_id;
guint start_timeout_id;
MceDisplay *display;
GSList *slots;
} ril_plugin;
@@ -222,9 +227,8 @@ typedef struct sailfish_slot_impl {
enum sailfish_slot_flags slot_flags;
guint start_timeout;
guint start_timeout_id;
MceDisplay *display;
gboolean display_on;
gulong display_event_id[DISPLAY_EVENT_COUNT];
struct ril_devmon *devmon;
struct ril_devmon_io *devmon_io;
GRilIoChannel *io;
gulong io_event_id[IO_EVENT_COUNT];
gulong sim_card_state_event_id;
@@ -254,10 +258,10 @@ GLOG_MODULE_DEFINE("rilmodem");
static const char ril_debug_trace_name[] = "ril_trace";
static GLogModule ril_debug_trace_module = {
.name = ril_debug_trace_name,
.max_level = GLOG_LEVEL_VERBOSE,
.level = GLOG_LEVEL_VERBOSE,
.flags = GLOG_FLAG_HIDE_NAME
.name = ril_debug_trace_name,
.max_level = GLOG_LEVEL_VERBOSE,
.level = GLOG_LEVEL_VERBOSE,
.flags = GLOG_FLAG_HIDE_NAME
};
static struct ofono_debug_desc ril_debug_trace OFONO_DEBUG_ATTR = {
@@ -336,41 +340,6 @@ static void ril_plugin_foreach_slot_manager(struct sailfish_slot_driver_reg *r,
ril_plugin_foreach_slot_manager_proc, fn);
}
static void ril_plugin_send_screen_state(ril_slot *slot)
{
if (slot->io && slot->io->connected) {
/**
* RIL_REQUEST_SCREEN_STATE (deprecated on 2017-01-10)
*
* ((int *)data)[0] is == 1 for "Screen On"
* ((int *)data)[0] is == 0 for "Screen Off"
*/
GRilIoRequest *req = grilio_request_array_int32_new(1,
slot->display_on);
grilio_channel_send_request(slot->io, req,
RIL_REQUEST_SCREEN_STATE);
grilio_request_unref(req);
}
}
static gboolean ril_plugin_display_on(MceDisplay *display)
{
return display && display->valid &&
display->state != MCE_DISPLAY_STATE_OFF;
}
static void ril_plugin_display_cb(MceDisplay *display, void *user_data)
{
ril_slot *slot = user_data;
const gboolean display_was_on = slot->display_on;
slot->display_on = ril_plugin_display_on(display);
if (slot->display_on != display_was_on) {
ril_plugin_send_screen_state(slot);
}
}
static void ril_plugin_remove_slot_handler(ril_slot *slot, int id)
{
GASSERT(id >= 0 && id<IO_EVENT_COUNT);
@@ -396,6 +365,11 @@ static void ril_plugin_shutdown_slot(ril_slot *slot, gboolean kill_io)
slot->retry_id = 0;
}
if (slot->devmon_io) {
ril_devmon_io_free(slot->devmon_io);
slot->devmon_io = NULL;
}
if (slot->cell_info) {
sailfish_cell_info_unref(slot->cell_info);
slot->cell_info = NULL;
@@ -934,13 +908,6 @@ static void ril_plugin_manager_started(ril_plugin *plugin)
{
ril_plugin_drop_orphan_slots(plugin);
sailfish_slot_manager_started(plugin->handle);
/*
* We no longer need this MceDisplay reference, the slots
* (if there are any) are holding references of their own.
*/
mce_display_unref(plugin->display);
plugin->display = NULL;
}
static void ril_plugin_all_slots_started_cb(ril_slot *slot, void *param)
@@ -1027,7 +994,7 @@ static void ril_plugin_slot_connected(ril_slot *slot)
GASSERT(!slot->cell_info);
if (slot->io->ril_version >= 9) {
slot->cell_info = ril_cell_info_new(slot->io, log_prefix,
slot->display, slot->radio, slot->sim_card);
slot->radio, slot->sim_card);
}
GASSERT(!slot->caps);
@@ -1041,6 +1008,12 @@ static void ril_plugin_slot_connected(ril_slot *slot)
ril_plugin_radio_caps_cb, slot);
}
GASSERT(!slot->devmon_io);
if (slot->devmon) {
slot->devmon_io = ril_devmon_start_io(slot->devmon,
slot->io, slot->cell_info);
}
if (!slot->handle) {
GASSERT(plugin->start_timeout_id);
GASSERT(slot->start_timeout_id);
@@ -1055,12 +1028,12 @@ static void ril_plugin_slot_connected(ril_slot *slot)
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);
}
ril_plugin_send_screen_state(slot);
ril_plugin_check_modem(slot);
ril_plugin_check_ready(slot);
}
@@ -1164,10 +1137,9 @@ static void ril_slot_free(ril_slot *slot)
DBG("%s", slot->path);
ril_plugin_shutdown_slot(slot, TRUE);
plugin->slots = g_slist_remove(plugin->slots, slot);
mce_display_remove_all_handlers(slot->display, slot->display_event_id);
mce_display_unref(slot->display);
ofono_watch_remove_all_handlers(slot->watch, slot->watch_event_id);
ofono_watch_unref(slot->watch);
ril_devmon_free(slot->devmon);
ril_sim_settings_unref(slot->sim_settings);
gutil_ints_unref(slot->config.local_hangup_reasons);
gutil_ints_unref(slot->config.remote_hangup_reasons);
@@ -1220,6 +1192,8 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE;
config->network_selection_manual_0 =
RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0;
config->use_data_profiles = RILMODEM_DEFAULT_USE_DATA_PROFILES;
config->mms_data_profile_id = RILMODEM_DEFAULT_MMS_DATA_PROFILE_ID;
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
slot->slot_flags = RILMODEM_DEFAULT_SLOT_FLAGS;
@@ -1232,15 +1206,7 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
slot->data_opt.data_call_retry_delay_ms =
RILMODEM_DEFAULT_DATA_CALL_RETRY_DELAY;
slot->display = mce_display_new();
slot->display_on = ril_plugin_display_on(slot->display);
slot->display_event_id[DISPLAY_EVENT_VALID] =
mce_display_add_valid_changed_handler(slot->display,
ril_plugin_display_cb, slot);
slot->display_event_id[DISPLAY_EVENT_STATE] =
mce_display_add_state_changed_handler(slot->display,
ril_plugin_display_cb, slot);
slot->devmon = ril_devmon_auto_new();
slot->watch = ofono_watch_new(dbus_path);
slot->watch_event_id[WATCH_EVENT_MODEM] =
ofono_watch_add_modem_changed_handler(slot->watch,
@@ -1260,6 +1226,8 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
defaults.enable_cbs = config->enable_cbs;
defaults.enable_stk = config->enable_stk;
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.query_available_band_mode =
config->query_available_band_mode;
@@ -1268,6 +1236,8 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
config->enable_cbs = defaults.enable_cbs;
config->enable_stk = defaults.enable_stk;
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->query_available_band_mode =
defaults.query_available_band_mode;
}
@@ -1496,6 +1466,21 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
config->network_selection_manual_0 ? "yes" : "no");
}
/* useDataProfiles */
if (ril_config_get_boolean(file, group, RILCONF_USE_DATA_PROFILES,
&config->use_data_profiles)) {
DBG("%s: " RILCONF_USE_DATA_PROFILES " %s", group,
config->use_data_profiles ? "yes" : "no");
}
/* mmsDataProfileId */
if (ril_config_get_integer(file, group, RILCONF_MMS_DATA_PROFILE_ID,
&ival) && ival >= 0) {
config->mms_data_profile_id = ival;
DBG("%s: " RILCONF_MMS_DATA_PROFILE_ID " %u", group,
config->mms_data_profile_id);
}
/* technologies */
strv = ril_config_get_strings(file, group, RILCONF_TECHNOLOGIES, ',');
if (strv) {
@@ -1675,6 +1660,27 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
slot->legacy_imei_query ? "on" : "off");
}
/* deviceStateTracking */
if (ril_config_get_enum(file, group, RILCONF_DEVMON, &ival,
"none", RIL_DEVMON_NONE,
"auto", RIL_DEVMON_AUTO,
"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);
}
}
return slot;
}
@@ -2016,13 +2022,6 @@ static ril_plugin *ril_plugin_manager_create(struct sailfish_slot_manager *m)
struct ril_plugin_settings *ps = &plugin->settings;
DBG("");
/*
* Create the MCE client instance early so that connection
* to the system bus gets established before we switch the
* identity.
*/
plugin->display = mce_display_new();
plugin->handle = m;
ril_plugin_parse_identity(&ps->identity, RILMODEM_DEFAULT_IDENTITY);
ps->dm_flags = RILMODEM_DEFAULT_DM_FLAGS;
@@ -2090,7 +2089,6 @@ static void ril_plugin_manager_free(ril_plugin *plugin)
{
if (plugin) {
GASSERT(!plugin->slots);
mce_display_unref(plugin->display);
ril_data_manager_unref(plugin->data_manager);
ril_radio_caps_manager_remove_handler(plugin->caps_manager,
plugin->caps_manager_event_id);
@@ -2111,7 +2109,9 @@ static void ril_slot_enabled_changed(struct sailfish_slot_impl *s)
{
if (s->handle->enabled) {
ril_plugin_check_modem(s);
grilio_channel_set_enabled(s->io, TRUE);
} else {
grilio_channel_set_enabled(s->io, FALSE);
ril_plugin_shutdown_slot(s, FALSE);
}
}

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2017 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
@@ -411,6 +411,11 @@ struct ril_radio *ril_radio_new(GRilIoChannel *io)
priv->state_event_id = grilio_channel_add_unsol_event_handler(priv->io,
ril_radio_state_changed,
RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, self);
/*
* Some RILs like to receive power off request at startup even if
* radio is already off. Make those happy.
*/
ril_radio_submit_power_request(self, FALSE);
return self;
}

View File

@@ -264,3 +264,29 @@ socket=/dev/socket/rild
# Default true
#
#networkSelectionManual0=true
# Enables use of SET_DATA_PROFILE requests. Everything used to work without
# profiles, that's why it's disabled by default.
#
# Default false
#
#useDataProfiles=false
# Configures MMS data profile ID. Must be non-zero.
# This option is ignored if useDataProfiles is false.
#
# Default 2 (RIL_DATA_PROFILE_IMS)
#
#mmsDataProfileId=2
# Configures device state tracking (basically, power saving strategy).
# Possible values are:
#
# 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
# none = Disable device state management
#
# Default auto
#
#deviceStateTracking=auto

View File

@@ -62,6 +62,8 @@ struct ril_slot_config {
gboolean enable_cbs;
gboolean enable_stk;
gboolean network_selection_manual_0;
gboolean use_data_profiles;
guint mms_data_profile_id;
GUtilInts *local_hangup_reasons;
GUtilInts *remote_hangup_reasons;
};

View File

@@ -239,6 +239,18 @@ const char *ril_request_to_string(guint request)
RIL_REQUEST_(SHUTDOWN);
RIL_REQUEST_(GET_RADIO_CAPABILITY);
RIL_REQUEST_(SET_RADIO_CAPABILITY);
RIL_REQUEST_(START_LCE);
RIL_REQUEST_(STOP_LCE);
RIL_REQUEST_(GET_ACTIVITY_INFO);
RIL_REQUEST_(GET_CARRIER_RESTRICTIONS);
RIL_REQUEST_(SEND_DEVICE_STATE);
RIL_REQUEST_(SET_UNSOLICITED_RESPONSE_FILTER);
RIL_REQUEST_(SET_SIM_CARD_POWER);
RIL_REQUEST_(SET_CARRIER_INFO_IMSI_ENCRYPTION);
RIL_REQUEST_(START_NETWORK_SCAN);
RIL_REQUEST_(STOP_NETWORK_SCAN);
RIL_REQUEST_(START_KEEPALIVE);
RIL_REQUEST_(STOP_KEEPALIVE);
case RIL_RESPONSE_ACKNOWLEDGEMENT:
return "RESPONSE_ACK";
default:

View File

@@ -90,18 +90,17 @@ void ril_vendor_set_network(RilVendor *self, struct ril_network *nw)
}
}
GRilIoRequest *ril_vendor_set_attach_apn_req(RilVendor *self,
const char *profile, const char *apn,
const char *username, const char *password,
GRilIoRequest *ril_vendor_set_attach_apn_req(RilVendor *self, const char *apn,
const char *user, const char *password,
enum ril_auth auth, const char *proto)
{
return G_LIKELY(self) ? RIL_VENDOR_GET_CLASS(self)->
set_attach_apn_req(self, profile, apn, username, password,
auth, proto) : NULL;
set_attach_apn_req(self, apn, user, password, auth, proto) :
NULL;
}
GRilIoRequest *ril_vendor_data_call_req(RilVendor *self,
int tech, const char *profile, const char *apn,
GRilIoRequest *ril_vendor_data_call_req(RilVendor *self, int tech,
enum ril_data_profile profile, const char *apn,
const char *username, const char *password,
enum ril_auth auth, const char *proto)
{
@@ -139,16 +138,16 @@ static const char *ril_vendor_default_id_to_string(RilVendor *self, guint id)
}
static GRilIoRequest *ril_vendor_default_set_attach_apn_req(RilVendor *self,
const char *profile, const char *apn,
const char *username, const char *password,
enum ril_auth auth, const char *proto)
const char *apn, const char *username,
const char *password, enum ril_auth auth,
const char *proto)
{
return NULL;
}
static GRilIoRequest *ril_vendor_default_data_call_req(RilVendor *self,
int tech, const char *profile, const char *apn,
const char *username, const char *password,
int tech, enum ril_data_profile profile,
const char *apn, const char *user, const char *passwd,
enum ril_auth auth, const char *proto)
{
return NULL;

View File

@@ -24,6 +24,8 @@ struct ril_vendor_defaults {
gboolean enable_cbs;
gboolean enable_stk;
gboolean query_available_band_mode;
gboolean use_data_profiles;
guint mms_data_profile_id;
};
struct ril_vendor_driver {
@@ -51,11 +53,11 @@ const char *ril_vendor_event_to_string(struct ril_vendor *vendor,
guint event);
void ril_vendor_set_network(struct ril_vendor *vendor, struct ril_network *nw);
GRilIoRequest *ril_vendor_set_attach_apn_req(struct ril_vendor *vendor,
const char *profile, const char *apn,
const char *username, const char *password,
enum ril_auth auth, const char *proto);
GRilIoRequest *ril_vendor_data_call_req(struct ril_vendor *vendor,
int tech, const char *profile, const char *apn,
const char *apn, const char *username,
const char *password, enum ril_auth auth,
const char *proto);
GRilIoRequest *ril_vendor_data_call_req(struct ril_vendor *vendor, int tech,
enum ril_data_profile profile, const char *apn,
const char *username, const char *password,
enum ril_auth auth, const char *proto);
gboolean ril_vendor_data_call_parse(struct ril_vendor *vendor,

View File

@@ -32,11 +32,11 @@ typedef struct ril_vendor_class {
const char *(*request_to_string)(RilVendor *vendor, guint request);
const char *(*event_to_string)(RilVendor *vendor, guint event);
GRilIoRequest *(*set_attach_apn_req)(RilVendor *vendor,
const char *profile, const char *apn,
const char *username, const char *password,
enum ril_auth auth, const char *proto);
GRilIoRequest *(*data_call_req)(RilVendor *vendor,
int tech, const char *profile, const char *apn,
const char *apn, const char *username,
const char *password, enum ril_auth auth,
const char *proto);
GRilIoRequest *(*data_call_req)(RilVendor *vendor, int tech,
enum ril_data_profile profile, const char *apn,
const char *username, const char *password,
enum ril_auth auth, const char *proto);
gboolean (*data_call_parse)(RilVendor *vendor,

View File

@@ -323,8 +323,8 @@ static void ril_vendor_mtk_incoming_call_indication(GRilIoChannel *io, guint id,
}
}
static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor,
int tech, const char *profile, const char *apn,
static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor, int tech,
enum ril_data_profile profile, const char *apn,
const char *username, const char *password,
enum ril_auth auth, const char *proto)
{
@@ -333,7 +333,7 @@ static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor,
grilio_request_append_int32(req, 8); /* Number of parameters */
grilio_request_append_format(req, "%d", tech);
grilio_request_append_utf8(req, profile);
grilio_request_append_format(req, "%d", profile);
grilio_request_append_utf8(req, apn);
grilio_request_append_utf8(req, username);
grilio_request_append_utf8(req, password);
@@ -344,8 +344,7 @@ static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor,
}
static GRilIoRequest *ril_vendor_mtk_set_attach_apn_req(RilVendor *vendor,
const char *profile, const char *apn,
const char *user, const char *pass,
const char *apn, const char *user, const char *pass,
enum ril_auth auth, const char *prot)
{
RilVendorMtk *self = RIL_VENDOR_MTK(vendor);

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2018 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
@@ -704,13 +704,18 @@ static void ril_voicecall_supp_svc_notification_event(GRilIoChannel *io,
phone.number[0] = 0;
}
DBG("RIL data: MT/MO: %i, code: %i, index: %i", type, code, index);
DBG("RIL data: MT/MO: %d, code: %d, index: %d", type, code, index);
/* 0 stands for MO intermediate (support TBD), 1 for MT unsolicited */
if (type == 1) {
switch (type) {
case 0: /* MO intermediate result code */
ofono_voicecall_ssn_mo_notify(vd->vc, 0, code, index);
break;
case 1: /* MT unsolicited result code */
ofono_voicecall_ssn_mt_notify(vd->vc, 0, code, index, &phone);
} else {
break;
default:
ofono_error("Unknown SS notification");
break;
}
}

View File

@@ -84,190 +84,205 @@ enum ril_status {
};
/* RIL Request Messages, ofono -> rild */
#define RIL_REQUEST_GET_SIM_STATUS 1
#define RIL_REQUEST_ENTER_SIM_PIN 2
#define RIL_REQUEST_ENTER_SIM_PUK 3
#define RIL_REQUEST_ENTER_SIM_PIN2 4
#define RIL_REQUEST_ENTER_SIM_PUK2 5
#define RIL_REQUEST_CHANGE_SIM_PIN 6
#define RIL_REQUEST_CHANGE_SIM_PIN2 7
#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8
#define RIL_REQUEST_GET_CURRENT_CALLS 9
#define RIL_REQUEST_DIAL 10
#define RIL_REQUEST_GET_IMSI 11
#define RIL_REQUEST_HANGUP 12
#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13
#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14
#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15
#define RIL_REQUEST_CONFERENCE 16
#define RIL_REQUEST_UDUB 17
#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18
#define RIL_REQUEST_SIGNAL_STRENGTH 19
#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20
#define RIL_REQUEST_DATA_REGISTRATION_STATE 21
#define RIL_REQUEST_OPERATOR 22
#define RIL_REQUEST_RADIO_POWER 23
#define RIL_REQUEST_DTMF 24
#define RIL_REQUEST_SEND_SMS 25
#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26
#define RIL_REQUEST_SETUP_DATA_CALL 27
#define RIL_REQUEST_SIM_IO 28
#define RIL_REQUEST_SEND_USSD 29
#define RIL_REQUEST_CANCEL_USSD 30
#define RIL_REQUEST_GET_CLIR 31
#define RIL_REQUEST_SET_CLIR 32
#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33
#define RIL_REQUEST_SET_CALL_FORWARD 34
#define RIL_REQUEST_QUERY_CALL_WAITING 35
#define RIL_REQUEST_SET_CALL_WAITING 36
#define RIL_REQUEST_SMS_ACKNOWLEDGE 37
#define RIL_REQUEST_GET_IMEI 38
#define RIL_REQUEST_GET_IMEISV 39
#define RIL_REQUEST_ANSWER 40
#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41
#define RIL_REQUEST_QUERY_FACILITY_LOCK 42
#define RIL_REQUEST_SET_FACILITY_LOCK 43
#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44
#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45
#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46
#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47
#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48
#define RIL_REQUEST_DTMF_START 49
#define RIL_REQUEST_DTMF_STOP 50
#define RIL_REQUEST_BASEBAND_VERSION 51
#define RIL_REQUEST_SEPARATE_CONNECTION 52
#define RIL_REQUEST_SET_MUTE 53
#define RIL_REQUEST_GET_MUTE 54
#define RIL_REQUEST_QUERY_CLIP 55
#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56
#define RIL_REQUEST_DATA_CALL_LIST 57
#define RIL_REQUEST_RESET_RADIO 58
#define RIL_REQUEST_OEM_HOOK_RAW 59
#define RIL_REQUEST_OEM_HOOK_STRINGS 60
#define RIL_REQUEST_SCREEN_STATE 61
#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62
#define RIL_REQUEST_WRITE_SMS_TO_SIM 63
#define RIL_REQUEST_DELETE_SMS_ON_SIM 64
#define RIL_REQUEST_SET_BAND_MODE 65
#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66
#define RIL_REQUEST_STK_GET_PROFILE 67
#define RIL_REQUEST_STK_SET_PROFILE 68
#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69
#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70
#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71
#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72
#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73
#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74
#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75
#define RIL_REQUEST_SET_LOCATION_UPDATES 76
#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77
#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78
#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79
#define RIL_REQUEST_SET_TTY_MODE 80
#define RIL_REQUEST_QUERY_TTY_MODE 81
#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82
#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83
#define RIL_REQUEST_CDMA_FLASH 84
#define RIL_REQUEST_CDMA_BURST_DTMF 85
#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86
#define RIL_REQUEST_CDMA_SEND_SMS 87
#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88
#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89
#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90
#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91
#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92
#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93
#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94
#define RIL_REQUEST_CDMA_SUBSCRIPTION 95
#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96
#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97
#define RIL_REQUEST_DEVICE_IDENTITY 98
#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99
#define RIL_REQUEST_GET_SMSC_ADDRESS 100
#define RIL_REQUEST_SET_SMSC_ADDRESS 101
#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102
#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103
#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104
#define RIL_REQUEST_ISIM_AUTHENTICATION 105
#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106
#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107
#define RIL_REQUEST_VOICE_RADIO_TECH 108
#define RIL_REQUEST_GET_CELL_INFO_LIST 109
#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110
#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111
#define RIL_REQUEST_IMS_REGISTRATION_STATE 112
#define RIL_REQUEST_IMS_SEND_SMS 113
#define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114
#define RIL_REQUEST_SIM_OPEN_CHANNEL 115
#define RIL_REQUEST_SIM_CLOSE_CHANNEL 116
#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117
#define RIL_REQUEST_NV_READ_ITEM 118
#define RIL_REQUEST_NV_WRITE_ITEM 119
#define RIL_REQUEST_NV_WRITE_CDMA_PRL 120
#define RIL_REQUEST_NV_RESET_CONFIG 121
/* SET_UICC_SUBSCRIPTION was 115 in v9 and 122 in v10 and later */
#define RIL_REQUEST_V9_SET_UICC_SUBSCRIPTION 115
#define RIL_REQUEST_SET_UICC_SUBSCRIPTION 122
#define RIL_REQUEST_ALLOW_DATA 123
#define RIL_REQUEST_GET_HARDWARE_CONFIG 124
#define RIL_REQUEST_SIM_AUTHENTICATION 125
#define RIL_REQUEST_GET_DC_RT_INFO 126
#define RIL_REQUEST_SET_DC_RT_INFO_RATE 127
#define RIL_REQUEST_SET_DATA_PROFILE 128
#define RIL_REQUEST_SHUTDOWN 129
#define RIL_REQUEST_GET_RADIO_CAPABILITY 130
#define RIL_REQUEST_SET_RADIO_CAPABILITY 131
enum ril_request {
RIL_REQUEST_GET_SIM_STATUS = 1,
RIL_REQUEST_ENTER_SIM_PIN = 2,
RIL_REQUEST_ENTER_SIM_PUK = 3,
RIL_REQUEST_ENTER_SIM_PIN2 = 4,
RIL_REQUEST_ENTER_SIM_PUK2 = 5,
RIL_REQUEST_CHANGE_SIM_PIN = 6,
RIL_REQUEST_CHANGE_SIM_PIN2 = 7,
RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION = 8,
RIL_REQUEST_GET_CURRENT_CALLS = 9,
RIL_REQUEST_DIAL = 10,
RIL_REQUEST_GET_IMSI = 11,
RIL_REQUEST_HANGUP = 12,
RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND = 13,
RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND = 14,
RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE = 15,
RIL_REQUEST_CONFERENCE = 16,
RIL_REQUEST_UDUB = 17,
RIL_REQUEST_LAST_CALL_FAIL_CAUSE = 18,
RIL_REQUEST_SIGNAL_STRENGTH = 19,
RIL_REQUEST_VOICE_REGISTRATION_STATE = 20,
RIL_REQUEST_DATA_REGISTRATION_STATE = 21,
RIL_REQUEST_OPERATOR = 22,
RIL_REQUEST_RADIO_POWER = 23,
RIL_REQUEST_DTMF = 24,
RIL_REQUEST_SEND_SMS = 25,
RIL_REQUEST_SEND_SMS_EXPECT_MORE = 26,
RIL_REQUEST_SETUP_DATA_CALL = 27,
RIL_REQUEST_SIM_IO = 28,
RIL_REQUEST_SEND_USSD = 29,
RIL_REQUEST_CANCEL_USSD = 30,
RIL_REQUEST_GET_CLIR = 31,
RIL_REQUEST_SET_CLIR = 32,
RIL_REQUEST_QUERY_CALL_FORWARD_STATUS = 33,
RIL_REQUEST_SET_CALL_FORWARD = 34,
RIL_REQUEST_QUERY_CALL_WAITING = 35,
RIL_REQUEST_SET_CALL_WAITING = 36,
RIL_REQUEST_SMS_ACKNOWLEDGE = 37,
RIL_REQUEST_GET_IMEI = 38,
RIL_REQUEST_GET_IMEISV = 39,
RIL_REQUEST_ANSWER = 40,
RIL_REQUEST_DEACTIVATE_DATA_CALL = 41,
RIL_REQUEST_QUERY_FACILITY_LOCK = 42,
RIL_REQUEST_SET_FACILITY_LOCK = 43,
RIL_REQUEST_CHANGE_BARRING_PASSWORD = 44,
RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE = 45,
RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC = 46,
RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL = 47,
RIL_REQUEST_QUERY_AVAILABLE_NETWORKS = 48,
RIL_REQUEST_DTMF_START = 49,
RIL_REQUEST_DTMF_STOP = 50,
RIL_REQUEST_BASEBAND_VERSION = 51,
RIL_REQUEST_SEPARATE_CONNECTION = 52,
RIL_REQUEST_SET_MUTE = 53,
RIL_REQUEST_GET_MUTE = 54,
RIL_REQUEST_QUERY_CLIP = 55,
RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE = 56,
RIL_REQUEST_DATA_CALL_LIST = 57,
RIL_REQUEST_RESET_RADIO = 58,
RIL_REQUEST_OEM_HOOK_RAW = 59,
RIL_REQUEST_OEM_HOOK_STRINGS = 60,
RIL_REQUEST_SCREEN_STATE = 61,
RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION = 62,
RIL_REQUEST_WRITE_SMS_TO_SIM = 63,
RIL_REQUEST_DELETE_SMS_ON_SIM = 64,
RIL_REQUEST_SET_BAND_MODE = 65,
RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE = 66,
RIL_REQUEST_STK_GET_PROFILE = 67,
RIL_REQUEST_STK_SET_PROFILE = 68,
RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND = 69,
RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE = 70,
RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM = 71,
RIL_REQUEST_EXPLICIT_CALL_TRANSFER = 72,
RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE = 73,
RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE = 74,
RIL_REQUEST_GET_NEIGHBORING_CELL_IDS = 75,
RIL_REQUEST_SET_LOCATION_UPDATES = 76,
RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE = 77,
RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE = 78,
RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE = 79,
RIL_REQUEST_SET_TTY_MODE = 80,
RIL_REQUEST_QUERY_TTY_MODE = 81,
RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE = 82,
RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE = 83,
RIL_REQUEST_CDMA_FLASH = 84,
RIL_REQUEST_CDMA_BURST_DTMF = 85,
RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY = 86,
RIL_REQUEST_CDMA_SEND_SMS = 87,
RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE = 88,
RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG = 89,
RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG = 90,
RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION = 91,
RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG = 92,
RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG = 93,
RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION = 94,
RIL_REQUEST_CDMA_SUBSCRIPTION = 95,
RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM = 96,
RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM = 97,
RIL_REQUEST_DEVICE_IDENTITY = 98,
RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE = 99,
RIL_REQUEST_GET_SMSC_ADDRESS = 100,
RIL_REQUEST_SET_SMSC_ADDRESS = 101,
RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102,
RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103,
RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104,
RIL_REQUEST_ISIM_AUTHENTICATION = 105,
RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106,
RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107,
RIL_REQUEST_VOICE_RADIO_TECH = 108,
RIL_REQUEST_GET_CELL_INFO_LIST = 109,
RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE = 110,
RIL_REQUEST_SET_INITIAL_ATTACH_APN = 111,
RIL_REQUEST_IMS_REGISTRATION_STATE = 112,
RIL_REQUEST_IMS_SEND_SMS = 113,
RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC = 114,
RIL_REQUEST_SIM_OPEN_CHANNEL = 115,
RIL_REQUEST_SIM_CLOSE_CHANNEL = 116,
RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL = 117,
RIL_REQUEST_NV_READ_ITEM = 118,
RIL_REQUEST_NV_WRITE_ITEM = 119,
RIL_REQUEST_NV_WRITE_CDMA_PRL = 120,
RIL_REQUEST_NV_RESET_CONFIG = 121,
/* SET_UICC_SUBSCRIPTION was 115 in v9 and 122 in v10 and later */
RIL_REQUEST_V9_SET_UICC_SUBSCRIPTION = 115,
RIL_REQUEST_SET_UICC_SUBSCRIPTION = 122,
RIL_REQUEST_ALLOW_DATA = 123,
RIL_REQUEST_GET_HARDWARE_CONFIG = 124,
RIL_REQUEST_SIM_AUTHENTICATION = 125,
RIL_REQUEST_GET_DC_RT_INFO = 126,
RIL_REQUEST_SET_DC_RT_INFO_RATE = 127,
RIL_REQUEST_SET_DATA_PROFILE = 128,
RIL_REQUEST_SHUTDOWN = 129,
RIL_REQUEST_GET_RADIO_CAPABILITY = 130,
RIL_REQUEST_SET_RADIO_CAPABILITY = 131,
RIL_REQUEST_START_LCE = 132,
RIL_REQUEST_STOP_LCE = 133,
RIL_REQUEST_GET_ACTIVITY_INFO = 135,
RIL_REQUEST_GET_CARRIER_RESTRICTIONS = 137,
RIL_REQUEST_SEND_DEVICE_STATE = 138,
RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER = 139,
RIL_REQUEST_SET_SIM_CARD_POWER = 140,
RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION = 141,
RIL_REQUEST_START_NETWORK_SCAN = 142,
RIL_REQUEST_STOP_NETWORK_SCAN = 143,
RIL_REQUEST_START_KEEPALIVE = 144,
RIL_REQUEST_STOP_KEEPALIVE = 145,
/* A special message, not really a request */
RIL_RESPONSE_ACKNOWLEDGEMENT = 800
};
/* RIL Unsolicited Messages, rild -> ofono */
#define RIL_UNSOL_RESPONSE_BASE 1000
#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000
#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001
#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002
#define RIL_UNSOL_RESPONSE_NEW_SMS 1003
#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004
#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005
#define RIL_UNSOL_ON_USSD 1006
#define RIL_UNSOL_ON_USSD_REQUEST 1007
#define RIL_UNSOL_NITZ_TIME_RECEIVED 1008
#define RIL_UNSOL_SIGNAL_STRENGTH 1009
#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010
#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011
#define RIL_UNSOL_STK_SESSION_END 1012
#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013
#define RIL_UNSOL_STK_EVENT_NOTIFY 1014
#define RIL_UNSOL_STK_CALL_SETUP 1015
#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016
#define RIL_UNSOL_SIM_REFRESH 1017
#define RIL_UNSOL_CALL_RING 1018
#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019
#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020
#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021
#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022
#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023
#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024
#define RIL_UNSOL_CDMA_CALL_WAITING 1025
#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026
#define RIL_UNSOL_CDMA_INFO_REC 1027
#define RIL_UNSOL_OEM_HOOK_RAW 1028
#define RIL_UNSOL_RINGBACK_TONE 1029
#define RIL_UNSOL_RESEND_INCALL_MUTE 1030
#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031
#define RIL_UNSOL_CDMA_PRL_CHANGED 1032
#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033
#define RIL_UNSOL_RIL_CONNECTED 1034
#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035
#define RIL_UNSOL_CELL_INFO_LIST 1036
#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038
#define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039
#define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040
#define RIL_UNSOL_DC_RT_INFO_CHANGED 1041
#define RIL_UNSOL_RADIO_CAPABILITY 1042
#define RIL_UNSOL_ON_SS 1043
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044
/* A special request, ofono -> rild */
#define RIL_RESPONSE_ACKNOWLEDGEMENT 800
enum ril_unsol {
RIL_UNSOL_RESPONSE_BASE = 1000,
RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000,
RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001,
RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002,
RIL_UNSOL_RESPONSE_NEW_SMS = 1003,
RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004,
RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005,
RIL_UNSOL_ON_USSD = 1006,
RIL_UNSOL_ON_USSD_REQUEST = 1007,
RIL_UNSOL_NITZ_TIME_RECEIVED = 1008,
RIL_UNSOL_SIGNAL_STRENGTH = 1009,
RIL_UNSOL_DATA_CALL_LIST_CHANGED = 1010,
RIL_UNSOL_SUPP_SVC_NOTIFICATION = 1011,
RIL_UNSOL_STK_SESSION_END = 1012,
RIL_UNSOL_STK_PROACTIVE_COMMAND = 1013,
RIL_UNSOL_STK_EVENT_NOTIFY = 1014,
RIL_UNSOL_STK_CALL_SETUP = 1015,
RIL_UNSOL_SIM_SMS_STORAGE_FULL = 1016,
RIL_UNSOL_SIM_REFRESH = 1017,
RIL_UNSOL_CALL_RING = 1018,
RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED = 1019,
RIL_UNSOL_RESPONSE_CDMA_NEW_SMS = 1020,
RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS = 1021,
RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL = 1022,
RIL_UNSOL_RESTRICTED_STATE_CHANGED = 1023,
RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE = 1024,
RIL_UNSOL_CDMA_CALL_WAITING = 1025,
RIL_UNSOL_CDMA_OTA_PROVISION_STATUS = 1026,
RIL_UNSOL_CDMA_INFO_REC = 1027,
RIL_UNSOL_OEM_HOOK_RAW = 1028,
RIL_UNSOL_RINGBACK_TONE = 1029,
RIL_UNSOL_RESEND_INCALL_MUTE = 1030,
RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1031,
RIL_UNSOL_CDMA_PRL_CHANGED = 1032,
RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE = 1033,
RIL_UNSOL_RIL_CONNECTED = 1034,
RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035,
RIL_UNSOL_CELL_INFO_LIST = 1036,
RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1037,
RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED = 1038,
RIL_UNSOL_SRVCC_STATE_NOTIFY = 1039,
RIL_UNSOL_HARDWARE_CONFIG_CHANGED = 1040,
RIL_UNSOL_DC_RT_INFO_CHANGED = 1041,
RIL_UNSOL_RADIO_CAPABILITY = 1042,
RIL_UNSOL_ON_SS = 1043,
RIL_UNSOL_STK_CC_ALPHA_NOTIFY = 1044
};
#ifdef __cplusplus
}

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2017-2018 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
@@ -88,6 +88,7 @@ struct sailfish_cell_info_proc {
gulong (*add_cells_changed_handler)(struct sailfish_cell_info *info,
sailfish_cell_info_cb_t cb, void *arg);
void (*remove_handler)(struct sailfish_cell_info *info, gulong id);
void (*set_update_interval)(struct sailfish_cell_info *info, int ms);
};
/* Utilities */
@@ -104,6 +105,8 @@ gulong sailfish_cell_info_add_cells_changed_handler
sailfish_cell_info_cb_t cb, void *arg);
void sailfish_cell_info_remove_handler(struct sailfish_cell_info *info,
gulong id);
void sailfish_cell_info_set_update_interval(struct sailfish_cell_info *info,
int ms);
#endif /* SAILFISH_CELINFO_H */

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2017 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
@@ -55,9 +55,9 @@ gint sailfish_cell_compare_location(const struct sailfish_cell *c1,
}
} else {
const struct sailfish_cell_info_lte *l1 =
&c1->info.lte;
&c1->info.lte;
const struct sailfish_cell_info_lte *l2 =
&c2->info.lte;
&c2->info.lte;
GASSERT(c1->type == SAILFISH_CELL_TYPE_LTE);
l1 = &c1->info.lte;
@@ -120,6 +120,14 @@ void sailfish_cell_info_remove_handler(struct sailfish_cell_info *info,
}
}
void sailfish_cell_info_set_update_interval(struct sailfish_cell_info *info,
int ms)
{
if (info && info->proc->set_update_interval) {
info->proc->set_update_interval(info, ms);
}
}
/*
* Local Variables:
* mode: C

View File

@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* 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
@@ -454,12 +455,9 @@ static void context_settings_append_ipv4(struct context_settings *settings,
ofono_dbus_dict_append(&array, "Interface",
DBUS_TYPE_STRING, &settings->interface);
/* If we have a Proxy, no other settings are relevant */
if (settings->ipv4->proxy) {
if (settings->ipv4->proxy)
ofono_dbus_dict_append(&array, "Proxy", DBUS_TYPE_STRING,
&settings->ipv4->proxy);
goto done;
}
if (settings->ipv4->static_ip == TRUE)
method = "static";
@@ -3938,3 +3936,21 @@ const struct ofono_gprs_primary_context *ofono_gprs_context_settings_by_type
return NULL;
}
enum ofono_gprs_context_type __ofono_gprs_context_get_assigned_type(
struct ofono_gprs_context *gc)
{
if (gc) {
struct ofono_gprs *gprs = gc->gprs;
GSList *l;
for (l = gprs->contexts; l; l = l->next) {
struct pri_context *pri = l->data;
if (pri->context_driver == gc)
return pri->type;
}
}
return OFONO_GPRS_CONTEXT_TYPE_ANY;
}

View File

@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* 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
@@ -275,6 +276,10 @@ gboolean __ofono_call_settings_is_busy(struct ofono_call_settings *cs);
gboolean __ofono_gprs_get_roaming_allowed(struct ofono_gprs *gprs);
#include <ofono/gprs-context.h>
enum ofono_gprs_context_type __ofono_gprs_context_get_assigned_type(
struct ofono_gprs_context *gc);
#include <ofono/radio-settings.h>
#include <ofono/audio-settings.h>
#include <ofono/ctm.h>

View File

@@ -88,10 +88,10 @@ static void test_null(void)
g_assert(!ril_vendor_ref(NULL));
g_assert(!ril_vendor_request_to_string(NULL, 0));
g_assert(!ril_vendor_event_to_string(NULL, 0));
g_assert(!ril_vendor_set_attach_apn_req(NULL, NULL, NULL, NULL, NULL,
RIL_AUTH_NONE, NULL));
g_assert(!ril_vendor_data_call_req(NULL, 0, NULL, NULL, NULL, NULL,
g_assert(!ril_vendor_set_attach_apn_req(NULL, NULL, NULL, NULL,
RIL_AUTH_NONE, NULL));
g_assert(!ril_vendor_data_call_req(NULL, 0, RIL_DATA_PROFILE_DEFAULT,
NULL, NULL, NULL, RIL_AUTH_NONE, NULL));
}
static void test_drivers(void)
@@ -134,10 +134,10 @@ static void test_base(void)
g_assert(!ril_vendor_request_to_string(base, 0));
g_assert(!ril_vendor_event_to_string(base, 0));
g_assert(!ril_vendor_set_attach_apn_req(base, NULL, NULL, NULL, NULL,
RIL_AUTH_NONE, NULL));
g_assert(!ril_vendor_data_call_req(base, 0, NULL, NULL, NULL, NULL,
g_assert(!ril_vendor_set_attach_apn_req(base, NULL, NULL, NULL,
RIL_AUTH_NONE, NULL));
g_assert(!ril_vendor_data_call_req(base, 0, RIL_DATA_PROFILE_DEFAULT,
NULL, NULL, NULL, RIL_AUTH_NONE, NULL));
g_assert(!ril_vendor_data_call_parse(base, NULL, 0, NULL));
g_assert(ril_vendor_ref(base) == base);
@@ -205,12 +205,12 @@ static void test_mtk1(void)
g_assert(!ril_vendor_data_call_parse(mtk1, NULL, 0, NULL));
/* Build RIL_REQUEST_SET_INITIAL_ATTACH_APN */
req = ril_vendor_set_attach_apn_req(mtk1, DATA_PROFILE_DEFAULT_STR,
"apn", "username", "password", RIL_AUTH_NONE, "IP");
req = ril_vendor_set_attach_apn_req(mtk1, "apn", "username",
"password", RIL_AUTH_NONE, "IP");
grilio_request_unref(req);
/* Build RIL_REQUEST_SETUP_DATA_CALL */
req = ril_vendor_data_call_req(mtk1, 1, DATA_PROFILE_DEFAULT_STR,
req = ril_vendor_data_call_req(mtk1, 1, RIL_DATA_PROFILE_DEFAULT,
"apn", "username", "password", RIL_AUTH_NONE, "IP");
grilio_request_unref(req);
@@ -317,12 +317,12 @@ static void test_mtk2(void)
MTK_INCOMING_CALL_INDICATION));
/* Build RIL_REQUEST_SET_INITIAL_ATTACH_APN */
req = ril_vendor_set_attach_apn_req(mtk2, DATA_PROFILE_DEFAULT_STR,
"apn", "username", "password", RIL_AUTH_NONE, "IP");
req = ril_vendor_set_attach_apn_req(mtk2, "apn", "username",
"password", RIL_AUTH_NONE, "IP");
grilio_request_unref(req);
/* Build RIL_REQUEST_SETUP_DATA_CALL */
req = ril_vendor_data_call_req(mtk2, 1, DATA_PROFILE_DEFAULT_STR,
req = ril_vendor_data_call_req(mtk2, 1, RIL_DATA_PROFILE_DEFAULT,
"apn", "username", "password", RIL_AUTH_NONE, "IP");
grilio_request_unref(req);

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2017 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
@@ -15,6 +15,7 @@
#include <sailfish_cell_info.h>
#include <gutil_macros.h>
#include <gutil_log.h>
/* Fake sailfish_cell_info */
@@ -54,15 +55,37 @@ static const struct sailfish_cell_info_proc fake_sailfish_cell_info_proc = {
fake_sailfish_cell_info_remove_handler
};
static struct sailfish_cell_info fake_sailfish_cell_info = {
&fake_sailfish_cell_info_proc,
NULL
struct test_sailfish_cell_info {
struct sailfish_cell_info info;
int interval;
};
static void test_sailfish_cell_info_set_update_interval
(struct sailfish_cell_info *info, int ms)
{
G_CAST(info, struct test_sailfish_cell_info, info)->interval = ms;
}
static const struct sailfish_cell_info_proc test_sailfish_cell_info_proc = {
fake_sailfish_cell_info_ref,
fake_sailfish_cell_info_unref,
fake_sailfish_cell_info_add_cells_changed_handler,
fake_sailfish_cell_info_remove_handler,
test_sailfish_cell_info_set_update_interval
};
/* ==== basic ==== */
static void test_basic(void)
{
struct sailfish_cell_info fake_sailfish_cell_info = {
&fake_sailfish_cell_info_proc, NULL
};
struct test_sailfish_cell_info test_info = {
{ &test_sailfish_cell_info_proc, NULL }, 0
};
/* NULL resistance */
g_assert(!sailfish_cell_info_ref(NULL));
sailfish_cell_info_unref(NULL);
@@ -70,6 +93,10 @@ static void test_basic(void)
g_assert(!sailfish_cell_info_add_cells_changed_handler(NULL, NULL,
NULL));
sailfish_cell_info_remove_handler(NULL, 0);
sailfish_cell_info_set_update_interval(NULL, 0);
/* NULL set_update_interval callback is tolerated */
sailfish_cell_info_set_update_interval(&fake_sailfish_cell_info, 0);
/* Make sure that callbacks are being invoked */
g_assert(sailfish_cell_info_ref(&fake_sailfish_cell_info) ==
@@ -81,6 +108,9 @@ static void test_basic(void)
FAKE_HANDLER_ID);
sailfish_cell_info_unref(&fake_sailfish_cell_info);
g_assert(!fake_sailfish_cell_info_ref_count);
sailfish_cell_info_set_update_interval(&test_info.info, 10);
g_assert(test_info.interval == 10);
}
/* ==== compare ==== */

View File

@@ -4,14 +4,19 @@ Version: 1.21
Release: 1
Group: Communications/Connectivity Adaptation
License: GPLv2
URL: https://git.merproject.org/mer-core/ofono
URL: https://git.sailfishos.org/mer-core/ofono
Source: %{name}-%{version}.tar.bz2
%define libgrilio_version 1.0.35
%define libglibutil_version 1.0.30
%define libmce_version 1.0.6
Requires: dbus
Requires: systemd
Requires: ofono-configs
Requires: libgrilio >= 1.0.25
Requires: libglibutil >= 1.0.30
Requires: libgrilio >= %{libgrilio_version}
Requires: libglibutil >= %{libglibutil_version}
Requires: libmce-glib >= %{libmce_version}
Requires: mobile-broadband-provider-info
Requires(preun): systemd
Requires(post): systemd
@@ -24,10 +29,10 @@ BuildRequires: pkgconfig(dbus-glib-1)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libudev) >= 145
BuildRequires: pkgconfig(libwspcodec) >= 2.0
BuildRequires: pkgconfig(libgrilio) >= 1.0.25
BuildRequires: pkgconfig(libglibutil) >= 1.0.30
BuildRequires: pkgconfig(libgrilio) >= %{libgrilio_version}
BuildRequires: pkgconfig(libglibutil) >= %{libglibutil_version}
BuildRequires: pkgconfig(libdbuslogserver-dbus)
BuildRequires: pkgconfig(libmce-glib) >= 1.0.5
BuildRequires: pkgconfig(libmce-glib) >= %{libmce_version}
BuildRequires: pkgconfig(libdbusaccess)
BuildRequires: pkgconfig(mobile-broadband-provider-info)
BuildRequires: libtool