mirror of
https://github.com/sailfishos/ofono
synced 2025-11-28 21:51:05 +08:00
Compare commits
86 Commits
upgrade-3.
...
upgrade-3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9331cc1ecb | ||
|
|
7c8da34a38 | ||
|
|
a05523974e | ||
|
|
71ef390b4a | ||
|
|
717f6452aa | ||
|
|
0803c21840 | ||
|
|
095060b001 | ||
|
|
c2971da092 | ||
|
|
f07424f0aa | ||
|
|
266a52a40a | ||
|
|
eeea5476d1 | ||
|
|
e38a63d179 | ||
|
|
0ff8608ac3 | ||
|
|
5a330b9852 | ||
|
|
78a9323619 | ||
|
|
8267e206eb | ||
|
|
fac7684958 | ||
|
|
6ba3170ce2 | ||
|
|
b29730b268 | ||
|
|
e095636c97 | ||
|
|
6fef5444fb | ||
|
|
0e62e613e8 | ||
|
|
c08be69130 | ||
|
|
419caedc2c | ||
|
|
ee6a307804 | ||
|
|
412d8c3d4d | ||
|
|
0efebd16d9 | ||
|
|
7a6928c02f | ||
|
|
ec134e68d2 | ||
|
|
a8be769c87 | ||
|
|
a2d87f64c4 | ||
|
|
3ecd55a205 | ||
|
|
d8ea82b2f1 | ||
|
|
c95fe16a9b | ||
|
|
55e923250a | ||
|
|
f5653ae240 | ||
|
|
ecf23c1333 | ||
|
|
e71036f7d7 | ||
|
|
b8e8b930f8 | ||
|
|
65a3f7ee46 | ||
|
|
26c5c4bfa3 | ||
|
|
2d35e5e28d | ||
|
|
ae78d9a946 | ||
|
|
243dd7d17c | ||
|
|
acaafafbb9 | ||
|
|
4f378c806b | ||
|
|
bd33ff471c | ||
|
|
d423608e46 | ||
|
|
3b708effd9 | ||
|
|
f01722cca5 | ||
|
|
f62d53fbd0 | ||
|
|
942aee3f25 | ||
|
|
ecc83568fd | ||
|
|
c911c05fcb | ||
|
|
680979f782 | ||
|
|
250a6abb71 | ||
|
|
6c5d2ab803 | ||
|
|
bf8cb3995c | ||
|
|
8973e52e45 | ||
|
|
0e8dc3605e | ||
|
|
537a39f94a | ||
|
|
c3d93e83d7 | ||
|
|
7cdf3db124 | ||
|
|
398942c78e | ||
|
|
26e39508ad | ||
|
|
a16fcd0d37 | ||
|
|
432e700272 | ||
|
|
aa694b592f | ||
|
|
c5c8b72761 | ||
|
|
2ab7aa0f97 | ||
|
|
549fe2355f | ||
|
|
7493187e47 | ||
|
|
9a3d8d671c | ||
|
|
39eac13743 | ||
|
|
6329bb8639 | ||
|
|
75b07c5c80 | ||
|
|
4f6f964ca4 | ||
|
|
7af95f6db5 | ||
|
|
99f4667eb7 | ||
|
|
c1c3ecab31 | ||
|
|
83dc99658c | ||
|
|
9a7b538087 | ||
|
|
9f7a1ffe3f | ||
|
|
1f81ec7d9d | ||
|
|
6e833401cc | ||
|
|
d9c68c4fb9 |
5
ofono/.gitignore
vendored
5
ofono/.gitignore
vendored
@@ -44,21 +44,24 @@ unit/test-mux
|
||||
unit/test-caif
|
||||
unit/test-stkutil
|
||||
unit/test-cdmasms
|
||||
unit/test-dbus-access
|
||||
unit/test-dbus-queue
|
||||
unit/test-gprs-filter
|
||||
unit/test-ril_config
|
||||
unit/test-ril_util
|
||||
unit/test-ril_vendor
|
||||
unit/test-ril-transport
|
||||
unit/test-rilmodem-cb
|
||||
unit/test-rilmodem-cs
|
||||
unit/test-rilmodem-gprs
|
||||
unit/test-rilmodem-sms
|
||||
unit/test-sailfish_access
|
||||
unit/test-sailfish_cell_info
|
||||
unit/test-sailfish_cell_info_dbus
|
||||
unit/test-sailfish_manager
|
||||
unit/test-sailfish_sim_info
|
||||
unit/test-sailfish_sim_info_dbus
|
||||
unit/test-sailfish_watch
|
||||
unit/test-watch
|
||||
unit/test-sms-filter
|
||||
unit/test-voicecall-filter
|
||||
unit/test-*.log
|
||||
|
||||
@@ -24,17 +24,17 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
|
||||
include/sim-mnclength.h \
|
||||
include/handsfree-audio.h include/siri.h \
|
||||
include/sms-filter.h include/gprs-filter.h \
|
||||
include/voicecall-filter.h \
|
||||
include/voicecall-filter.h include/dbus-access.h \
|
||||
include/ril-constants.h include/ril-transport.h \
|
||||
include/netmon.h include/lte.h \
|
||||
include/storage.h \
|
||||
include/storage.h include/watch.h \
|
||||
gdbus/gdbus.h
|
||||
|
||||
nodist_pkginclude_HEADERS = include/version.h
|
||||
|
||||
if SAILFISH_MANAGER
|
||||
nodist_pkginclude_HEADERS += include/sailfish_cell_info.h \
|
||||
include/sailfish_manager.h include/sailfish_watch.h
|
||||
include/sailfish_manager.h
|
||||
endif
|
||||
|
||||
local_headers = $(foreach file,$(pkginclude_HEADERS) \
|
||||
@@ -131,8 +131,13 @@ builtin_sources += plugins/sailfish_manager/sailfish_cell_info.c \
|
||||
plugins/sailfish_manager/sailfish_manager.c \
|
||||
plugins/sailfish_manager/sailfish_manager_dbus.c \
|
||||
plugins/sailfish_manager/sailfish_sim_info.c \
|
||||
plugins/sailfish_manager/sailfish_sim_info_dbus.c \
|
||||
plugins/sailfish_manager/sailfish_watch.c
|
||||
plugins/sailfish_manager/sailfish_sim_info_dbus.c
|
||||
endif
|
||||
|
||||
|
||||
if SAILFISH_ACCESS
|
||||
builtin_modules += sailfish_access
|
||||
builtin_sources += plugins/sailfish_access.c
|
||||
endif
|
||||
|
||||
if RILMODEM
|
||||
@@ -145,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 \
|
||||
@@ -564,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
|
||||
|
||||
@@ -738,9 +745,10 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
|
||||
src/cdma-provision.c src/handsfree.c \
|
||||
src/handsfree-audio.c src/bluetooth.h \
|
||||
src/sim-mnclength.c src/voicecallagent.c \
|
||||
src/sms-filter.c src/gprs-filter.c src/dbus-queue.c \
|
||||
src/sms-filter.c src/gprs-filter.c \
|
||||
src/dbus-queue.c src/dbus-access.c \
|
||||
src/voicecall-filter.c src/ril-transport.c \
|
||||
src/hfp.h src/siri.c \
|
||||
src/hfp.h src/siri.c src/watchlist.c \
|
||||
src/netmon.c src/lte.c \
|
||||
src/netmonagent.c src/netmonagent.h
|
||||
|
||||
@@ -949,9 +957,9 @@ unit_objects += $(unit_test_sailfish_cell_info_dbus_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_cell_info_dbus
|
||||
|
||||
unit_test_sailfish_sim_info_SOURCES = unit/test-sailfish_sim_info.c \
|
||||
unit/fake_sailfish_watch.c \
|
||||
unit/fake_watch.c \
|
||||
plugins/sailfish_manager/sailfish_sim_info.c \
|
||||
src/storage.c src/watch.c src/log.c
|
||||
src/storage.c src/watchlist.c src/log.c
|
||||
unit_test_sailfish_sim_info_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS) \
|
||||
-DSTORAGEDIR='"/tmp/ofono"' -Iplugins/sailfish_manager
|
||||
unit_test_sailfish_sim_info_LDADD = @GLIB_LIBS@ -ldl
|
||||
@@ -959,11 +967,11 @@ unit_objects += $(unit_test_sailfish_sim_info_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_sim_info
|
||||
|
||||
unit_test_sailfish_sim_info_dbus_SOURCES = unit/test-sailfish_sim_info_dbus.c \
|
||||
unit/test-dbus.c unit/fake_sailfish_watch.c \
|
||||
unit/test-dbus.c unit/fake_watch.c \
|
||||
plugins/sailfish_manager/sailfish_sim_info.c \
|
||||
plugins/sailfish_manager/sailfish_sim_info_dbus.c \
|
||||
gdbus/object.c \
|
||||
src/dbus.c src/storage.c src/watch.c src/log.c
|
||||
src/dbus.c src/storage.c src/watchlist.c src/log.c
|
||||
unit_test_sailfish_sim_info_dbus_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS) \
|
||||
@DBUS_GLIB_CFLAGS@ -DSTORAGEDIR='"/tmp/ofono"' \
|
||||
-Iplugins/sailfish_manager
|
||||
@@ -972,7 +980,7 @@ unit_objects += $(unit_test_sailfish_sim_info_dbus_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_sim_info_dbus
|
||||
|
||||
unit_test_sailfish_manager_SOURCES = unit/test-sailfish_manager.c \
|
||||
unit/fake_sailfish_watch.c \
|
||||
unit/fake_watch.c \
|
||||
plugins/sailfish_manager/sailfish_manager.c \
|
||||
plugins/sailfish_manager/sailfish_cell_info.c \
|
||||
plugins/sailfish_manager/sailfish_sim_info.c \
|
||||
@@ -983,17 +991,32 @@ unit_test_sailfish_manager_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_sailfish_manager_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_manager
|
||||
|
||||
unit_test_sailfish_watch_SOURCES = unit/test-sailfish_watch.c \
|
||||
plugins/sailfish_manager/sailfish_watch.c \
|
||||
src/log.c src/watch.c
|
||||
unit_test_sailfish_watch_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||
unit_test_watch_SOURCES = unit/test-watch.c src/watch.c \
|
||||
src/log.c src/watchlist.c
|
||||
unit_test_watch_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||
-DSTORAGEDIR='"/tmp/ofono"' -Iplugins/sailfish_manager
|
||||
unit_test_sailfish_watch_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_sailfish_watch_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_watch
|
||||
unit_test_watch_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_watch_OBJECTS)
|
||||
unit_tests += unit/test-watch
|
||||
|
||||
endif
|
||||
|
||||
if SAILFISH_ACCESS
|
||||
unit_test_sailfish_access_SOURCES = unit/test-sailfish_access.c \
|
||||
plugins/sailfish_access.c src/dbus-access.c src/log.c
|
||||
unit_test_sailfish_access_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT)
|
||||
unit_test_sailfish_access_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_sailfish_access_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_access
|
||||
endif
|
||||
|
||||
unit_test_dbus_access_SOURCES = unit/test-dbus-access.c src/dbus-access.c \
|
||||
src/log.c
|
||||
unit_test_dbus_access_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT)
|
||||
unit_test_dbus_access_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_dbus_access_OBJECTS)
|
||||
unit_tests += unit/test-dbus-access
|
||||
|
||||
if RILMODEM
|
||||
if SAILFISH_RILMODEM
|
||||
|
||||
@@ -1011,6 +1034,14 @@ unit_test_ril_util_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_ril_util_OBJECTS)
|
||||
unit_tests += unit/test-ril_util
|
||||
|
||||
unit_test_ril_vendor_SOURCES = unit/test-ril_vendor.c unit/fake_watch.c \
|
||||
drivers/ril/ril_vendor.c drivers/ril/ril_vendor_mtk.c \
|
||||
drivers/ril/ril_util.c src/log.c
|
||||
unit_test_ril_vendor_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
|
||||
unit_test_ril_vendor_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_ril_vendor_OBJECTS)
|
||||
unit_tests += unit/test-ril_vendor
|
||||
|
||||
else
|
||||
unit_tests += unit/test-rilmodem-cs \
|
||||
unit/test-rilmodem-cs \
|
||||
|
||||
@@ -33,7 +33,7 @@ AC_PROG_LIBTOOL
|
||||
AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization],
|
||||
[disable code optimization through compiler]), [
|
||||
if (test "${enableval}" = "no"); then
|
||||
CFLAGS="$CFLAGS -O0"
|
||||
CFLAGS="$CFLAGS -O0 -U_FORTIFY_SOURCE"
|
||||
fi
|
||||
])
|
||||
|
||||
@@ -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,23 @@ 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],
|
||||
[enable Sailfish OS access plugin]),
|
||||
[enable_sailfish_access=${enableval}],
|
||||
[enable_sailfish_access="no"])
|
||||
|
||||
AM_CONDITIONAL(SAILFISH_ACCESS, test "${enable_sailfish_access}" != "no")
|
||||
if (test "${enable_sailfish_access}" == "yes"); then
|
||||
PKG_CHECK_MODULES(DBUSACCESS, libdbusaccess, dummy=yes,
|
||||
AC_MSG_ERROR(libdbusaccess is required))
|
||||
CFLAGS="$CFLAGS $DBUSACCESS_CFLAGS"
|
||||
LIBS="$LIBS $DBUSACCESS_LIBS"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(sailfish-debuglog, AC_HELP_STRING([--enable-sailfish-debuglog],
|
||||
@@ -324,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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
622
ofono/drivers/ril/ril_connman.c
Normal file
622
ofono/drivers/ril/ril_connman.c
Normal 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:
|
||||
*/
|
||||
61
ofono/drivers/ril/ril_connman.h
Normal file
61
ofono/drivers/ril/ril_connman.h
Normal 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:
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Canonical Ltd.
|
||||
* Copyright (C) 2013-2018 Jolla Ltd.
|
||||
* Copyright (C) 2013-2019 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -28,11 +28,8 @@
|
||||
#include <grilio_parser.h>
|
||||
#include <grilio_request.h>
|
||||
|
||||
#define DATA_PROFILE_DEFAULT_STR "0"
|
||||
|
||||
#define PROTO_IP_STR "IP"
|
||||
#define PROTO_IPV6_STR "IPV6"
|
||||
#define PROTO_IPV4V6_STR "IPV4V6"
|
||||
/* Yes, it does sometimes take minutes in roaming */
|
||||
#define SETUP_DATA_CALL_TIMEOUT (300*1000) /* ms */
|
||||
|
||||
enum ril_data_priv_flags {
|
||||
RIL_DATA_FLAG_NONE = 0x00,
|
||||
@@ -100,7 +97,7 @@ struct ril_data_priv {
|
||||
struct ril_radio *radio;
|
||||
struct ril_network *network;
|
||||
struct ril_data_manager *dm;
|
||||
struct ril_vendor_hook *vendor_hook;
|
||||
struct ril_vendor *vendor;
|
||||
|
||||
enum ril_data_priv_flags flags;
|
||||
enum ril_restricted_state restricted_state;
|
||||
@@ -109,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;
|
||||
@@ -165,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;
|
||||
@@ -285,34 +285,6 @@ static gint ril_data_call_compare(gconstpointer a, gconstpointer b)
|
||||
}
|
||||
}
|
||||
|
||||
const char *ril_data_ofono_protocol_to_ril(enum ofono_gprs_proto proto)
|
||||
{
|
||||
switch (proto) {
|
||||
case OFONO_GPRS_PROTO_IPV6:
|
||||
return PROTO_IPV6_STR;
|
||||
case OFONO_GPRS_PROTO_IPV4V6:
|
||||
return PROTO_IPV4V6_STR;
|
||||
case OFONO_GPRS_PROTO_IP:
|
||||
return PROTO_IP_STR;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int ril_data_protocol_to_ofono(const gchar *str)
|
||||
{
|
||||
if (str) {
|
||||
if (!strcmp(str, PROTO_IPV6_STR)) {
|
||||
return OFONO_GPRS_PROTO_IPV6;
|
||||
} else if (!strcmp(str, PROTO_IPV4V6_STR)) {
|
||||
return OFONO_GPRS_PROTO_IPV4V6;
|
||||
} else if (!strcmp(str, PROTO_IP_STR)) {
|
||||
return OFONO_GPRS_PROTO_IP;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gboolean ril_data_call_parse_default(struct ril_data_call *call,
|
||||
int version, GRilIoParser *rilp)
|
||||
{
|
||||
@@ -332,7 +304,7 @@ static gboolean ril_data_call_parse_default(struct ril_data_call *call,
|
||||
call->dnses = grilio_parser_split_utf8(rilp, " ");
|
||||
call->gateways = grilio_parser_split_utf8(rilp, " ");
|
||||
|
||||
prot = ril_data_protocol_to_ofono(prot_str);
|
||||
prot = ril_protocol_to_ofono(prot_str);
|
||||
if (prot < 0 && status == PDP_FAIL_NONE) {
|
||||
ofono_error("Invalid protocol: %s", prot_str);
|
||||
}
|
||||
@@ -357,12 +329,12 @@ static gboolean ril_data_call_parse_default(struct ril_data_call *call,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct ril_data_call *ril_data_call_parse(struct ril_vendor_hook *hook,
|
||||
static struct ril_data_call *ril_data_call_parse(struct ril_vendor *vendor,
|
||||
int version, GRilIoParser *parser)
|
||||
{
|
||||
GRilIoParser copy = *parser;
|
||||
struct ril_data_call *call = ril_data_call_new();
|
||||
gboolean parsed = ril_vendor_hook_data_call_parse(hook, call,
|
||||
gboolean parsed = ril_vendor_data_call_parse(vendor, call,
|
||||
version, parser);
|
||||
|
||||
if (!parsed) {
|
||||
@@ -378,7 +350,7 @@ static struct ril_data_call *ril_data_call_parse(struct ril_vendor_hook *hook,
|
||||
"mtu=%d,address=%s,dns=%s %s,gateways=%s]",
|
||||
call->status, call->retry_time,
|
||||
call->cid, call->active,
|
||||
ril_data_ofono_protocol_to_ril(call->prot),
|
||||
ril_protocol_from_ofono(call->prot),
|
||||
call->ifname, call->mtu,
|
||||
call->addresses ? call->addresses[0] : NULL,
|
||||
call->dnses ? call->dnses[0] : NULL,
|
||||
@@ -393,7 +365,7 @@ static struct ril_data_call *ril_data_call_parse(struct ril_vendor_hook *hook,
|
||||
}
|
||||
|
||||
static struct ril_data_call_list *ril_data_call_list_parse(const void *data,
|
||||
guint len, struct ril_vendor_hook *hook,
|
||||
guint len, struct ril_vendor *vendor,
|
||||
enum ril_data_call_format format)
|
||||
{
|
||||
guint32 version, n, i;
|
||||
@@ -414,7 +386,7 @@ static struct ril_data_call_list *ril_data_call_list_parse(const void *data,
|
||||
}
|
||||
|
||||
for (i = 0; i < n && !grilio_parser_at_end(&rilp); i++) {
|
||||
struct ril_data_call *call = ril_data_call_parse(hook,
|
||||
struct ril_data_call *call = ril_data_call_parse(vendor,
|
||||
list->version, &rilp);
|
||||
|
||||
if (call) {
|
||||
@@ -632,7 +604,7 @@ static void ril_data_call_list_changed_cb(GRilIoChannel *io, guint event,
|
||||
}
|
||||
|
||||
ril_data_set_calls(self, ril_data_call_list_parse(data, len,
|
||||
priv->vendor_hook, priv->options.data_call_format));
|
||||
priv->vendor, priv->options.data_call_format));
|
||||
}
|
||||
|
||||
static void ril_data_query_data_calls_cb(GRilIoChannel *io, int ril_status,
|
||||
@@ -649,7 +621,7 @@ static void ril_data_query_data_calls_cb(GRilIoChannel *io, int ril_status,
|
||||
priv->query_id = 0;
|
||||
if (ril_status == RIL_E_SUCCESS) {
|
||||
ril_data_set_calls(self, ril_data_call_list_parse(data, len,
|
||||
priv->vendor_hook, priv->options.data_call_format));
|
||||
priv->vendor, priv->options.data_call_format));
|
||||
} else {
|
||||
/* RADIO_NOT_AVAILABLE == no calls */
|
||||
ril_data_set_calls(self, NULL);
|
||||
@@ -854,8 +826,8 @@ static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
|
||||
struct ril_data_call *call = NULL;
|
||||
|
||||
if (ril_status == RIL_E_SUCCESS) {
|
||||
list = ril_data_call_list_parse(data, len,
|
||||
priv->vendor_hook, priv->options.data_call_format);
|
||||
list = ril_data_call_list_parse(data, len, priv->vendor,
|
||||
priv->options.data_call_format);
|
||||
}
|
||||
|
||||
if (list) {
|
||||
@@ -917,7 +889,7 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
|
||||
struct ril_data_request_setup *setup =
|
||||
G_CAST(req, struct ril_data_request_setup, req);
|
||||
struct ril_data_priv *priv = req->data->priv;
|
||||
const char *proto_str = ril_data_ofono_protocol_to_ril(setup->proto);
|
||||
const char *proto_str = ril_protocol_from_ofono(setup->proto);
|
||||
GRilIoRequest *ioreq;
|
||||
int tech, auth = RIL_AUTH_NONE;
|
||||
|
||||
@@ -943,25 +915,12 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
|
||||
}
|
||||
|
||||
if (setup->username && setup->username[0]) {
|
||||
switch (setup->auth_method) {
|
||||
case OFONO_GPRS_AUTH_METHOD_ANY:
|
||||
auth = RIL_AUTH_BOTH;
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_NONE:
|
||||
auth = RIL_AUTH_NONE;
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_CHAP:
|
||||
auth = RIL_AUTH_CHAP;
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_PAP:
|
||||
auth = RIL_AUTH_PAP;
|
||||
break;
|
||||
}
|
||||
auth = ril_auth_method_from_ofono(setup->auth_method);
|
||||
}
|
||||
|
||||
/* Give vendor code a chance to build a vendor specific packet */
|
||||
ioreq = ril_vendor_hook_data_call_req(priv->vendor_hook, tech,
|
||||
DATA_PROFILE_DEFAULT_STR, setup->apn, setup->username,
|
||||
ioreq = ril_vendor_data_call_req(priv->vendor, tech,
|
||||
setup->profile_id, setup->apn, setup->username,
|
||||
setup->password, auth, proto_str);
|
||||
|
||||
if (!ioreq) {
|
||||
@@ -969,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);
|
||||
@@ -978,6 +937,7 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
|
||||
}
|
||||
|
||||
GASSERT(!req->pending_id);
|
||||
grilio_request_set_timeout(ioreq, SETUP_DATA_CALL_TIMEOUT);
|
||||
req->pending_id = grilio_queue_send_request_full(priv->q, ioreq,
|
||||
RIL_REQUEST_SETUP_DATA_CALL, ril_data_call_setup_cb,
|
||||
NULL, setup);
|
||||
@@ -998,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);
|
||||
@@ -1227,7 +1193,7 @@ struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
|
||||
struct ril_radio *radio, struct ril_network *network,
|
||||
GRilIoChannel *io, const struct ril_data_options *options,
|
||||
const struct ril_slot_config *config,
|
||||
struct ril_vendor_hook *vendor_hook)
|
||||
struct ril_vendor *vendor)
|
||||
{
|
||||
GASSERT(dm);
|
||||
if (G_LIKELY(dm)) {
|
||||
@@ -1254,13 +1220,15 @@ 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);
|
||||
priv->dm = ril_data_manager_ref(dm);
|
||||
priv->radio = ril_radio_ref(radio);
|
||||
priv->network = ril_network_ref(network);
|
||||
priv->vendor_hook = ril_vendor_hook_ref(vendor_hook);
|
||||
priv->vendor = ril_vendor_ref(vendor);
|
||||
|
||||
priv->io_event_id[IO_EVENT_DATA_CALL_LIST_CHANGED] =
|
||||
grilio_channel_add_unsol_event_handler(io,
|
||||
@@ -1507,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;
|
||||
@@ -1603,7 +1572,7 @@ static void ril_data_finalize(GObject *object)
|
||||
ril_network_unref(priv->network);
|
||||
ril_data_manager_unref(priv->dm);
|
||||
ril_data_call_list_free(self->data_calls);
|
||||
ril_vendor_hook_unref(priv->vendor_hook);
|
||||
ril_vendor_unref(priv->vendor);
|
||||
G_OBJECT_CLASS(ril_data_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -100,7 +100,7 @@ struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
|
||||
struct ril_radio *radio, struct ril_network *network,
|
||||
GRilIoChannel *io, const struct ril_data_options *options,
|
||||
const struct ril_slot_config *config,
|
||||
struct ril_vendor_hook *vendor_hook);
|
||||
struct ril_vendor *vendor);
|
||||
struct ril_data *ril_data_ref(struct ril_data *data);
|
||||
void ril_data_unref(struct ril_data *data);
|
||||
gboolean ril_data_allowed(struct ril_data *data);
|
||||
@@ -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);
|
||||
@@ -131,9 +132,6 @@ struct ril_data_call *ril_data_call_dup(const struct ril_data_call *call);
|
||||
struct ril_data_call *ril_data_call_find(struct ril_data_call_list *list,
|
||||
int cid);
|
||||
|
||||
const char *ril_data_ofono_protocol_to_ril(enum ofono_gprs_proto proto);
|
||||
int ril_data_protocol_to_ofono(const gchar *str);
|
||||
|
||||
/* Constructors of various kinds of RIL requests */
|
||||
GRilIoRequest *ril_request_allow_data_new(gboolean allow);
|
||||
GRilIoRequest *ril_request_deactivate_data_call_new(int cid);
|
||||
|
||||
44
ofono/drivers/ril/ril_devmon.c
Normal file
44
ofono/drivers/ril/ril_devmon.c
Normal 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:
|
||||
*/
|
||||
72
ofono/drivers/ril/ril_devmon.h
Normal file
72
ofono/drivers/ril/ril_devmon.h
Normal 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:
|
||||
*/
|
||||
92
ofono/drivers/ril/ril_devmon_auto.c
Normal file
92
ofono/drivers/ril/ril_devmon_auto.c
Normal 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:
|
||||
*/
|
||||
342
ofono/drivers/ril/ril_devmon_ds.c
Normal file
342
ofono/drivers/ril/ril_devmon_ds.c
Normal 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:
|
||||
*/
|
||||
248
ofono/drivers/ril/ril_devmon_ss.c
Normal file
248
ofono/drivers/ril/ril_devmon_ss.c
Normal 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:
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -482,24 +483,23 @@ static void ril_gprs_context_deactivate_primary_cb(struct ril_data *data,
|
||||
* invoked and gcd->deactivate.req will be NULL.
|
||||
*/
|
||||
if (gcd->deactivate.req) {
|
||||
struct ofono_error error;
|
||||
ofono_gprs_context_cb_t cb = gcd->deactivate.cb;
|
||||
gpointer cb_data = gcd->deactivate.data;
|
||||
|
||||
if (ril_status == RIL_E_SUCCESS) {
|
||||
GASSERT(gcd->active_call);
|
||||
ril_error_init_ok(&error);
|
||||
ofono_info("Deactivated data call");
|
||||
} else {
|
||||
ril_error_init_failure(&error);
|
||||
ofono_error("Deactivate failure: %s",
|
||||
ril_error_to_string(ril_status));
|
||||
}
|
||||
|
||||
memset(&gcd->deactivate, 0, sizeof(gcd->deactivate));
|
||||
if (cb) {
|
||||
struct ofono_error error;
|
||||
|
||||
ril_gprs_context_free_active_call(gcd);
|
||||
cb(&error, cb_data);
|
||||
cb(ril_error_ok(&error), cb_data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -513,7 +513,7 @@ static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
|
||||
{
|
||||
struct ril_gprs_context *gcd = ril_gprs_context_get_data(gc);
|
||||
|
||||
GASSERT(gcd->active_call && gcd->active_ctx_cid == id);
|
||||
GASSERT(gcd->active_ctx_cid == id);
|
||||
ofono_info("Deactivating context: %u", id);
|
||||
|
||||
if (gcd->active_call && gcd->active_ctx_cid == id) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||
* 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
|
||||
@@ -25,7 +26,7 @@
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
#include "sailfish_watch.h"
|
||||
#include <ofono/watch.h>
|
||||
|
||||
#define MAX_PDP_CONTEXTS (2)
|
||||
#define ONLINE_TIMEOUT_SECS (15) /* 20 sec is hardcoded in ofono core */
|
||||
@@ -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;
|
||||
@@ -52,13 +61,16 @@ struct ril_modem_online_request {
|
||||
|
||||
struct ril_modem_data {
|
||||
struct ril_modem modem;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
GRilIoQueue *q;
|
||||
char *log_prefix;
|
||||
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;
|
||||
@@ -234,7 +246,7 @@ static void ril_modem_radio_state_cb(struct ril_radio *radio, void *data)
|
||||
ril_modem_update_online_state(md);
|
||||
}
|
||||
|
||||
static void ril_modem_imsi_cb(struct sailfish_watch *watch, void *data)
|
||||
static void ril_modem_imsi_cb(struct ofono_watch *watch, void *data)
|
||||
{
|
||||
struct ril_modem_data *md = data;
|
||||
|
||||
@@ -242,6 +254,32 @@ static void ril_modem_imsi_cb(struct sailfish_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);
|
||||
@@ -284,8 +322,16 @@ static void ril_modem_post_sim(struct ofono_modem *modem)
|
||||
ofono_phonebook_create(modem, 0, RILMODEM_DRIVER, md);
|
||||
ofono_call_forwarding_create(modem, 0, RILMODEM_DRIVER, md);
|
||||
ofono_call_barring_create(modem, 0, RILMODEM_DRIVER, md);
|
||||
ofono_stk_create(modem, 0, RILMODEM_DRIVER, md);
|
||||
ofono_message_waiting_register(ofono_message_waiting_create(modem));
|
||||
if (md->modem.config.enable_stk) {
|
||||
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);
|
||||
}
|
||||
@@ -374,8 +420,8 @@ static void ril_modem_remove(struct ofono_modem *ofono)
|
||||
ril_radio_unref(modem->radio);
|
||||
ril_sim_settings_unref(modem->sim_settings);
|
||||
|
||||
sailfish_watch_remove_handler(md->watch, md->imsi_event_id);
|
||||
sailfish_watch_unref(md->watch);
|
||||
ofono_watch_remove_all_handlers(md->watch, md->watch_event_id);
|
||||
ofono_watch_unref(md->watch);
|
||||
|
||||
if (md->online_check_id) {
|
||||
g_source_remove(md->online_check_id);
|
||||
@@ -396,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);
|
||||
@@ -443,13 +491,22 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
|
||||
modem->data = ril_data_ref(data);
|
||||
modem->io = grilio_channel_ref(io);
|
||||
md->q = grilio_queue_new(io);
|
||||
md->watch = sailfish_watch_new(path);
|
||||
md->watch = ofono_watch_new(path);
|
||||
md->last_known_iccid = g_strdup(md->watch->iccid);
|
||||
|
||||
md->imsi_event_id =
|
||||
sailfish_watch_add_imsi_changed_handler(md->watch,
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
@@ -21,6 +21,9 @@
|
||||
#include "common.h"
|
||||
#include "simutil.h"
|
||||
|
||||
#define REGISTRATION_TIMEOUT (100*1000) /* ms */
|
||||
#define REGISTRATION_MAX_RETRIES (2)
|
||||
|
||||
enum ril_netreg_events {
|
||||
NETREG_RIL_EVENT_NITZ_TIME_RECEIVED,
|
||||
NETREG_RIL_EVENT_SIGNAL_STRENGTH,
|
||||
@@ -36,6 +39,7 @@ enum ril_netreg_network_events {
|
||||
struct ril_netreg {
|
||||
GRilIoChannel *io;
|
||||
GRilIoQueue *q;
|
||||
gboolean network_selection_manual_0;
|
||||
struct ofono_netreg *netreg;
|
||||
struct ril_network *network;
|
||||
char *log_prefix;
|
||||
@@ -296,12 +300,16 @@ static void ril_netreg_register_auto(struct ofono_netreg *netreg,
|
||||
ofono_netreg_register_cb_t cb, void *data)
|
||||
{
|
||||
struct ril_netreg *nd = ril_netreg_get_data(netreg);
|
||||
GRilIoRequest *req = grilio_request_new();
|
||||
|
||||
ofono_info("nw select automatic");
|
||||
grilio_queue_send_request_full(nd->q, NULL,
|
||||
grilio_request_set_timeout(req, REGISTRATION_TIMEOUT);
|
||||
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
|
||||
grilio_queue_send_request_full(nd->q, req,
|
||||
RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
|
||||
ril_netreg_register_cb, ril_netreg_cbd_free,
|
||||
ril_netreg_cbd_new(nd, cb, data));
|
||||
grilio_request_unref(req);
|
||||
}
|
||||
|
||||
static void ril_netreg_register_manual(struct ofono_netreg *netreg,
|
||||
@@ -310,9 +318,12 @@ static void ril_netreg_register_manual(struct ofono_netreg *netreg,
|
||||
{
|
||||
struct ril_netreg *nd = ril_netreg_get_data(netreg);
|
||||
GRilIoRequest *req = grilio_request_new();
|
||||
const char *suffix = nd->network_selection_manual_0 ? "+0" : "";
|
||||
|
||||
ofono_info("nw select manual: %s%s", mcc, mnc);
|
||||
grilio_request_append_format(req, "%s%s+0", mcc, mnc);
|
||||
ofono_info("nw select manual: %s%s%s", mcc, mnc, suffix);
|
||||
grilio_request_append_format(req, "%s%s%s", mcc, mnc, suffix);
|
||||
grilio_request_set_timeout(req, REGISTRATION_TIMEOUT);
|
||||
grilio_request_set_retry(req, 0, REGISTRATION_MAX_RETRIES);
|
||||
grilio_queue_send_request_full(nd->q, req,
|
||||
RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
|
||||
ril_netreg_register_cb, ril_netreg_cbd_free,
|
||||
@@ -320,15 +331,24 @@ static void ril_netreg_register_manual(struct ofono_netreg *netreg,
|
||||
grilio_request_unref(req);
|
||||
}
|
||||
|
||||
static int ril_netreg_dbm_to_percentage(int dbm)
|
||||
{
|
||||
const int min_dbm = -100; /* very weak signal, 0.0000000001 mW */
|
||||
const int max_dbm = -60; /* strong signal, 0.000001 mW */
|
||||
|
||||
return (dbm <= min_dbm) ? 1 :
|
||||
(dbm >= max_dbm) ? 100 :
|
||||
(100 * (dbm - min_dbm) / (max_dbm - min_dbm));
|
||||
}
|
||||
|
||||
static int ril_netreg_get_signal_strength(const void *data, guint len)
|
||||
{
|
||||
GRilIoParser rilp;
|
||||
int gw_signal = 0, cdma_dbm = 0, evdo_dbm = 0, lte_signal = 0;
|
||||
int rsrp = 0;
|
||||
int rsrp = 0, tdscdma_dbm = 0;
|
||||
|
||||
grilio_parser_init(&rilp, data, len);
|
||||
|
||||
/* RIL_SignalStrength_v6 */
|
||||
/* GW_SignalStrength */
|
||||
grilio_parser_get_int32(&rilp, &gw_signal);
|
||||
grilio_parser_get_int32(&rilp, NULL); /* bitErrorRate */
|
||||
@@ -345,14 +365,25 @@ static int ril_netreg_get_signal_strength(const void *data, guint len)
|
||||
/* LTE_SignalStrength */
|
||||
grilio_parser_get_int32(&rilp, <e_signal);
|
||||
grilio_parser_get_int32(&rilp, &rsrp);
|
||||
/* The rest is ignored */
|
||||
|
||||
/* Skip the rest of LTE_SignalStrength_v8 */
|
||||
if (grilio_parser_get_int32(&rilp, NULL) && /* rsrq */
|
||||
grilio_parser_get_int32(&rilp, NULL) && /* rssnr */
|
||||
grilio_parser_get_int32(&rilp, NULL) && /* cqi */
|
||||
grilio_parser_get_int32(&rilp, NULL)) { /* timingAdvance */
|
||||
|
||||
/* TD_SCDMA_SignalStrength */
|
||||
grilio_parser_get_int32(&rilp, &tdscdma_dbm); /* rscp */
|
||||
}
|
||||
|
||||
if (rsrp == INT_MAX) {
|
||||
DBG("gw: %d, cdma: %d, evdo: %d, lte: %d", gw_signal,
|
||||
cdma_dbm, evdo_dbm, lte_signal);
|
||||
DBG("gw: %d, cdma: %d, evdo: %d, lte: %d, tdscdma: %d",
|
||||
gw_signal, cdma_dbm, evdo_dbm,
|
||||
lte_signal, tdscdma_dbm);
|
||||
} else {
|
||||
DBG("gw: %d, cdma: %d, evdo: %d, lte: %d rsrp: %d", gw_signal,
|
||||
cdma_dbm, evdo_dbm, lte_signal, rsrp);
|
||||
DBG("gw: %d, cdma: %d, evdo: %d, lte: %d rsrp: %d, tdscdma: %d",
|
||||
gw_signal, cdma_dbm, evdo_dbm,
|
||||
lte_signal, rsrp, tdscdma_dbm);
|
||||
}
|
||||
|
||||
/* Return the first valid one */
|
||||
@@ -369,9 +400,14 @@ static int ril_netreg_get_signal_strength(const void *data, guint len)
|
||||
return (lte_signal * 100) / 31;
|
||||
}
|
||||
|
||||
/* RSCP range: 25 to 120 dBm as defined in 3GPP TS 25.123 */
|
||||
if (tdscdma_dbm >= 25 && tdscdma_dbm <= 120) {
|
||||
return ril_netreg_dbm_to_percentage(-tdscdma_dbm);
|
||||
}
|
||||
|
||||
/* RSRP range: 44 to 140 dBm as defined in 3GPP TS 36.133 */
|
||||
if (lte_signal == 99 && rsrp >= 44 && rsrp <= 140) {
|
||||
return 140 - rsrp;
|
||||
return ril_netreg_dbm_to_percentage(-rsrp);
|
||||
}
|
||||
|
||||
/* If we've got zero strength and no valid RSRP, then so be it */
|
||||
@@ -514,6 +550,7 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
|
||||
{
|
||||
struct ril_modem *modem = data;
|
||||
struct ril_netreg *nd = g_new0(struct ril_netreg, 1);
|
||||
const struct ril_slot_config *config = &modem->config;
|
||||
|
||||
nd->log_prefix = (modem->log_prefix && modem->log_prefix[0]) ?
|
||||
g_strconcat(modem->log_prefix, " ", NULL) : g_strdup("");
|
||||
@@ -523,6 +560,7 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
|
||||
nd->q = grilio_queue_new(nd->io);
|
||||
nd->network = ril_network_ref(modem->network);
|
||||
nd->netreg = netreg;
|
||||
nd->network_selection_manual_0 = config->network_selection_manual_0;
|
||||
|
||||
ofono_netreg_set_data(netreg, nd);
|
||||
nd->timer_id = g_idle_add(ril_netreg_register, nd);
|
||||
|
||||
@@ -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
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ril_radio.h"
|
||||
#include "ril_sim_card.h"
|
||||
#include "ril_sim_settings.h"
|
||||
#include "ril_vendor.h"
|
||||
#include "ril_util.h"
|
||||
#include "ril_log.h"
|
||||
|
||||
@@ -25,8 +26,11 @@
|
||||
#include <grilio_parser.h>
|
||||
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_macros.h>
|
||||
|
||||
#include <ofono/netreg.h>
|
||||
#include <ofono/watch.h>
|
||||
#include <ofono/gprs.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -59,13 +63,36 @@ enum ril_network_unsol_event {
|
||||
UNSOL_EVENT_COUNT
|
||||
};
|
||||
|
||||
enum ril_network_watch_event {
|
||||
WATCH_EVENT_GPRS,
|
||||
WATCH_EVENT_GPRS_SETTINGS,
|
||||
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;
|
||||
struct ril_radio *radio;
|
||||
struct ril_sim_card *simcard;
|
||||
struct ril_vendor *vendor;
|
||||
struct ofono_watch *watch;
|
||||
int rat;
|
||||
int lte_network_mode;
|
||||
enum ril_pref_net_type lte_network_mode;
|
||||
enum ril_pref_net_type umts_network_mode;
|
||||
int network_mode_timeout;
|
||||
char *log_prefix;
|
||||
guint operator_poll_id;
|
||||
@@ -78,8 +105,15 @@ struct ril_network_priv {
|
||||
gulong settings_event_id;
|
||||
gulong radio_event_id[RADIO_EVENT_COUNT];
|
||||
gulong simcard_event_id[SIM_EVENT_COUNT];
|
||||
gulong watch_ids[WATCH_EVENT_COUNT];
|
||||
gboolean need_initial_attach_apn;
|
||||
gboolean set_initial_attach_apn;
|
||||
struct ofono_network_operator operator;
|
||||
gboolean assert_rat;
|
||||
gboolean use_data_profiles;
|
||||
int mms_data_profile_id;
|
||||
GSList *data_profiles;
|
||||
guint set_data_profiles_id;
|
||||
};
|
||||
|
||||
enum ril_network_signal {
|
||||
@@ -453,17 +487,20 @@ static enum ofono_radio_access_mode ril_network_rat_to_mode(int rat)
|
||||
static int ril_network_mode_to_rat(struct ril_network *self,
|
||||
enum ofono_radio_access_mode mode)
|
||||
{
|
||||
struct ril_sim_settings *settings = self->settings;
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
|
||||
switch (mode) {
|
||||
case OFONO_RADIO_ACCESS_MODE_ANY:
|
||||
case OFONO_RADIO_ACCESS_MODE_LTE:
|
||||
if (self->settings->techs & OFONO_RADIO_ACCESS_MODE_LTE) {
|
||||
return self->priv->lte_network_mode;
|
||||
if (settings->techs & OFONO_RADIO_ACCESS_MODE_LTE) {
|
||||
return priv->lte_network_mode;
|
||||
}
|
||||
/* no break */
|
||||
default:
|
||||
case OFONO_RADIO_ACCESS_MODE_UMTS:
|
||||
if (self->settings->techs & OFONO_RADIO_ACCESS_MODE_UMTS) {
|
||||
return PREF_NET_TYPE_GSM_WCDMA_AUTO;
|
||||
if (settings->techs & OFONO_RADIO_ACCESS_MODE_UMTS) {
|
||||
return priv->umts_network_mode;
|
||||
}
|
||||
/* no break */
|
||||
case OFONO_RADIO_ACCESS_MODE_GSM:
|
||||
@@ -471,7 +508,8 @@ static int ril_network_mode_to_rat(struct ril_network *self,
|
||||
}
|
||||
}
|
||||
|
||||
static int ril_network_pref_mode_expected(struct ril_network *self)
|
||||
static enum ofono_radio_access_mode ril_network_actual_pref_mode
|
||||
(struct ril_network *self)
|
||||
{
|
||||
struct ril_sim_settings *settings = self->settings;
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
@@ -494,12 +532,285 @@ static int ril_network_pref_mode_expected(struct ril_network *self)
|
||||
* and max_pref_mode are not ANY, we pick the smallest value.
|
||||
* Otherwise we take any non-zero value if there is one.
|
||||
*/
|
||||
const enum ofono_radio_access_mode pref_mode =
|
||||
(settings->pref_mode && max_pref_mode) ?
|
||||
return (settings->pref_mode && max_pref_mode) ?
|
||||
MIN(settings->pref_mode, max_pref_mode) :
|
||||
settings->pref_mode ? settings->pref_mode :
|
||||
max_pref_mode;
|
||||
return ril_network_mode_to_rat(self, pref_mode);
|
||||
settings->pref_mode ? settings->pref_mode : max_pref_mode;
|
||||
}
|
||||
|
||||
static gboolean ril_network_need_initial_attach_apn(struct ril_network *self)
|
||||
{
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
struct ril_radio *radio = priv->radio;
|
||||
struct ofono_watch *watch = priv->watch;
|
||||
|
||||
if (watch->gprs && radio->state == RADIO_STATE_ON) {
|
||||
switch (ril_network_actual_pref_mode(self)) {
|
||||
case OFONO_RADIO_ACCESS_MODE_ANY:
|
||||
case OFONO_RADIO_ACCESS_MODE_LTE:
|
||||
return TRUE;
|
||||
case OFONO_RADIO_ACCESS_MODE_UMTS:
|
||||
case OFONO_RADIO_ACCESS_MODE_GSM:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void ril_network_set_initial_attach_apn(struct ril_network *self,
|
||||
const struct ofono_gprs_primary_context *ctx)
|
||||
{
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
const char *proto = ril_protocol_from_ofono(ctx->proto);
|
||||
const char *username;
|
||||
const char *password;
|
||||
enum ril_auth auth;
|
||||
GRilIoRequest *req;
|
||||
|
||||
if (ctx->username[0] || ctx->password[0]) {
|
||||
auth = ril_auth_method_from_ofono(ctx->auth_method);
|
||||
username = ctx->username;
|
||||
password = ctx->password;
|
||||
} else {
|
||||
auth = RIL_AUTH_NONE;
|
||||
username = "";
|
||||
password = "";
|
||||
}
|
||||
|
||||
req = ril_vendor_set_attach_apn_req(priv->vendor,ctx->apn,
|
||||
username, password, auth, proto);
|
||||
|
||||
if (!req) {
|
||||
/* Default format */
|
||||
req = grilio_request_new();
|
||||
grilio_request_append_utf8(req, ctx->apn);
|
||||
grilio_request_append_utf8(req, proto);
|
||||
grilio_request_append_int32(req, auth);
|
||||
grilio_request_append_utf8(req, username);
|
||||
grilio_request_append_utf8(req, password);
|
||||
}
|
||||
|
||||
DBG_(self, "\"%s\"", ctx->apn);
|
||||
grilio_queue_send_request(priv->q, req,
|
||||
RIL_REQUEST_SET_INITIAL_ATTACH_APN);
|
||||
grilio_request_unref(req);
|
||||
}
|
||||
|
||||
static void ril_network_try_set_initial_attach_apn(struct ril_network *self)
|
||||
{
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
|
||||
if (priv->need_initial_attach_apn && priv->set_initial_attach_apn) {
|
||||
struct ofono_gprs *gprs = priv->watch->gprs;
|
||||
const struct ofono_gprs_primary_context *ctx =
|
||||
ofono_gprs_context_settings_by_type(gprs,
|
||||
OFONO_GPRS_CONTEXT_TYPE_INTERNET);
|
||||
|
||||
if (ctx) {
|
||||
priv->set_initial_attach_apn = FALSE;
|
||||
ril_network_set_initial_attach_apn(self, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_network_check_initial_attach_apn(struct ril_network *self)
|
||||
{
|
||||
const gboolean need = ril_network_need_initial_attach_apn(self);
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
|
||||
if (priv->need_initial_attach_apn != need) {
|
||||
DBG_(self, "%sneed initial attach apn", need ? "" : "don't ");
|
||||
priv->need_initial_attach_apn = need;
|
||||
if (need) {
|
||||
/* We didn't need initial attach APN and now we do */
|
||||
priv->set_initial_attach_apn = TRUE;
|
||||
}
|
||||
}
|
||||
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)
|
||||
@@ -591,7 +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_pref_mode_expected(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);
|
||||
@@ -603,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 {
|
||||
@@ -706,6 +1024,7 @@ void ril_network_set_max_pref_mode(struct ril_network *self,
|
||||
ofono_radio_access_mode_to_string(max_mode));
|
||||
self->max_pref_mode = max_mode;
|
||||
ril_network_emit(self, SIGNAL_MAX_PREF_MODE_CHANGED);
|
||||
ril_network_check_initial_attach_apn(self);
|
||||
}
|
||||
ril_network_check_pref_mode(self, TRUE);
|
||||
}
|
||||
@@ -791,6 +1110,7 @@ static void ril_network_radio_state_cb(struct ril_radio *radio, void *data)
|
||||
struct ril_network *self = RIL_NETWORK(data);
|
||||
|
||||
ril_network_check_pref_mode(self, FALSE);
|
||||
ril_network_check_initial_attach_apn(self);
|
||||
if (radio->state == RADIO_STATE_ON) {
|
||||
ril_network_poll_state(self);
|
||||
}
|
||||
@@ -815,6 +1135,7 @@ static gboolean ril_network_check_pref_mode_cb(gpointer user_data)
|
||||
|
||||
DBG_(self, "checking pref mode");
|
||||
ril_network_check_pref_mode(self, TRUE);
|
||||
ril_network_check_initial_attach_apn(self);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -848,11 +1169,46 @@ static void ril_network_sim_status_changed_cb(struct ril_sim_card *sc,
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_network_watch_gprs_cb(struct ofono_watch *watch,
|
||||
void* user_data)
|
||||
{
|
||||
struct ril_network *self = RIL_NETWORK(user_data);
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void ril_network_watch_gprs_settings_cb(struct ofono_watch *watch,
|
||||
enum ofono_gprs_context_type type,
|
||||
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_priv *priv = self->priv;
|
||||
|
||||
priv->set_initial_attach_apn = TRUE;
|
||||
ril_network_check_initial_attach_apn(self);
|
||||
}
|
||||
}
|
||||
|
||||
struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
||||
const char *log_prefix, struct ril_radio *radio,
|
||||
struct ril_sim_card *simcard,
|
||||
struct ril_sim_settings *settings,
|
||||
const struct ril_slot_config *config)
|
||||
const struct ril_slot_config *config,
|
||||
struct ril_vendor *vendor)
|
||||
{
|
||||
struct ril_network *self = g_object_new(RIL_NETWORK_TYPE, NULL);
|
||||
struct ril_network_priv *priv = self->priv;
|
||||
@@ -862,13 +1218,18 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
||||
priv->q = grilio_queue_new(priv->io);
|
||||
priv->radio = ril_radio_ref(radio);
|
||||
priv->simcard = ril_sim_card_ref(simcard);
|
||||
priv->vendor = ril_vendor_ref(vendor);
|
||||
priv->watch = ofono_watch_new(path);
|
||||
priv->log_prefix = (log_prefix && log_prefix[0]) ?
|
||||
g_strconcat(log_prefix, " ", NULL) : g_strdup("");
|
||||
DBG_(self, "");
|
||||
|
||||
/* Copy relevant config values */
|
||||
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] =
|
||||
@@ -879,12 +1240,14 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
||||
grilio_channel_add_unsol_event_handler(priv->io,
|
||||
ril_network_radio_capability_changed_cb,
|
||||
RIL_UNSOL_RADIO_CAPABILITY, self);
|
||||
|
||||
priv->radio_event_id[RADIO_EVENT_STATE_CHANGED] =
|
||||
ril_radio_add_state_changed_handler(priv->radio,
|
||||
ril_network_radio_state_cb, self);
|
||||
priv->radio_event_id[RADIO_EVENT_ONLINE_CHANGED] =
|
||||
ril_radio_add_online_changed_handler(priv->radio,
|
||||
ril_network_radio_online_cb, self);
|
||||
|
||||
priv->simcard_event_id[SIM_EVENT_STATUS_CHANGED] =
|
||||
ril_sim_card_add_status_changed_handler(priv->simcard,
|
||||
ril_network_sim_status_changed_cb, self);
|
||||
@@ -895,6 +1258,13 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
||||
ril_sim_settings_add_pref_mode_changed_handler(settings,
|
||||
ril_network_pref_mode_changed_cb, self);
|
||||
|
||||
priv->watch_ids[WATCH_EVENT_GPRS] =
|
||||
ofono_watch_add_gprs_changed_handler(priv->watch,
|
||||
ril_network_watch_gprs_cb, self);
|
||||
priv->watch_ids[WATCH_EVENT_GPRS_SETTINGS] =
|
||||
ofono_watch_add_gprs_settings_changed_handler(priv->watch,
|
||||
ril_network_watch_gprs_settings_cb, self);
|
||||
|
||||
/*
|
||||
* Query the initial state. Querying network state before the radio
|
||||
* has been turned on makes RIL unhappy.
|
||||
@@ -906,6 +1276,15 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
||||
ril_network_poll_state(self);
|
||||
}
|
||||
|
||||
priv->set_initial_attach_apn =
|
||||
priv->need_initial_attach_apn =
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -949,6 +1328,8 @@ static void ril_network_finalize(GObject *object)
|
||||
ril_network_stop_timer(self, tid);
|
||||
}
|
||||
|
||||
ofono_watch_remove_all_handlers(priv->watch, priv->watch_ids);
|
||||
ofono_watch_unref(priv->watch);
|
||||
grilio_queue_cancel_all(priv->q, FALSE);
|
||||
grilio_channel_remove_all_handlers(priv->io, priv->unsol_event_id);
|
||||
grilio_channel_unref(priv->io);
|
||||
@@ -960,6 +1341,8 @@ static void ril_network_finalize(GObject *object)
|
||||
ril_sim_settings_remove_handler(self->settings,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -49,7 +49,8 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
||||
const char *log_prefix, struct ril_radio *radio,
|
||||
struct ril_sim_card *sim_card,
|
||||
struct ril_sim_settings *settings,
|
||||
const struct ril_slot_config *ril_slot_config);
|
||||
const struct ril_slot_config *ril_slot_config,
|
||||
struct ril_vendor *vendor);
|
||||
struct ril_network *ril_network_ref(struct ril_network *net);
|
||||
void ril_network_unref(struct ril_network *net);
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||
* Contact: Slava Monich <slava.monich@jolla.com>
|
||||
* 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
|
||||
@@ -25,10 +24,11 @@
|
||||
#include "ril_data.h"
|
||||
#include "ril_util.h"
|
||||
#include "ril_vendor.h"
|
||||
#include "ril_devmon.h"
|
||||
#include "ril_log.h"
|
||||
|
||||
#include <sailfish_manager.h>
|
||||
#include <sailfish_watch.h>
|
||||
#include <ofono/sailfish_manager.h>
|
||||
#include <ofono/watch.h>
|
||||
|
||||
#include <grilio_transport.h>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <gutil_macros.h>
|
||||
#include <gutil_misc.h>
|
||||
|
||||
#include <mce_display.h>
|
||||
#include <mce_log.h>
|
||||
|
||||
#include <linux/capability.h>
|
||||
@@ -68,9 +67,11 @@
|
||||
#define RILMODEM_DEFAULT_SUB "SUB1"
|
||||
#define RILMODEM_DEFAULT_TECHS OFONO_RADIO_ACCESS_MODE_ALL
|
||||
#define RILMODEM_DEFAULT_LTE_MODE PREF_NET_TYPE_LTE_GSM_WCDMA
|
||||
#define RILMODEM_DEFAULT_UMTS_MODE PREF_NET_TYPE_GSM_WCDMA_AUTO
|
||||
#define RILMODEM_DEFAULT_NETWORK_MODE_TIMEOUT (20*1000) /* ms */
|
||||
#define RILMODEM_DEFAULT_ENABLE_VOICECALL TRUE
|
||||
#define RILMODEM_DEFAULT_ENABLE_CBS TRUE
|
||||
#define RILMODEM_DEFAULT_ENABLE_STK TRUE
|
||||
#define RILMODEM_DEFAULT_SLOT 0xffffffff
|
||||
#define RILMODEM_DEFAULT_TIMEOUT 0 /* No timeout */
|
||||
#define RILMODEM_DEFAULT_SIM_FLAGS RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND
|
||||
@@ -85,8 +86,13 @@
|
||||
#define RILMODEM_DEFAULT_LEGACY_IMEI_QUERY FALSE
|
||||
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
|
||||
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
|
||||
#define RILMODEM_DEFAULT_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 */
|
||||
#define RIL_TRANSPORT_MODEM "modem"
|
||||
#define RIL_TRANSPORT_SOCKET "socket"
|
||||
#define RIL_TRANSPORT_SOCKET_PATH "path"
|
||||
#define RIL_TRANSPORT_SOCKET_SUB "sub"
|
||||
@@ -114,8 +120,10 @@
|
||||
#define RILCONF_4G "enable4G" /* Deprecated */
|
||||
#define RILCONF_ENABLE_VOICECALL "enableVoicecall"
|
||||
#define RILCONF_ENABLE_CBS "enableCellBroadcast"
|
||||
#define RILCONF_ENABLE_STK "enableSimToolkit"
|
||||
#define RILCONF_TECHNOLOGIES "technologies"
|
||||
#define RILCONF_LTE_MODE "lteNetworkMode"
|
||||
#define RILCONF_UMTS_MODE "umtsNetworkMode"
|
||||
#define RILCONF_NETWORK_MODE_TIMEOUT "networkModeTimeout"
|
||||
#define RILCONF_UICC_WORKAROUND "uiccWorkaround"
|
||||
#define RILCONF_ECCLIST_FILE "ecclistFile"
|
||||
@@ -130,6 +138,11 @@
|
||||
#define RILCONF_LEGACY_IMEI_QUERY "legacyImeiQuery"
|
||||
#define RILCONF_RADIO_POWER_CYCLE "radioPowerCycle"
|
||||
#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"
|
||||
@@ -143,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
|
||||
@@ -160,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;
|
||||
@@ -178,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;
|
||||
|
||||
@@ -186,7 +199,7 @@ typedef struct sailfish_slot_impl {
|
||||
ril_plugin* plugin;
|
||||
struct sailfish_slot *handle;
|
||||
struct sailfish_cell_info *cell_info;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
gulong watch_event_id[WATCH_EVENT_COUNT];
|
||||
char *path;
|
||||
char *imei;
|
||||
@@ -207,15 +220,15 @@ typedef struct sailfish_slot_impl {
|
||||
struct ril_sim_card *sim_card;
|
||||
struct ril_sim_settings *sim_settings;
|
||||
struct ril_oem_raw *oem_raw;
|
||||
const struct ril_vendor_driver *vendor;
|
||||
struct ril_vendor_hook *vendor_hook;
|
||||
const struct ril_vendor_driver *vendor_driver;
|
||||
struct ril_vendor *vendor;
|
||||
struct ril_data *data;
|
||||
gboolean legacy_imei_query;
|
||||
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;
|
||||
@@ -245,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 = {
|
||||
@@ -327,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);
|
||||
@@ -387,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;
|
||||
@@ -422,9 +405,9 @@ static void ril_plugin_shutdown_slot(ril_slot *slot, gboolean kill_io)
|
||||
slot->received_sim_status = FALSE;
|
||||
}
|
||||
|
||||
if (slot->vendor_hook) {
|
||||
ril_vendor_hook_unref(slot->vendor_hook);
|
||||
slot->vendor_hook = NULL;
|
||||
if (slot->vendor) {
|
||||
ril_vendor_unref(slot->vendor);
|
||||
slot->vendor = NULL;
|
||||
}
|
||||
|
||||
if (slot->io) {
|
||||
@@ -746,7 +729,7 @@ static void ril_plugin_trace(GRilIoChannel *io, GRILIO_PACKET_TYPE type,
|
||||
guint id, guint code, const void *data, guint data_len, void *user_data)
|
||||
{
|
||||
ril_slot *slot = user_data;
|
||||
struct ril_vendor_hook *hook = slot->vendor_hook;
|
||||
struct ril_vendor *vendor = slot->vendor;
|
||||
static const GLogModule* log_module = &ril_debug_trace_module;
|
||||
const char *prefix = io->name ? io->name : "";
|
||||
const char dir = (type == GRILIO_PACKET_REQ) ? '<' : '>';
|
||||
@@ -758,8 +741,9 @@ static void ril_plugin_trace(GRilIoChannel *io, GRILIO_PACKET_TYPE type,
|
||||
code == RIL_REQUEST_V9_SET_UICC_SUBSCRIPTION) {
|
||||
scode = "V9_SET_UICC_SUBSCRIPTION";
|
||||
} else {
|
||||
scode = ril_vendor_hook_request_to_string(hook, code);
|
||||
scode = ril_vendor_request_to_string(vendor, code);
|
||||
if (!scode) {
|
||||
/* Not a vendor specific request */
|
||||
scode = ril_request_to_string(code);
|
||||
}
|
||||
}
|
||||
@@ -777,8 +761,9 @@ static void ril_plugin_trace(GRilIoChannel *io, GRILIO_PACKET_TYPE type,
|
||||
break;
|
||||
case GRILIO_PACKET_UNSOL:
|
||||
case GRILIO_PACKET_UNSOL_ACK_EXP:
|
||||
scode = ril_vendor_hook_event_to_string(hook, code);
|
||||
scode = ril_vendor_event_to_string(vendor, code);
|
||||
if (!scode) {
|
||||
/* Not a vendor specific event */
|
||||
scode = ril_unsol_event_to_string(code);
|
||||
}
|
||||
gutil_log(log_module, GLOG_LEVEL_VERBOSE, "%s%c %s",
|
||||
@@ -923,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)
|
||||
@@ -999,24 +977,24 @@ static void ril_plugin_slot_connected(ril_slot *slot)
|
||||
GASSERT(!slot->sim_card->status);
|
||||
GASSERT(!slot->received_sim_status);
|
||||
|
||||
GASSERT(!slot->vendor);
|
||||
slot->vendor = ril_vendor_create(slot->vendor_driver, slot->io,
|
||||
slot->path, &slot->config);
|
||||
|
||||
GASSERT(!slot->network);
|
||||
slot->network = ril_network_new(slot->path, slot->io, log_prefix,
|
||||
slot->radio, slot->sim_card, slot->sim_settings,
|
||||
&slot->config);
|
||||
|
||||
GASSERT(!slot->vendor_hook);
|
||||
slot->vendor_hook = ril_vendor_create_hook(slot->vendor, slot->io,
|
||||
slot->path, &slot->config, slot->network);
|
||||
&slot->config, slot->vendor);
|
||||
|
||||
GASSERT(!slot->data);
|
||||
slot->data = ril_data_new(plugin->data_manager, log_prefix,
|
||||
slot->radio, slot->network, slot->io, &slot->data_opt,
|
||||
&slot->config, slot->vendor_hook);
|
||||
&slot->config, slot->vendor);
|
||||
|
||||
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);
|
||||
@@ -1030,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);
|
||||
@@ -1039,16 +1023,17 @@ static void ril_plugin_slot_connected(ril_slot *slot)
|
||||
slot->start_timeout_id = 0;
|
||||
|
||||
/* Register this slot with the sailfish manager plugin */
|
||||
slot->handle = sailfish_manager_slot_add(plugin->handle, slot,
|
||||
slot->handle = sailfish_manager_slot_add2(plugin->handle, slot,
|
||||
slot->path, slot->config.techs, slot->imei,
|
||||
slot->imeisv, ril_plugin_sim_state(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);
|
||||
}
|
||||
@@ -1126,7 +1111,7 @@ static void ril_plugin_retry_init_io(ril_slot *slot)
|
||||
ril_plugin_retry_init_io_cb, slot);
|
||||
}
|
||||
|
||||
static void ril_plugin_slot_modem_changed(struct sailfish_watch *w,
|
||||
static void ril_plugin_slot_modem_changed(struct ofono_watch *w,
|
||||
void *user_data)
|
||||
{
|
||||
ril_slot *slot = user_data;
|
||||
@@ -1152,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);
|
||||
sailfish_watch_remove_all_handlers(slot->watch, slot->watch_event_id);
|
||||
sailfish_watch_unref(slot->watch);
|
||||
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);
|
||||
@@ -1196,16 +1180,23 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
|
||||
config->slot = slot_index;
|
||||
config->techs = RILMODEM_DEFAULT_TECHS;
|
||||
config->lte_network_mode = RILMODEM_DEFAULT_LTE_MODE;
|
||||
config->umts_network_mode = RILMODEM_DEFAULT_UMTS_MODE;
|
||||
config->empty_pin_query = RILMODEM_DEFAULT_EMPTY_PIN_QUERY;
|
||||
config->radio_power_cycle = RILMODEM_DEFAULT_RADIO_POWER_CYCLE;
|
||||
config->confirm_radio_power_on =
|
||||
RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON;
|
||||
config->enable_voicecall = RILMODEM_DEFAULT_ENABLE_VOICECALL;
|
||||
config->enable_cbs = RILMODEM_DEFAULT_ENABLE_CBS;
|
||||
config->enable_stk = RILMODEM_DEFAULT_ENABLE_STK;
|
||||
config->query_available_band_mode =
|
||||
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;
|
||||
slot->legacy_imei_query = RILMODEM_DEFAULT_LEGACY_IMEI_QUERY;
|
||||
slot->start_timeout = RILMODEM_DEFAULT_START_TIMEOUT;
|
||||
slot->data_opt.allow_data = RILMODEM_DEFAULT_DATA_OPT;
|
||||
@@ -1215,25 +1206,17 @@ 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->watch = sailfish_watch_new(dbus_path);
|
||||
slot->devmon = ril_devmon_auto_new();
|
||||
slot->watch = ofono_watch_new(dbus_path);
|
||||
slot->watch_event_id[WATCH_EVENT_MODEM] =
|
||||
sailfish_watch_add_modem_changed_handler(slot->watch,
|
||||
ofono_watch_add_modem_changed_handler(slot->watch,
|
||||
ril_plugin_slot_modem_changed, slot);
|
||||
return slot;
|
||||
}
|
||||
|
||||
static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
|
||||
{
|
||||
if (slot->vendor) {
|
||||
if (slot->vendor_driver) {
|
||||
struct ril_slot_config *config = &slot->config;
|
||||
struct ril_vendor_defaults defaults;
|
||||
|
||||
@@ -1241,14 +1224,20 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
|
||||
memset(&defaults, 0, sizeof(defaults));
|
||||
defaults.legacy_imei_query = slot->legacy_imei_query;
|
||||
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;
|
||||
|
||||
ril_vendor_get_defaults(slot->vendor, &defaults);
|
||||
ril_vendor_get_defaults(slot->vendor_driver, &defaults);
|
||||
slot->legacy_imei_query = defaults.legacy_imei_query;
|
||||
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;
|
||||
}
|
||||
@@ -1353,9 +1342,11 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
{
|
||||
ril_slot *slot;
|
||||
struct ril_slot_config *config;
|
||||
gboolean bval;
|
||||
int ival;
|
||||
char *sval;
|
||||
char **strv;
|
||||
char *modem;
|
||||
GHashTable *transport_params = g_hash_table_new_full(g_str_hash,
|
||||
g_str_equal, g_free, g_free);
|
||||
char *transport = NULL;
|
||||
@@ -1401,8 +1392,14 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
slot = ril_plugin_slot_new_take(transport, transport_params,
|
||||
g_strconcat("/", group, NULL),
|
||||
/* ril_plugin_slot_new_take() will take ownership of this memory */
|
||||
modem = g_strconcat("/", group, NULL);
|
||||
|
||||
/* Add "modem" entry to point to the actual modem path */
|
||||
g_hash_table_replace(transport_params, g_strdup(RIL_TRANSPORT_MODEM),
|
||||
g_strdup(modem));
|
||||
|
||||
slot = ril_plugin_slot_new_take(transport, transport_params, modem,
|
||||
ril_config_get_string(file, group, RILCONF_NAME),
|
||||
RILMODEM_DEFAULT_SLOT);
|
||||
config = &slot->config;
|
||||
@@ -1417,17 +1414,11 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
/* vendorDriver */
|
||||
sval = ril_config_get_string(file, group, RILCONF_VENDOR_DRIVER);
|
||||
if (sval) {
|
||||
const struct ril_vendor_driver *vendor;
|
||||
RIL_VENDOR_DRIVER_FOREACH(vendor) {
|
||||
if (!strcasecmp(vendor->name, sval)) {
|
||||
DBG("%s: " RILCONF_VENDOR_DRIVER " %s", group,
|
||||
sval);
|
||||
slot->vendor = vendor;
|
||||
ril_plugin_slot_apply_vendor_defaults(slot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!slot->vendor) {
|
||||
slot->vendor_driver = ril_vendor_find_driver(sval);
|
||||
if (slot->vendor_driver) {
|
||||
DBG("%s: " RILCONF_VENDOR_DRIVER " %s", group, sval);
|
||||
ril_plugin_slot_apply_vendor_defaults(slot);
|
||||
} else {
|
||||
ofono_warn("Unknown vendor '%s'", sval);
|
||||
}
|
||||
g_free(sval);
|
||||
@@ -1460,6 +1451,36 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
config->enable_cbs ? "yes" : "no");
|
||||
}
|
||||
|
||||
/* enableSimTookit */
|
||||
if (ril_config_get_boolean(file, group, RILCONF_ENABLE_STK,
|
||||
&config->enable_stk)) {
|
||||
DBG("%s: " RILCONF_ENABLE_STK " %s", group,
|
||||
config->enable_stk ? "yes" : "no");
|
||||
}
|
||||
|
||||
/* networkSelectionManual0 */
|
||||
if (ril_config_get_boolean(file, group,
|
||||
RILCONF_NETWORK_SELECTION_MANUAL_0,
|
||||
&config->network_selection_manual_0)) {
|
||||
DBG("%s: " RILCONF_NETWORK_SELECTION_MANUAL_0 " %s", group,
|
||||
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) {
|
||||
@@ -1497,10 +1518,15 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
}
|
||||
|
||||
/* lteNetworkMode */
|
||||
if (ril_config_get_integer(file, group, RILCONF_LTE_MODE,
|
||||
&config->lte_network_mode)) {
|
||||
DBG("%s: " RILCONF_LTE_MODE " %d", group,
|
||||
config->lte_network_mode);
|
||||
if (ril_config_get_integer(file, group, RILCONF_LTE_MODE, &ival)) {
|
||||
DBG("%s: " RILCONF_LTE_MODE " %d", group, ival);
|
||||
config->lte_network_mode = ival;
|
||||
}
|
||||
|
||||
/* umtsNetworkMode */
|
||||
if (ril_config_get_integer(file, group, RILCONF_UMTS_MODE, &ival)) {
|
||||
DBG("%s: " RILCONF_UMTS_MODE " %d", group, ival);
|
||||
config->umts_network_mode = ival;
|
||||
}
|
||||
|
||||
/* networkModeTimeout */
|
||||
@@ -1540,6 +1566,14 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
config->confirm_radio_power_on ? "on" : "off");
|
||||
}
|
||||
|
||||
/* singleDataContext */
|
||||
if (ril_config_get_boolean(file, group, RILCONF_SINGLE_DATA_CONTEXT,
|
||||
&bval) && bval) {
|
||||
DBG("%s: " RILCONF_SINGLE_DATA_CONTEXT " %s", group,
|
||||
bval ? "on" : "off");
|
||||
slot->slot_flags |= SAILFISH_SLOT_SINGLE_CONTEXT;
|
||||
}
|
||||
|
||||
/* uiccWorkaround */
|
||||
if (ril_config_get_flag(file, group, RILCONF_UICC_WORKAROUND,
|
||||
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND,
|
||||
@@ -1626,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;
|
||||
}
|
||||
|
||||
@@ -1967,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;
|
||||
@@ -2041,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);
|
||||
@@ -2062,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -18,7 +18,8 @@
|
||||
#include "ril_util.h"
|
||||
#include "ril_log.h"
|
||||
|
||||
#include "sailfish_watch.h"
|
||||
#include <ofono/watch.h>
|
||||
|
||||
#include "simutil.h"
|
||||
#include "util.h"
|
||||
#include "ofono.h"
|
||||
@@ -92,7 +93,7 @@ struct ril_sim {
|
||||
const char *log_prefix;
|
||||
char *allocated_log_prefix;
|
||||
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
gulong sim_state_watch_id;
|
||||
|
||||
/* query_passwd_state context */
|
||||
@@ -872,7 +873,7 @@ static void ril_sim_status_changed_cb(struct ril_sim_card *sc, void *user_data)
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_sim_state_changed_cb(struct sailfish_watch *watch, void *data)
|
||||
static void ril_sim_state_changed_cb(struct ofono_watch *watch, void *data)
|
||||
{
|
||||
struct ril_sim *sd = data;
|
||||
const enum ofono_sim_state state = ofono_sim_get_state(watch->sim);
|
||||
@@ -1445,7 +1446,7 @@ static gboolean ril_sim_register(gpointer user)
|
||||
ril_sim_card_add_app_changed_handler(sd->card,
|
||||
ril_sim_app_changed_cb, sd);
|
||||
sd->sim_state_watch_id =
|
||||
sailfish_watch_add_sim_state_changed_handler(sd->watch,
|
||||
ofono_watch_add_sim_state_changed_handler(sd->watch,
|
||||
ril_sim_state_changed_cb, sd);
|
||||
|
||||
/* And RIL events */
|
||||
@@ -1470,7 +1471,7 @@ static int ril_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
||||
sd->io = grilio_channel_ref(ril_modem_io(modem));
|
||||
sd->card = ril_sim_card_ref(modem->sim_card);
|
||||
sd->q = grilio_queue_new(sd->io);
|
||||
sd->watch = sailfish_watch_new(ril_modem_get_path(modem));
|
||||
sd->watch = ofono_watch_new(ril_modem_get_path(modem));
|
||||
|
||||
if (modem->log_prefix && modem->log_prefix[0]) {
|
||||
sd->log_prefix = sd->allocated_log_prefix =
|
||||
@@ -1508,8 +1509,8 @@ static void ril_sim_remove(struct ofono_sim *sim)
|
||||
sd->query_passwd_state_sim_status_refresh_id);
|
||||
}
|
||||
|
||||
sailfish_watch_remove_handler(sd->watch, sd->sim_state_watch_id);
|
||||
sailfish_watch_unref(sd->watch);
|
||||
ofono_watch_remove_handler(sd->watch, sd->sim_state_watch_id);
|
||||
ofono_watch_unref(sd->watch);
|
||||
|
||||
ril_sim_card_remove_handlers(sd->card, sd->card_event_id,
|
||||
G_N_ELEMENTS(sd->card_event_id));
|
||||
|
||||
@@ -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
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "ril_sim_settings.h"
|
||||
#include "ril_log.h"
|
||||
|
||||
#include "sailfish_watch.h"
|
||||
#include <ofono/watch.h>
|
||||
|
||||
#include <gutil_misc.h>
|
||||
|
||||
@@ -30,14 +30,14 @@
|
||||
typedef GObjectClass RilSimSettingsClass;
|
||||
typedef struct ril_sim_settings RilSimSettings;
|
||||
|
||||
enum sailfish_watch_events {
|
||||
enum ofono_watch_events {
|
||||
WATCH_EVENT_IMSI,
|
||||
WATCH_EVENT_COUNT
|
||||
};
|
||||
|
||||
struct ril_sim_settings_priv {
|
||||
gulong watch_event_id[WATCH_EVENT_COUNT];
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
char *imsi;
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ void ril_sim_settings_set_pref_mode(struct ril_sim_settings *self,
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_sim_settings_imsi_changed(struct sailfish_watch *watch,
|
||||
static void ril_sim_settings_imsi_changed(struct ofono_watch *watch,
|
||||
void *user_data)
|
||||
{
|
||||
struct ril_sim_settings *self = RIL_SIM_SETTINGS(user_data);
|
||||
@@ -106,9 +106,9 @@ struct ril_sim_settings *ril_sim_settings_new(const char *path,
|
||||
priv = self->priv;
|
||||
self->techs = techs;
|
||||
self->pref_mode = RIL_PREF_MODE_DEFAULT(self);
|
||||
priv->watch = sailfish_watch_new(path);
|
||||
priv->watch = ofono_watch_new(path);
|
||||
priv->watch_event_id[WATCH_EVENT_IMSI] =
|
||||
sailfish_watch_add_imsi_changed_handler(priv->watch,
|
||||
ofono_watch_add_imsi_changed_handler(priv->watch,
|
||||
ril_sim_settings_imsi_changed, self);
|
||||
self->imsi = priv->imsi = g_strdup(priv->watch->imsi);
|
||||
}
|
||||
@@ -173,8 +173,8 @@ static void ril_sim_settings_finalize(GObject *object)
|
||||
struct ril_sim_settings *self = RIL_SIM_SETTINGS(object);
|
||||
struct ril_sim_settings_priv *priv = self->priv;
|
||||
|
||||
sailfish_watch_remove_all_handlers(priv->watch, priv->watch_event_id);
|
||||
sailfish_watch_unref(priv->watch);
|
||||
ofono_watch_remove_all_handlers(priv->watch, priv->watch_event_id);
|
||||
ofono_watch_unref(priv->watch);
|
||||
g_free(priv->imsi);
|
||||
G_OBJECT_CLASS(ril_sim_settings_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
# If it's set to true, all [ril_x] sections are ignored even
|
||||
# if they are present, and no default configurtation is created.
|
||||
#
|
||||
# Default is false
|
||||
# Default false
|
||||
#
|
||||
#EmptyConfig=false
|
||||
|
||||
# User and group for the ofono process. RIL clients are typically
|
||||
# expected to run under radio:radio.
|
||||
#
|
||||
# Default is radio:radio
|
||||
# Default radio:radio
|
||||
#
|
||||
#Identity=radio:radio
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# 3G/LTE modules for each slot or you don't need 4G for both slots).
|
||||
# Obviously, it only has any effect if you have more than one SIM.
|
||||
#
|
||||
# Default is true (switch the current data modem to 2G when changing
|
||||
# Defaults to true (switch the current data modem to 2G when changing
|
||||
# the data modems)
|
||||
#
|
||||
#3GLTEHandover=true
|
||||
@@ -49,7 +49,7 @@
|
||||
#
|
||||
# Possible values are auto, on and off
|
||||
#
|
||||
# Default is auto (enable for RIL version >= 11)
|
||||
# Default auto (enable for RIL version >= 11)
|
||||
#
|
||||
#SetRadioCapability=auto
|
||||
|
||||
@@ -81,7 +81,7 @@ socket=/dev/socket/rild
|
||||
|
||||
# RIL request timeout, in milliseconds.
|
||||
#
|
||||
# The default is zero (no timeout)
|
||||
# Default zero (no timeout)
|
||||
#
|
||||
#timeout=0
|
||||
|
||||
@@ -89,7 +89,7 @@ socket=/dev/socket/rild
|
||||
# Valid technologies are "gsm", "umts" and "lte". The special value
|
||||
# "all" means that all technologies are supported.
|
||||
#
|
||||
# The default is all
|
||||
# Default all
|
||||
#
|
||||
#technologies=all
|
||||
|
||||
@@ -102,7 +102,7 @@ socket=/dev/socket/rild
|
||||
# which RIL version it's dealing with, it makes the decision at runtime.
|
||||
# Settings it to false disables the workaround and always sends 122.
|
||||
#
|
||||
# Default is true (select SET_UICC_SUBSCRIPTION based on the RIL version)
|
||||
# Default true (select SET_UICC_SUBSCRIPTION based on the RIL version)
|
||||
#
|
||||
#uiccWorkaround=true
|
||||
|
||||
@@ -124,7 +124,7 @@ socket=/dev/socket/rild
|
||||
# This option allows you to forcibly enable or disable use of this request.
|
||||
# Possible values are auto, on and off
|
||||
#
|
||||
# Default is auto (enable for RIL version >= 11)
|
||||
# Default auto (enable for RIL version >= 11)
|
||||
#
|
||||
#allowDataReq=auto
|
||||
|
||||
@@ -134,7 +134,7 @@ socket=/dev/socket/rild
|
||||
# actually does check the empty pin (and decrements the retry count)
|
||||
# then you should turn this feature off.
|
||||
#
|
||||
# Default is true
|
||||
# Default true
|
||||
#
|
||||
#emptyPinQuery=true
|
||||
|
||||
@@ -146,7 +146,7 @@ socket=/dev/socket/rild
|
||||
# but sometimes you have to explicitly tell ofono which one to use.
|
||||
# Possible values are 6, 9, 11 and auto.
|
||||
#
|
||||
# Default is auto
|
||||
# Default auto
|
||||
#
|
||||
#dataCallFormat=auto
|
||||
|
||||
@@ -155,7 +155,7 @@ socket=/dev/socket/rild
|
||||
# this parameter. Usually, one retry is enough. The first retry occurs
|
||||
# immediately, the subsequent ones after dataCallRetryDelay (see below)
|
||||
#
|
||||
# Default is 4
|
||||
# Default 4
|
||||
#
|
||||
#dataCallRetryLimit=4
|
||||
|
||||
@@ -163,7 +163,7 @@ socket=/dev/socket/rild
|
||||
# retry occurs immediately after the first failure, the delays are only
|
||||
# applied if the first retry fails too.
|
||||
#
|
||||
# Default is 200 ms
|
||||
# Default 200 ms
|
||||
#
|
||||
#dataCallRetryDelay=200
|
||||
|
||||
@@ -191,6 +191,13 @@ socket=/dev/socket/rild
|
||||
#
|
||||
#enableCellBroadcast=true
|
||||
|
||||
# Support for Sim Toolkit (STK). By default, its enabled but if your rild
|
||||
# and/or modem is not happy about it, you can turn it off.
|
||||
#
|
||||
# Default true
|
||||
#
|
||||
#enableSimToolkit=true
|
||||
|
||||
# Timeout for the modem to show up, in milliseconds. Those that don't
|
||||
# show up before this timeout expires, will be dropped (ignored).
|
||||
#
|
||||
@@ -198,7 +205,7 @@ socket=/dev/socket/rild
|
||||
# optional modems (which may or may not be available), to speed up the
|
||||
# boot up process.
|
||||
#
|
||||
# The default is 20000 (20 seconds)
|
||||
# Default 20000 (20 seconds)
|
||||
#
|
||||
#startTimeout=20000
|
||||
|
||||
@@ -206,26 +213,26 @@ socket=/dev/socket/rild
|
||||
# RIL_REQUEST_DEVICE_IDENTITY to query IMEI from the modem. Some
|
||||
# RILs (e.g. MTK) still don't understand RIL_REQUEST_DEVICE_IDENTITY.
|
||||
#
|
||||
# Default is false (use RIL_REQUEST_DEVICE_IDENTITY)
|
||||
# Default false (use RIL_REQUEST_DEVICE_IDENTITY)
|
||||
#
|
||||
#legacyImeiQuery=false
|
||||
|
||||
# Some devices don't support LTE RAT mode PREF_NET_TYPE_LTE_GSM_WCDMA.
|
||||
# This option allows to set a custom LTE mode.
|
||||
#
|
||||
# The default is 9 (PREF_NET_TYPE_LTE_GSM_WCDMA)
|
||||
# Default 9 (PREF_NET_TYPE_LTE_GSM_WCDMA)
|
||||
#
|
||||
#lteNetworkMode=9
|
||||
|
||||
# Timeout for RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, in milliseconds.
|
||||
#
|
||||
# The default is 20000 (20 seconds)
|
||||
# Default 20000 (20 seconds)
|
||||
#
|
||||
#networkModeTimeout=20000
|
||||
|
||||
# Cycle radio power at startup.
|
||||
#
|
||||
# The default is true (cycle the power)
|
||||
# Default true (cycle the power)
|
||||
#
|
||||
#radioPowerCycle=true
|
||||
|
||||
@@ -237,6 +244,49 @@ socket=/dev/socket/rild
|
||||
# On the other hand, with some RILs it's causing some trouble (like this
|
||||
# extra RIL_REQUEST_RADIO_POWER getting stuck indefinitely).
|
||||
#
|
||||
# The default is true for historical reasons
|
||||
# Default true (for historical reasons)
|
||||
#
|
||||
#confirmRadioPowerOn=true
|
||||
|
||||
# Normally we should be able to have two simultaneously active data
|
||||
# contexts - one for mobile data and one for MMS. Some devices however
|
||||
# require that mobile data is disconnected before we can send or receive
|
||||
# MMS. In other words, activation of the second data context fails.
|
||||
#
|
||||
# Default false (more than one context is supported)
|
||||
#
|
||||
#singleDataContext=false
|
||||
|
||||
# Configures whether +0 is added to MCCMNC string passed to
|
||||
# RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL. Some Qualcomm RILs
|
||||
# require it, some MediaTek RILs don't like it.
|
||||
#
|
||||
# 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
|
||||
|
||||
@@ -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
|
||||
@@ -46,12 +46,13 @@ struct ril_modem;
|
||||
struct ril_radio;
|
||||
struct ril_network;
|
||||
struct ril_sim_card;
|
||||
struct ril_vendor_hook;
|
||||
struct ril_vendor;
|
||||
|
||||
struct ril_slot_config {
|
||||
guint slot;
|
||||
enum ofono_radio_access_mode techs;
|
||||
int lte_network_mode;
|
||||
enum ril_pref_net_type lte_network_mode;
|
||||
enum ril_pref_net_type umts_network_mode;
|
||||
int network_mode_timeout;
|
||||
gboolean query_available_band_mode;
|
||||
gboolean empty_pin_query;
|
||||
@@ -59,6 +60,10 @@ struct ril_slot_config {
|
||||
gboolean confirm_radio_power_on;
|
||||
gboolean enable_voicecall;
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -26,6 +26,10 @@
|
||||
#include "common.h"
|
||||
#include "netreg.h"
|
||||
|
||||
#define RIL_PROTO_IP_STR "IP"
|
||||
#define RIL_PROTO_IPV6_STR "IPV6"
|
||||
#define RIL_PROTO_IPV4V6_STR "IPV4V6"
|
||||
|
||||
const char *ril_error_to_string(int error)
|
||||
{
|
||||
#define RIL_E_(name) case RIL_E_##name: return #name
|
||||
@@ -235,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:
|
||||
@@ -321,6 +337,50 @@ const char *ril_radio_state_to_string(int radio_state)
|
||||
}
|
||||
}
|
||||
|
||||
const char *ril_protocol_from_ofono(enum ofono_gprs_proto proto)
|
||||
{
|
||||
switch (proto) {
|
||||
case OFONO_GPRS_PROTO_IPV6:
|
||||
return RIL_PROTO_IPV6_STR;
|
||||
case OFONO_GPRS_PROTO_IPV4V6:
|
||||
return RIL_PROTO_IPV4V6_STR;
|
||||
case OFONO_GPRS_PROTO_IP:
|
||||
return RIL_PROTO_IP_STR;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ril_protocol_to_ofono(const gchar *str)
|
||||
{
|
||||
if (str) {
|
||||
if (!strcmp(str, RIL_PROTO_IPV6_STR)) {
|
||||
return OFONO_GPRS_PROTO_IPV6;
|
||||
} else if (!strcmp(str, RIL_PROTO_IPV4V6_STR)) {
|
||||
return OFONO_GPRS_PROTO_IPV4V6;
|
||||
} else if (!strcmp(str, RIL_PROTO_IP_STR)) {
|
||||
return OFONO_GPRS_PROTO_IP;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
enum ril_auth ril_auth_method_from_ofono(enum ofono_gprs_auth_method auth)
|
||||
{
|
||||
switch (auth) {
|
||||
case OFONO_GPRS_AUTH_METHOD_NONE:
|
||||
return RIL_AUTH_NONE;
|
||||
case OFONO_GPRS_AUTH_METHOD_CHAP:
|
||||
return RIL_AUTH_CHAP;
|
||||
case OFONO_GPRS_AUTH_METHOD_PAP:
|
||||
return RIL_AUTH_PAP;
|
||||
case OFONO_GPRS_AUTH_METHOD_ANY:
|
||||
/* Use default */
|
||||
break;
|
||||
}
|
||||
/* Default */
|
||||
return RIL_AUTH_BOTH;
|
||||
}
|
||||
|
||||
/* Returns enum access_technology or -1 on failure. */
|
||||
int ril_parse_tech(const char *stech, int *ril_tech)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -18,12 +18,17 @@
|
||||
|
||||
#include "ril_types.h"
|
||||
|
||||
#include <ofono/gprs-context.h>
|
||||
|
||||
struct ofono_network_operator;
|
||||
|
||||
const char *ril_error_to_string(int error);
|
||||
const char *ril_request_to_string(guint request);
|
||||
const char *ril_unsol_event_to_string(guint event);
|
||||
const char *ril_radio_state_to_string(int radio_state);
|
||||
const char *ril_protocol_from_ofono(enum ofono_gprs_proto proto);
|
||||
int ril_protocol_to_ofono(const char *str);
|
||||
enum ril_auth ril_auth_method_from_ofono(enum ofono_gprs_auth_method auth);
|
||||
int ril_parse_tech(const char *stech, int *ril_tech);
|
||||
gboolean ril_parse_mcc_mnc(const char *str, struct ofono_network_operator *op);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2016-2018 Jolla Ltd.
|
||||
* 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
|
||||
@@ -14,147 +14,184 @@
|
||||
*/
|
||||
|
||||
#include "ril_vendor.h"
|
||||
#include "ril_vendor_impl.h"
|
||||
#include "ril_log.h"
|
||||
|
||||
struct ril_vendor_hook *ril_vendor_create_hook
|
||||
(const struct ril_vendor_driver *vendor, GRilIoChannel *io,
|
||||
const char *path, const struct ril_slot_config *config,
|
||||
struct ril_network *network)
|
||||
{
|
||||
if (vendor) {
|
||||
const void *data = vendor->driver_data;
|
||||
#include <grilio_channel.h>
|
||||
|
||||
/*
|
||||
* NOTE: we are looking for the callback in the base but
|
||||
* keeping the original driver data.
|
||||
*/
|
||||
while (!vendor->create_hook && vendor->base) {
|
||||
vendor = vendor->base;
|
||||
}
|
||||
if (vendor->create_hook) {
|
||||
return vendor->create_hook(data, io, path, config,
|
||||
network);
|
||||
G_DEFINE_ABSTRACT_TYPE(RilVendor, ril_vendor, G_TYPE_OBJECT)
|
||||
|
||||
/* Vendor driver descriptors are in the "__vendor" section */
|
||||
extern const struct ril_vendor_driver __start___vendor[];
|
||||
extern const struct ril_vendor_driver __stop___vendor[];
|
||||
|
||||
const struct ril_vendor_driver *ril_vendor_find_driver(const char *name)
|
||||
{
|
||||
if (name) {
|
||||
const struct ril_vendor_driver *d;
|
||||
|
||||
for (d = __start___vendor; d < __stop___vendor; d++) {
|
||||
if (!strcasecmp(d->name, name)) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ril_vendor_hook *ril_vendor_hook_init(struct ril_vendor_hook *self,
|
||||
const struct ril_vendor_hook_proc *proc,
|
||||
ril_vendor_hook_free_proc free)
|
||||
RilVendor *ril_vendor_create(const struct ril_vendor_driver *driver,
|
||||
GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *config)
|
||||
{
|
||||
self->proc = proc;
|
||||
self->free = free;
|
||||
g_atomic_int_set(&self->ref_count, 1);
|
||||
return self;
|
||||
return (driver && driver->create_vendor) ?
|
||||
driver->create_vendor(driver->driver_data, io, path, config) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
struct ril_vendor_hook *ril_vendor_hook_ref(struct ril_vendor_hook *self)
|
||||
RilVendor *ril_vendor_ref(RilVendor *self)
|
||||
{
|
||||
if (self) {
|
||||
GASSERT(self->ref_count > 0);
|
||||
g_atomic_int_inc(&self->ref_count);
|
||||
if (G_LIKELY(self)) {
|
||||
g_object_ref(RIL_VENDOR(self));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
static void ril_vendor_hook_free(struct ril_vendor_hook *self)
|
||||
void ril_vendor_unref(RilVendor *self)
|
||||
{
|
||||
if (self->free) {
|
||||
self->free(self);
|
||||
}
|
||||
}
|
||||
|
||||
void ril_vendor_hook_unref(struct ril_vendor_hook *self)
|
||||
{
|
||||
if (self) {
|
||||
GASSERT(self->ref_count > 0);
|
||||
if (g_atomic_int_dec_and_test(&self->ref_count)) {
|
||||
ril_vendor_hook_free(self);
|
||||
}
|
||||
if (G_LIKELY(self)) {
|
||||
g_object_unref(RIL_VENDOR(self));
|
||||
}
|
||||
}
|
||||
|
||||
void ril_vendor_get_defaults(const struct ril_vendor_driver *vendor,
|
||||
struct ril_vendor_defaults *defaults)
|
||||
{
|
||||
if (vendor) {
|
||||
while (!vendor->get_defaults && vendor->base) {
|
||||
vendor = vendor->base;
|
||||
}
|
||||
if (vendor->get_defaults) {
|
||||
vendor->get_defaults(defaults);
|
||||
}
|
||||
if (vendor && vendor->get_defaults) {
|
||||
vendor->get_defaults(defaults);
|
||||
}
|
||||
}
|
||||
|
||||
const char *ril_vendor_hook_request_to_string(struct ril_vendor_hook *self,
|
||||
guint request)
|
||||
const char *ril_vendor_request_to_string(RilVendor *self, guint request)
|
||||
{
|
||||
if (self) {
|
||||
const struct ril_vendor_hook_proc *proc = self->proc;
|
||||
|
||||
while (!proc->request_to_string && proc->base) {
|
||||
proc = proc->base;
|
||||
}
|
||||
if (proc->request_to_string) {
|
||||
return proc->request_to_string(self, request);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return G_LIKELY(self) ? RIL_VENDOR_GET_CLASS(self)->
|
||||
request_to_string(self, request) : NULL;
|
||||
}
|
||||
|
||||
const char *ril_vendor_hook_event_to_string(struct ril_vendor_hook *self,
|
||||
guint event)
|
||||
const char *ril_vendor_event_to_string(RilVendor *self, guint event)
|
||||
{
|
||||
if (self) {
|
||||
const struct ril_vendor_hook_proc *proc = self->proc;
|
||||
|
||||
while (!proc->event_to_string && proc->base) {
|
||||
proc = proc->base;
|
||||
}
|
||||
if (proc->event_to_string) {
|
||||
return proc->event_to_string(self, event);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return G_LIKELY(self) ? RIL_VENDOR_GET_CLASS(self)->
|
||||
event_to_string(self, event) : NULL;
|
||||
}
|
||||
|
||||
GRilIoRequest *ril_vendor_hook_data_call_req(struct ril_vendor_hook *self,
|
||||
int tech, const char *profile, const char *apn,
|
||||
void ril_vendor_set_network(RilVendor *self, struct ril_network *nw)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
RIL_VENDOR_GET_CLASS(self)->set_network(self, nw);
|
||||
}
|
||||
}
|
||||
|
||||
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, apn, user, password, auth, proto) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (self) {
|
||||
const struct ril_vendor_hook_proc *proc = self->proc;
|
||||
return G_LIKELY(self) ? RIL_VENDOR_GET_CLASS(self)->
|
||||
data_call_req(self, tech, profile, apn, username, password,
|
||||
auth, proto) : NULL;
|
||||
}
|
||||
|
||||
while (!proc->data_call_req && proc->base) {
|
||||
proc = proc->base;
|
||||
gboolean ril_vendor_data_call_parse(RilVendor *self,
|
||||
struct ril_data_call *call, int ver, GRilIoParser *rilp)
|
||||
{
|
||||
return G_LIKELY(self) && RIL_VENDOR_GET_CLASS(self)->
|
||||
data_call_parse(self, call, ver, rilp);
|
||||
}
|
||||
|
||||
static void ril_vendor_default_set_network(RilVendor *self,
|
||||
struct ril_network *network)
|
||||
{
|
||||
if (self->network != network) {
|
||||
if (self->network) {
|
||||
g_object_remove_weak_pointer(G_OBJECT(self->network),
|
||||
(gpointer*) &self->network);
|
||||
}
|
||||
if (proc->data_call_req) {
|
||||
return proc->data_call_req(self, tech, profile, apn,
|
||||
username, password, auth, proto);
|
||||
self->network = network;
|
||||
if (self->network) {
|
||||
g_object_add_weak_pointer(G_OBJECT(network),
|
||||
(gpointer*) &self->network);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char *ril_vendor_default_id_to_string(RilVendor *self, guint id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean ril_vendor_hook_data_call_parse(struct ril_vendor_hook *self,
|
||||
struct ril_data_call *call, int ver, GRilIoParser *rilp)
|
||||
static GRilIoRequest *ril_vendor_default_set_attach_apn_req(RilVendor *self,
|
||||
const char *apn, const char *username,
|
||||
const char *password, enum ril_auth auth,
|
||||
const char *proto)
|
||||
{
|
||||
if (self) {
|
||||
const struct ril_vendor_hook_proc *proc = self->proc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (!proc->data_call_parse && proc->base) {
|
||||
proc = proc->base;
|
||||
}
|
||||
if (proc->data_call_parse) {
|
||||
return proc->data_call_parse(self, call, ver, rilp);
|
||||
}
|
||||
}
|
||||
static GRilIoRequest *ril_vendor_default_data_call_req(RilVendor *self,
|
||||
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;
|
||||
}
|
||||
|
||||
static gboolean ril_vendor_default_data_call_parse(RilVendor *self,
|
||||
struct ril_data_call *call, int version,
|
||||
GRilIoParser *rilp)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void ril_vendor_init_base(RilVendor *self, GRilIoChannel *io)
|
||||
{
|
||||
self->io = grilio_channel_ref(io);
|
||||
}
|
||||
|
||||
static void ril_vendor_init(RilVendor *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void ril_vendor_finalize(GObject* object)
|
||||
{
|
||||
RilVendor *self = RIL_VENDOR(object);
|
||||
|
||||
if (self->network) {
|
||||
g_object_remove_weak_pointer(G_OBJECT(self->network),
|
||||
(gpointer*) &self->network);
|
||||
}
|
||||
grilio_channel_unref(self->io);
|
||||
G_OBJECT_CLASS(ril_vendor_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void ril_vendor_class_init(RilVendorClass* klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = ril_vendor_finalize;
|
||||
klass->set_network = ril_vendor_default_set_network;
|
||||
klass->request_to_string = ril_vendor_default_id_to_string;
|
||||
klass->event_to_string = ril_vendor_default_id_to_string;
|
||||
klass->set_attach_apn_req = ril_vendor_default_set_attach_apn_req;
|
||||
klass->data_call_req = ril_vendor_default_data_call_req;
|
||||
klass->data_call_parse = ril_vendor_default_data_call_parse;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
|
||||
@@ -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
|
||||
@@ -22,75 +22,51 @@ struct ril_vendor_defaults {
|
||||
gboolean empty_pin_query;
|
||||
gboolean legacy_imei_query;
|
||||
gboolean enable_cbs;
|
||||
gboolean enable_stk;
|
||||
gboolean query_available_band_mode;
|
||||
gboolean use_data_profiles;
|
||||
guint mms_data_profile_id;
|
||||
};
|
||||
|
||||
struct ril_vendor_driver {
|
||||
const char *name;
|
||||
const void *driver_data;
|
||||
const struct ril_vendor_driver *base;
|
||||
void (*get_defaults)(struct ril_vendor_defaults *defaults);
|
||||
struct ril_vendor_hook *(*create_hook)(const void *driver_data,
|
||||
struct ril_vendor *(*create_vendor)(const void *driver_data,
|
||||
GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *cfg,
|
||||
struct ril_network *network);
|
||||
const struct ril_slot_config *cfg);
|
||||
};
|
||||
|
||||
struct ril_vendor_hook_proc {
|
||||
const struct ril_vendor_hook_proc *base;
|
||||
const char *(*request_to_string)(struct ril_vendor_hook *hook,
|
||||
guint request);
|
||||
const char *(*event_to_string)(struct ril_vendor_hook *hook,
|
||||
guint event);
|
||||
GRilIoRequest *(*data_call_req)(struct ril_vendor_hook *hook,
|
||||
int tech, const char *profile, const char *apn,
|
||||
const char *username, const char *password,
|
||||
enum ril_auth auth, const char *proto);
|
||||
gboolean (*data_call_parse)(struct ril_vendor_hook *hook,
|
||||
struct ril_data_call *call, int version,
|
||||
GRilIoParser *rilp);
|
||||
};
|
||||
|
||||
typedef void (*ril_vendor_hook_free_proc)(struct ril_vendor_hook *hook);
|
||||
struct ril_vendor_hook {
|
||||
const struct ril_vendor_hook_proc *proc;
|
||||
ril_vendor_hook_free_proc free;
|
||||
gint ref_count;
|
||||
};
|
||||
|
||||
struct ril_vendor_hook *ril_vendor_create_hook
|
||||
const struct ril_vendor_driver *ril_vendor_find_driver(const char *name);
|
||||
struct ril_vendor *ril_vendor_create
|
||||
(const struct ril_vendor_driver *vendor, GRilIoChannel *io,
|
||||
const char *path, const struct ril_slot_config *cfg,
|
||||
struct ril_network *network);
|
||||
const char *path, const struct ril_slot_config *cfg);
|
||||
void ril_vendor_get_defaults(const struct ril_vendor_driver *vendor,
|
||||
struct ril_vendor_defaults *defaults);
|
||||
|
||||
struct ril_vendor_hook *ril_vendor_hook_init(struct ril_vendor_hook *hook,
|
||||
const struct ril_vendor_hook_proc *proc,
|
||||
ril_vendor_hook_free_proc free);
|
||||
struct ril_vendor_hook *ril_vendor_hook_ref(struct ril_vendor_hook *hook);
|
||||
void ril_vendor_hook_unref(struct ril_vendor_hook *hook);
|
||||
struct ril_vendor *ril_vendor_ref(struct ril_vendor *vendor);
|
||||
void ril_vendor_unref(struct ril_vendor *vendor);
|
||||
|
||||
const char *ril_vendor_hook_request_to_string(struct ril_vendor_hook *hook,
|
||||
const char *ril_vendor_request_to_string(struct ril_vendor *vendor,
|
||||
guint request);
|
||||
const char *ril_vendor_hook_event_to_string(struct ril_vendor_hook *hook,
|
||||
const char *ril_vendor_event_to_string(struct ril_vendor *vendor,
|
||||
guint event);
|
||||
GRilIoRequest *ril_vendor_hook_data_call_req(struct ril_vendor_hook *hook,
|
||||
int tech, const char *profile, const char *apn,
|
||||
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 *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_hook_data_call_parse(struct ril_vendor_hook *hook,
|
||||
gboolean ril_vendor_data_call_parse(struct ril_vendor *vendor,
|
||||
struct ril_data_call *call, int version,
|
||||
GRilIoParser *rilp);
|
||||
|
||||
/* Put vendor driver descriptors to the "__vendor" section */
|
||||
#define RIL_VENDOR_DRIVER_DEFINE(name) \
|
||||
const struct ril_vendor_driver name \
|
||||
#define RIL_VENDOR_DRIVER_DEFINE(name) const struct ril_vendor_driver name \
|
||||
__attribute__((used, section("__vendor"))) =
|
||||
#define RIL_VENDOR_DRIVER_FOREACH(var) \
|
||||
for ((var) = __start___vendor; (var) < __stop___vendor; (var)++)
|
||||
extern const struct ril_vendor_driver __start___vendor[];
|
||||
extern const struct ril_vendor_driver __stop___vendor[];
|
||||
|
||||
#endif /* RIL_VENDOR_H */
|
||||
|
||||
|
||||
66
ofono/drivers/ril/ril_vendor_impl.h
Normal file
66
ofono/drivers/ril/ril_vendor_impl.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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_VENDOR_IMPL_H
|
||||
#define RIL_VENDOR_IMPL_H
|
||||
|
||||
#include "ril_vendor.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
typedef struct ril_vendor {
|
||||
GObject parent;
|
||||
GRilIoChannel *io;
|
||||
struct ril_network *network;
|
||||
} RilVendor;
|
||||
|
||||
typedef struct ril_vendor_class {
|
||||
GObjectClass parent;
|
||||
void (*set_network)(RilVendor *vendor, struct ril_network *network);
|
||||
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 *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,
|
||||
struct ril_data_call *call, int version,
|
||||
GRilIoParser *rilp);
|
||||
} RilVendorClass;
|
||||
|
||||
GType ril_vendor_get_type(void);
|
||||
#define RIL_VENDOR_TYPE (ril_vendor_get_type())
|
||||
#define RIL_VENDOR(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
RIL_VENDOR_TYPE, RilVendor)
|
||||
#define RIL_VENDOR_GET_CLASS(obj) G_TYPE_INSTANCE_GET_CLASS((obj), \
|
||||
RIL_VENDOR_TYPE, RilVendorClass)
|
||||
#define RIL_VENDOR_CLASS(klass) G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
RIL_VENDOR_TYPE, RilVendorClass)
|
||||
|
||||
void ril_vendor_init_base(RilVendor *vendor, GRilIoChannel *io);
|
||||
|
||||
#endif /* RIL_VENDOR_IMPL_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -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
|
||||
@@ -13,36 +13,25 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "ril_plugin.h"
|
||||
#include "ril_vendor.h"
|
||||
#include "ril_vendor_impl.h"
|
||||
#include "ril_network.h"
|
||||
#include "ril_data.h"
|
||||
#include "ril_util.h"
|
||||
#include "ril_log.h"
|
||||
|
||||
#include "sailfish_watch.h"
|
||||
|
||||
#include <grilio_channel.h>
|
||||
#include <grilio_parser.h>
|
||||
#include <grilio_request.h>
|
||||
#include <grilio_queue.h>
|
||||
|
||||
#include <gutil_macros.h>
|
||||
#include <gutil_misc.h>
|
||||
|
||||
#include "ofono.h"
|
||||
#include <ofono/watch.h>
|
||||
#include <ofono/gprs.h>
|
||||
|
||||
#define SET_INITIAL_ATTACH_APN_TIMEOUT (20*1000)
|
||||
|
||||
enum ril_mtk_watch_events {
|
||||
WATCH_EVENT_IMSI_CHANGED,
|
||||
WATCH_EVENT_COUNT
|
||||
};
|
||||
|
||||
enum ril_mtk_network_events {
|
||||
NETWORK_EVENT_PREF_MODE_CHANGED,
|
||||
NETWORK_EVENT_COUNT
|
||||
};
|
||||
|
||||
enum ril_mtk_events {
|
||||
MTK_EVENT_REGISTRATION_SUSPENDED,
|
||||
MTK_EVENT_SET_ATTACH_APN,
|
||||
@@ -51,38 +40,49 @@ enum ril_mtk_events {
|
||||
MTK_EVENT_COUNT
|
||||
};
|
||||
|
||||
struct ril_vendor_hook_mtk {
|
||||
struct ril_vendor_hook hook;
|
||||
const struct ril_mtk_msg *msg;
|
||||
typedef struct ril_vendor_mtk {
|
||||
RilVendor vendor;
|
||||
const struct ril_mtk_flavor *flavor;
|
||||
GRilIoQueue *q;
|
||||
GRilIoChannel *io;
|
||||
struct ril_network *network;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
guint set_initial_attach_apn_id;
|
||||
gboolean initial_attach_apn_ok;
|
||||
gulong network_event_id[NETWORK_EVENT_COUNT];
|
||||
gulong watch_event_id[WATCH_EVENT_COUNT];
|
||||
gulong ril_event_id[MTK_EVENT_COUNT];
|
||||
guint slot;
|
||||
};
|
||||
} RilVendorMtk;
|
||||
|
||||
typedef struct ril_vendor_mtk_auto {
|
||||
RilVendorMtk mtk;
|
||||
gulong detect_id;
|
||||
} RilVendorMtkAuto;
|
||||
|
||||
typedef RilVendorClass RilVendorMtkClass;
|
||||
typedef RilVendorMtkClass RilVendorMtkAutoClass;
|
||||
|
||||
#define RIL_VENDOR_TYPE_MTK (ril_vendor_mtk_get_type())
|
||||
#define RIL_VENDOR_TYPE_MTK_AUTO (ril_vendor_mtk_auto_get_type())
|
||||
|
||||
G_DEFINE_TYPE(RilVendorMtk, ril_vendor_mtk, RIL_VENDOR_TYPE)
|
||||
G_DEFINE_TYPE(RilVendorMtkAuto, ril_vendor_mtk_auto, RIL_VENDOR_TYPE_MTK)
|
||||
|
||||
#define RIL_VENDOR_MTK(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
RIL_VENDOR_TYPE_MTK, RilVendorMtk)
|
||||
#define RIL_VENDOR_MTK_AUTO(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
RIL_VENDOR_TYPE_MTK_AUTO, RilVendorMtkAuto)
|
||||
|
||||
/* driver_data point this this: */
|
||||
struct ril_vendor_mtk_driver_data {
|
||||
struct ril_mtk_flavor {
|
||||
const char *name;
|
||||
const struct ril_mtk_msg *msg;
|
||||
const struct ril_vendor_hook_proc *proc;
|
||||
};
|
||||
|
||||
/* Hook with auto-detection */
|
||||
struct ril_vendor_hook_mtk_auto {
|
||||
struct ril_vendor_hook_mtk mtk;
|
||||
const struct ril_vendor_mtk_driver_data *type;
|
||||
gulong detect_id;
|
||||
void (*build_attach_apn_req_fn)(GRilIoRequest *req, const char *apn,
|
||||
const char *username, const char *password,
|
||||
enum ril_auth auth, const char *proto);
|
||||
gboolean (*data_call_parse_fn)(struct ril_data_call *call,
|
||||
int version, GRilIoParser *rilp);
|
||||
};
|
||||
|
||||
/* MTK specific RIL messages (actual codes differ from model to model!) */
|
||||
struct ril_mtk_msg {
|
||||
gboolean attach_apn_has_roaming_protocol;
|
||||
guint request_resume_registration;
|
||||
guint request_set_call_indication;
|
||||
|
||||
@@ -97,7 +97,6 @@ struct ril_mtk_msg {
|
||||
};
|
||||
|
||||
static const struct ril_mtk_msg msg_mtk1 = {
|
||||
.attach_apn_has_roaming_protocol = TRUE,
|
||||
.request_resume_registration = 2050,
|
||||
.request_set_call_indication = 2065,
|
||||
.unsol_ps_network_state_changed = 3012,
|
||||
@@ -107,7 +106,6 @@ static const struct ril_mtk_msg msg_mtk1 = {
|
||||
};
|
||||
|
||||
static const struct ril_mtk_msg msg_mtk2 = {
|
||||
.attach_apn_has_roaming_protocol = FALSE,
|
||||
.request_resume_registration = 2065,
|
||||
.request_set_call_indication = 2086,
|
||||
.unsol_ps_network_state_changed = 3015,
|
||||
@@ -116,23 +114,11 @@ static const struct ril_mtk_msg msg_mtk2 = {
|
||||
.unsol_set_attach_apn = 3073
|
||||
};
|
||||
|
||||
static inline struct ril_vendor_hook_mtk *ril_vendor_hook_mtk_cast
|
||||
(struct ril_vendor_hook *hook)
|
||||
static const char *ril_vendor_mtk_request_to_string(RilVendor *vendor,
|
||||
guint request)
|
||||
{
|
||||
return G_CAST(hook, struct ril_vendor_hook_mtk, hook);
|
||||
}
|
||||
|
||||
static inline struct ril_vendor_hook_mtk_auto *ril_vendor_hook_mtk_auto_cast
|
||||
(struct ril_vendor_hook *hook)
|
||||
{
|
||||
return G_CAST(hook, struct ril_vendor_hook_mtk_auto, mtk.hook);
|
||||
}
|
||||
|
||||
static const char *ril_vendor_mtk_request_to_string
|
||||
(struct ril_vendor_hook *hook, guint request)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = ril_vendor_hook_mtk_cast(hook);
|
||||
const struct ril_mtk_msg *msg = self->msg;
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(vendor);
|
||||
const struct ril_mtk_msg *msg = self->flavor->msg;
|
||||
|
||||
if (request == msg->request_resume_registration) {
|
||||
return "MTK_RESUME_REGISTRATION";
|
||||
@@ -159,19 +145,19 @@ static const char *ril_vendor_mtk_unsol_msg_name(const struct ril_mtk_msg *msg,
|
||||
}
|
||||
}
|
||||
|
||||
static const char *ril_vendor_mtk_event_to_string(struct ril_vendor_hook *hook,
|
||||
static const char *ril_vendor_mtk_event_to_string(RilVendor *vendor,
|
||||
guint event)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = ril_vendor_hook_mtk_cast(hook);
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(vendor);
|
||||
|
||||
return ril_vendor_mtk_unsol_msg_name(self->msg, event);
|
||||
return ril_vendor_mtk_unsol_msg_name(self->flavor->msg, event);
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_registration_suspended(GRilIoChannel *io, guint id,
|
||||
const void *data, guint len, void *user_data)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = user_data;
|
||||
const struct ril_mtk_msg *msg = self->msg;
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(user_data);
|
||||
const struct ril_mtk_msg *msg = self->flavor->msg;
|
||||
GRilIoParser rilp;
|
||||
int session_id;
|
||||
|
||||
@@ -189,80 +175,41 @@ static void ril_vendor_mtk_registration_suspended(GRilIoChannel *io, guint id,
|
||||
}
|
||||
}
|
||||
|
||||
static GRilIoRequest *ril_vendor_mtk_build_set_attach_apn_req
|
||||
(const struct ofono_gprs_primary_context *pc,
|
||||
gboolean roamingProtocol)
|
||||
static void ril_vendor_mtk_build_attach_apn_req_1(GRilIoRequest *req,
|
||||
const char *apn, const char *username, const char *password,
|
||||
enum ril_auth auth, const char *proto)
|
||||
{
|
||||
GRilIoRequest *req = grilio_request_new();
|
||||
const char *proto = ril_data_ofono_protocol_to_ril(pc->proto);
|
||||
|
||||
DBG("%s %d", pc->apn, roamingProtocol);
|
||||
grilio_request_append_utf8(req, pc->apn); /* apn */
|
||||
grilio_request_append_utf8(req, proto); /* protocol */
|
||||
if (roamingProtocol) {
|
||||
grilio_request_append_utf8(req, proto); /* roamingProtocol */
|
||||
}
|
||||
|
||||
if (pc->username[0]) {
|
||||
int auth;
|
||||
|
||||
switch (pc->auth_method) {
|
||||
case OFONO_GPRS_AUTH_METHOD_ANY:
|
||||
auth = RIL_AUTH_BOTH;
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_NONE:
|
||||
auth = RIL_AUTH_NONE;
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_CHAP:
|
||||
auth = RIL_AUTH_CHAP;
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_PAP:
|
||||
auth = RIL_AUTH_PAP;
|
||||
break;
|
||||
default:
|
||||
auth = RIL_AUTH_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
grilio_request_append_int32(req, auth);
|
||||
grilio_request_append_utf8(req, pc->username);
|
||||
grilio_request_append_utf8(req, pc->password);
|
||||
} else {
|
||||
grilio_request_append_int32(req, RIL_AUTH_NONE);
|
||||
grilio_request_append_utf8(req, "");
|
||||
grilio_request_append_utf8(req, "");
|
||||
}
|
||||
|
||||
DBG("\"%s\" %s", apn, proto);
|
||||
grilio_request_append_utf8(req, apn);
|
||||
grilio_request_append_utf8(req, proto);
|
||||
grilio_request_append_utf8(req, proto); /* roamingProtocol */
|
||||
grilio_request_append_int32(req, auth);
|
||||
grilio_request_append_utf8(req, username);
|
||||
grilio_request_append_utf8(req, password);
|
||||
grilio_request_append_utf8(req, ""); /* operatorNumeric */
|
||||
grilio_request_append_int32(req, FALSE); /* canHandleIms */
|
||||
grilio_request_append_int32(req, -1); /* dualApnPlmnList */
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static const struct ofono_gprs_primary_context *ril_vendor_mtk_internet_context
|
||||
(struct ril_vendor_hook_mtk *self)
|
||||
static void ril_vendor_mtk_build_attach_apn_req_2(GRilIoRequest *req,
|
||||
const char *apn, const char *username, const char *password,
|
||||
enum ril_auth auth, const char *proto)
|
||||
{
|
||||
struct sailfish_watch *watch = self->watch;
|
||||
|
||||
if (watch->imsi) {
|
||||
struct ofono_atom *atom = __ofono_modem_find_atom(watch->modem,
|
||||
OFONO_ATOM_TYPE_GPRS);
|
||||
|
||||
if (atom) {
|
||||
return __ofono_gprs_context_settings_by_type
|
||||
(__ofono_atom_get_data(atom),
|
||||
OFONO_GPRS_CONTEXT_TYPE_INTERNET);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
DBG("\"%s\" %s", apn, proto);
|
||||
grilio_request_append_utf8(req, apn);
|
||||
grilio_request_append_utf8(req, proto);
|
||||
grilio_request_append_int32(req, auth);
|
||||
grilio_request_append_utf8(req, username);
|
||||
grilio_request_append_utf8(req, password);
|
||||
grilio_request_append_utf8(req, ""); /* operatorNumeric */
|
||||
grilio_request_append_int32(req, FALSE); /* canHandleIms */
|
||||
grilio_request_append_int32(req, -1); /* dualApnPlmnList */
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_initial_attach_apn_resp(GRilIoChannel *io,
|
||||
int ril_status, const void *data, guint len, void *user_data)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = user_data;
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(user_data);
|
||||
|
||||
GASSERT(self->set_initial_attach_apn_id);
|
||||
self->set_initial_attach_apn_id = 0;
|
||||
@@ -272,19 +219,35 @@ static void ril_vendor_mtk_initial_attach_apn_resp(GRilIoChannel *io,
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_initial_attach_apn_check
|
||||
(struct ril_vendor_hook_mtk *self)
|
||||
static void ril_vendor_mtk_initial_attach_apn_check(RilVendorMtk *self)
|
||||
{
|
||||
|
||||
if (!self->set_initial_attach_apn_id && !self->initial_attach_apn_ok) {
|
||||
struct ofono_watch *watch = self->watch;
|
||||
const struct ofono_gprs_primary_context *pc =
|
||||
ril_vendor_mtk_internet_context(self);
|
||||
ofono_gprs_context_settings_by_type(watch->gprs,
|
||||
OFONO_GPRS_CONTEXT_TYPE_INTERNET);
|
||||
|
||||
if (pc) {
|
||||
GRilIoRequest *req =
|
||||
ril_vendor_mtk_build_set_attach_apn_req(pc,
|
||||
self->msg->attach_apn_has_roaming_protocol);
|
||||
const char *username;
|
||||
const char *password;
|
||||
enum ril_auth auth;
|
||||
GRilIoRequest *req = grilio_request_new();
|
||||
|
||||
if (pc->username[0] || pc->password[0]) {
|
||||
username = pc->username;
|
||||
password = pc->password;
|
||||
auth = ril_auth_method_from_ofono
|
||||
(pc->auth_method);
|
||||
} else {
|
||||
username = "";
|
||||
password = "";
|
||||
auth = RIL_AUTH_NONE;
|
||||
}
|
||||
|
||||
self->flavor->build_attach_apn_req_fn(req,
|
||||
pc->apn, username, password, auth,
|
||||
ril_protocol_from_ofono(pc->proto));
|
||||
grilio_request_set_timeout(req,
|
||||
SET_INITIAL_ATTACH_APN_TIMEOUT);
|
||||
self->set_initial_attach_apn_id =
|
||||
@@ -297,60 +260,23 @@ static void ril_vendor_mtk_initial_attach_apn_check
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_initial_attach_apn_reset
|
||||
(struct ril_vendor_hook_mtk *self)
|
||||
{
|
||||
self->initial_attach_apn_ok = FALSE;
|
||||
if (self->set_initial_attach_apn_id) {
|
||||
grilio_queue_cancel_request(self->q,
|
||||
self->set_initial_attach_apn_id, FALSE);
|
||||
self->set_initial_attach_apn_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_watch_imsi_changed(struct sailfish_watch *watch,
|
||||
void *user_data)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = user_data;
|
||||
|
||||
if (watch->imsi) {
|
||||
ril_vendor_mtk_initial_attach_apn_check(self);
|
||||
} else {
|
||||
ril_vendor_mtk_initial_attach_apn_reset(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_network_pref_mode_changed(struct ril_network *net,
|
||||
void *user_data)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = user_data;
|
||||
|
||||
if (net->pref_mode >= OFONO_RADIO_ACCESS_MODE_LTE) {
|
||||
ril_vendor_mtk_initial_attach_apn_check(self);
|
||||
} else {
|
||||
ril_vendor_mtk_initial_attach_apn_reset(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_set_attach_apn(GRilIoChannel *io, guint id,
|
||||
const void *data, guint len, void *self)
|
||||
const void *data, guint len, void *user_data)
|
||||
{
|
||||
ril_vendor_mtk_initial_attach_apn_check(self);
|
||||
ril_vendor_mtk_initial_attach_apn_check(RIL_VENDOR_MTK(user_data));
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_ps_network_state_changed(GRilIoChannel *io,
|
||||
guint id, const void *data, guint len, void *user_data)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = user_data;
|
||||
|
||||
ril_network_query_registration_state(self->network);
|
||||
ril_network_query_registration_state(RIL_VENDOR(user_data)->network);
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_incoming_call_indication(GRilIoChannel *io, guint id,
|
||||
const void *data, guint len, void *user_data)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = user_data;
|
||||
const struct ril_mtk_msg *msg = self->msg;
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(user_data);
|
||||
const struct ril_mtk_msg *msg = self->flavor->msg;
|
||||
GRilIoRequest* req = NULL;
|
||||
|
||||
GASSERT(id == msg->unsol_incoming_call_indication);
|
||||
@@ -393,21 +319,21 @@ static void ril_vendor_mtk_incoming_call_indication(GRilIoChannel *io, guint id,
|
||||
} else {
|
||||
/* Let ril_voicecall.c know that something happened */
|
||||
grilio_channel_inject_unsol_event(io,
|
||||
RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
|
||||
RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static GRilIoRequest *ril_vendor_mtk_data_call_req
|
||||
(struct ril_vendor_hook *hook, int tech, const char *profile,
|
||||
const char *apn, const char *username, const char *password,
|
||||
enum ril_auth auth, const char *proto)
|
||||
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)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = ril_vendor_hook_mtk_cast(hook);
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(vendor);
|
||||
GRilIoRequest *req = grilio_request_new();
|
||||
|
||||
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);
|
||||
@@ -417,9 +343,19 @@ static GRilIoRequest *ril_vendor_mtk_data_call_req
|
||||
return req;
|
||||
}
|
||||
|
||||
static gboolean ril_vendor_mtk_data_call_parse_v6(struct ril_vendor_hook *hook,
|
||||
struct ril_data_call *call, int version,
|
||||
GRilIoParser *rilp)
|
||||
static GRilIoRequest *ril_vendor_mtk_set_attach_apn_req(RilVendor *vendor,
|
||||
const char *apn, const char *user, const char *pass,
|
||||
enum ril_auth auth, const char *prot)
|
||||
{
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(vendor);
|
||||
GRilIoRequest *req = grilio_request_new();
|
||||
|
||||
self->flavor->build_attach_apn_req_fn(req, apn, user, pass, auth, prot);
|
||||
return req;
|
||||
}
|
||||
|
||||
static gboolean ril_vendor_mtk_data_call_parse_v6(struct ril_data_call *call,
|
||||
int version, GRilIoParser *rilp)
|
||||
{
|
||||
if (version < 11) {
|
||||
int prot;
|
||||
@@ -434,7 +370,7 @@ static gboolean ril_vendor_mtk_data_call_parse_v6(struct ril_vendor_hook *hook,
|
||||
grilio_parser_get_uint32(rilp, &active);
|
||||
grilio_parser_get_int32(rilp, &call->mtu); /* MTK specific */
|
||||
prot_str = grilio_parser_get_utf8(rilp);
|
||||
prot = ril_data_protocol_to_ofono(prot_str);
|
||||
prot = ril_protocol_to_ofono(prot_str);
|
||||
g_free(prot_str);
|
||||
|
||||
if (prot >= 0) {
|
||||
@@ -453,6 +389,18 @@ static gboolean ril_vendor_mtk_data_call_parse_v6(struct ril_vendor_hook *hook,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean ril_vendor_mtk_data_call_parse(RilVendor *vendor,
|
||||
struct ril_data_call *call, int version,
|
||||
GRilIoParser *rilp)
|
||||
{
|
||||
const struct ril_mtk_flavor *flavor = RIL_VENDOR_MTK(vendor)->flavor;
|
||||
|
||||
return flavor->data_call_parse_fn ?
|
||||
flavor->data_call_parse_fn(call, version, rilp) :
|
||||
RIL_VENDOR_CLASS(ril_vendor_mtk_parent_class)->
|
||||
data_call_parse(vendor, call, version, rilp);
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_get_defaults(struct ril_vendor_defaults *defaults)
|
||||
{
|
||||
/*
|
||||
@@ -469,229 +417,197 @@ static void ril_vendor_mtk_get_defaults(struct ril_vendor_defaults *defaults)
|
||||
defaults->legacy_imei_query = TRUE;
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_hook_subscribe(struct ril_vendor_hook_mtk *self)
|
||||
static void ril_vendor_mtk_base_init(RilVendorMtk *self, GRilIoChannel *io,
|
||||
const char *path, const struct ril_slot_config *config)
|
||||
{
|
||||
const struct ril_mtk_msg *msg = self->msg;
|
||||
ril_vendor_init_base(&self->vendor, io);
|
||||
self->q = grilio_queue_new(io);
|
||||
self->watch = ofono_watch_new(path);
|
||||
self->slot = config->slot;
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_set_flavor(RilVendorMtk *self,
|
||||
const struct ril_mtk_flavor *flavor)
|
||||
{
|
||||
GRilIoChannel *io = self->vendor.io;
|
||||
const struct ril_mtk_msg *msg = flavor->msg;
|
||||
|
||||
grilio_channel_remove_all_handlers(io, self->ril_event_id);
|
||||
self->flavor = flavor;
|
||||
self->ril_event_id[MTK_EVENT_REGISTRATION_SUSPENDED] =
|
||||
grilio_channel_add_unsol_event_handler(self->io,
|
||||
grilio_channel_add_unsol_event_handler(io,
|
||||
ril_vendor_mtk_registration_suspended,
|
||||
msg->unsol_registration_suspended, self);
|
||||
if (msg->unsol_set_attach_apn) {
|
||||
self->ril_event_id[MTK_EVENT_SET_ATTACH_APN] =
|
||||
grilio_channel_add_unsol_event_handler(self->io,
|
||||
grilio_channel_add_unsol_event_handler(io,
|
||||
ril_vendor_mtk_set_attach_apn,
|
||||
msg->unsol_set_attach_apn, self);
|
||||
}
|
||||
if (msg->unsol_ps_network_state_changed) {
|
||||
self->ril_event_id[MTK_EVENT_PS_NETWORK_STATE_CHANGED] =
|
||||
grilio_channel_add_unsol_event_handler(self->io,
|
||||
grilio_channel_add_unsol_event_handler(io,
|
||||
ril_vendor_mtk_ps_network_state_changed,
|
||||
msg->unsol_ps_network_state_changed, self);
|
||||
}
|
||||
if (msg->unsol_incoming_call_indication) {
|
||||
self->ril_event_id[MTK_EVENT_INCOMING_CALL_INDICATION] =
|
||||
grilio_channel_add_unsol_event_handler(self->io,
|
||||
grilio_channel_add_unsol_event_handler(io,
|
||||
ril_vendor_mtk_incoming_call_indication,
|
||||
msg->unsol_incoming_call_indication, self);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_hook_init(struct ril_vendor_hook_mtk *self,
|
||||
const struct ril_vendor_mtk_driver_data *mtk_driver_data,
|
||||
ril_vendor_hook_free_proc free, GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *config, struct ril_network *network)
|
||||
static RilVendor *ril_vendor_mtk_create_from_data(const void *driver_data,
|
||||
GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *config)
|
||||
{
|
||||
self->msg = mtk_driver_data->msg;
|
||||
self->q = grilio_queue_new(io);
|
||||
self->io = grilio_channel_ref(io);
|
||||
self->watch = sailfish_watch_new(path);
|
||||
self->slot = config->slot;
|
||||
self->network = ril_network_ref(network);
|
||||
self->watch_event_id[WATCH_EVENT_IMSI_CHANGED] =
|
||||
sailfish_watch_add_imsi_changed_handler(self->watch,
|
||||
ril_vendor_mtk_watch_imsi_changed, self);
|
||||
self->network_event_id[NETWORK_EVENT_PREF_MODE_CHANGED] =
|
||||
ril_network_add_pref_mode_changed_handler(self->network,
|
||||
ril_vendor_mtk_network_pref_mode_changed, self);
|
||||
ril_vendor_mtk_hook_subscribe(self);
|
||||
ril_vendor_hook_init(&self->hook, mtk_driver_data->proc, free);
|
||||
const struct ril_mtk_flavor *flavor = driver_data;
|
||||
RilVendorMtk *mtk = g_object_new(RIL_VENDOR_TYPE_MTK, NULL);
|
||||
|
||||
ril_vendor_mtk_base_init(mtk, io, path, config);
|
||||
ril_vendor_mtk_set_flavor(mtk, flavor);
|
||||
DBG("%s slot %u", flavor->name, mtk->slot);
|
||||
return &mtk->vendor;
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_destroy(struct ril_vendor_hook_mtk *self)
|
||||
static void ril_vendor_mtk_init(RilVendorMtk *self)
|
||||
{
|
||||
grilio_queue_cancel_all(self->q, FALSE);
|
||||
grilio_channel_remove_all_handlers(self->io, self->ril_event_id);
|
||||
grilio_queue_unref(self->q);
|
||||
grilio_channel_unref(self->io);
|
||||
sailfish_watch_remove_all_handlers(self->watch, self->watch_event_id);
|
||||
sailfish_watch_unref(self->watch);
|
||||
ril_network_remove_all_handlers(self->network, self->network_event_id);
|
||||
ril_network_unref(self->network);
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_free(struct ril_vendor_hook *hook)
|
||||
static void ril_vendor_mtk_finalize(GObject* object)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *self = ril_vendor_hook_mtk_cast(hook);
|
||||
RilVendorMtk *self = RIL_VENDOR_MTK(object);
|
||||
RilVendor *vendor = &self->vendor;
|
||||
|
||||
DBG("slot %u", self->slot);
|
||||
ril_vendor_mtk_destroy(self);
|
||||
g_free(self);
|
||||
grilio_queue_cancel_all(self->q, FALSE);
|
||||
grilio_queue_unref(self->q);
|
||||
ofono_watch_unref(self->watch);
|
||||
grilio_channel_remove_all_handlers(vendor->io, self->ril_event_id);
|
||||
G_OBJECT_CLASS(ril_vendor_mtk_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static struct ril_vendor_hook *ril_vendor_mtk_create_hook_from_data
|
||||
(const void *driver_data, GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *config,
|
||||
struct ril_network *network)
|
||||
static void ril_vendor_mtk_class_init(RilVendorMtkClass* klass)
|
||||
{
|
||||
const struct ril_vendor_mtk_driver_data *mtk_driver_data = driver_data;
|
||||
struct ril_vendor_hook_mtk *self =
|
||||
g_new0(struct ril_vendor_hook_mtk, 1);
|
||||
|
||||
ril_vendor_mtk_hook_init(self, mtk_driver_data, ril_vendor_mtk_free,
|
||||
io, path, config, network);
|
||||
DBG("%s slot %u", mtk_driver_data->name, self->slot);
|
||||
return &self->hook;
|
||||
G_OBJECT_CLASS(klass)->finalize = ril_vendor_mtk_finalize;
|
||||
klass->request_to_string = ril_vendor_mtk_request_to_string;
|
||||
klass->event_to_string = ril_vendor_mtk_event_to_string;
|
||||
klass->set_attach_apn_req = ril_vendor_mtk_set_attach_apn_req;
|
||||
klass->data_call_req = ril_vendor_mtk_data_call_req;
|
||||
klass->data_call_parse = ril_vendor_mtk_data_call_parse;
|
||||
}
|
||||
|
||||
static const struct ril_vendor_hook_proc ril_vendor_mtk_hook_base_proc = {
|
||||
.request_to_string = ril_vendor_mtk_request_to_string,
|
||||
.event_to_string = ril_vendor_mtk_event_to_string,
|
||||
.data_call_req = ril_vendor_mtk_data_call_req
|
||||
static const struct ril_mtk_flavor ril_mtk_flavor1 = {
|
||||
.name = "mtk1",
|
||||
.msg = &msg_mtk1,
|
||||
.build_attach_apn_req_fn = &ril_vendor_mtk_build_attach_apn_req_1,
|
||||
.data_call_parse_fn = NULL
|
||||
};
|
||||
|
||||
static const struct ril_vendor_driver ril_vendor_mtk_base = {
|
||||
.get_defaults = ril_vendor_mtk_get_defaults,
|
||||
.create_hook = ril_vendor_mtk_create_hook_from_data
|
||||
static const struct ril_mtk_flavor ril_mtk_flavor2 = {
|
||||
.name = "mtk2",
|
||||
.msg = &msg_mtk2,
|
||||
.build_attach_apn_req_fn = &ril_vendor_mtk_build_attach_apn_req_2,
|
||||
.data_call_parse_fn = &ril_vendor_mtk_data_call_parse_v6
|
||||
};
|
||||
|
||||
static const struct ril_vendor_mtk_driver_data ril_vendor_mtk1_data = {
|
||||
.name = "mtk1",
|
||||
.msg = &msg_mtk1,
|
||||
.proc = &ril_vendor_mtk_hook_base_proc
|
||||
};
|
||||
#define DEFAULT_MTK_TYPE (&ril_mtk_flavor1)
|
||||
|
||||
static struct ril_vendor_hook_proc ril_vendor_mtk2_proc = {
|
||||
.base = &ril_vendor_mtk_hook_base_proc,
|
||||
.data_call_parse = ril_vendor_mtk_data_call_parse_v6
|
||||
};
|
||||
|
||||
static const struct ril_vendor_mtk_driver_data ril_vendor_mtk2_data = {
|
||||
.name = "mtk2",
|
||||
.msg = &msg_mtk2,
|
||||
.proc = &ril_vendor_mtk2_proc
|
||||
};
|
||||
|
||||
#define DEFAULT_MTK_TYPE (&ril_vendor_mtk1_data)
|
||||
|
||||
static const struct ril_vendor_mtk_driver_data *mtk_types [] = {
|
||||
&ril_vendor_mtk1_data,
|
||||
&ril_vendor_mtk2_data
|
||||
static const struct ril_mtk_flavor *mtk_flavors [] = {
|
||||
&ril_mtk_flavor1,
|
||||
&ril_mtk_flavor2
|
||||
};
|
||||
|
||||
RIL_VENDOR_DRIVER_DEFINE(ril_vendor_driver_mtk1) {
|
||||
.name = "mtk1",
|
||||
.driver_data = &ril_vendor_mtk1_data,
|
||||
.base = &ril_vendor_mtk_base
|
||||
.driver_data = &ril_mtk_flavor1,
|
||||
.get_defaults = ril_vendor_mtk_get_defaults,
|
||||
.create_vendor = ril_vendor_mtk_create_from_data
|
||||
};
|
||||
|
||||
RIL_VENDOR_DRIVER_DEFINE(ril_vendor_driver_mtk2) {
|
||||
.name = "mtk2",
|
||||
.driver_data = &ril_vendor_mtk2_data,
|
||||
.base = &ril_vendor_mtk_base
|
||||
.driver_data = &ril_mtk_flavor2,
|
||||
.get_defaults = ril_vendor_mtk_get_defaults,
|
||||
.create_vendor = ril_vendor_mtk_create_from_data
|
||||
};
|
||||
|
||||
/* Auto-selection */
|
||||
|
||||
static gboolean ril_vendor_mtk_auto_set_type
|
||||
(struct ril_vendor_hook_mtk_auto *self,
|
||||
const struct ril_vendor_mtk_driver_data *type)
|
||||
{
|
||||
struct ril_vendor_hook_mtk *mtk = &self->mtk;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
if (self->type != type) {
|
||||
DBG("switching type %s -> %s", self->type->name, type->name);
|
||||
self->type = type;
|
||||
mtk->msg = type->msg;
|
||||
mtk->hook.proc = type->proc;
|
||||
grilio_channel_remove_all_handlers(mtk->io, mtk->ril_event_id);
|
||||
ril_vendor_mtk_hook_subscribe(mtk);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
grilio_channel_remove_handler(mtk->io, self->detect_id);
|
||||
self->detect_id = 0;
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_auto_detect_event(GRilIoChannel *io, guint id,
|
||||
const void *data, guint len, void *self)
|
||||
const void *data, guint len, void *user_data)
|
||||
{
|
||||
RilVendorMtkAuto *self = RIL_VENDOR_MTK_AUTO(user_data);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(mtk_types); i++) {
|
||||
const struct ril_vendor_mtk_driver_data *type = mtk_types[i];
|
||||
const struct ril_mtk_msg *msg = type->msg;
|
||||
for (i = 0; i < G_N_ELEMENTS(mtk_flavors); i++) {
|
||||
const struct ril_mtk_flavor *flavor = mtk_flavors[i];
|
||||
const struct ril_mtk_msg *msg = flavor->msg;
|
||||
const guint *ids = &msg->unsol_msgs;
|
||||
guint j;
|
||||
|
||||
for (j = 0; j < MTK_UNSOL_MSGS; j++) {
|
||||
if (ids[j] == id) {
|
||||
DBG("event %u is %s %s", id, type->name,
|
||||
DBG("event %u is %s %s", id, flavor->name,
|
||||
ril_vendor_mtk_unsol_msg_name(msg,id));
|
||||
if (ril_vendor_mtk_auto_set_type(self, type)) {
|
||||
/* And repeat the event to invoke
|
||||
* the handler */
|
||||
grilio_channel_inject_unsol_event(io,
|
||||
id, data, len);
|
||||
}
|
||||
ril_vendor_mtk_set_flavor(&self->mtk, flavor);
|
||||
/* We are done */
|
||||
grilio_channel_remove_handler(io,
|
||||
self->detect_id);
|
||||
self->detect_id = 0;
|
||||
/* And repeat the event to invoke the handler */
|
||||
grilio_channel_inject_unsol_event(io, id,
|
||||
data, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_auto_free(struct ril_vendor_hook *hook)
|
||||
static void ril_vendor_mtk_auto_init(RilVendorMtkAuto *self)
|
||||
{
|
||||
struct ril_vendor_hook_mtk_auto *self =
|
||||
ril_vendor_hook_mtk_auto_cast(hook);
|
||||
struct ril_vendor_hook_mtk *mtk = &self->mtk;
|
||||
|
||||
DBG("slot %u", mtk->slot);
|
||||
grilio_channel_remove_handler(mtk->io, self->detect_id);
|
||||
ril_vendor_mtk_destroy(mtk);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
static struct ril_vendor_hook *ril_vendor_mtk_create_hook_auto
|
||||
(const void *driver_data, GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *cfg, struct ril_network *network)
|
||||
static void ril_vendor_mtk_auto_finalize(GObject* object)
|
||||
{
|
||||
struct ril_vendor_hook_mtk_auto *self =
|
||||
g_new0(struct ril_vendor_hook_mtk_auto, 1);
|
||||
struct ril_vendor_hook_mtk *mtk = &self->mtk;
|
||||
RilVendorMtkAuto *self = RIL_VENDOR_MTK_AUTO(object);
|
||||
|
||||
/* Pick the default */
|
||||
self->type = DEFAULT_MTK_TYPE;
|
||||
ril_vendor_mtk_hook_init(mtk, self->type, ril_vendor_mtk_auto_free,
|
||||
io, path, cfg, network);
|
||||
DBG("%s slot %u", self->type->name, mtk->slot);
|
||||
DBG("slot %u", self->mtk.slot);
|
||||
grilio_channel_remove_handler(self->mtk.vendor.io, self->detect_id);
|
||||
G_OBJECT_CLASS(ril_vendor_mtk_auto_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void ril_vendor_mtk_auto_class_init(RilVendorMtkAutoClass* klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = ril_vendor_mtk_auto_finalize;
|
||||
}
|
||||
|
||||
static RilVendor *ril_vendor_mtk_auto_create_vendor(const void *driver_data,
|
||||
GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *config)
|
||||
{
|
||||
RilVendorMtkAuto *self = g_object_new(RIL_VENDOR_TYPE_MTK_AUTO, NULL);
|
||||
RilVendorMtk *mtk = &self->mtk;
|
||||
|
||||
ril_vendor_mtk_base_init(mtk, io, path, config);
|
||||
ril_vendor_mtk_set_flavor(mtk, DEFAULT_MTK_TYPE);
|
||||
DBG("%s slot %u", mtk->flavor->name, mtk->slot);
|
||||
|
||||
/*
|
||||
* Subscribe for (all) unsolicited events. Keep on listening until
|
||||
* we receive an MTK specific event that tells us which particular
|
||||
* kind of MTK adaptation we are using.
|
||||
*/
|
||||
self->detect_id = grilio_channel_add_unsol_event_handler(mtk->io,
|
||||
self->detect_id = grilio_channel_add_unsol_event_handler(io,
|
||||
ril_vendor_mtk_auto_detect_event, 0, self);
|
||||
return &mtk->hook;
|
||||
return &mtk->vendor;
|
||||
}
|
||||
|
||||
RIL_VENDOR_DRIVER_DEFINE(ril_vendor_driver_mtk) {
|
||||
.name = "mtk",
|
||||
.get_defaults = ril_vendor_mtk_get_defaults,
|
||||
.create_hook = ril_vendor_mtk_create_hook_auto
|
||||
.create_vendor = ril_vendor_mtk_auto_create_vendor
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
|
||||
unsigned int len = sizeof(saddr);
|
||||
int fd;
|
||||
struct ofono_emulator *em;
|
||||
struct ofono_modem *modem;
|
||||
GList *i;
|
||||
|
||||
if (cond != G_IO_IN)
|
||||
return FALSE;
|
||||
@@ -63,15 +63,16 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
|
||||
if (fd == -1)
|
||||
return FALSE;
|
||||
|
||||
/* Pick the first powered modem */
|
||||
modem = modems->data;
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator.");
|
||||
|
||||
em = ofono_emulator_create(modem, GPOINTER_TO_INT(user));
|
||||
if (em == NULL)
|
||||
close(fd);
|
||||
else
|
||||
em = ofono_emulator_create(GPOINTER_TO_INT(user));
|
||||
|
||||
if (em) {
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
ofono_emulator_register(em, fd);
|
||||
} else
|
||||
close(fd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
158
ofono/include/dbus-access.h
Normal file
158
ofono/include/dbus-access.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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 __OFONO_DBUS_ACCESS_H
|
||||
#define __OFONO_DBUS_ACCESS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ofono/types.h>
|
||||
|
||||
enum ofono_dbus_access {
|
||||
OFONO_DBUS_ACCESS_DENY, /* Deny access */
|
||||
OFONO_DBUS_ACCESS_ALLOW, /* Allow access */
|
||||
OFONO_DBUS_ACCESS_DONT_CARE, /* No decision */
|
||||
};
|
||||
|
||||
enum ofono_dbus_access_intf {
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGE, /* org.ofono.Message */
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGEMGR, /* org.ofono.MessageManager */
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALL, /* org.ofono.VoiceCall */
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR, /* org.ofono.VoiceCallManager */
|
||||
OFONO_DBUS_ACCESS_INTF_CONNCTX, /* org.ofono.ConnectionContext */
|
||||
OFONO_DBUS_ACCESS_INTF_CONNMGR, /* org.ofono.ConnectionManager */
|
||||
OFONO_DBUS_ACCESS_INTF_SIMMGR, /* org.ofono.SimManager */
|
||||
OFONO_DBUS_ACCESS_INTF_MODEM, /* org.ofono.Modem */
|
||||
OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS, /* org.ofono.RadioSettings */
|
||||
OFONO_DBUS_ACCESS_INTF_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_MESSAGE */
|
||||
enum ofono_dbus_access_message_method {
|
||||
OFONO_DBUS_ACCESS_MESSAGE_CANCEL,
|
||||
OFONO_DBUS_ACCESS_MESSAGE_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_MESSAGEMGR */
|
||||
enum ofono_dbus_access_messagemgr_method {
|
||||
OFONO_DBUS_ACCESS_MESSAGEMGR_SEND_MESSAGE,
|
||||
OFONO_DBUS_ACCESS_MESSAGEMGR_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_VOICECALL */
|
||||
enum ofono_dbus_access_voicecall_method {
|
||||
OFONO_DBUS_ACCESS_VOICECALL_DEFLECT,
|
||||
OFONO_DBUS_ACCESS_VOICECALL_HANGUP,
|
||||
OFONO_DBUS_ACCESS_VOICECALL_ANSWER,
|
||||
OFONO_DBUS_ACCESS_VOICECALL_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_VOICECALLMGR */
|
||||
enum ofono_dbus_access_voicecallmgr_method {
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_TRANSFER,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_SWAP_CALLS,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_RELEASE_AND_ANSWER,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_RELEASE_AND_SWAP,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_HOLD_AND_ANSWER,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_HANGUP_ALL,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_CREATE_MULTIPARTY,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_HANGUP_MULTIPARTY,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_SEND_TONES,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_REGISTER_VOICECALL_AGENT,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_UNREGISTER_VOICECALL_AGENT,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_CONNCTX */
|
||||
enum ofono_dbus_access_connctx_method {
|
||||
OFONO_DBUS_ACCESS_CONNCTX_SET_PROPERTY,
|
||||
OFONO_DBUS_ACCESS_CONNCTX_PROVISION_CONTEXT,
|
||||
OFONO_DBUS_ACCESS_CONNCTX_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_CONNMGR */
|
||||
enum ofono_dbus_access_connmgr_method {
|
||||
OFONO_DBUS_ACCESS_CONNMGR_SET_PROPERTY,
|
||||
OFONO_DBUS_ACCESS_CONNMGR_DEACTIVATE_ALL,
|
||||
OFONO_DBUS_ACCESS_CONNMGR_RESET_CONTEXTS,
|
||||
OFONO_DBUS_ACCESS_CONNMGR_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_SIMMGR */
|
||||
enum ofono_dbus_access_simmgr_method {
|
||||
OFONO_DBUS_ACCESS_SIMMGR_SET_PROPERTY,
|
||||
OFONO_DBUS_ACCESS_SIMMGR_CHANGE_PIN,
|
||||
OFONO_DBUS_ACCESS_SIMMGR_ENTER_PIN,
|
||||
OFONO_DBUS_ACCESS_SIMMGR_RESET_PIN,
|
||||
OFONO_DBUS_ACCESS_SIMMGR_LOCK_PIN,
|
||||
OFONO_DBUS_ACCESS_SIMMGR_UNLOCK_PIN,
|
||||
OFONO_DBUS_ACCESS_SIMMGR_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_MODEM */
|
||||
enum ofono_dbus_access_modem_method {
|
||||
OFONO_DBUS_ACCESS_MODEM_SET_PROPERTY,
|
||||
OFONO_DBUS_ACCESS_MODEM_METHOD_COUNT
|
||||
};
|
||||
|
||||
/* OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS */
|
||||
enum ofono_dbus_access_radiosettings_method {
|
||||
OFONO_DBUS_ACCESS_RADIOSETTINGS_SET_PROPERTY,
|
||||
OFONO_DBUS_ACCESS_RADIOSETTINGS_METHOD_COUNT
|
||||
};
|
||||
|
||||
#define OFONO_DBUS_ACCESS_PRIORITY_LOW (-100)
|
||||
#define OFONO_DBUS_ACCESS_PRIORITY_DEFAULT (0)
|
||||
#define OFONO_DBUS_ACCESS_PRIORITY_HIGH (100)
|
||||
|
||||
struct ofono_dbus_access_plugin {
|
||||
const char *name;
|
||||
int priority;
|
||||
enum ofono_dbus_access (*method_access)(const char *sender,
|
||||
enum ofono_dbus_access_intf intf,
|
||||
int method, const char *arg);
|
||||
|
||||
void (*_reserved[10])(void);
|
||||
|
||||
/* api_level will remain zero (and ignored) until we run out of
|
||||
* the above placeholders. */
|
||||
int api_level;
|
||||
};
|
||||
|
||||
int ofono_dbus_access_plugin_register
|
||||
(const struct ofono_dbus_access_plugin *plugin);
|
||||
void ofono_dbus_access_plugin_unregister
|
||||
(const struct ofono_dbus_access_plugin *plugin);
|
||||
|
||||
const char *ofono_dbus_access_intf_name(enum ofono_dbus_access_intf intf);
|
||||
const char *ofono_dbus_access_method_name(enum ofono_dbus_access_intf intf,
|
||||
int method);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OFONO_DBUS_ACCESS_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -68,8 +68,9 @@ typedef void (*ofono_emulator_request_cb_t)(struct ofono_emulator *em,
|
||||
struct ofono_emulator_request *req,
|
||||
void *data);
|
||||
|
||||
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
||||
enum ofono_emulator_type type);
|
||||
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type);
|
||||
void ofono_emulator_add_modem(struct ofono_emulator *em,
|
||||
struct ofono_modem *modem);
|
||||
|
||||
void ofono_emulator_register(struct ofono_emulator *em, int fd);
|
||||
|
||||
|
||||
@@ -26,10 +26,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ofono/types.h>
|
||||
#include <ofono/gprs-context.h>
|
||||
|
||||
struct ofono_gprs;
|
||||
struct ofono_gprs_context;
|
||||
|
||||
typedef void (*ofono_gprs_status_cb_t)(const struct ofono_error *error,
|
||||
int status, void *data);
|
||||
@@ -85,6 +84,9 @@ void ofono_gprs_cid_activated(struct ofono_gprs *gprs, unsigned int cid,
|
||||
|
||||
void ofono_gprs_attached_update(struct ofono_gprs *gprs);
|
||||
|
||||
const struct ofono_gprs_primary_context *ofono_gprs_context_settings_by_type
|
||||
(struct ofono_gprs *gprs, enum ofono_gprs_context_type type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -35,6 +35,18 @@ struct sailfish_cell_info;
|
||||
typedef void (*sailfish_slot_manager_impl_cb_t)
|
||||
(struct sailfish_slot_manager_impl *impl, void *user_data);
|
||||
|
||||
enum sailfish_slot_flags {
|
||||
SAILFISH_SLOT_NO_FLAGS = 0,
|
||||
/* Normally we should be able to have two simultaneously active
|
||||
* data contexts - one for mobile data and one for MMS. The flag
|
||||
* below says that for whatever reason it's impossible and mobile
|
||||
* data has to be disconnected before we can send or receive MMS.
|
||||
* On such devices it may not be a good idea to automatically
|
||||
* download MMS because that would kill active mobile data
|
||||
* connections. */
|
||||
SAILFISH_SLOT_SINGLE_CONTEXT = 0x01
|
||||
};
|
||||
|
||||
typedef struct sailfish_slot {
|
||||
const char *path;
|
||||
const char *imei;
|
||||
@@ -81,6 +93,12 @@ struct sailfish_slot *sailfish_manager_slot_add
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state);
|
||||
struct sailfish_slot *sailfish_manager_slot_add2
|
||||
(struct sailfish_slot_manager *m, struct sailfish_slot_impl *i,
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state,
|
||||
enum sailfish_slot_flags flags);
|
||||
void sailfish_manager_imei_obtained(struct sailfish_slot *s, const char *imei);
|
||||
void sailfish_manager_imeisv_obtained(struct sailfish_slot *s,
|
||||
const char *imeisv);
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 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 SAILFISH_WATCH_H
|
||||
#define SAILFISH_WATCH_H
|
||||
|
||||
struct ofono_modem;
|
||||
struct ofono_sim;
|
||||
struct ofono_netreg;
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
/* This object watches ofono modem and various related things */
|
||||
struct sailfish_watch_priv;
|
||||
struct sailfish_watch {
|
||||
GObject object;
|
||||
struct sailfish_watch_priv *priv;
|
||||
const char *path;
|
||||
/* Modem */
|
||||
struct ofono_modem *modem;
|
||||
gboolean online;
|
||||
/* OFONO_ATOM_TYPE_SIM */
|
||||
struct ofono_sim *sim;
|
||||
const char *iccid;
|
||||
const char *imsi;
|
||||
const char *spn;
|
||||
/* OFONO_ATOM_TYPE_NETREG */
|
||||
struct ofono_netreg *netreg;
|
||||
};
|
||||
|
||||
typedef void (*sailfish_watch_cb_t)(struct sailfish_watch *w, void *user_data);
|
||||
|
||||
struct sailfish_watch *sailfish_watch_new(const char *path);
|
||||
struct sailfish_watch *sailfish_watch_ref(struct sailfish_watch *w);
|
||||
void sailfish_watch_unref(struct sailfish_watch *w);
|
||||
|
||||
gulong sailfish_watch_add_modem_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
gulong sailfish_watch_add_online_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
gulong sailfish_watch_add_sim_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
gulong sailfish_watch_add_sim_state_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
gulong sailfish_watch_add_iccid_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
gulong sailfish_watch_add_imsi_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
gulong sailfish_watch_add_spn_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
gulong sailfish_watch_add_netreg_changed_handler(struct sailfish_watch *w,
|
||||
sailfish_watch_cb_t cb, void *user_data);
|
||||
void sailfish_watch_remove_handler(struct sailfish_watch *w, gulong id);
|
||||
void sailfish_watch_remove_handlers(struct sailfish_watch *w, gulong *ids,
|
||||
int count);
|
||||
|
||||
#define sailfish_watch_remove_all_handlers(w,ids) \
|
||||
sailfish_watch_remove_handlers(w, ids, G_N_ELEMENTS(ids))
|
||||
|
||||
#endif /* SAILFISH_WATCH_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
113
ofono/include/watch.h
Normal file
113
ofono/include/watch.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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
|
||||
* 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 OFONO_WATCH_H
|
||||
#define OFONO_WATCH_H
|
||||
|
||||
#include <ofono/gprs-context.h>
|
||||
|
||||
struct ofono_modem;
|
||||
struct ofono_sim;
|
||||
struct ofono_netreg;
|
||||
|
||||
enum ofono_netreg_status {
|
||||
OFONO_NETREG_STATUS_NONE = -1,
|
||||
OFONO_NETREG_STATUS_NOT_REGISTERED = 0,
|
||||
OFONO_NETREG_STATUS_REGISTERED = 1,
|
||||
OFONO_NETREG_STATUS_SEARCHING = 2,
|
||||
OFONO_NETREG_STATUS_DENIED = 3,
|
||||
OFONO_NETREG_STATUS_UNKNOWN = 4,
|
||||
OFONO_NETREG_STATUS_ROAMING = 5
|
||||
};
|
||||
|
||||
/* This object watches ofono modem and various other things */
|
||||
struct ofono_watch {
|
||||
const char *path;
|
||||
/* Modem */
|
||||
struct ofono_modem *modem;
|
||||
ofono_bool_t online;
|
||||
/* OFONO_ATOM_TYPE_SIM */
|
||||
struct ofono_sim *sim;
|
||||
const char *iccid;
|
||||
const char *imsi;
|
||||
const char *spn;
|
||||
/* OFONO_ATOM_TYPE_NETREG */
|
||||
struct ofono_netreg *netreg;
|
||||
/* Since mer/1.21+git47 */
|
||||
enum ofono_netreg_status reg_status;
|
||||
const char *reg_mcc;
|
||||
const char *reg_mnc;
|
||||
const char *reg_name;
|
||||
/* OFONO_ATOM_TYPE_GPRS */
|
||||
struct ofono_gprs *gprs;
|
||||
};
|
||||
|
||||
typedef void (*ofono_watch_cb_t)(struct ofono_watch *w, void *user_data);
|
||||
typedef void (*ofono_watch_gprs_settings_cb_t)(struct ofono_watch *watch,
|
||||
enum ofono_gprs_context_type type,
|
||||
const struct ofono_gprs_primary_context *settings,
|
||||
void *user_data);
|
||||
|
||||
struct ofono_watch *ofono_watch_new(const char *path);
|
||||
struct ofono_watch *ofono_watch_ref(struct ofono_watch *w);
|
||||
void ofono_watch_unref(struct ofono_watch *w);
|
||||
|
||||
unsigned long ofono_watch_add_modem_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_online_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_sim_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_sim_state_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_iccid_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_imsi_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_spn_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_netreg_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
void ofono_watch_remove_handler(struct ofono_watch *w, unsigned long id);
|
||||
void ofono_watch_remove_handlers(struct ofono_watch *w, unsigned long *ids,
|
||||
unsigned int count);
|
||||
|
||||
#define ofono_watch_remove_all_handlers(w,ids) \
|
||||
ofono_watch_remove_handlers(w, ids, sizeof(ids)/sizeof((ids)[0]))
|
||||
|
||||
/* Since mer/1.21+git47 */
|
||||
unsigned long ofono_watch_add_reg_status_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_reg_mcc_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_reg_mnc_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_reg_name_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_gprs_changed_handler(struct ofono_watch *w,
|
||||
ofono_watch_cb_t cb, void *user_data);
|
||||
unsigned long ofono_watch_add_gprs_settings_changed_handler
|
||||
(struct ofono_watch *watch, ofono_watch_gprs_settings_cb_t cb,
|
||||
void *user_data);
|
||||
|
||||
#endif /* OFONO_WATCH_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -79,7 +79,7 @@ static const gchar *dun_record =
|
||||
static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
{
|
||||
struct ofono_emulator *em = user_data;
|
||||
struct ofono_modem *modem;
|
||||
GList *i;
|
||||
int fd;
|
||||
|
||||
DBG("");
|
||||
@@ -90,16 +90,17 @@ static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pick the first powered modem */
|
||||
modem = modems->data;
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator");
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
|
||||
if (em == NULL) {
|
||||
g_io_channel_shutdown(io, TRUE, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
fd = g_io_channel_unix_get_fd(io);
|
||||
g_io_channel_set_close_on_unref(io, FALSE);
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
const char *device;
|
||||
int fd;
|
||||
struct ofono_emulator *em;
|
||||
struct ofono_modem *modem;
|
||||
GList *i;
|
||||
|
||||
DBG("Profile handler NewConnection");
|
||||
|
||||
@@ -80,7 +80,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
|
||||
DBG("%s", device);
|
||||
|
||||
/* Pick the first powered modem */
|
||||
if (modems == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -88,10 +87,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"No GPRS capable modem");
|
||||
}
|
||||
|
||||
modem = modems->data;
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator.");
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
|
||||
if (em == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -99,6 +97,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"Not enough resources");
|
||||
}
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
ofono_emulator_register(em, fd);
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
|
||||
@@ -91,6 +91,7 @@ static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_emulator *em;
|
||||
int fd;
|
||||
GList *i;
|
||||
|
||||
DBG("");
|
||||
|
||||
@@ -99,17 +100,18 @@ static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pick the first voicecall capable modem */
|
||||
modem = modems->data;
|
||||
if (modem == NULL)
|
||||
if (modems == NULL)
|
||||
return;
|
||||
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator");
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_HFP);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_HFP);
|
||||
if (em == NULL)
|
||||
return;
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
fd = g_io_channel_unix_get_fd(io);
|
||||
g_io_channel_set_close_on_unref(io, FALSE);
|
||||
|
||||
|
||||
@@ -47,19 +47,18 @@ typedef struct GAtResult GAtResult;
|
||||
#include "bluez5.h"
|
||||
#include "bluetooth.h"
|
||||
|
||||
#ifndef DBUS_TYPE_UNIX_FD
|
||||
#define DBUS_TYPE_UNIX_FD -1
|
||||
#endif
|
||||
|
||||
#define HFP_AG_EXT_PROFILE_PATH "/bluetooth/profile/hfp_ag"
|
||||
#define BT_ADDR_SIZE 18
|
||||
|
||||
#define HFP_AG_DRIVER "hfp-ag-driver"
|
||||
|
||||
static gboolean hfp_ag_enabled;
|
||||
static guint service_watch_id;
|
||||
static guint modemwatch_id;
|
||||
static GList *modems;
|
||||
static GHashTable *sim_hash = NULL;
|
||||
static GHashTable *connection_hash;
|
||||
static struct ofono_emulator *emulator = NULL;
|
||||
|
||||
static int hfp_card_probe(struct ofono_handsfree_card *card,
|
||||
unsigned int vendor, void *data)
|
||||
@@ -72,6 +71,8 @@ static int hfp_card_probe(struct ofono_handsfree_card *card,
|
||||
static void hfp_card_remove(struct ofono_handsfree_card *card)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
emulator = NULL;
|
||||
}
|
||||
|
||||
static void codec_negotiation_done_cb(int err, void *data)
|
||||
@@ -172,9 +173,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
struct sockaddr_rc saddr;
|
||||
socklen_t optlen;
|
||||
struct ofono_emulator *em;
|
||||
struct ofono_modem *modem;
|
||||
char local[BT_ADDR_SIZE], remote[BT_ADDR_SIZE];
|
||||
struct ofono_handsfree_card *card;
|
||||
GList *i;
|
||||
int err;
|
||||
|
||||
DBG("Profile handler NewConnection");
|
||||
@@ -202,7 +203,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
/* Pick the first voicecall capable modem */
|
||||
if (modems == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -210,9 +210,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"No voice call capable modem");
|
||||
}
|
||||
|
||||
modem = modems->data;
|
||||
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator.");
|
||||
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
optlen = sizeof(saddr);
|
||||
@@ -240,7 +238,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
|
||||
bt_ba2str(&saddr.rc_bdaddr, remote);
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_HFP);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_HFP);
|
||||
if (em == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -248,6 +246,10 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"Not enough resources");
|
||||
}
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
emulator = em;
|
||||
ofono_emulator_register(em, fd);
|
||||
|
||||
fd_dup = dup(fd);
|
||||
@@ -367,6 +369,9 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *data)
|
||||
|
||||
modems = g_list_append(modems, modem);
|
||||
|
||||
if (emulator)
|
||||
ofono_emulator_add_modem(emulator, modem);
|
||||
|
||||
if (modems->next != NULL)
|
||||
return;
|
||||
|
||||
@@ -459,29 +464,27 @@ static void call_modemwatch(struct ofono_modem *modem, void *user)
|
||||
modem_watch(modem, TRUE, user);
|
||||
}
|
||||
|
||||
static int hfp_ag_init(void)
|
||||
static void hfp_ag_enable(DBusConnection *conn)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
int err;
|
||||
|
||||
if (DBUS_TYPE_UNIX_FD < 0)
|
||||
return -EBADF;
|
||||
|
||||
/* Registers External Profile handler */
|
||||
if (!g_dbus_register_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE,
|
||||
profile_methods, NULL,
|
||||
NULL, NULL, NULL)) {
|
||||
if (!g_dbus_register_interface(conn,
|
||||
HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE,
|
||||
profile_methods,
|
||||
NULL, NULL, NULL, NULL)) {
|
||||
ofono_error("Register Profile interface failed: %s",
|
||||
HFP_AG_EXT_PROFILE_PATH);
|
||||
return -EIO;
|
||||
HFP_AG_EXT_PROFILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
err = ofono_handsfree_card_driver_register(&hfp_ag_driver);
|
||||
if (err < 0) {
|
||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
return err;
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
ofono_error("Failed to register driver: %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
sim_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
@@ -490,10 +493,65 @@ static int hfp_ag_init(void)
|
||||
__ofono_modem_foreach(call_modemwatch, NULL);
|
||||
|
||||
connection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
g_free, connection_destroy);
|
||||
g_free, connection_destroy);
|
||||
|
||||
ofono_handsfree_audio_ref();
|
||||
|
||||
hfp_ag_enabled = TRUE;
|
||||
}
|
||||
|
||||
static void hfp_ag_disable(DBusConnection *conn)
|
||||
{
|
||||
if (modemwatch_id) {
|
||||
__ofono_modemwatch_remove(modemwatch_id);
|
||||
modemwatch_id = 0;
|
||||
}
|
||||
|
||||
if (connection_hash) {
|
||||
g_hash_table_destroy(connection_hash);
|
||||
connection_hash = NULL;
|
||||
}
|
||||
|
||||
g_list_free(modems);
|
||||
modems = NULL;
|
||||
|
||||
if (sim_hash) {
|
||||
g_hash_table_foreach_remove(sim_hash, sim_watch_remove, NULL);
|
||||
g_hash_table_destroy(sim_hash);
|
||||
sim_hash = NULL;
|
||||
}
|
||||
|
||||
if (hfp_ag_enabled) {
|
||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
|
||||
ofono_handsfree_audio_unref();
|
||||
}
|
||||
|
||||
hfp_ag_enabled = FALSE;
|
||||
}
|
||||
|
||||
static void bluez_connect_cb(DBusConnection *connection, void *user_data)
|
||||
{
|
||||
hfp_ag_enable(connection);
|
||||
}
|
||||
|
||||
static void bluez_disconnect_cb(DBusConnection *connection, void *user_data)
|
||||
{
|
||||
hfp_ag_disable(connection);
|
||||
}
|
||||
|
||||
static int hfp_ag_init(void)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
hfp_ag_enable(conn);
|
||||
|
||||
service_watch_id = g_dbus_add_service_watch(conn, "org.bluez",
|
||||
bluez_connect_cb,
|
||||
bluez_disconnect_cb,
|
||||
NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -501,19 +559,12 @@ static void hfp_ag_exit(void)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
__ofono_modemwatch_remove(modemwatch_id);
|
||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
if (service_watch_id) {
|
||||
g_dbus_remove_watch(conn, service_watch_id);
|
||||
service_watch_id = 0;
|
||||
}
|
||||
|
||||
ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
|
||||
|
||||
g_hash_table_destroy(connection_hash);
|
||||
|
||||
g_list_free(modems);
|
||||
g_hash_table_foreach_remove(sim_hash, sim_watch_remove, NULL);
|
||||
g_hash_table_destroy(sim_hash);
|
||||
|
||||
ofono_handsfree_audio_unref();
|
||||
hfp_ag_disable(conn);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(hfp_ag_bluez5, "Hands-Free Audio Gateway Profile Plugins",
|
||||
|
||||
257
ofono/plugins/sailfish_access.c
Normal file
257
ofono/plugins/sailfish_access.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
|
||||
#include <ofono/dbus-access.h>
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include <dbusaccess_policy.h>
|
||||
#include <dbusaccess_peer.h>
|
||||
|
||||
struct sailfish_access_intf {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct sailfish_access_intf_policy {
|
||||
const char* intf;
|
||||
int n_methods;
|
||||
DAPolicy* policy[1];
|
||||
};
|
||||
|
||||
#define OFONO_BUS DA_BUS_SYSTEM
|
||||
|
||||
#define COMMON_GROUP "Common"
|
||||
#define DEFAULT_POLICY "DefaultAccess"
|
||||
#define DEFAULT_INTF_POLICY "*"
|
||||
|
||||
/* File name is external for unit testing */
|
||||
const char *sailfish_access_config_file = "/etc/ofono/dbusaccess.conf";
|
||||
static GHashTable* access_table = NULL;
|
||||
static const char *default_access_policy = DA_POLICY_VERSION "; "
|
||||
"* = deny; "
|
||||
"group(sailfish-radio) | group(privileged) = allow";
|
||||
|
||||
/*
|
||||
* Configuration is loaded from /etc/ofono/dbusaccess.conf
|
||||
* If configuration is missing, default access rules are used.
|
||||
* Syntax goes like this:
|
||||
*
|
||||
* [Common]
|
||||
* DefaultAccess = <default rules for all controlled interfaces/methods>
|
||||
*
|
||||
* [InterfaceX]
|
||||
* * = <default access rules for all methods in this interface>
|
||||
* MethodY = <access rule for this method>
|
||||
*/
|
||||
|
||||
static void sailfish_access_policy_free(gpointer user_data)
|
||||
{
|
||||
da_policy_unref((DAPolicy*)user_data);
|
||||
}
|
||||
|
||||
static void sailfish_access_load_config_intf(GKeyFile *config,
|
||||
enum ofono_dbus_access_intf intf, DAPolicy* default_policy)
|
||||
{
|
||||
struct sailfish_access_intf_policy *intf_policy;
|
||||
const char *group = ofono_dbus_access_intf_name(intf);
|
||||
const char *method;
|
||||
DAPolicy *default_intf_policy = NULL;
|
||||
char *default_intf_policy_spec = g_key_file_get_string(config, group,
|
||||
DEFAULT_INTF_POLICY, NULL);
|
||||
GPtrArray *policies = g_ptr_array_new_with_free_func
|
||||
(sailfish_access_policy_free);
|
||||
int i = 0;
|
||||
|
||||
/* Parse the default policy for this interface */
|
||||
if (default_intf_policy_spec) {
|
||||
default_intf_policy = da_policy_new(default_intf_policy_spec);
|
||||
if (default_intf_policy) {
|
||||
default_policy = default_intf_policy;
|
||||
} else {
|
||||
ofono_warn("Failed to parse default %s rule \"%s\"",
|
||||
group, default_intf_policy_spec);
|
||||
}
|
||||
g_free(default_intf_policy_spec);
|
||||
}
|
||||
|
||||
/* Parse individual policies for each method */
|
||||
while ((method = ofono_dbus_access_method_name(intf, i++)) != NULL) {
|
||||
DAPolicy* policy;
|
||||
char *spec = g_key_file_get_string(config, group, method, NULL);
|
||||
|
||||
if (spec) {
|
||||
policy = da_policy_new(spec);
|
||||
if (!policy) {
|
||||
ofono_warn("Failed to parse %s.%s rule \"%s\"",
|
||||
group, method, spec);
|
||||
policy = da_policy_ref(default_policy);
|
||||
}
|
||||
} else {
|
||||
policy = da_policy_ref(default_policy);
|
||||
}
|
||||
g_ptr_array_add(policies, policy);
|
||||
g_free(spec);
|
||||
}
|
||||
|
||||
/* Allocate storage for interface policy information */
|
||||
intf_policy = g_malloc0(
|
||||
G_STRUCT_OFFSET(struct sailfish_access_intf_policy, policy) +
|
||||
sizeof(DAPolicy*) * policies->len);
|
||||
intf_policy->intf = group;
|
||||
intf_policy->n_methods = policies->len;
|
||||
|
||||
for (i = 0; i < intf_policy->n_methods; i++) {
|
||||
intf_policy->policy[i] = da_policy_ref(policies->pdata[i]);
|
||||
}
|
||||
|
||||
da_policy_unref(default_intf_policy);
|
||||
g_hash_table_insert(access_table, GINT_TO_POINTER(intf), intf_policy);
|
||||
g_ptr_array_free(policies, TRUE);
|
||||
}
|
||||
|
||||
static void sailfish_access_load_config()
|
||||
{
|
||||
GKeyFile *config = g_key_file_new();
|
||||
char *default_policy_spec;
|
||||
DAPolicy* default_policy;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Try to load config file, in case of error just make sure
|
||||
* that it config is empty.
|
||||
*/
|
||||
if (g_file_test(sailfish_access_config_file, G_FILE_TEST_EXISTS)) {
|
||||
if (g_key_file_load_from_file(config,
|
||||
sailfish_access_config_file,
|
||||
G_KEY_FILE_NONE, NULL)) {
|
||||
DBG("Loading D-Bus access rules from %s",
|
||||
sailfish_access_config_file);
|
||||
} else {
|
||||
g_key_file_unref(config);
|
||||
config = g_key_file_new();
|
||||
}
|
||||
}
|
||||
|
||||
default_policy_spec = g_key_file_get_string(config, COMMON_GROUP,
|
||||
DEFAULT_POLICY, NULL);
|
||||
default_policy = da_policy_new(default_policy_spec);
|
||||
|
||||
if (!default_policy) {
|
||||
default_policy = da_policy_new(default_access_policy);
|
||||
if (!default_policy) {
|
||||
ofono_warn("Failed to parse default D-Bus policy "
|
||||
"\"%s\" (missing group?)",
|
||||
default_access_policy);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < OFONO_DBUS_ACCESS_INTF_COUNT; i++) {
|
||||
sailfish_access_load_config_intf(config, i, default_policy);
|
||||
}
|
||||
|
||||
da_policy_unref(default_policy);
|
||||
g_free(default_policy_spec);
|
||||
g_key_file_unref(config);
|
||||
}
|
||||
|
||||
static void sailfish_access_intf_free(gpointer user_data)
|
||||
{
|
||||
struct sailfish_access_intf_policy* intf = user_data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < intf->n_methods; i++) {
|
||||
da_policy_unref(intf->policy[i]);
|
||||
}
|
||||
g_free(intf);
|
||||
}
|
||||
|
||||
static enum ofono_dbus_access sailfish_access_method_access(const char *sender,
|
||||
enum ofono_dbus_access_intf intf,
|
||||
int method, const char *arg)
|
||||
{
|
||||
struct sailfish_access_intf_policy *intf_policy = g_hash_table_lookup
|
||||
(access_table, GINT_TO_POINTER(intf));
|
||||
|
||||
if (intf_policy && method >= 0 && method < intf_policy->n_methods) {
|
||||
DAPeer *peer = da_peer_get(OFONO_BUS, sender);
|
||||
|
||||
if (peer) {
|
||||
switch (da_policy_check(intf_policy->policy[method],
|
||||
&peer->cred, 0, arg, DA_ACCESS_ALLOW)) {
|
||||
case DA_ACCESS_ALLOW:
|
||||
return OFONO_DBUS_ACCESS_ALLOW;
|
||||
case DA_ACCESS_DENY:
|
||||
return OFONO_DBUS_ACCESS_DENY;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Deny access to unknown peers. Those are
|
||||
* already gone from the bus and won't be
|
||||
* able to receive our reply anyway.
|
||||
*/
|
||||
return OFONO_DBUS_ACCESS_DENY;
|
||||
}
|
||||
}
|
||||
return OFONO_DBUS_ACCESS_DONT_CARE;
|
||||
}
|
||||
|
||||
static const struct ofono_dbus_access_plugin sailfish_access_plugin = {
|
||||
.name = "Sailfish D-Bus access",
|
||||
.priority = OFONO_DBUS_ACCESS_PRIORITY_DEFAULT,
|
||||
.method_access = sailfish_access_method_access
|
||||
};
|
||||
|
||||
static int sailfish_access_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG("");
|
||||
ret = ofono_dbus_access_plugin_register(&sailfish_access_plugin);
|
||||
if (ret == 0) {
|
||||
access_table = g_hash_table_new_full(g_direct_hash,
|
||||
g_direct_equal, NULL, sailfish_access_intf_free);
|
||||
sailfish_access_load_config();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sailfish_access_exit(void)
|
||||
{
|
||||
DBG("");
|
||||
ofono_dbus_access_plugin_unregister(&sailfish_access_plugin);
|
||||
da_peer_flush(OFONO_BUS, NULL);
|
||||
if (access_table) {
|
||||
g_hash_table_destroy(access_table);
|
||||
access_table = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(sailfish_access, "Sailfish D-Bus access plugin", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT,
|
||||
sailfish_access_init, sailfish_access_exit)
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <gutil_macros.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ofono/watch.h>
|
||||
|
||||
#include "src/ofono.h"
|
||||
#include "src/storage.h"
|
||||
|
||||
@@ -31,12 +33,11 @@
|
||||
#include "sailfish_manager_dbus.h"
|
||||
#include "sailfish_cell_info_dbus.h"
|
||||
#include "sailfish_sim_info.h"
|
||||
#include "sailfish_watch.h"
|
||||
|
||||
/* How long we wait for all drivers to register (number of idle loops) */
|
||||
#define SF_INIT_IDLE_COUNT (5)
|
||||
|
||||
enum sailfish_watch_events {
|
||||
enum ofono_watch_events {
|
||||
WATCH_EVENT_MODEM,
|
||||
WATCH_EVENT_ONLINE,
|
||||
WATCH_EVENT_IMSI,
|
||||
@@ -83,12 +84,13 @@ struct sailfish_slot_priv {
|
||||
struct sailfish_slot_priv *next;
|
||||
struct sailfish_slot_manager *manager;
|
||||
struct sailfish_slot_impl *impl;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
struct sailfish_sim_info *siminfo;
|
||||
struct sailfish_sim_info_dbus *siminfo_dbus;
|
||||
struct sailfish_cell_info *cellinfo;
|
||||
struct sailfish_cell_info_dbus *cellinfo_dbus;
|
||||
enum sailfish_sim_state sim_state;
|
||||
enum sailfish_slot_flags flags;
|
||||
gulong watch_event_id[WATCH_EVENT_COUNT];
|
||||
char *imei;
|
||||
char *imeisv;
|
||||
@@ -230,7 +232,7 @@ static void sailfish_manager_slot_update_cell_info_dbus
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_manager_slot_modem_changed(struct sailfish_watch *w,
|
||||
static void sailfish_manager_slot_modem_changed(struct ofono_watch *w,
|
||||
void *user_data)
|
||||
{
|
||||
struct sailfish_slot_priv *s = user_data;
|
||||
@@ -241,7 +243,7 @@ static void sailfish_manager_slot_modem_changed(struct sailfish_watch *w,
|
||||
sailfish_manager_update_ready(p);
|
||||
}
|
||||
|
||||
static void sailfish_manager_slot_imsi_changed(struct sailfish_watch *w,
|
||||
static void sailfish_manager_slot_imsi_changed(struct ofono_watch *w,
|
||||
void *user_data)
|
||||
{
|
||||
struct sailfish_slot_priv *slot = user_data;
|
||||
@@ -320,6 +322,17 @@ struct sailfish_slot *sailfish_manager_slot_add
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state)
|
||||
{
|
||||
return sailfish_manager_slot_add2(m, impl, path, techs, imei, imeisv,
|
||||
sim_state, SAILFISH_SLOT_NO_FLAGS);
|
||||
}
|
||||
|
||||
struct sailfish_slot *sailfish_manager_slot_add2
|
||||
(struct sailfish_slot_manager *m, struct sailfish_slot_impl *impl,
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state,
|
||||
enum sailfish_slot_flags flags)
|
||||
{
|
||||
/* Only accept these calls when we are starting! We have been
|
||||
* assuming all along that the number of slots is known right
|
||||
@@ -339,7 +352,8 @@ struct sailfish_slot *sailfish_manager_slot_add
|
||||
s->impl = impl;
|
||||
s->manager = m;
|
||||
s->sim_state = sim_state;
|
||||
s->watch = sailfish_watch_new(path);
|
||||
s->flags = flags;
|
||||
s->watch = ofono_watch_new(path);
|
||||
s->siminfo = sailfish_sim_info_new(path);
|
||||
s->siminfo_dbus = sailfish_sim_info_dbus_new(s->siminfo);
|
||||
s->pub.path = s->watch->path;
|
||||
@@ -389,13 +403,13 @@ struct sailfish_slot *sailfish_manager_slot_add
|
||||
|
||||
/* Register for events */
|
||||
s->watch_event_id[WATCH_EVENT_MODEM] =
|
||||
sailfish_watch_add_modem_changed_handler(s->watch,
|
||||
ofono_watch_add_modem_changed_handler(s->watch,
|
||||
sailfish_manager_slot_modem_changed, s);
|
||||
s->watch_event_id[WATCH_EVENT_ONLINE] =
|
||||
sailfish_watch_add_online_changed_handler(s->watch,
|
||||
ofono_watch_add_online_changed_handler(s->watch,
|
||||
sailfish_manager_slot_modem_changed, s);
|
||||
s->watch_event_id[WATCH_EVENT_IMSI] =
|
||||
sailfish_watch_add_imsi_changed_handler(s->watch,
|
||||
ofono_watch_add_imsi_changed_handler(s->watch,
|
||||
sailfish_manager_slot_imsi_changed, s);
|
||||
|
||||
return &s->pub;
|
||||
@@ -426,8 +440,8 @@ static void sailfish_slot_free(struct sailfish_slot_priv *s)
|
||||
sailfish_sim_info_dbus_free(s->siminfo_dbus);
|
||||
sailfish_cell_info_dbus_free(s->cellinfo_dbus);
|
||||
sailfish_cell_info_unref(s->cellinfo);
|
||||
sailfish_watch_remove_all_handlers(s->watch, s->watch_event_id);
|
||||
sailfish_watch_unref(s->watch);
|
||||
ofono_watch_remove_all_handlers(s->watch, s->watch_event_id);
|
||||
ofono_watch_unref(s->watch);
|
||||
g_free(s->imei);
|
||||
g_free(s->imeisv);
|
||||
s->next = NULL;
|
||||
@@ -649,10 +663,12 @@ static int sailfish_manager_update_modem_paths(struct sailfish_manager_priv *p)
|
||||
mms_slot = sailfish_manager_find_slot_imsi(p, p->mms_imsi);
|
||||
}
|
||||
|
||||
if (mms_slot && mms_slot != slot) {
|
||||
if (mms_slot && (mms_slot != slot ||
|
||||
(slot->flags & SAILFISH_SLOT_SINGLE_CONTEXT))) {
|
||||
/*
|
||||
* Reset default data SIM if another SIM is
|
||||
* temporarily selected for MMS.
|
||||
* Reset default data SIM if
|
||||
* a) another SIM is temporarily selected for MMS; or
|
||||
* b) this slot can't have more than one context active.
|
||||
*/
|
||||
slot = NULL;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -17,8 +17,9 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ofono/watch.h>
|
||||
|
||||
#include "sailfish_sim_info.h"
|
||||
#include "sailfish_watch.h"
|
||||
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_log.h>
|
||||
@@ -42,7 +43,7 @@ G_STATIC_ASSERT(DEFAULT_SPN_BUFSIZE >= \
|
||||
typedef GObjectClass SailfishSimInfoClass;
|
||||
typedef struct sailfish_sim_info SailfishSimInfo;
|
||||
|
||||
enum sailfish_watch_events {
|
||||
enum ofono_watch_events {
|
||||
WATCH_EVENT_SIM,
|
||||
WATCH_EVENT_SIM_STATE,
|
||||
WATCH_EVENT_ICCID,
|
||||
@@ -53,7 +54,7 @@ enum sailfish_watch_events {
|
||||
};
|
||||
|
||||
struct sailfish_sim_info_priv {
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
struct ofono_netreg *netreg;
|
||||
char *iccid;
|
||||
char *imsi;
|
||||
@@ -251,7 +252,7 @@ static void sailfish_sim_info_set_spn(struct sailfish_sim_info *self,
|
||||
|
||||
static void sailfish_sim_info_update_spn(struct sailfish_sim_info *self)
|
||||
{
|
||||
struct sailfish_watch *watch = self->priv->watch;
|
||||
struct ofono_watch *watch = self->priv->watch;
|
||||
|
||||
if (watch->spn && watch->spn[0]) {
|
||||
sailfish_sim_info_set_spn(self, watch->spn);
|
||||
@@ -431,7 +432,7 @@ static void sailfish_sim_info_set_iccid(struct sailfish_sim_info *self,
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_iccid_watch_cb(struct sailfish_watch *watch,
|
||||
static void sailfish_sim_info_iccid_watch_cb(struct ofono_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
@@ -441,7 +442,7 @@ static void sailfish_sim_info_iccid_watch_cb(struct sailfish_watch *watch,
|
||||
sailfish_sim_info_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_imsi_watch_cb(struct sailfish_watch *watch,
|
||||
static void sailfish_sim_info_imsi_watch_cb(struct ofono_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
@@ -450,7 +451,7 @@ static void sailfish_sim_info_imsi_watch_cb(struct sailfish_watch *watch,
|
||||
sailfish_sim_info_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_spn_watch_cb(struct sailfish_watch *watch,
|
||||
static void sailfish_sim_info_spn_watch_cb(struct ofono_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
@@ -503,7 +504,7 @@ static void sailfish_sim_info_set_netreg(struct sailfish_sim_info *self,
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_netreg_changed(struct sailfish_watch *watch,
|
||||
static void sailfish_sim_info_netreg_changed(struct ofono_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
@@ -517,7 +518,7 @@ struct sailfish_sim_info *sailfish_sim_info_new(const char *path)
|
||||
struct sailfish_sim_info *self = NULL;
|
||||
|
||||
if (path) {
|
||||
struct sailfish_watch *watch = sailfish_watch_new(path);
|
||||
struct ofono_watch *watch = ofono_watch_new(path);
|
||||
struct sailfish_sim_info_priv *priv;
|
||||
|
||||
self = g_object_new(SAILFISH_SIMINFO_TYPE, NULL);
|
||||
@@ -525,16 +526,16 @@ struct sailfish_sim_info *sailfish_sim_info_new(const char *path)
|
||||
priv->watch = watch;
|
||||
self->path = watch->path;
|
||||
priv->watch_event_id[WATCH_EVENT_ICCID] =
|
||||
sailfish_watch_add_iccid_changed_handler(watch,
|
||||
ofono_watch_add_iccid_changed_handler(watch,
|
||||
sailfish_sim_info_iccid_watch_cb, self);
|
||||
priv->watch_event_id[WATCH_EVENT_IMSI] =
|
||||
sailfish_watch_add_imsi_changed_handler(watch,
|
||||
ofono_watch_add_imsi_changed_handler(watch,
|
||||
sailfish_sim_info_imsi_watch_cb, self);
|
||||
priv->watch_event_id[WATCH_EVENT_SPN] =
|
||||
sailfish_watch_add_spn_changed_handler(watch,
|
||||
ofono_watch_add_spn_changed_handler(watch,
|
||||
sailfish_sim_info_spn_watch_cb, self);
|
||||
priv->watch_event_id[WATCH_EVENT_NETREG] =
|
||||
sailfish_watch_add_netreg_changed_handler(watch,
|
||||
ofono_watch_add_netreg_changed_handler(watch,
|
||||
sailfish_sim_info_netreg_changed, self);
|
||||
sailfish_sim_info_set_iccid(self, watch->iccid);
|
||||
sailfish_sim_info_set_netreg(self, watch->netreg);
|
||||
@@ -610,8 +611,8 @@ static void sailfish_sim_info_finalize(GObject *object)
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(object);
|
||||
struct sailfish_sim_info_priv *priv = self->priv;
|
||||
|
||||
sailfish_watch_remove_all_handlers(priv->watch, priv->watch_event_id);
|
||||
sailfish_watch_unref(priv->watch);
|
||||
ofono_watch_remove_all_handlers(priv->watch, priv->watch_event_id);
|
||||
ofono_watch_unref(priv->watch);
|
||||
g_free(priv->iccid);
|
||||
g_free(priv->imsi);
|
||||
g_free(priv->sim_spn);
|
||||
|
||||
@@ -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
|
||||
@@ -14,9 +14,9 @@
|
||||
*/
|
||||
|
||||
#include "sailfish_sim_info.h"
|
||||
#include "sailfish_watch.h"
|
||||
|
||||
#include <ofono/dbus.h>
|
||||
#include <ofono/watch.h>
|
||||
|
||||
#include <gdbus.h>
|
||||
|
||||
@@ -36,7 +36,7 @@ enum sim_info_event_id {
|
||||
|
||||
struct sailfish_sim_info_dbus {
|
||||
struct sailfish_sim_info *info;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
DBusConnection *conn;
|
||||
gulong watch_event_id[WATCH_EVENT_COUNT];
|
||||
gulong info_event_id[SIM_INFO_EVENT_COUNT];
|
||||
@@ -165,7 +165,7 @@ static const GDBusSignalTable sailfish_sim_info_dbus_signals[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static void sailfish_sim_info_dbus_modem_cb(struct sailfish_watch *watch,
|
||||
static void sailfish_sim_info_dbus_modem_cb(struct ofono_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
if (watch->modem) {
|
||||
@@ -214,7 +214,7 @@ struct sailfish_sim_info_dbus *sailfish_sim_info_dbus_new
|
||||
|
||||
DBG("%s", info->path);
|
||||
dbus->info = sailfish_sim_info_ref(info);
|
||||
dbus->watch = sailfish_watch_new(info->path);
|
||||
dbus->watch = ofono_watch_new(info->path);
|
||||
dbus->conn = dbus_connection_ref(ofono_dbus_get_connection());
|
||||
|
||||
/* Register D-Bus interface */
|
||||
@@ -229,7 +229,7 @@ struct sailfish_sim_info_dbus *sailfish_sim_info_dbus_new
|
||||
}
|
||||
|
||||
dbus->watch_event_id[WATCH_EVENT_MODEM] =
|
||||
sailfish_watch_add_modem_changed_handler(dbus->watch,
|
||||
ofono_watch_add_modem_changed_handler(dbus->watch,
|
||||
sailfish_sim_info_dbus_modem_cb, dbus);
|
||||
dbus->info_event_id[SIM_INFO_EVENT_ICCID] =
|
||||
sailfish_sim_info_add_iccid_changed_handler(info,
|
||||
@@ -275,9 +275,9 @@ void sailfish_sim_info_dbus_free(struct sailfish_sim_info_dbus *dbus)
|
||||
}
|
||||
dbus_connection_unref(dbus->conn);
|
||||
|
||||
sailfish_watch_remove_all_handlers(dbus->watch,
|
||||
ofono_watch_remove_all_handlers(dbus->watch,
|
||||
dbus->watch_event_id);
|
||||
sailfish_watch_unref(dbus->watch);
|
||||
ofono_watch_unref(dbus->watch);
|
||||
|
||||
sailfish_sim_info_remove_all_handlers(dbus->info,
|
||||
dbus->info_event_id);
|
||||
|
||||
@@ -1,692 +0,0 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017-2018 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* 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 "sailfish_watch.h"
|
||||
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_log.h>
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
typedef GObjectClass SailfishWatchClass;
|
||||
typedef struct sailfish_watch SailfishWatch;
|
||||
|
||||
struct sailfish_watch_priv {
|
||||
char *path;
|
||||
char *iccid;
|
||||
char *imsi;
|
||||
char *spn;
|
||||
int signals_suspended;
|
||||
int queued_signals;
|
||||
guint modem_watch_id;
|
||||
guint online_watch_id;
|
||||
guint sim_watch_id;
|
||||
guint sim_state_watch_id;
|
||||
guint iccid_watch_id;
|
||||
guint imsi_watch_id;
|
||||
guint spn_watch_id;
|
||||
guint netreg_watch_id;
|
||||
};
|
||||
|
||||
enum sailfish_watch_signal {
|
||||
SIGNAL_MODEM_CHANGED,
|
||||
SIGNAL_ONLINE_CHANGED,
|
||||
SIGNAL_SIM_CHANGED,
|
||||
SIGNAL_SIM_STATE_CHANGED,
|
||||
SIGNAL_ICCID_CHANGED,
|
||||
SIGNAL_IMSI_CHANGED,
|
||||
SIGNAL_SPN_CHANGED,
|
||||
SIGNAL_NETREG_CHANGED,
|
||||
SIGNAL_COUNT
|
||||
};
|
||||
|
||||
#define SIGNAL_MODEM_CHANGED_NAME "sailfish-watch-modem-changed"
|
||||
#define SIGNAL_ONLINE_CHANGED_NAME "sailfish-watch-online-changed"
|
||||
#define SIGNAL_SIM_CHANGED_NAME "sailfish-watch-sim-changed"
|
||||
#define SIGNAL_SIM_STATE_CHANGED_NAME "sailfish-watch-sim-state-changed"
|
||||
#define SIGNAL_ICCID_CHANGED_NAME "sailfish-watch-iccid-changed"
|
||||
#define SIGNAL_IMSI_CHANGED_NAME "sailfish-watch-imsi-changed"
|
||||
#define SIGNAL_SPN_CHANGED_NAME "sailfish-watch-spn-changed"
|
||||
#define SIGNAL_NETREG_CHANGED_NAME "sailfish-watch-netreg-changed"
|
||||
|
||||
static guint sailfish_watch_signals[SIGNAL_COUNT] = { 0 };
|
||||
static GHashTable* sailfish_watch_table = NULL;
|
||||
|
||||
G_DEFINE_TYPE(SailfishWatch, sailfish_watch, G_TYPE_OBJECT)
|
||||
#define SAILFISH_WATCH_TYPE (sailfish_watch_get_type())
|
||||
#define SAILFISH_WATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||
SAILFISH_WATCH_TYPE, SailfishWatch))
|
||||
|
||||
#define NEW_SIGNAL(klass,name) \
|
||||
sailfish_watch_signals[SIGNAL_##name##_CHANGED] = \
|
||||
g_signal_new(SIGNAL_##name##_CHANGED_NAME, \
|
||||
G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, \
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 0)
|
||||
|
||||
/* Skip the leading slash from the modem path: */
|
||||
#define DBG_(obj,fmt,args...) DBG("%s " fmt, (obj)->path+1, ##args)
|
||||
|
||||
static inline int sailfish_watch_signal_bit(enum sailfish_watch_signal id)
|
||||
{
|
||||
return (1 << id);
|
||||
}
|
||||
|
||||
static inline void sailfish_watch_signal_emit(struct sailfish_watch *self,
|
||||
enum sailfish_watch_signal id)
|
||||
{
|
||||
self->priv->queued_signals &= ~sailfish_watch_signal_bit(id);
|
||||
g_signal_emit(self, sailfish_watch_signals[id], 0);
|
||||
}
|
||||
|
||||
static inline void sailfish_watch_signal_queue(struct sailfish_watch *self,
|
||||
enum sailfish_watch_signal id)
|
||||
{
|
||||
self->priv->queued_signals |= sailfish_watch_signal_bit(id);
|
||||
}
|
||||
|
||||
static void sailfish_watch_emit_queued_signals(struct sailfish_watch *self)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (priv->signals_suspended < 1) {
|
||||
int i;
|
||||
|
||||
for (i = 0; priv->queued_signals && i < SIGNAL_COUNT; i++) {
|
||||
if (priv->queued_signals &
|
||||
sailfish_watch_signal_bit(i)) {
|
||||
sailfish_watch_signal_emit(self, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sailfish_watch_suspend_signals(struct sailfish_watch *self)
|
||||
{
|
||||
self->priv->signals_suspended++;
|
||||
}
|
||||
|
||||
static inline void sailfish_watch_resume_signals(struct sailfish_watch *self)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(priv->signals_suspended > 0);
|
||||
priv->signals_suspended--;
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_iccid_update(struct sailfish_watch *self,
|
||||
const char *iccid)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (g_strcmp0(priv->iccid, iccid)) {
|
||||
g_free(priv->iccid);
|
||||
self->iccid = priv->iccid = g_strdup(iccid);
|
||||
sailfish_watch_signal_queue(self, SIGNAL_ICCID_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_iccid_notify(const char *iccid, void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
sailfish_watch_iccid_update(self, iccid);
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_iccid_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(priv->iccid_watch_id);
|
||||
priv->iccid_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_spn_update(struct sailfish_watch *self,
|
||||
const char *spn)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (g_strcmp0(priv->spn, spn)) {
|
||||
g_free(priv->spn);
|
||||
self->spn = priv->spn = g_strdup(spn);
|
||||
sailfish_watch_signal_queue(self, SIGNAL_SPN_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_spn_notify(const char *spn, const char *dc,
|
||||
void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
sailfish_watch_spn_update(self, spn);
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_spn_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(priv->spn_watch_id);
|
||||
priv->spn_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_imsi_update(struct sailfish_watch *self,
|
||||
const char *imsi)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (g_strcmp0(priv->imsi, imsi)) {
|
||||
g_free(priv->imsi);
|
||||
self->imsi = priv->imsi = g_strdup(imsi);
|
||||
sailfish_watch_signal_queue(self, SIGNAL_IMSI_CHANGED);
|
||||
/* ofono core crashes if we add spn watch too early */
|
||||
if (imsi) {
|
||||
ofono_sim_add_spn_watch(self->sim, &priv->spn_watch_id,
|
||||
sailfish_watch_spn_notify, self,
|
||||
sailfish_watch_spn_destroy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_imsi_notify(const char *imsi, void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
sailfish_watch_imsi_update(self, imsi);
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_imsi_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(priv->imsi_watch_id);
|
||||
priv->imsi_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_state_notify(enum ofono_sim_state new_state,
|
||||
void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
/*
|
||||
* ofono core doesn't notify SIM watches when SIM card gets removed.
|
||||
* So we have to reset things here based on the SIM state.
|
||||
*/
|
||||
if (new_state == OFONO_SIM_STATE_NOT_PRESENT) {
|
||||
sailfish_watch_iccid_update(self, NULL);
|
||||
}
|
||||
if (new_state != OFONO_SIM_STATE_READY) {
|
||||
sailfish_watch_imsi_update(self, NULL);
|
||||
sailfish_watch_spn_update(self, NULL);
|
||||
}
|
||||
sailfish_watch_signal_queue(self, SIGNAL_SIM_STATE_CHANGED);
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_state_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(priv->sim_state_watch_id);
|
||||
priv->sim_state_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_set_sim(struct sailfish_watch *self,
|
||||
struct ofono_sim *sim)
|
||||
{
|
||||
if (self->sim != sim) {
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (priv->sim_state_watch_id) {
|
||||
ofono_sim_remove_state_watch(self->sim,
|
||||
priv->sim_state_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
GASSERT(!priv->sim_state_watch_id);
|
||||
}
|
||||
if (priv->iccid_watch_id) {
|
||||
ofono_sim_remove_iccid_watch(self->sim,
|
||||
priv->iccid_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
GASSERT(!priv->iccid_watch_id);
|
||||
}
|
||||
if (priv->imsi_watch_id) {
|
||||
ofono_sim_remove_imsi_watch(self->sim,
|
||||
priv->imsi_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
GASSERT(!priv->imsi_watch_id);
|
||||
}
|
||||
if (priv->spn_watch_id) {
|
||||
ofono_sim_remove_spn_watch(self->sim,
|
||||
&priv->spn_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
GASSERT(!priv->spn_watch_id);
|
||||
}
|
||||
self->sim = sim;
|
||||
sailfish_watch_signal_queue(self, SIGNAL_SIM_CHANGED);
|
||||
sailfish_watch_suspend_signals(self);
|
||||
|
||||
/* Reset the current state */
|
||||
sailfish_watch_iccid_update(self, NULL);
|
||||
sailfish_watch_imsi_update(self, NULL);
|
||||
sailfish_watch_spn_update(self, NULL);
|
||||
if (sim) {
|
||||
priv->sim_state_watch_id =
|
||||
ofono_sim_add_state_watch(sim,
|
||||
sailfish_watch_sim_state_notify, self,
|
||||
sailfish_watch_sim_state_destroy);
|
||||
/*
|
||||
* Unlike ofono_sim_add_state_watch, the rest
|
||||
* of ofono_sim_add_xxx_watch functions call the
|
||||
* notify callback if the value is already known
|
||||
* to the ofono core.
|
||||
*
|
||||
* Also note that ofono core crashes if we add
|
||||
* spn watch too early.
|
||||
*/
|
||||
priv->iccid_watch_id =
|
||||
ofono_sim_add_iccid_watch(self->sim,
|
||||
sailfish_watch_iccid_notify, self,
|
||||
sailfish_watch_iccid_destroy);
|
||||
priv->imsi_watch_id =
|
||||
ofono_sim_add_imsi_watch(self->sim,
|
||||
sailfish_watch_imsi_notify, self,
|
||||
sailfish_watch_imsi_destroy);
|
||||
}
|
||||
|
||||
/* Emit the pending signals. */
|
||||
sailfish_watch_resume_signals(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_notify(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
struct ofono_sim *sim = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG_(self, "sim registered");
|
||||
sailfish_watch_set_sim(self, sim);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG_(self, "sim unregistered");
|
||||
sailfish_watch_set_sim(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
self->priv->sim_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_set_netreg(struct sailfish_watch *self,
|
||||
struct ofono_netreg *netreg)
|
||||
{
|
||||
if (self->netreg != netreg) {
|
||||
self->netreg = netreg;
|
||||
sailfish_watch_signal_emit(self, SIGNAL_NETREG_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_netreg_notify(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
struct ofono_netreg *netreg = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG_(self, "netreg registered");
|
||||
sailfish_watch_set_netreg(self, netreg);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG_(self, "netreg unregistered");
|
||||
sailfish_watch_set_netreg(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_netreg_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
self->priv->netreg_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_online_update(struct sailfish_watch *self,
|
||||
gboolean online)
|
||||
{
|
||||
if (self->online != online) {
|
||||
self->online = online;
|
||||
sailfish_watch_signal_queue(self, SIGNAL_ONLINE_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_online_notify(struct ofono_modem *modem,
|
||||
ofono_bool_t online, void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
GASSERT(self->modem == modem);
|
||||
GASSERT(online == ofono_modem_get_online(modem));
|
||||
sailfish_watch_online_update(self, online);
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_online_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
self->priv->online_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_setup_modem(struct sailfish_watch *self)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(!priv->online_watch_id);
|
||||
priv->online_watch_id =
|
||||
__ofono_modem_add_online_watch(self->modem,
|
||||
sailfish_watch_online_notify, self,
|
||||
sailfish_watch_online_destroy);
|
||||
|
||||
/* __ofono_modem_add_atom_watch() calls the notify callback if the
|
||||
* atom is already registered */
|
||||
GASSERT(!priv->sim_watch_id);
|
||||
priv->sim_watch_id = __ofono_modem_add_atom_watch(self->modem,
|
||||
OFONO_ATOM_TYPE_SIM, sailfish_watch_sim_notify,
|
||||
self, sailfish_watch_sim_destroy);
|
||||
|
||||
GASSERT(!priv->netreg_watch_id);
|
||||
priv->netreg_watch_id = __ofono_modem_add_atom_watch(self->modem,
|
||||
OFONO_ATOM_TYPE_NETREG, sailfish_watch_netreg_notify,
|
||||
self, sailfish_watch_netreg_destroy);
|
||||
}
|
||||
|
||||
static void sailfish_watch_cleanup_modem(struct sailfish_watch *self,
|
||||
struct ofono_modem *modem)
|
||||
{
|
||||
/* Caller checks the self->modem isn't NULL */
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (priv->online_watch_id) {
|
||||
__ofono_modem_remove_online_watch(modem,
|
||||
priv->online_watch_id);
|
||||
GASSERT(!priv->online_watch_id);
|
||||
}
|
||||
|
||||
if (priv->sim_watch_id) {
|
||||
__ofono_modem_remove_atom_watch(modem, priv->sim_watch_id);
|
||||
GASSERT(!priv->sim_watch_id);
|
||||
}
|
||||
|
||||
if (priv->netreg_watch_id) {
|
||||
__ofono_modem_remove_atom_watch(modem, priv->netreg_watch_id);
|
||||
GASSERT(!priv->netreg_watch_id);
|
||||
}
|
||||
|
||||
sailfish_watch_set_sim(self, NULL);
|
||||
sailfish_watch_set_netreg(self, NULL);
|
||||
}
|
||||
|
||||
static void sailfish_watch_set_modem(struct sailfish_watch *self,
|
||||
struct ofono_modem *modem)
|
||||
{
|
||||
if (self->modem != modem) {
|
||||
struct ofono_modem *old_modem = self->modem;
|
||||
|
||||
self->modem = modem;
|
||||
sailfish_watch_signal_queue(self, SIGNAL_MODEM_CHANGED);
|
||||
if (old_modem) {
|
||||
sailfish_watch_cleanup_modem(self, old_modem);
|
||||
}
|
||||
if (modem) {
|
||||
sailfish_watch_setup_modem(self);
|
||||
}
|
||||
sailfish_watch_online_update(self,
|
||||
ofono_modem_get_online(self->modem));
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_modem_notify(struct ofono_modem *modem,
|
||||
gboolean added, void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
if (added) {
|
||||
if (!g_strcmp0(self->path, ofono_modem_get_path(modem))) {
|
||||
sailfish_watch_set_modem(self, modem);
|
||||
}
|
||||
} else if (self->modem == modem) {
|
||||
sailfish_watch_set_modem(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_modem_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
self->priv->modem_watch_id = 0;
|
||||
}
|
||||
|
||||
static ofono_bool_t sailfish_watch_modem_find(struct ofono_modem *modem,
|
||||
void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
if (!g_strcmp0(self->path, ofono_modem_get_path(modem))) {
|
||||
self->modem = modem;
|
||||
sailfish_watch_setup_modem(self);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_initialize(struct sailfish_watch *self,
|
||||
const char *path)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
self->path = priv->path = g_strdup(path);
|
||||
ofono_modem_find(sailfish_watch_modem_find, self);
|
||||
self->online = ofono_modem_get_online(self->modem);
|
||||
priv->modem_watch_id =
|
||||
__ofono_modemwatch_add(sailfish_watch_modem_notify, self,
|
||||
sailfish_watch_modem_destroy);
|
||||
}
|
||||
|
||||
static void sailfish_watch_destroyed(gpointer key, GObject* obj)
|
||||
{
|
||||
GASSERT(sailfish_watch_table);
|
||||
DBG("%s", (char*)key);
|
||||
if (sailfish_watch_table) {
|
||||
GASSERT(g_hash_table_lookup(sailfish_watch_table, key) == obj);
|
||||
g_hash_table_remove(sailfish_watch_table, key);
|
||||
if (g_hash_table_size(sailfish_watch_table) == 0) {
|
||||
g_hash_table_unref(sailfish_watch_table);
|
||||
sailfish_watch_table = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct sailfish_watch *sailfish_watch_new(const char *path)
|
||||
{
|
||||
struct sailfish_watch *watch = NULL;
|
||||
|
||||
if (path) {
|
||||
if (sailfish_watch_table) {
|
||||
watch = sailfish_watch_ref(g_hash_table_lookup(
|
||||
sailfish_watch_table, path));
|
||||
}
|
||||
if (!watch) {
|
||||
char* key = g_strdup(path);
|
||||
|
||||
watch = g_object_new(SAILFISH_WATCH_TYPE, NULL);
|
||||
sailfish_watch_initialize(watch, path);
|
||||
if (!sailfish_watch_table) {
|
||||
/* Create the table on demand */
|
||||
sailfish_watch_table =
|
||||
g_hash_table_new_full(g_str_hash,
|
||||
g_str_equal, g_free, NULL);
|
||||
}
|
||||
g_hash_table_replace(sailfish_watch_table, key, watch);
|
||||
g_object_weak_ref(G_OBJECT(watch),
|
||||
sailfish_watch_destroyed, key);
|
||||
DBG_(watch, "created");
|
||||
}
|
||||
}
|
||||
return watch;
|
||||
}
|
||||
|
||||
struct sailfish_watch *sailfish_watch_ref(struct sailfish_watch *self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_ref(SAILFISH_WATCH(self));
|
||||
return self;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void sailfish_watch_unref(struct sailfish_watch *self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_unref(SAILFISH_WATCH(self));
|
||||
}
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_modem_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_MODEM_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_online_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_ONLINE_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_sim_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_SIM_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_sim_state_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_SIM_STATE_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_iccid_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_ICCID_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_imsi_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_IMSI_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_spn_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_SPN_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_netreg_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_NETREG_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
void sailfish_watch_remove_handler(struct sailfish_watch *self, gulong id)
|
||||
{
|
||||
if (self && id) {
|
||||
g_signal_handler_disconnect(self, id);
|
||||
}
|
||||
}
|
||||
|
||||
void sailfish_watch_remove_handlers(struct sailfish_watch *self, gulong *ids,
|
||||
int count)
|
||||
{
|
||||
gutil_disconnect_handlers(self, ids, count);
|
||||
}
|
||||
|
||||
static void sailfish_watch_init(struct sailfish_watch *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SAILFISH_WATCH_TYPE,
|
||||
struct sailfish_watch_priv);
|
||||
}
|
||||
|
||||
static void sailfish_watch_finalize(GObject *object)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(object);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (self->modem) {
|
||||
struct ofono_modem *modem = self->modem;
|
||||
|
||||
self->modem = NULL;
|
||||
sailfish_watch_cleanup_modem(self, modem);
|
||||
}
|
||||
if (priv->modem_watch_id) {
|
||||
__ofono_modemwatch_remove(priv->modem_watch_id);
|
||||
GASSERT(!priv->modem_watch_id);
|
||||
}
|
||||
g_free(priv->path);
|
||||
G_OBJECT_CLASS(sailfish_watch_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void sailfish_watch_class_init(SailfishWatchClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = sailfish_watch_finalize;
|
||||
g_type_class_add_private(klass, sizeof(struct sailfish_watch_priv));
|
||||
NEW_SIGNAL(klass, MODEM);
|
||||
NEW_SIGNAL(klass, ONLINE);
|
||||
NEW_SIGNAL(klass, SIM);
|
||||
NEW_SIGNAL(klass, SIM_STATE);
|
||||
NEW_SIGNAL(klass, ICCID);
|
||||
NEW_SIGNAL(klass, IMSI);
|
||||
NEW_SIGNAL(klass, SPN);
|
||||
NEW_SIGNAL(klass, NETREG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -1124,7 +1124,6 @@ static gboolean setup_xmm7xxx(struct modem_info *modem)
|
||||
const char *mdm = NULL, *net = NULL;
|
||||
GSList *list;
|
||||
|
||||
DBG("%s %s\n", __DATE__, __TIME__);
|
||||
DBG("%s %s %s %s %s %s\n", modem->syspath, modem->devname,
|
||||
modem->driver, modem->vendor, modem->model, modem->sysattr);
|
||||
|
||||
|
||||
252
ofono/src/dbus-access.c
Normal file
252
ofono/src/dbus-access.c
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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 "ofono.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
static GSList *dbus_access_plugins = NULL;
|
||||
|
||||
const char *ofono_dbus_access_intf_name(enum ofono_dbus_access_intf intf)
|
||||
{
|
||||
switch (intf) {
|
||||
case OFONO_DBUS_ACCESS_INTF_MESSAGE:
|
||||
return OFONO_MESSAGE_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_MESSAGEMGR:
|
||||
return OFONO_MESSAGE_MANAGER_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_VOICECALL:
|
||||
return OFONO_VOICECALL_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_VOICECALLMGR:
|
||||
return OFONO_VOICECALL_MANAGER_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_CONNCTX:
|
||||
return OFONO_CONNECTION_CONTEXT_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_CONNMGR:
|
||||
return OFONO_CONNECTION_MANAGER_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_SIMMGR:
|
||||
return OFONO_SIM_MANAGER_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_MODEM:
|
||||
return OFONO_MODEM_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS:
|
||||
return OFONO_RADIO_SETTINGS_INTERFACE;
|
||||
case OFONO_DBUS_ACCESS_INTF_COUNT:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ofono_dbus_access_method_name(enum ofono_dbus_access_intf intf,
|
||||
int method)
|
||||
{
|
||||
switch (intf) {
|
||||
case OFONO_DBUS_ACCESS_INTF_MESSAGE:
|
||||
switch ((enum ofono_dbus_access_message_method)method) {
|
||||
case OFONO_DBUS_ACCESS_MESSAGE_CANCEL:
|
||||
return "Cancel";
|
||||
case OFONO_DBUS_ACCESS_MESSAGE_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_MESSAGEMGR:
|
||||
switch ((enum ofono_dbus_access_messagemgr_method)method) {
|
||||
case OFONO_DBUS_ACCESS_MESSAGEMGR_SEND_MESSAGE:
|
||||
return "SendMessage";
|
||||
case OFONO_DBUS_ACCESS_MESSAGEMGR_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_VOICECALL:
|
||||
switch ((enum ofono_dbus_access_voicecall_method)method) {
|
||||
case OFONO_DBUS_ACCESS_VOICECALL_DEFLECT:
|
||||
return "Deflect";
|
||||
case OFONO_DBUS_ACCESS_VOICECALL_HANGUP:
|
||||
return "Hangup";
|
||||
case OFONO_DBUS_ACCESS_VOICECALL_ANSWER:
|
||||
return "Answer";
|
||||
case OFONO_DBUS_ACCESS_VOICECALL_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_VOICECALLMGR:
|
||||
switch ((enum ofono_dbus_access_voicecallmgr_method)method) {
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL:
|
||||
return "Dial";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_TRANSFER:
|
||||
return "Transfer";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_SWAP_CALLS:
|
||||
return "SwapCalls";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_RELEASE_AND_ANSWER:
|
||||
return "ReleaseAndAnswer";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_RELEASE_AND_SWAP:
|
||||
return "ReleaseAndSwap";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_HOLD_AND_ANSWER:
|
||||
return "HoldAndAnswer";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_HANGUP_ALL:
|
||||
return "HangupAll";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_CREATE_MULTIPARTY:
|
||||
return "CreateMultiparty";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_HANGUP_MULTIPARTY:
|
||||
return "HangupMultiparty";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_SEND_TONES:
|
||||
return "SendTones";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_REGISTER_VOICECALL_AGENT:
|
||||
return "RegisterVoicecallAgent";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_UNREGISTER_VOICECALL_AGENT:
|
||||
return "UnregisterVoicecallAgent";
|
||||
case OFONO_DBUS_ACCESS_VOICECALLMGR_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_CONNCTX:
|
||||
switch ((enum ofono_dbus_access_connctx_method)method) {
|
||||
case OFONO_DBUS_ACCESS_CONNCTX_SET_PROPERTY:
|
||||
return "SetProperty";
|
||||
case OFONO_DBUS_ACCESS_CONNCTX_PROVISION_CONTEXT:
|
||||
return "ProvisionContext";
|
||||
case OFONO_DBUS_ACCESS_CONNCTX_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_CONNMGR:
|
||||
switch ((enum ofono_dbus_access_connmgr_method)method) {
|
||||
case OFONO_DBUS_ACCESS_CONNMGR_SET_PROPERTY:
|
||||
return "SetProperty";
|
||||
case OFONO_DBUS_ACCESS_CONNMGR_DEACTIVATE_ALL:
|
||||
return "DeactivateAll";
|
||||
case OFONO_DBUS_ACCESS_CONNMGR_RESET_CONTEXTS:
|
||||
return "ResetContexts";
|
||||
case OFONO_DBUS_ACCESS_CONNMGR_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_SIMMGR:
|
||||
switch ((enum ofono_dbus_access_simmgr_method)method) {
|
||||
case OFONO_DBUS_ACCESS_SIMMGR_SET_PROPERTY:
|
||||
return "SetProperty";
|
||||
case OFONO_DBUS_ACCESS_SIMMGR_CHANGE_PIN:
|
||||
return "ChangePin";
|
||||
case OFONO_DBUS_ACCESS_SIMMGR_ENTER_PIN:
|
||||
return "EnterPin";
|
||||
case OFONO_DBUS_ACCESS_SIMMGR_RESET_PIN:
|
||||
return "ResetPin";
|
||||
case OFONO_DBUS_ACCESS_SIMMGR_LOCK_PIN:
|
||||
return "LockPin";
|
||||
case OFONO_DBUS_ACCESS_SIMMGR_UNLOCK_PIN:
|
||||
return "UnlockPin";
|
||||
case OFONO_DBUS_ACCESS_SIMMGR_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_MODEM:
|
||||
switch ((enum ofono_dbus_access_modem_method)method) {
|
||||
case OFONO_DBUS_ACCESS_MODEM_SET_PROPERTY:
|
||||
return "SetProperty";
|
||||
case OFONO_DBUS_ACCESS_MODEM_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS:
|
||||
switch ((enum ofono_dbus_access_radiosettings_method)method) {
|
||||
case OFONO_DBUS_ACCESS_RADIOSETTINGS_SET_PROPERTY:
|
||||
return "SetProperty";
|
||||
case OFONO_DBUS_ACCESS_RADIOSETTINGS_METHOD_COUNT:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OFONO_DBUS_ACCESS_INTF_COUNT:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean __ofono_dbus_access_method_allowed(const char *sender,
|
||||
enum ofono_dbus_access_intf intf,
|
||||
int method, const char *arg)
|
||||
{
|
||||
GSList *l = dbus_access_plugins;
|
||||
|
||||
while (l) {
|
||||
GSList *next = l->next;
|
||||
const struct ofono_dbus_access_plugin *plugin = l->data;
|
||||
|
||||
switch (plugin->method_access(sender, intf, method, arg)) {
|
||||
case OFONO_DBUS_ACCESS_DENY:
|
||||
return FALSE;
|
||||
case OFONO_DBUS_ACCESS_ALLOW:
|
||||
return TRUE;
|
||||
case OFONO_DBUS_ACCESS_DONT_CARE:
|
||||
break;
|
||||
}
|
||||
|
||||
l = next;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0 if both are equal;
|
||||
* <0 if a comes before b;
|
||||
* >0 if a comes after b.
|
||||
*/
|
||||
static gint ofono_dbus_access_plugin_sort(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct ofono_dbus_access_plugin *a_plugin = a;
|
||||
const struct ofono_dbus_access_plugin *b_plugin = b;
|
||||
|
||||
if (a_plugin->priority > b_plugin->priority) {
|
||||
/* a comes before b */
|
||||
return -1;
|
||||
} else if (a_plugin->priority < b_plugin->priority) {
|
||||
/* a comes after b */
|
||||
return 1;
|
||||
} else {
|
||||
/* Whatever, as long as the sort is stable */
|
||||
return strcmp(a_plugin->name, b_plugin->name);
|
||||
}
|
||||
}
|
||||
|
||||
int ofono_dbus_access_plugin_register
|
||||
(const struct ofono_dbus_access_plugin *plugin)
|
||||
{
|
||||
if (!plugin || !plugin->name) {
|
||||
return -EINVAL;
|
||||
} else if (g_slist_find(dbus_access_plugins, plugin)) {
|
||||
return -EALREADY;
|
||||
} else {
|
||||
DBG("%s", plugin->name);
|
||||
dbus_access_plugins = g_slist_insert_sorted(dbus_access_plugins,
|
||||
(void*)plugin, ofono_dbus_access_plugin_sort);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_dbus_access_plugin_unregister
|
||||
(const struct ofono_dbus_access_plugin *plugin)
|
||||
{
|
||||
if (plugin) {
|
||||
DBG("%s", plugin->name);
|
||||
dbus_access_plugins = g_slist_remove(dbus_access_plugins,
|
||||
plugin);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -51,7 +51,9 @@ struct hfp_codec_info {
|
||||
};
|
||||
|
||||
struct ofono_emulator {
|
||||
struct ofono_atom *atom;
|
||||
GList *atoms;
|
||||
GList *registered_atoms;
|
||||
gboolean emulator_registered;
|
||||
enum ofono_emulator_type type;
|
||||
GAtServer *server;
|
||||
GAtPPP *ppp;
|
||||
@@ -355,10 +357,17 @@ static struct indicator *find_indicator(struct ofono_emulator *em,
|
||||
static struct ofono_call *find_call_with_status(struct ofono_emulator *em,
|
||||
int status)
|
||||
{
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(em->atom);
|
||||
struct ofono_voicecall *vc;
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_voicecall *vc = NULL;
|
||||
GList *i;
|
||||
|
||||
for (i = em->atoms; i; i = i->next) {
|
||||
modem = __ofono_atom_get_modem(i->data);
|
||||
if ((vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem);
|
||||
if (vc == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -1153,7 +1162,20 @@ static void emulator_unregister(struct ofono_atom *atom)
|
||||
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
||||
GSList *l;
|
||||
|
||||
DBG("%p", em);
|
||||
DBG("%p (atom %p)", em, atom);
|
||||
|
||||
em->registered_atoms = g_list_remove(em->registered_atoms, atom);
|
||||
if (em->registered_atoms)
|
||||
return;
|
||||
|
||||
if (!em->emulator_registered) {
|
||||
DBG("emulator already unregistered");
|
||||
return;
|
||||
}
|
||||
|
||||
em->emulator_registered = FALSE;
|
||||
|
||||
DBG("%p no more atoms registered", em);
|
||||
|
||||
if (em->callsetup_source) {
|
||||
g_source_remove(em->callsetup_source);
|
||||
@@ -1185,12 +1207,27 @@ static void emulator_unregister(struct ofono_atom *atom)
|
||||
em->card = NULL;
|
||||
}
|
||||
|
||||
static void emulator_register_atom(struct ofono_emulator *em, struct ofono_atom *atom)
|
||||
{
|
||||
if (!g_list_find(em->registered_atoms, atom)) {
|
||||
em->registered_atoms = g_list_append(em->registered_atoms, atom);
|
||||
DBG("%p", atom);
|
||||
__ofono_atom_register(atom, emulator_unregister);
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
{
|
||||
GIOChannel *io;
|
||||
GList *i;
|
||||
|
||||
DBG("%p, %d", em, fd);
|
||||
|
||||
if (em->emulator_registered) {
|
||||
DBG("emulator already registered");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
@@ -1240,7 +1277,8 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
g_at_server_register(em->server, "+BCS", bcs_cb, em, NULL);
|
||||
}
|
||||
|
||||
__ofono_atom_register(em->atom, emulator_unregister);
|
||||
for (i = em->atoms; i; i = i->next)
|
||||
emulator_register_atom(em, i->data);
|
||||
|
||||
switch (em->type) {
|
||||
case OFONO_EMULATOR_TYPE_DUN:
|
||||
@@ -1254,31 +1292,41 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
em->emulator_registered = TRUE;
|
||||
}
|
||||
|
||||
static void emulator_free(struct ofono_emulator *em)
|
||||
{
|
||||
g_assert(!em->atoms);
|
||||
|
||||
DBG("free emulator %p", em);
|
||||
if (em->registered_atoms)
|
||||
g_list_free(em->registered_atoms);
|
||||
g_free(em);
|
||||
}
|
||||
|
||||
static void emulator_remove(struct ofono_atom *atom)
|
||||
{
|
||||
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG("atom: %p", atom);
|
||||
DBG("remove atom %p", atom);
|
||||
em->atoms = g_list_remove(em->atoms, atom);
|
||||
|
||||
g_free(em);
|
||||
if (!em->atoms)
|
||||
emulator_free(em);
|
||||
}
|
||||
|
||||
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
||||
enum ofono_emulator_type type)
|
||||
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type)
|
||||
{
|
||||
struct ofono_emulator *em;
|
||||
enum ofono_atom_type atom_t;
|
||||
|
||||
DBG("modem: %p, type: %d", modem, type);
|
||||
|
||||
if (type == OFONO_EMULATOR_TYPE_DUN)
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_DUN;
|
||||
else if (type == OFONO_EMULATOR_TYPE_HFP)
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_HFP;
|
||||
else
|
||||
if (type != OFONO_EMULATOR_TYPE_DUN && type != OFONO_EMULATOR_TYPE_HFP) {
|
||||
DBG("unsupported emulator type %d", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBG("create emulator of type %d", type);
|
||||
|
||||
em = g_try_new0(struct ofono_emulator, 1);
|
||||
|
||||
@@ -1296,15 +1344,59 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
||||
em->events_mode = 3; /* default mode is forwarding events */
|
||||
em->cmee_mode = 0; /* CME ERROR disabled by default */
|
||||
|
||||
em->atom = __ofono_modem_add_atom_offline(modem, atom_t,
|
||||
emulator_remove, em);
|
||||
|
||||
return em;
|
||||
}
|
||||
|
||||
void ofono_emulator_add_modem(struct ofono_emulator *em,
|
||||
struct ofono_modem *modem)
|
||||
{
|
||||
struct ofono_atom *atom;
|
||||
enum ofono_atom_type atom_t;
|
||||
|
||||
if (em->type == OFONO_EMULATOR_TYPE_DUN)
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_DUN;
|
||||
else
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_HFP;
|
||||
|
||||
if ((atom = __ofono_modem_find_atom(modem, atom_t))) {
|
||||
if (g_list_find(em->atoms, atom)) {
|
||||
DBG("modem %p already added", modem);
|
||||
goto register_atom;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
atom = __ofono_modem_add_atom_offline(modem, atom_t,
|
||||
emulator_remove, em);
|
||||
em->atoms = g_list_append(em->atoms, atom);
|
||||
|
||||
register_atom:
|
||||
if (em->emulator_registered)
|
||||
emulator_register_atom(em, atom);
|
||||
}
|
||||
|
||||
void ofono_emulator_remove(struct ofono_emulator *em)
|
||||
{
|
||||
__ofono_atom_free(em->atom);
|
||||
GList *remove_list;
|
||||
GList *i;
|
||||
|
||||
DBG("");
|
||||
|
||||
/* If emulator has atoms we make a copy of the atom list here,
|
||||
* as the list is modified when the atoms are being destroyed.
|
||||
* When last atom is gone struct ofono_emulator is freed as
|
||||
* well (in emulator_remove()). */
|
||||
if (em->atoms) {
|
||||
remove_list = g_list_copy(em->atoms);
|
||||
for (i = remove_list; i; i = i->next) {
|
||||
DBG("free atom %p", i->data);
|
||||
__ofono_atom_free(i->data);
|
||||
}
|
||||
g_list_free(remove_list);
|
||||
} else {
|
||||
emulator_free(em);
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_emulator_send_final(struct ofono_emulator *em,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 Jolla Ltd.
|
||||
* Copyright (C) 2018-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
|
||||
@@ -114,7 +114,7 @@ static void gprs_filter_request_free(struct gprs_filter_request *req)
|
||||
req->fn->free(req);
|
||||
}
|
||||
|
||||
#define gprs_filter_request_ref(req) ((req)->refcount++, req)
|
||||
#define gprs_filter_request_ref(req) ((void)((req)->refcount++))
|
||||
|
||||
static int gprs_filter_request_unref(struct gprs_filter_request *req)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -46,6 +47,7 @@
|
||||
#include "idmap.h"
|
||||
#include "simutil.h"
|
||||
#include "util.h"
|
||||
#include "watch_p.h"
|
||||
|
||||
#define GPRS_FLAG_ATTACHING 0x1
|
||||
#define GPRS_FLAG_RECHECK 0x2
|
||||
@@ -453,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";
|
||||
@@ -915,6 +914,13 @@ static void pri_str_signal_change(struct pri_context *ctx,
|
||||
name, DBUS_TYPE_STRING, &value);
|
||||
}
|
||||
|
||||
static void pri_settings_changed(struct pri_context *ctx)
|
||||
{
|
||||
const char *path = __ofono_atom_get_path(ctx->gprs->atom);
|
||||
|
||||
__ofono_watch_gprs_settings_changed(path, ctx->type, &ctx->context);
|
||||
}
|
||||
|
||||
static void pri_reset_context_properties(struct pri_context *ctx,
|
||||
const struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
@@ -981,6 +987,10 @@ static void pri_reset_context_properties(struct pri_context *ctx,
|
||||
write_context_settings(gprs, ctx);
|
||||
storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
pri_settings_changed(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ap_valid(const struct ofono_gprs_provision_data *ap)
|
||||
@@ -1034,6 +1044,13 @@ static gboolean pri_deactivation_required(struct pri_context *ctx,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean connctx_allow(DBusMessage *msg,
|
||||
enum ofono_dbus_access_connctx_method method, const char *arg)
|
||||
{
|
||||
return __ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_CONNCTX, method, arg);
|
||||
}
|
||||
|
||||
static DBusMessage *pri_provision_context(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
@@ -1046,6 +1063,10 @@ static DBusMessage *pri_provision_context(DBusConnection *conn,
|
||||
DBusMessage *reply = NULL;
|
||||
int i, count = 0;
|
||||
|
||||
if (!connctx_allow(msg, OFONO_DBUS_ACCESS_CONNCTX_PROVISION_CONTEXT,
|
||||
NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (sim == NULL)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
@@ -1162,8 +1183,6 @@ static void pri_activate_callback(const struct ofono_error *error, void *data)
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
dbus_bool_t value;
|
||||
|
||||
DBG("%p", ctx);
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
DBG("Activating context failed with error: %s",
|
||||
telephony_error_to_str(error));
|
||||
@@ -1174,6 +1193,8 @@ static void pri_activate_callback(const struct ofono_error *error, void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("%p", ctx);
|
||||
|
||||
ctx->active = TRUE;
|
||||
__ofono_dbus_pending_reply(&ctx->pending,
|
||||
dbus_message_new_method_return(ctx->pending));
|
||||
@@ -1209,6 +1230,8 @@ static void pri_deactivate_callback(const struct ofono_error *error, void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("%p", ctx);
|
||||
|
||||
__ofono_dbus_pending_reply(&ctx->pending,
|
||||
dbus_message_new_method_return(ctx->pending));
|
||||
|
||||
@@ -1321,6 +1344,7 @@ static DBusMessage *pri_set_apn(struct pri_context *ctx, DBusConnection *conn,
|
||||
"AccessPointName",
|
||||
DBUS_TYPE_STRING, &apn);
|
||||
|
||||
pri_settings_changed(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1351,6 +1375,7 @@ static DBusMessage *pri_set_username(struct pri_context *ctx,
|
||||
"Username",
|
||||
DBUS_TYPE_STRING, &username);
|
||||
|
||||
pri_settings_changed(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1381,6 +1406,7 @@ static DBusMessage *pri_set_password(struct pri_context *ctx,
|
||||
"Password",
|
||||
DBUS_TYPE_STRING, &password);
|
||||
|
||||
pri_settings_changed(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1409,6 +1435,7 @@ static DBusMessage *pri_set_type(struct pri_context *ctx, DBusConnection *conn,
|
||||
OFONO_CONNECTION_CONTEXT_INTERFACE,
|
||||
"Type", DBUS_TYPE_STRING, &type);
|
||||
|
||||
pri_settings_changed(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1438,6 +1465,7 @@ static DBusMessage *pri_set_proto(struct pri_context *ctx,
|
||||
OFONO_CONNECTION_CONTEXT_INTERFACE,
|
||||
"Protocol", DBUS_TYPE_STRING, &str);
|
||||
|
||||
pri_settings_changed(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1554,6 +1582,7 @@ static DBusMessage *pri_set_auth_method(struct pri_context *ctx,
|
||||
"AuthenticationMethod",
|
||||
DBUS_TYPE_STRING, &str);
|
||||
|
||||
pri_settings_changed(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1624,6 +1653,10 @@ static DBusMessage *pri_set_property(DBusConnection *conn,
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
if (!connctx_allow(msg, OFONO_DBUS_ACCESS_CONNCTX_SET_PROPERTY,
|
||||
property))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
dbus_message_iter_recurse(&iter, &var);
|
||||
|
||||
if (g_str_equal(property, "Active")) {
|
||||
@@ -2154,6 +2187,13 @@ static DBusMessage *gprs_get_properties(DBusConnection *conn,
|
||||
return reply;
|
||||
}
|
||||
|
||||
static gboolean gprs_allow(DBusMessage *msg,
|
||||
enum ofono_dbus_access_connmgr_method method, const char *arg)
|
||||
{
|
||||
return __ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_CONNMGR, method, arg);
|
||||
}
|
||||
|
||||
static DBusMessage *gprs_set_property(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
@@ -2179,6 +2219,9 @@ static DBusMessage *gprs_set_property(DBusConnection *conn,
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
if (!gprs_allow(msg, OFONO_DBUS_ACCESS_CONNMGR_SET_PROPERTY, property))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
dbus_message_iter_recurse(&iter, &var);
|
||||
|
||||
if (!strcmp(property, "RoamingAllowed")) {
|
||||
@@ -2399,6 +2442,7 @@ void ofono_gprs_cid_activated(struct ofono_gprs *gprs, unsigned int cid,
|
||||
OFONO_CONNECTION_CONTEXT_INTERFACE,
|
||||
"AccessPointName",
|
||||
DBUS_TYPE_STRING, &apn);
|
||||
pri_settings_changed(pri_ctx);
|
||||
}
|
||||
|
||||
/* Prevent ofono_gprs_status_notify from changing the 'attached'
|
||||
@@ -2645,6 +2689,9 @@ static DBusMessage *gprs_deactivate_all(DBusConnection *conn,
|
||||
GSList *l;
|
||||
struct pri_context *ctx;
|
||||
|
||||
if (!gprs_allow(msg, OFONO_DBUS_ACCESS_CONNMGR_DEACTIVATE_ALL, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (gprs->pending)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -2849,6 +2896,9 @@ static DBusMessage *gprs_reset_contexts(DBusConnection *conn,
|
||||
DBusMessage *reply;
|
||||
GSList *l;
|
||||
|
||||
if (!gprs_allow(msg, OFONO_DBUS_ACCESS_CONNMGR_RESET_CONTEXTS, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (gprs->pending)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -3869,7 +3919,7 @@ gboolean __ofono_gprs_get_roaming_allowed(struct ofono_gprs *gprs)
|
||||
return gprs->roaming_allowed;
|
||||
}
|
||||
|
||||
const struct ofono_gprs_primary_context *__ofono_gprs_context_settings_by_type
|
||||
const struct ofono_gprs_primary_context *ofono_gprs_context_settings_by_type
|
||||
(struct ofono_gprs *gprs, enum ofono_gprs_context_type type)
|
||||
{
|
||||
GSList *l;
|
||||
@@ -3886,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;
|
||||
}
|
||||
|
||||
@@ -912,6 +912,7 @@ void ofono_handsfree_audio_unref(void)
|
||||
if (agent) {
|
||||
agent_release(agent);
|
||||
agent_free(agent);
|
||||
agent = NULL;
|
||||
}
|
||||
|
||||
__ofono_handsfree_audio_manager_cleanup();
|
||||
|
||||
@@ -83,6 +83,11 @@ static DBusMessage *message_cancel(DBusConnection *conn,
|
||||
struct message *m = data;
|
||||
int res;
|
||||
|
||||
if (!__ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGE,
|
||||
OFONO_DBUS_ACCESS_MESSAGE_CANCEL, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID) == FALSE)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
|
||||
@@ -1095,6 +1095,11 @@ static DBusMessage *modem_set_property(DBusConnection *conn,
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
if (!__ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_MODEM,
|
||||
OFONO_DBUS_ACCESS_MODEM_SET_PROPERTY, name))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (powering_down == TRUE)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
|
||||
@@ -1527,9 +1527,8 @@ static void init_registration_status(const struct ofono_error *error,
|
||||
}
|
||||
|
||||
if (netreg->mode != NETWORK_REGISTRATION_MODE_MANUAL &&
|
||||
(status == NETWORK_REGISTRATION_STATUS_NOT_REGISTERED ||
|
||||
status == NETWORK_REGISTRATION_STATUS_DENIED ||
|
||||
status == NETWORK_REGISTRATION_STATUS_UNKNOWN)) {
|
||||
status != NETWORK_REGISTRATION_STATUS_REGISTERED &&
|
||||
status != NETWORK_REGISTRATION_STATUS_ROAMING) {
|
||||
if (netreg->driver->register_auto != NULL)
|
||||
netreg->driver->register_auto(netreg, init_register,
|
||||
netreg);
|
||||
|
||||
@@ -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
|
||||
@@ -276,8 +277,8 @@ gboolean __ofono_gprs_get_roaming_allowed(struct ofono_gprs *gprs);
|
||||
|
||||
#include <ofono/gprs-context.h>
|
||||
|
||||
const struct ofono_gprs_primary_context *__ofono_gprs_context_settings_by_type
|
||||
(struct ofono_gprs *gprs, enum ofono_gprs_context_type type);
|
||||
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>
|
||||
@@ -635,6 +636,12 @@ void __ofono_voicecall_filter_chain_incoming(struct voicecall_filter_chain *c,
|
||||
ofono_voicecall_filter_incoming_cb_t cb,
|
||||
ofono_destroy_func destroy, void *user_data);
|
||||
|
||||
#include <ofono/dbus-access.h>
|
||||
|
||||
gboolean __ofono_dbus_access_method_allowed(const char *sender,
|
||||
enum ofono_dbus_access_intf iface,
|
||||
int method, const char *arg);
|
||||
|
||||
#include <ofono/sim-mnclength.h>
|
||||
|
||||
int __ofono_sim_mnclength_get_mnclength(const char *imsi);
|
||||
|
||||
@@ -552,6 +552,11 @@ static DBusMessage *radio_set_property_handler(DBusMessage *msg, void *data)
|
||||
dbus_message_iter_get_basic(&iter, &property);
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
if (!__ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS,
|
||||
OFONO_DBUS_ACCESS_RADIOSETTINGS_SET_PROPERTY, property))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
|
||||
@@ -646,6 +646,13 @@ static gboolean set_own_numbers(struct ofono_sim *sim,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean sim_allow(DBusMessage *msg,
|
||||
enum ofono_dbus_access_simmgr_method method, const char *arg)
|
||||
{
|
||||
return __ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_SIMMGR, method, arg);
|
||||
}
|
||||
|
||||
static DBusMessage *sim_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||
void *data)
|
||||
{
|
||||
@@ -663,6 +670,9 @@ static DBusMessage *sim_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &name);
|
||||
|
||||
if (!sim_allow(msg, OFONO_DBUS_ACCESS_SIMMGR_SET_PROPERTY, name))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (!strcmp(name, "SubscriberNumbers")) {
|
||||
gboolean set_ok = FALSE;
|
||||
struct ofono_phone_number *own;
|
||||
@@ -826,6 +836,9 @@ static DBusMessage *sim_lock_pin(DBusConnection *conn, DBusMessage *msg,
|
||||
{
|
||||
struct ofono_sim *sim = data;
|
||||
|
||||
if (!sim_allow(msg, OFONO_DBUS_ACCESS_SIMMGR_LOCK_PIN, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
return sim_lock_or_unlock(sim, 1, conn, msg);
|
||||
}
|
||||
|
||||
@@ -834,6 +847,9 @@ static DBusMessage *sim_unlock_pin(DBusConnection *conn, DBusMessage *msg,
|
||||
{
|
||||
struct ofono_sim *sim = data;
|
||||
|
||||
if (!sim_allow(msg, OFONO_DBUS_ACCESS_SIMMGR_UNLOCK_PIN, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
return sim_lock_or_unlock(sim, 0, conn, msg);
|
||||
}
|
||||
|
||||
@@ -865,6 +881,9 @@ static DBusMessage *sim_change_pin(DBusConnection *conn, DBusMessage *msg,
|
||||
const char *old;
|
||||
const char *new;
|
||||
|
||||
if (!sim_allow(msg, OFONO_DBUS_ACCESS_SIMMGR_CHANGE_PIN, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (sim->driver->change_passwd == NULL)
|
||||
return __ofono_error_not_implemented(msg);
|
||||
|
||||
@@ -921,6 +940,9 @@ static DBusMessage *sim_enter_pin(DBusConnection *conn, DBusMessage *msg,
|
||||
enum ofono_sim_password_type type;
|
||||
const char *pin;
|
||||
|
||||
if (!sim_allow(msg, OFONO_DBUS_ACCESS_SIMMGR_ENTER_PIN, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (sim->driver->send_passwd == NULL)
|
||||
return __ofono_error_not_implemented(msg);
|
||||
|
||||
@@ -1156,6 +1178,9 @@ static DBusMessage *sim_reset_pin(DBusConnection *conn, DBusMessage *msg,
|
||||
const char *puk;
|
||||
const char *pin;
|
||||
|
||||
if (!sim_allow(msg, OFONO_DBUS_ACCESS_SIMMGR_RESET_PIN, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (sim->driver->reset_passwd == NULL)
|
||||
return __ofono_error_not_implemented(msg);
|
||||
|
||||
|
||||
@@ -1033,6 +1033,11 @@ static DBusMessage *sms_send_message(DBusConnection *conn, DBusMessage *msg,
|
||||
struct sms_message_data *message;
|
||||
struct sms_address addr;
|
||||
|
||||
if (!__ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGEMGR,
|
||||
OFONO_DBUS_ACCESS_MESSAGEMGR_SEND_MESSAGE, NULL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &to,
|
||||
DBUS_TYPE_STRING, &text,
|
||||
DBUS_TYPE_INVALID))
|
||||
@@ -2145,7 +2150,7 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list,
|
||||
g_queue_push_tail(sms->txq, entry);
|
||||
|
||||
if (sms->registered && g_queue_get_length(sms->txq) == 1)
|
||||
sms->tx_source = g_timeout_add(0, tx_next, sms);
|
||||
sms->tx_source = g_timeout_add(100, tx_next, sms);
|
||||
|
||||
if (uuid)
|
||||
memcpy(uuid, &entry->uuid, sizeof(*uuid));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 Jolla Ltd.
|
||||
* Copyright (C) 2018-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
|
||||
@@ -118,7 +118,7 @@ static void voicecall_filter_request_free(struct voicecall_filter_request *req)
|
||||
req->fn->free(req);
|
||||
}
|
||||
|
||||
#define voicecall_filter_request_ref(req) ((req)->refcount++, req)
|
||||
#define voicecall_filter_request_ref(req) ((void)((req)->refcount++))
|
||||
|
||||
static int voicecall_filter_request_unref(struct voicecall_filter_request *req)
|
||||
{
|
||||
|
||||
@@ -354,6 +354,7 @@ static int tone_queue(struct ofono_voicecall *vc, const char *tone_str,
|
||||
for (i = 0; tone_str[i]; i++)
|
||||
if (!g_ascii_isdigit(tone_str[i]) && tone_str[i] != 'p' &&
|
||||
tone_str[i] != 'P' && tone_str[i] != '*' &&
|
||||
tone_str[i] != '.' && tone_str[i] != ',' &&
|
||||
tone_str[i] != '#' && (tone_str[i] < 'A' ||
|
||||
tone_str[i] > 'D'))
|
||||
return -EINVAL;
|
||||
@@ -505,6 +506,13 @@ static DBusMessage *voicecall_get_properties(DBusConnection *conn,
|
||||
return reply;
|
||||
}
|
||||
|
||||
static gboolean voicecall_allow(DBusMessage *msg,
|
||||
enum ofono_dbus_access_voicecall_method method)
|
||||
{
|
||||
return __ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALL, method, NULL);
|
||||
}
|
||||
|
||||
static DBusMessage *voicecall_deflect(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
@@ -515,6 +523,9 @@ static DBusMessage *voicecall_deflect(DBusConnection *conn,
|
||||
struct ofono_phone_number ph;
|
||||
const char *number;
|
||||
|
||||
if (!voicecall_allow(msg, OFONO_DBUS_ACCESS_VOICECALL_DEFLECT))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (call->status != CALL_STATUS_INCOMING &&
|
||||
call->status != CALL_STATUS_WAITING)
|
||||
return __ofono_error_failed(msg);
|
||||
@@ -550,6 +561,9 @@ static DBusMessage *voicecall_hangup(DBusConnection *conn,
|
||||
gboolean single_call = vc->call_list->next == 0;
|
||||
struct tone_queue_entry *tone_entry = NULL;
|
||||
|
||||
if (!voicecall_allow(msg, OFONO_DBUS_ACCESS_VOICECALL_HANGUP))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
/* clear any remaining tones */
|
||||
while ((tone_entry = g_queue_peek_head(vc->toneq)))
|
||||
tone_request_finish(vc, tone_entry, ENOENT, TRUE);
|
||||
@@ -650,6 +664,9 @@ static DBusMessage *voicecall_answer(DBusConnection *conn,
|
||||
struct ofono_voicecall *vc = v->vc;
|
||||
struct ofono_call *call = v->call;
|
||||
|
||||
if (!voicecall_allow(msg, OFONO_DBUS_ACCESS_VOICECALL_ANSWER))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (call->status != CALL_STATUS_INCOMING)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
@@ -1726,6 +1743,13 @@ static int voicecall_dial(struct ofono_voicecall *vc, const char *number,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean manager_allow(DBusMessage *msg,
|
||||
enum ofono_dbus_access_voicecallmgr_method method)
|
||||
{
|
||||
return __ofono_dbus_access_method_allowed(dbus_message_get_sender(msg),
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR, method, NULL);
|
||||
}
|
||||
|
||||
static DBusMessage *manager_dial(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
@@ -1735,6 +1759,9 @@ static DBusMessage *manager_dial(DBusConnection *conn,
|
||||
enum ofono_clir_option clir;
|
||||
int err;
|
||||
|
||||
if (!manager_allow(msg, OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->dial_req || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -1777,6 +1804,9 @@ static DBusMessage *manager_transfer(DBusConnection *conn,
|
||||
int numactive;
|
||||
int numheld;
|
||||
|
||||
if (!manager_allow(msg, OFONO_DBUS_ACCESS_VOICECALLMGR_TRANSFER))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->dial_req || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -1832,6 +1862,9 @@ static DBusMessage *manager_swap_calls(DBusConnection *conn,
|
||||
struct ofono_voicecall *vc = data;
|
||||
ofono_voicecall_cb_t cb;
|
||||
|
||||
if (!manager_allow(msg, OFONO_DBUS_ACCESS_VOICECALLMGR_SWAP_CALLS))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->driver->swap_without_accept)
|
||||
return manager_swap_without_accept(conn, msg, data);
|
||||
|
||||
@@ -1861,6 +1894,10 @@ static DBusMessage *manager_release_and_answer(DBusConnection *conn,
|
||||
{
|
||||
struct ofono_voicecall *vc = data;
|
||||
|
||||
if (!manager_allow(msg,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_RELEASE_AND_ANSWER))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->dial_req || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -1882,6 +1919,10 @@ static DBusMessage *manager_release_and_swap(DBusConnection *conn,
|
||||
{
|
||||
struct ofono_voicecall *vc = data;
|
||||
|
||||
if (!manager_allow(msg,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_RELEASE_AND_SWAP))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->dial_req || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -1903,6 +1944,10 @@ static DBusMessage *manager_hold_and_answer(DBusConnection *conn,
|
||||
{
|
||||
struct ofono_voicecall *vc = data;
|
||||
|
||||
if (!manager_allow(msg,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_HOLD_AND_ANSWER))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->dial_req || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -1931,6 +1976,9 @@ static DBusMessage *manager_hangup_all(DBusConnection *conn,
|
||||
{
|
||||
struct ofono_voicecall *vc = data;
|
||||
|
||||
if (!manager_allow(msg, OFONO_DBUS_ACCESS_VOICECALLMGR_HANGUP_ALL))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -2141,6 +2189,10 @@ static DBusMessage *multiparty_create(DBusConnection *conn,
|
||||
{
|
||||
struct ofono_voicecall *vc = data;
|
||||
|
||||
if (!manager_allow(msg,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_CREATE_MULTIPARTY))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->dial_req || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -2162,6 +2214,10 @@ static DBusMessage *multiparty_hangup(DBusConnection *conn,
|
||||
{
|
||||
struct ofono_voicecall *vc = data;
|
||||
|
||||
if (!manager_allow(msg,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_HANGUP_MULTIPARTY))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending || vc->dial_req || vc->pending_em)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -2233,6 +2289,9 @@ static DBusMessage *manager_tone(DBusConnection *conn,
|
||||
char *tones;
|
||||
int err, len;
|
||||
|
||||
if (!manager_allow(msg, OFONO_DBUS_ACCESS_VOICECALLMGR_SEND_TONES))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->pending)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -2330,6 +2389,10 @@ static DBusMessage *voicecall_register_agent(DBusConnection *conn,
|
||||
struct ofono_voicecall *vc = data;
|
||||
const char *agent_path;
|
||||
|
||||
if (!manager_allow(msg,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_REGISTER_VOICECALL_AGENT))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (vc->vc_agent)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
@@ -2359,6 +2422,10 @@ static DBusMessage *voicecall_unregister_agent(DBusConnection *conn,
|
||||
const char *agent_path;
|
||||
const char *agent_bus = dbus_message_get_sender(msg);
|
||||
|
||||
if (!manager_allow(msg,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_UNREGISTER_VOICECALL_AGENT))
|
||||
return __ofono_error_access_denied(msg);
|
||||
|
||||
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &agent_path,
|
||||
DBUS_TYPE_INVALID) == FALSE)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
@@ -4180,7 +4247,7 @@ static void tone_request_cb(const struct ofono_error *error, void *data)
|
||||
goto done;
|
||||
}
|
||||
|
||||
len = strspn(entry->left, "pP");
|
||||
len = strspn(entry->left, "pP.,");
|
||||
entry->left += len;
|
||||
|
||||
done:
|
||||
@@ -4214,7 +4281,7 @@ static gboolean tone_request_run(gpointer user_data)
|
||||
if (entry == NULL)
|
||||
return FALSE;
|
||||
|
||||
len = strcspn(entry->left, "pP");
|
||||
len = strcspn(entry->left, "pP.,");
|
||||
|
||||
if (len) {
|
||||
if (len > 8) /* Arbitrary length limit per request */
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* 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
|
||||
@@ -10,98 +9,856 @@
|
||||
*
|
||||
* 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include "watch_p.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include "ofono.h"
|
||||
|
||||
struct ofono_watchlist *__ofono_watchlist_new(ofono_destroy_func destroy)
|
||||
#include <glib-object.h>
|
||||
|
||||
typedef GObjectClass OfonoWatchObjectClass;
|
||||
typedef struct ofono_watch_object OfonoWatchObject;
|
||||
|
||||
struct ofono_watch_object {
|
||||
GObject object;
|
||||
struct ofono_watch pub;
|
||||
char *path;
|
||||
char *iccid;
|
||||
char *imsi;
|
||||
char *spn;
|
||||
char *reg_mcc;
|
||||
char *reg_mnc;
|
||||
char *reg_name;
|
||||
int queued_signals;
|
||||
guint modem_watch_id;
|
||||
guint online_watch_id;
|
||||
guint sim_watch_id;
|
||||
guint sim_state_watch_id;
|
||||
guint iccid_watch_id;
|
||||
guint imsi_watch_id;
|
||||
guint spn_watch_id;
|
||||
guint netreg_watch_id;
|
||||
guint gprs_watch_id;
|
||||
};
|
||||
|
||||
struct ofono_watch_closure {
|
||||
GCClosure cclosure;
|
||||
union ofono_watch_closure_cb {
|
||||
GCallback ptr;
|
||||
ofono_watch_cb_t generic;
|
||||
ofono_watch_gprs_settings_cb_t gprs_settings;
|
||||
} cb;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
enum ofono_watch_signal {
|
||||
SIGNAL_MODEM_CHANGED,
|
||||
SIGNAL_ONLINE_CHANGED,
|
||||
SIGNAL_SIM_CHANGED,
|
||||
SIGNAL_SIM_STATE_CHANGED,
|
||||
SIGNAL_ICCID_CHANGED,
|
||||
SIGNAL_IMSI_CHANGED,
|
||||
SIGNAL_SPN_CHANGED,
|
||||
SIGNAL_NETREG_CHANGED,
|
||||
SIGNAL_REG_STATUS_CHANGED,
|
||||
SIGNAL_REG_MCC_CHANGED,
|
||||
SIGNAL_REG_MNC_CHANGED,
|
||||
SIGNAL_REG_NAME_CHANGED,
|
||||
SIGNAL_GPRS_CHANGED,
|
||||
SIGNAL_GPRS_SETTINGS_CHANGED,
|
||||
SIGNAL_COUNT
|
||||
};
|
||||
|
||||
#define SIGNAL_MODEM_CHANGED_NAME "ofono-watch-modem-changed"
|
||||
#define SIGNAL_ONLINE_CHANGED_NAME "ofono-watch-online-changed"
|
||||
#define SIGNAL_SIM_CHANGED_NAME "ofono-watch-sim-changed"
|
||||
#define SIGNAL_SIM_STATE_CHANGED_NAME "ofono-watch-sim-state-changed"
|
||||
#define SIGNAL_ICCID_CHANGED_NAME "ofono-watch-iccid-changed"
|
||||
#define SIGNAL_IMSI_CHANGED_NAME "ofono-watch-imsi-changed"
|
||||
#define SIGNAL_SPN_CHANGED_NAME "ofono-watch-spn-changed"
|
||||
#define SIGNAL_NETREG_CHANGED_NAME "ofono-watch-netreg-changed"
|
||||
#define SIGNAL_REG_STATUS_CHANGED_NAME "ofono-watch-reg-status-changed"
|
||||
#define SIGNAL_REG_MCC_CHANGED_NAME "ofono-watch-reg-mcc-changed"
|
||||
#define SIGNAL_REG_MNC_CHANGED_NAME "ofono-watch-reg-mnc-changed"
|
||||
#define SIGNAL_REG_NAME_CHANGED_NAME "ofono-watch-reg-name-changed"
|
||||
#define SIGNAL_GPRS_CHANGED_NAME "ofono-watch-gprs-changed"
|
||||
#define SIGNAL_GPRS_SETTINGS_CHANGED_NAME "ofono-watch-gprs-settings-changed"
|
||||
|
||||
static guint ofono_watch_signals[SIGNAL_COUNT] = { 0 };
|
||||
static GHashTable *ofono_watch_table = NULL;
|
||||
|
||||
G_DEFINE_TYPE(OfonoWatchObject, ofono_watch_object, G_TYPE_OBJECT)
|
||||
#define OFONO_WATCH_OBJECT_TYPE (ofono_watch_object_get_type())
|
||||
#define OFONO_WATCH_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||
OFONO_WATCH_OBJECT_TYPE, OfonoWatchObject))
|
||||
|
||||
#define NEW_SIGNAL(klass,name) \
|
||||
ofono_watch_signals[SIGNAL_##name##_CHANGED] = \
|
||||
g_signal_new(SIGNAL_##name##_CHANGED_NAME, \
|
||||
G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, \
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 0)
|
||||
|
||||
/* Skip the leading slash from the modem path: */
|
||||
#define DBG_(obj,fmt,args...) DBG("%s " fmt, (obj)->path+1, ##args)
|
||||
#define ASSERT(expr) ((void)0)
|
||||
|
||||
static inline struct ofono_watch_object *ofono_watch_object_cast
|
||||
(struct ofono_watch *watch)
|
||||
{
|
||||
struct ofono_watchlist *watchlist;
|
||||
|
||||
watchlist = g_new0(struct ofono_watchlist, 1);
|
||||
watchlist->destroy = destroy;
|
||||
|
||||
return watchlist;
|
||||
return watch ? OFONO_WATCH_OBJECT(G_STRUCT_MEMBER_P(watch,
|
||||
- G_STRUCT_OFFSET(struct ofono_watch_object, pub))) : NULL;
|
||||
}
|
||||
|
||||
unsigned int __ofono_watchlist_add_item(struct ofono_watchlist *watchlist,
|
||||
struct ofono_watchlist_item *item)
|
||||
static inline int ofono_watch_signal_bit(enum ofono_watch_signal id)
|
||||
{
|
||||
item->id = ++watchlist->next_id;
|
||||
|
||||
if (item->id == 0)
|
||||
item->id = ++watchlist->next_id;
|
||||
|
||||
watchlist->items = g_slist_prepend(watchlist->items, item);
|
||||
|
||||
return item->id;
|
||||
return (1 << id);
|
||||
}
|
||||
|
||||
gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist,
|
||||
unsigned int id)
|
||||
static inline void ofono_watch_signal_emit(struct ofono_watch_object *self,
|
||||
enum ofono_watch_signal id)
|
||||
{
|
||||
struct ofono_watchlist_item *item;
|
||||
GSList *p;
|
||||
GSList *c;
|
||||
self->queued_signals &= ~ofono_watch_signal_bit(id);
|
||||
g_signal_emit(self, ofono_watch_signals[id], 0);
|
||||
}
|
||||
|
||||
p = NULL;
|
||||
c = watchlist->items;
|
||||
static inline void ofono_watch_signal_queue(struct ofono_watch_object *self,
|
||||
enum ofono_watch_signal id)
|
||||
{
|
||||
self->queued_signals |= ofono_watch_signal_bit(id);
|
||||
}
|
||||
|
||||
while (c) {
|
||||
item = c->data;
|
||||
static void ofono_watch_emit_queued_signals(struct ofono_watch_object *self)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (item->id != id) {
|
||||
p = c;
|
||||
c = c->next;
|
||||
continue;
|
||||
for (i = 0; self->queued_signals && i < SIGNAL_COUNT; i++) {
|
||||
if (self->queued_signals & ofono_watch_signal_bit(i)) {
|
||||
ofono_watch_signal_emit(self, i);
|
||||
}
|
||||
|
||||
if (p)
|
||||
p->next = c->next;
|
||||
else
|
||||
watchlist->items = c->next;
|
||||
|
||||
if (item->destroy)
|
||||
item->destroy(item->notify_data);
|
||||
|
||||
if (watchlist->destroy)
|
||||
watchlist->destroy(item);
|
||||
g_slist_free_1(c);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void __ofono_watchlist_free(struct ofono_watchlist *watchlist)
|
||||
static void ofono_watch_iccid_update(struct ofono_watch_object *self,
|
||||
const char *iccid)
|
||||
{
|
||||
struct ofono_watchlist_item *item;
|
||||
GSList *l;
|
||||
if (g_strcmp0(self->iccid, iccid)) {
|
||||
g_free(self->iccid);
|
||||
self->pub.iccid = self->iccid = g_strdup(iccid);
|
||||
ofono_watch_signal_queue(self, SIGNAL_ICCID_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
for (l = watchlist->items; l; l = l->next) {
|
||||
item = l->data;
|
||||
static void ofono_watch_iccid_notify(const char *iccid, void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
if (item->destroy)
|
||||
item->destroy(item->notify_data);
|
||||
ofono_watch_iccid_update(self, iccid);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
if (watchlist->destroy)
|
||||
watchlist->destroy(item);
|
||||
static void ofono_watch_iccid_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
ASSERT(self->iccid_watch_id);
|
||||
self->iccid_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_spn_update(struct ofono_watch_object *self,
|
||||
const char *spn)
|
||||
{
|
||||
if (g_strcmp0(self->spn, spn)) {
|
||||
g_free(self->spn);
|
||||
self->pub.spn = self->spn = g_strdup(spn);
|
||||
ofono_watch_signal_queue(self, SIGNAL_SPN_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_spn_notify(const char *spn, const char *dc,
|
||||
void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
ofono_watch_spn_update(self, spn);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void ofono_watch_spn_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
ASSERT(self->spn_watch_id);
|
||||
self->spn_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_imsi_update(struct ofono_watch_object *self,
|
||||
const char *imsi)
|
||||
{
|
||||
if (g_strcmp0(self->imsi, imsi)) {
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
g_free(self->imsi);
|
||||
watch->imsi = self->imsi = g_strdup(imsi);
|
||||
ofono_watch_signal_queue(self, SIGNAL_IMSI_CHANGED);
|
||||
/* ofono core crashes if we add spn watch too early */
|
||||
if (imsi) {
|
||||
ofono_sim_add_spn_watch(watch->sim,
|
||||
&self->spn_watch_id,
|
||||
ofono_watch_spn_notify, self,
|
||||
ofono_watch_spn_destroy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_imsi_notify(const char *imsi, void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
ofono_watch_imsi_update(self, imsi);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void ofono_watch_imsi_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
ASSERT(self->imsi_watch_id);
|
||||
self->imsi_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_sim_state_notify(enum ofono_sim_state new_state,
|
||||
void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
/*
|
||||
* ofono core doesn't notify SIM watches when SIM card gets removed.
|
||||
* So we have to reset things here based on the SIM state.
|
||||
*/
|
||||
if (new_state == OFONO_SIM_STATE_NOT_PRESENT) {
|
||||
ofono_watch_iccid_update(self, NULL);
|
||||
}
|
||||
if (new_state != OFONO_SIM_STATE_READY) {
|
||||
ofono_watch_imsi_update(self, NULL);
|
||||
ofono_watch_spn_update(self, NULL);
|
||||
}
|
||||
ofono_watch_signal_queue(self, SIGNAL_SIM_STATE_CHANGED);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void ofono_watch_sim_state_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
ASSERT(self->sim_state_watch_id);
|
||||
self->sim_state_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_set_sim(struct ofono_watch_object *self,
|
||||
struct ofono_sim *sim)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
if (watch->sim != sim) {
|
||||
if (self->sim_state_watch_id) {
|
||||
ofono_sim_remove_state_watch(watch->sim,
|
||||
self->sim_state_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
ASSERT(!self->sim_state_watch_id);
|
||||
}
|
||||
if (self->iccid_watch_id) {
|
||||
ofono_sim_remove_iccid_watch(watch->sim,
|
||||
self->iccid_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
ASSERT(!self->iccid_watch_id);
|
||||
}
|
||||
if (self->imsi_watch_id) {
|
||||
ofono_sim_remove_imsi_watch(watch->sim,
|
||||
self->imsi_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
ASSERT(!self->imsi_watch_id);
|
||||
}
|
||||
if (self->spn_watch_id) {
|
||||
ofono_sim_remove_spn_watch(watch->sim,
|
||||
&self->spn_watch_id);
|
||||
/* The destroy callback clears it */
|
||||
ASSERT(!self->spn_watch_id);
|
||||
}
|
||||
watch->sim = sim;
|
||||
ofono_watch_signal_queue(self, SIGNAL_SIM_CHANGED);
|
||||
|
||||
/* Reset the current state */
|
||||
ofono_watch_iccid_update(self, NULL);
|
||||
ofono_watch_imsi_update(self, NULL);
|
||||
ofono_watch_spn_update(self, NULL);
|
||||
if (sim) {
|
||||
self->sim_state_watch_id =
|
||||
ofono_sim_add_state_watch(sim,
|
||||
ofono_watch_sim_state_notify, self,
|
||||
ofono_watch_sim_state_destroy);
|
||||
/*
|
||||
* Unlike ofono_sim_add_state_watch, the rest
|
||||
* of ofono_sim_add_xxx_watch functions call the
|
||||
* notify callback if the value is already known
|
||||
* to the ofono core.
|
||||
*
|
||||
* Also note that ofono core crashes if we add
|
||||
* spn watch too early.
|
||||
*/
|
||||
self->iccid_watch_id =
|
||||
ofono_sim_add_iccid_watch(sim,
|
||||
ofono_watch_iccid_notify, self,
|
||||
ofono_watch_iccid_destroy);
|
||||
self->imsi_watch_id =
|
||||
ofono_sim_add_imsi_watch(sim,
|
||||
ofono_watch_imsi_notify, self,
|
||||
ofono_watch_imsi_destroy);
|
||||
}
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_sim_notify(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
struct ofono_sim *sim = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG_(self, "sim registered");
|
||||
ofono_watch_set_sim(self, sim);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG_(self, "sim unregistered");
|
||||
ofono_watch_set_sim(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_sim_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
self->sim_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_netreg_update(struct ofono_watch_object *self)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
struct ofono_netreg *netreg = watch->netreg;
|
||||
enum ofono_netreg_status status = ofono_netreg_get_status(netreg);
|
||||
const char *mcc = ofono_netreg_get_mcc(netreg);
|
||||
const char *mnc = ofono_netreg_get_mnc(netreg);
|
||||
const char *name = ofono_netreg_get_name(netreg);
|
||||
|
||||
if (watch->reg_status != status) {
|
||||
watch->reg_status = status;
|
||||
ofono_watch_signal_queue(self, SIGNAL_REG_STATUS_CHANGED);
|
||||
}
|
||||
if (g_strcmp0(self->reg_mcc, mcc)) {
|
||||
g_free(self->reg_mcc);
|
||||
watch->reg_mcc = self->reg_mcc = g_strdup(mcc);
|
||||
ofono_watch_signal_queue(self, SIGNAL_REG_MCC_CHANGED);
|
||||
}
|
||||
if (g_strcmp0(self->reg_mnc, mnc)) {
|
||||
g_free(self->reg_mnc);
|
||||
watch->reg_mnc = self->reg_mnc = g_strdup(mnc);
|
||||
ofono_watch_signal_queue(self, SIGNAL_REG_MNC_CHANGED);
|
||||
}
|
||||
if (g_strcmp0(self->reg_name, name)) {
|
||||
g_free(self->reg_name);
|
||||
watch->reg_name = self->reg_name = g_strdup(name);
|
||||
ofono_watch_signal_queue(self, SIGNAL_REG_NAME_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_set_netreg(struct ofono_watch_object *self,
|
||||
struct ofono_netreg *netreg)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
if (watch->netreg != netreg) {
|
||||
watch->netreg = netreg;
|
||||
ofono_watch_signal_queue(self, SIGNAL_NETREG_CHANGED);
|
||||
}
|
||||
ofono_watch_netreg_update(self);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void ofono_watch_netreg_notify(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
struct ofono_netreg *netreg = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG_(self, "netreg registered");
|
||||
ofono_watch_set_netreg(self, netreg);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG_(self, "netreg unregistered");
|
||||
ofono_watch_set_netreg(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_netreg_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
self->netreg_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_set_gprs(struct ofono_watch_object *self,
|
||||
struct ofono_gprs *gprs)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
if (watch->gprs != gprs) {
|
||||
watch->gprs = gprs;
|
||||
ofono_watch_signal_queue(self, SIGNAL_GPRS_CHANGED);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_gprs_notify(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
struct ofono_gprs *gprs = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG_(self, "gprs registered");
|
||||
ofono_watch_set_gprs(self, gprs);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG_(self, "gprs unregistered");
|
||||
ofono_watch_set_gprs(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_gprs_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
self->gprs_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_online_update(struct ofono_watch_object *self,
|
||||
gboolean online)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
if (watch->online != online) {
|
||||
watch->online = online;
|
||||
ofono_watch_signal_queue(self, SIGNAL_ONLINE_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_online_notify(struct ofono_modem *modem,
|
||||
ofono_bool_t online, void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
ASSERT(self->pub.modem == modem);
|
||||
ASSERT(online == ofono_modem_get_online(modem));
|
||||
ofono_watch_online_update(self, online);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void ofono_watch_online_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
self->online_watch_id = 0;
|
||||
}
|
||||
|
||||
static void ofono_watch_setup_modem(struct ofono_watch_object *self)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
ASSERT(!self->online_watch_id);
|
||||
self->online_watch_id =
|
||||
__ofono_modem_add_online_watch(watch->modem,
|
||||
ofono_watch_online_notify, self,
|
||||
ofono_watch_online_destroy);
|
||||
|
||||
/* __ofono_modem_add_atom_watch() calls the notify callback if the
|
||||
* atom is already registered */
|
||||
ASSERT(!self->sim_watch_id);
|
||||
self->sim_watch_id = __ofono_modem_add_atom_watch(watch->modem,
|
||||
OFONO_ATOM_TYPE_SIM, ofono_watch_sim_notify,
|
||||
self, ofono_watch_sim_destroy);
|
||||
|
||||
ASSERT(!self->netreg_watch_id);
|
||||
self->netreg_watch_id = __ofono_modem_add_atom_watch(watch->modem,
|
||||
OFONO_ATOM_TYPE_NETREG, ofono_watch_netreg_notify,
|
||||
self, ofono_watch_netreg_destroy);
|
||||
|
||||
ASSERT(!self->gprs_watch_id);
|
||||
self->gprs_watch_id = __ofono_modem_add_atom_watch(watch->modem,
|
||||
OFONO_ATOM_TYPE_GPRS, ofono_watch_gprs_notify,
|
||||
self, ofono_watch_gprs_destroy);
|
||||
}
|
||||
|
||||
static void ofono_watch_cleanup_modem(struct ofono_watch_object *self,
|
||||
struct ofono_modem *modem)
|
||||
{
|
||||
/*
|
||||
* Caller checks that modem isn't NULL.
|
||||
*
|
||||
* Watch ids are getting zeroed when __ofono_watchlist_free() is
|
||||
* called for the respective watch list. Therefore ids can be zero
|
||||
* even if we never explicitely removed them.
|
||||
*
|
||||
* Calling __ofono_modem_remove_online_watch() and other such
|
||||
* functions after respective watch lists have been deallocated
|
||||
* by modem_unregister() will crash the core.
|
||||
*/
|
||||
if (self->online_watch_id) {
|
||||
__ofono_modem_remove_online_watch(modem, self->online_watch_id);
|
||||
ASSERT(!self->online_watch_id);
|
||||
}
|
||||
|
||||
g_slist_free(watchlist->items);
|
||||
watchlist->items = NULL;
|
||||
g_free(watchlist);
|
||||
if (self->sim_watch_id) {
|
||||
__ofono_modem_remove_atom_watch(modem, self->sim_watch_id);
|
||||
ASSERT(!self->sim_watch_id);
|
||||
}
|
||||
|
||||
if (self->netreg_watch_id) {
|
||||
__ofono_modem_remove_atom_watch(modem, self->netreg_watch_id);
|
||||
ASSERT(!self->netreg_watch_id);
|
||||
}
|
||||
|
||||
if (self->gprs_watch_id) {
|
||||
__ofono_modem_remove_atom_watch(modem, self->gprs_watch_id);
|
||||
ASSERT(!self->gprs_watch_id);
|
||||
}
|
||||
|
||||
ofono_watch_set_sim(self, NULL);
|
||||
ofono_watch_set_netreg(self, NULL);
|
||||
ofono_watch_set_gprs(self, NULL);
|
||||
}
|
||||
|
||||
static void ofono_watch_set_modem(struct ofono_watch_object *self,
|
||||
struct ofono_modem *modem)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
if (watch->modem != modem) {
|
||||
struct ofono_modem *old_modem = watch->modem;
|
||||
|
||||
watch->modem = modem;
|
||||
ofono_watch_signal_queue(self, SIGNAL_MODEM_CHANGED);
|
||||
if (old_modem) {
|
||||
ofono_watch_cleanup_modem(self, old_modem);
|
||||
}
|
||||
if (modem) {
|
||||
ofono_watch_setup_modem(self);
|
||||
}
|
||||
ofono_watch_online_update(self, ofono_modem_get_online(modem));
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_modem_notify(struct ofono_modem *modem,
|
||||
gboolean added, void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
if (added) {
|
||||
if (!g_strcmp0(self->path, ofono_modem_get_path(modem))) {
|
||||
ofono_watch_set_modem(self, modem);
|
||||
}
|
||||
} else if (self->pub.modem == modem) {
|
||||
ofono_watch_set_modem(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_modem_destroy(void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
self->modem_watch_id = 0;
|
||||
}
|
||||
|
||||
static ofono_bool_t ofono_watch_modem_find(struct ofono_modem *modem,
|
||||
void *user_data)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(user_data);
|
||||
|
||||
if (!g_strcmp0(self->path, ofono_modem_get_path(modem))) {
|
||||
self->pub.modem = modem;
|
||||
ofono_watch_setup_modem(self);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_initialize(struct ofono_watch_object *self,
|
||||
const char *path)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
watch->path = self->path = g_strdup(path);
|
||||
ofono_modem_find(ofono_watch_modem_find, self);
|
||||
watch->online = ofono_modem_get_online(watch->modem);
|
||||
self->modem_watch_id =
|
||||
__ofono_modemwatch_add(ofono_watch_modem_notify, self,
|
||||
ofono_watch_modem_destroy);
|
||||
}
|
||||
|
||||
static void ofono_watch_destroyed(gpointer key, GObject *obj)
|
||||
{
|
||||
ASSERT(ofono_watch_table);
|
||||
DBG("%s", (char*)key);
|
||||
if (ofono_watch_table) {
|
||||
ASSERT(g_hash_table_lookup(ofono_watch_table, key) == obj);
|
||||
g_hash_table_remove(ofono_watch_table, key);
|
||||
if (g_hash_table_size(ofono_watch_table) == 0) {
|
||||
g_hash_table_unref(ofono_watch_table);
|
||||
ofono_watch_table = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ofono_watch *ofono_watch_new(const char *path)
|
||||
{
|
||||
if (path) {
|
||||
struct ofono_watch_object *self = NULL;
|
||||
|
||||
if (ofono_watch_table) {
|
||||
self = g_hash_table_lookup(ofono_watch_table, path);
|
||||
}
|
||||
if (self) {
|
||||
g_object_ref(self);
|
||||
} else {
|
||||
char *key = g_strdup(path);
|
||||
|
||||
self = g_object_new(OFONO_WATCH_OBJECT_TYPE, NULL);
|
||||
ofono_watch_initialize(self, path);
|
||||
if (!ofono_watch_table) {
|
||||
/* Create the table on demand */
|
||||
ofono_watch_table =
|
||||
g_hash_table_new_full(g_str_hash,
|
||||
g_str_equal, g_free, NULL);
|
||||
}
|
||||
g_hash_table_replace(ofono_watch_table, key, self);
|
||||
g_object_weak_ref(G_OBJECT(self),
|
||||
ofono_watch_destroyed, key);
|
||||
DBG_(self, "created");
|
||||
}
|
||||
return &self->pub;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ofono_watch *ofono_watch_ref(struct ofono_watch *watch)
|
||||
{
|
||||
if (watch) {
|
||||
g_object_ref(ofono_watch_object_cast(watch));
|
||||
return watch;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_watch_unref(struct ofono_watch *watch)
|
||||
{
|
||||
if (watch) {
|
||||
g_object_unref(ofono_watch_object_cast(watch));
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_signal_cb(struct ofono_watch_object *source,
|
||||
struct ofono_watch_closure *closure)
|
||||
{
|
||||
closure->cb.generic(&source->pub, closure->user_data);
|
||||
}
|
||||
|
||||
static unsigned long ofono_watch_add_handler(struct ofono_watch_object *self,
|
||||
enum ofono_watch_signal signal, GCallback handler,
|
||||
GCallback cb, void *user_data)
|
||||
{
|
||||
if (self && cb) {
|
||||
/*
|
||||
* We can't directly connect the provided callback because
|
||||
* it expects the first parameter to point to the public
|
||||
* part of ofono_watch_object (i.e. ofono_watch) but glib
|
||||
* will invoke it with ofono_watch_object as the first
|
||||
* parameter. ofono_watch_signal_cb() will do the conversion.
|
||||
*/
|
||||
struct ofono_watch_closure *closure =
|
||||
(struct ofono_watch_closure *)g_closure_new_simple
|
||||
(sizeof(struct ofono_watch_closure), NULL);
|
||||
|
||||
closure->cclosure.closure.data = closure;
|
||||
closure->cclosure.callback = handler;
|
||||
closure->cb.ptr = cb;
|
||||
closure->user_data = user_data;
|
||||
|
||||
return g_signal_connect_closure_by_id(self,
|
||||
ofono_watch_signals[signal], 0,
|
||||
&closure->cclosure.closure, FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long ofono_watch_add_signal_handler(struct ofono_watch *watch,
|
||||
enum ofono_watch_signal signal, ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return ofono_watch_add_handler(ofono_watch_object_cast(watch), signal,
|
||||
G_CALLBACK(ofono_watch_signal_cb), G_CALLBACK(cb), user_data);
|
||||
}
|
||||
|
||||
#define ADD_SIGNAL_HANDLER_PROC(name,NAME) \
|
||||
unsigned long ofono_watch_add_##name##_changed_handler \
|
||||
(struct ofono_watch *w, ofono_watch_cb_t cb, void *arg) \
|
||||
{ return ofono_watch_add_signal_handler(w, SIGNAL_##NAME##_CHANGED, cb, arg); }
|
||||
|
||||
ADD_SIGNAL_HANDLER_PROC(modem,MODEM)
|
||||
ADD_SIGNAL_HANDLER_PROC(online,ONLINE)
|
||||
ADD_SIGNAL_HANDLER_PROC(sim,SIM)
|
||||
ADD_SIGNAL_HANDLER_PROC(sim_state,SIM_STATE)
|
||||
ADD_SIGNAL_HANDLER_PROC(iccid,ICCID)
|
||||
ADD_SIGNAL_HANDLER_PROC(imsi,IMSI)
|
||||
ADD_SIGNAL_HANDLER_PROC(spn,SPN)
|
||||
ADD_SIGNAL_HANDLER_PROC(netreg,NETREG)
|
||||
ADD_SIGNAL_HANDLER_PROC(reg_status,REG_STATUS)
|
||||
ADD_SIGNAL_HANDLER_PROC(reg_mcc,REG_MCC)
|
||||
ADD_SIGNAL_HANDLER_PROC(reg_mnc,REG_MNC)
|
||||
ADD_SIGNAL_HANDLER_PROC(reg_name,REG_NAME)
|
||||
ADD_SIGNAL_HANDLER_PROC(gprs,GPRS)
|
||||
|
||||
static void ofono_watch_gprs_settings_signal_cb(struct ofono_watch_object *src,
|
||||
enum ofono_gprs_context_type type,
|
||||
const struct ofono_gprs_primary_context *ctx,
|
||||
struct ofono_watch_closure *closure)
|
||||
{
|
||||
closure->cb.gprs_settings(&src->pub, type, ctx, closure->user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_gprs_settings_changed_handler
|
||||
(struct ofono_watch *watch, ofono_watch_gprs_settings_cb_t cb,
|
||||
void *user_data)
|
||||
{
|
||||
return ofono_watch_add_handler(ofono_watch_object_cast(watch),
|
||||
SIGNAL_GPRS_SETTINGS_CHANGED,
|
||||
G_CALLBACK(ofono_watch_gprs_settings_signal_cb),
|
||||
G_CALLBACK(cb), user_data);
|
||||
}
|
||||
|
||||
void ofono_watch_remove_handler(struct ofono_watch *watch, unsigned long id)
|
||||
{
|
||||
if (watch && id) {
|
||||
g_signal_handler_disconnect(ofono_watch_object_cast(watch),
|
||||
id);
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_watch_remove_handlers(struct ofono_watch *watch, unsigned long *ids,
|
||||
unsigned int count)
|
||||
{
|
||||
struct ofono_watch_object *self = ofono_watch_object_cast(watch);
|
||||
|
||||
if (self && ids && count) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (ids[i]) {
|
||||
g_signal_handler_disconnect(self, ids[i]);
|
||||
ids[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __ofono_watch_netreg_changed(const char *path)
|
||||
{
|
||||
if (path && ofono_watch_table) {
|
||||
struct ofono_watch_object *self =
|
||||
g_hash_table_lookup(ofono_watch_table, path);
|
||||
|
||||
if (self) {
|
||||
g_object_ref(self);
|
||||
ofono_watch_netreg_update(self);
|
||||
ofono_watch_emit_queued_signals(self);
|
||||
g_object_unref(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __ofono_watch_gprs_settings_changed(const char *path,
|
||||
enum ofono_gprs_context_type type,
|
||||
const struct ofono_gprs_primary_context *settings)
|
||||
{
|
||||
if (path && ofono_watch_table) {
|
||||
struct ofono_watch_object *self =
|
||||
g_hash_table_lookup(ofono_watch_table, path);
|
||||
|
||||
if (self) {
|
||||
g_object_ref(self);
|
||||
g_signal_emit(self, ofono_watch_signals
|
||||
[SIGNAL_GPRS_SETTINGS_CHANGED], 0, type,
|
||||
settings);
|
||||
g_object_unref(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ofono_watch_object_init(struct ofono_watch_object *self)
|
||||
{
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
watch->reg_status = OFONO_NETREG_STATUS_NONE;
|
||||
}
|
||||
|
||||
static void ofono_watch_object_finalize(GObject *object)
|
||||
{
|
||||
struct ofono_watch_object *self = OFONO_WATCH_OBJECT(object);
|
||||
struct ofono_watch *watch = &self->pub;
|
||||
|
||||
if (watch->modem) {
|
||||
struct ofono_modem *modem = watch->modem;
|
||||
|
||||
watch->modem = NULL;
|
||||
ofono_watch_cleanup_modem(self, modem);
|
||||
}
|
||||
__ofono_modemwatch_remove(self->modem_watch_id);
|
||||
ASSERT(!self->modem_watch_id);
|
||||
g_free(self->path);
|
||||
G_OBJECT_CLASS(ofono_watch_object_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void ofono_watch_object_class_init(OfonoWatchObjectClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = ofono_watch_object_finalize;
|
||||
NEW_SIGNAL(klass, MODEM);
|
||||
NEW_SIGNAL(klass, ONLINE);
|
||||
NEW_SIGNAL(klass, SIM);
|
||||
NEW_SIGNAL(klass, SIM_STATE);
|
||||
NEW_SIGNAL(klass, ICCID);
|
||||
NEW_SIGNAL(klass, IMSI);
|
||||
NEW_SIGNAL(klass, SPN);
|
||||
NEW_SIGNAL(klass, NETREG);
|
||||
NEW_SIGNAL(klass, REG_STATUS);
|
||||
NEW_SIGNAL(klass, REG_MCC);
|
||||
NEW_SIGNAL(klass, REG_MNC);
|
||||
NEW_SIGNAL(klass, REG_NAME);
|
||||
NEW_SIGNAL(klass, GPRS);
|
||||
ofono_watch_signals[SIGNAL_GPRS_SETTINGS_CHANGED] =
|
||||
g_signal_new(SIGNAL_GPRS_SETTINGS_CHANGED_NAME,
|
||||
G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE,
|
||||
2, G_TYPE_INT, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
|
||||
34
ofono/src/watch_p.h
Normal file
34
ofono/src/watch_p.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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 OFONO_WATCH_PRIVATE_H
|
||||
#define OFONO_WATCH_PRIVATE_H
|
||||
|
||||
#include <ofono/watch.h>
|
||||
|
||||
void __ofono_watch_netreg_changed(const char *path);
|
||||
void __ofono_watch_gprs_settings_changed(const char *path,
|
||||
enum ofono_gprs_context_type type,
|
||||
const struct ofono_gprs_primary_context *settings);
|
||||
|
||||
#endif /* OFONO_WATCH_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
107
ofono/src/watchlist.c
Normal file
107
ofono/src/watchlist.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include "ofono.h"
|
||||
|
||||
struct ofono_watchlist *__ofono_watchlist_new(ofono_destroy_func destroy)
|
||||
{
|
||||
struct ofono_watchlist *watchlist;
|
||||
|
||||
watchlist = g_new0(struct ofono_watchlist, 1);
|
||||
watchlist->destroy = destroy;
|
||||
|
||||
return watchlist;
|
||||
}
|
||||
|
||||
unsigned int __ofono_watchlist_add_item(struct ofono_watchlist *watchlist,
|
||||
struct ofono_watchlist_item *item)
|
||||
{
|
||||
item->id = ++watchlist->next_id;
|
||||
|
||||
if (item->id == 0)
|
||||
item->id = ++watchlist->next_id;
|
||||
|
||||
watchlist->items = g_slist_prepend(watchlist->items, item);
|
||||
|
||||
return item->id;
|
||||
}
|
||||
|
||||
gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist,
|
||||
unsigned int id)
|
||||
{
|
||||
struct ofono_watchlist_item *item;
|
||||
GSList *p;
|
||||
GSList *c;
|
||||
|
||||
p = NULL;
|
||||
c = watchlist->items;
|
||||
|
||||
while (c) {
|
||||
item = c->data;
|
||||
|
||||
if (item->id != id) {
|
||||
p = c;
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p)
|
||||
p->next = c->next;
|
||||
else
|
||||
watchlist->items = c->next;
|
||||
|
||||
if (item->destroy)
|
||||
item->destroy(item->notify_data);
|
||||
|
||||
if (watchlist->destroy)
|
||||
watchlist->destroy(item);
|
||||
g_slist_free_1(c);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void __ofono_watchlist_free(struct ofono_watchlist *watchlist)
|
||||
{
|
||||
struct ofono_watchlist_item *item;
|
||||
GSList *l;
|
||||
|
||||
for (l = watchlist->items; l; l = l->next) {
|
||||
item = l->data;
|
||||
|
||||
if (item->destroy)
|
||||
item->destroy(item->notify_data);
|
||||
|
||||
if (watchlist->destroy)
|
||||
watchlist->destroy(item);
|
||||
}
|
||||
|
||||
g_slist_free(watchlist->items);
|
||||
watchlist->items = NULL;
|
||||
g_free(watchlist);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import dbus
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import dbus
|
||||
|
||||
@@ -17,19 +17,22 @@ TESTS="\
|
||||
test-sms-root \
|
||||
test-caif \
|
||||
test-dbus-queue \
|
||||
test-dbus-access \
|
||||
test-gprs-filter \
|
||||
test-provision \
|
||||
test-watch \
|
||||
test-ril_util \
|
||||
test-ril_config \
|
||||
test-ril-transport \
|
||||
test-ril_vendor \
|
||||
test-sms-filter \
|
||||
test-voicecall-filter \
|
||||
test-sailfish_access \
|
||||
test-sailfish_cell_info \
|
||||
test-sailfish_cell_info_dbus \
|
||||
test-sailfish_manager \
|
||||
test-sailfish_sim_info \
|
||||
test-sailfish_sim_info_dbus \
|
||||
test-sailfish_watch"
|
||||
test-sailfish_sim_info_dbus"
|
||||
|
||||
pushd `dirname $0` > /dev/null
|
||||
TEST_DIR="$PWD"
|
||||
|
||||
@@ -1,326 +0,0 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 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 "fake_sailfish_watch.h"
|
||||
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_log.h>
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
typedef GObjectClass SailfishWatchClass;
|
||||
typedef struct sailfish_watch SailfishWatch;
|
||||
|
||||
struct sailfish_watch_priv {
|
||||
char *path;
|
||||
char *iccid;
|
||||
char *imsi;
|
||||
char *spn;
|
||||
int queued_signals;
|
||||
};
|
||||
|
||||
#define SIGNAL_MODEM_CHANGED_NAME "sailfish-watch-modem-changed"
|
||||
#define SIGNAL_ONLINE_CHANGED_NAME "sailfish-watch-online-changed"
|
||||
#define SIGNAL_SIM_CHANGED_NAME "sailfish-watch-sim-changed"
|
||||
#define SIGNAL_SIM_STATE_CHANGED_NAME "sailfish-watch-sim-state-changed"
|
||||
#define SIGNAL_ICCID_CHANGED_NAME "sailfish-watch-iccid-changed"
|
||||
#define SIGNAL_IMSI_CHANGED_NAME "sailfish-watch-imsi-changed"
|
||||
#define SIGNAL_SPN_CHANGED_NAME "sailfish-watch-spn-changed"
|
||||
#define SIGNAL_NETREG_CHANGED_NAME "sailfish-watch-netreg-changed"
|
||||
|
||||
static guint sailfish_watch_signals[WATCH_SIGNAL_COUNT] = { 0 };
|
||||
static GHashTable* sailfish_watch_table = NULL;
|
||||
|
||||
G_DEFINE_TYPE(SailfishWatch, sailfish_watch, G_TYPE_OBJECT)
|
||||
#define SAILFISH_WATCH_TYPE (sailfish_watch_get_type())
|
||||
#define SAILFISH_WATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||
SAILFISH_WATCH_TYPE, SailfishWatch))
|
||||
|
||||
#define NEW_SIGNAL(klass,name) \
|
||||
sailfish_watch_signals[WATCH_SIGNAL_##name##_CHANGED] = \
|
||||
g_signal_new(SIGNAL_##name##_CHANGED_NAME, \
|
||||
G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, \
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 0)
|
||||
|
||||
#define DBG_(obj,fmt,args...) DBG("%s " fmt, (obj)->path+1, ##args)
|
||||
|
||||
static inline int sailfish_watch_signal_bit(enum sailfish_watch_signal id)
|
||||
{
|
||||
return (1 << id);
|
||||
}
|
||||
|
||||
static inline void sailfish_watch_signal_emit(struct sailfish_watch *self,
|
||||
enum sailfish_watch_signal id)
|
||||
{
|
||||
self->priv->queued_signals &= ~sailfish_watch_signal_bit(id);
|
||||
g_signal_emit(self, sailfish_watch_signals[id], 0);
|
||||
}
|
||||
|
||||
void fake_sailfish_watch_signal_queue(struct sailfish_watch *self,
|
||||
enum sailfish_watch_signal id)
|
||||
{
|
||||
self->priv->queued_signals |= sailfish_watch_signal_bit(id);
|
||||
}
|
||||
|
||||
void fake_sailfish_watch_emit_queued_signals(struct sailfish_watch *self)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; priv->queued_signals && i < WATCH_SIGNAL_COUNT; i++) {
|
||||
if (priv->queued_signals & sailfish_watch_signal_bit(i)) {
|
||||
sailfish_watch_signal_emit(self, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fake_sailfish_watch_set_ofono_iccid(struct sailfish_watch *self,
|
||||
const char *iccid)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (g_strcmp0(priv->iccid, iccid)) {
|
||||
g_free(priv->iccid);
|
||||
self->iccid = priv->iccid = g_strdup(iccid);
|
||||
fake_sailfish_watch_signal_queue(self,
|
||||
WATCH_SIGNAL_ICCID_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
void fake_sailfish_watch_set_ofono_imsi(struct sailfish_watch *self,
|
||||
const char *imsi)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (g_strcmp0(priv->imsi, imsi)) {
|
||||
g_free(priv->imsi);
|
||||
self->imsi = priv->imsi = g_strdup(imsi);
|
||||
fake_sailfish_watch_signal_queue(self,
|
||||
WATCH_SIGNAL_IMSI_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
void fake_sailfish_watch_set_ofono_spn(struct sailfish_watch *self,
|
||||
const char *spn)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
if (g_strcmp0(priv->spn, spn)) {
|
||||
g_free(priv->spn);
|
||||
self->spn = priv->spn = g_strdup(spn);
|
||||
fake_sailfish_watch_signal_queue(self,
|
||||
WATCH_SIGNAL_SPN_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
void fake_sailfish_watch_set_ofono_sim(struct sailfish_watch *self,
|
||||
struct ofono_sim *sim)
|
||||
{
|
||||
if (self->sim != sim) {
|
||||
self->sim = sim;
|
||||
fake_sailfish_watch_signal_queue(self,
|
||||
WATCH_SIGNAL_SIM_CHANGED);
|
||||
if (!sim) {
|
||||
fake_sailfish_watch_set_ofono_iccid(self, NULL);
|
||||
fake_sailfish_watch_set_ofono_imsi(self, NULL);
|
||||
fake_sailfish_watch_set_ofono_spn(self, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fake_sailfish_watch_set_ofono_netreg(struct sailfish_watch *self,
|
||||
struct ofono_netreg *netreg)
|
||||
{
|
||||
if (self->netreg != netreg) {
|
||||
self->netreg = netreg;
|
||||
fake_sailfish_watch_signal_queue(self,
|
||||
WATCH_SIGNAL_NETREG_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_watch_initialize(struct sailfish_watch *self,
|
||||
const char *path)
|
||||
{
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
self->path = priv->path = g_strdup(path);
|
||||
}
|
||||
|
||||
static void sailfish_watch_destroyed(gpointer key, GObject* obj)
|
||||
{
|
||||
GASSERT(sailfish_watch_table);
|
||||
DBG("%s", (char*)key);
|
||||
if (sailfish_watch_table) {
|
||||
GASSERT(g_hash_table_lookup(sailfish_watch_table, key) == obj);
|
||||
g_hash_table_remove(sailfish_watch_table, key);
|
||||
if (g_hash_table_size(sailfish_watch_table) == 0) {
|
||||
g_hash_table_unref(sailfish_watch_table);
|
||||
sailfish_watch_table = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct sailfish_watch *sailfish_watch_new(const char *path)
|
||||
{
|
||||
struct sailfish_watch *watch = NULL;
|
||||
|
||||
if (path) {
|
||||
if (sailfish_watch_table) {
|
||||
watch = sailfish_watch_ref(g_hash_table_lookup(
|
||||
sailfish_watch_table, path));
|
||||
}
|
||||
if (!watch) {
|
||||
char* key = g_strdup(path);
|
||||
|
||||
watch = g_object_new(SAILFISH_WATCH_TYPE, NULL);
|
||||
sailfish_watch_initialize(watch, path);
|
||||
if (!sailfish_watch_table) {
|
||||
/* Create the table on demand */
|
||||
sailfish_watch_table =
|
||||
g_hash_table_new_full(g_str_hash,
|
||||
g_str_equal, g_free, NULL);
|
||||
}
|
||||
g_hash_table_replace(sailfish_watch_table, key, watch);
|
||||
g_object_weak_ref(G_OBJECT(watch),
|
||||
sailfish_watch_destroyed, key);
|
||||
DBG_(watch, "created");
|
||||
}
|
||||
}
|
||||
return watch;
|
||||
}
|
||||
|
||||
struct sailfish_watch *sailfish_watch_ref(struct sailfish_watch *self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_ref(SAILFISH_WATCH(self));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void sailfish_watch_unref(struct sailfish_watch *self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_unref(SAILFISH_WATCH(self));
|
||||
}
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_modem_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_MODEM_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_online_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_ONLINE_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_sim_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_SIM_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_sim_state_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_SIM_STATE_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_iccid_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_ICCID_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_imsi_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_IMSI_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_spn_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_SPN_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong sailfish_watch_add_netreg_changed_handler(struct sailfish_watch *self,
|
||||
sailfish_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return (self && cb) ? g_signal_connect(self,
|
||||
SIGNAL_NETREG_CHANGED_NAME, G_CALLBACK(cb), user_data) : 0;
|
||||
}
|
||||
|
||||
void sailfish_watch_remove_handler(struct sailfish_watch *self, gulong id)
|
||||
{
|
||||
if (self && id) {
|
||||
g_signal_handler_disconnect(self, id);
|
||||
}
|
||||
}
|
||||
|
||||
void sailfish_watch_remove_handlers(struct sailfish_watch *self, gulong *ids,
|
||||
int count)
|
||||
{
|
||||
gutil_disconnect_handlers(self, ids, count);
|
||||
}
|
||||
|
||||
static void sailfish_watch_init(struct sailfish_watch *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SAILFISH_WATCH_TYPE,
|
||||
struct sailfish_watch_priv);
|
||||
}
|
||||
|
||||
static void sailfish_watch_finalize(GObject *object)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(object);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
g_free(priv->path);
|
||||
g_free(priv->iccid);
|
||||
g_free(priv->imsi);
|
||||
g_free(priv->spn);
|
||||
G_OBJECT_CLASS(sailfish_watch_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void sailfish_watch_class_init(SailfishWatchClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = sailfish_watch_finalize;
|
||||
g_type_class_add_private(klass, sizeof(struct sailfish_watch_priv));
|
||||
NEW_SIGNAL(klass, MODEM);
|
||||
NEW_SIGNAL(klass, ONLINE);
|
||||
NEW_SIGNAL(klass, SIM);
|
||||
NEW_SIGNAL(klass, SIM_STATE);
|
||||
NEW_SIGNAL(klass, ICCID);
|
||||
NEW_SIGNAL(klass, IMSI);
|
||||
NEW_SIGNAL(klass, SPN);
|
||||
NEW_SIGNAL(klass, NETREG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 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 SAILFISH_FAKE_WATCH_H
|
||||
#define SAILFISH_FAKE_WATCH_H
|
||||
|
||||
#include "sailfish_watch.h"
|
||||
|
||||
enum sailfish_watch_signal {
|
||||
WATCH_SIGNAL_MODEM_CHANGED,
|
||||
WATCH_SIGNAL_ONLINE_CHANGED,
|
||||
WATCH_SIGNAL_SIM_CHANGED,
|
||||
WATCH_SIGNAL_SIM_STATE_CHANGED,
|
||||
WATCH_SIGNAL_ICCID_CHANGED,
|
||||
WATCH_SIGNAL_IMSI_CHANGED,
|
||||
WATCH_SIGNAL_SPN_CHANGED,
|
||||
WATCH_SIGNAL_NETREG_CHANGED,
|
||||
WATCH_SIGNAL_COUNT
|
||||
};
|
||||
|
||||
void fake_sailfish_watch_signal_queue(struct sailfish_watch *watch,
|
||||
enum sailfish_watch_signal id);
|
||||
void fake_sailfish_watch_emit_queued_signals(struct sailfish_watch *watch);
|
||||
void fake_sailfish_watch_set_ofono_sim(struct sailfish_watch *watch,
|
||||
struct ofono_sim *sim);
|
||||
void fake_sailfish_watch_set_ofono_iccid(struct sailfish_watch *watch,
|
||||
const char *iccid);
|
||||
void fake_sailfish_watch_set_ofono_imsi(struct sailfish_watch *watch,
|
||||
const char *imsi);
|
||||
void fake_sailfish_watch_set_ofono_spn(struct sailfish_watch *watch,
|
||||
const char *spn);
|
||||
void fake_sailfish_watch_set_ofono_netreg(struct sailfish_watch *watch,
|
||||
struct ofono_netreg *netreg);
|
||||
|
||||
#endif /* FAKE_SAILFISH_WATCH_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
364
ofono/unit/fake_watch.c
Normal file
364
ofono/unit/fake_watch.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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
|
||||
* 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 "fake_watch.h"
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
#include <gutil_log.h>
|
||||
#include <gutil_macros.h>
|
||||
#include <gutil_misc.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
typedef GObjectClass FakeOfonoWatchClass;
|
||||
typedef struct fake_ofono_watch FakeOfonoWatch;
|
||||
|
||||
struct fake_ofono_watch {
|
||||
GObject object;
|
||||
struct ofono_watch pub;
|
||||
char *path;
|
||||
char *iccid;
|
||||
char *imsi;
|
||||
char *spn;
|
||||
int queued_signals;
|
||||
};
|
||||
|
||||
struct fake_ofono_watch_closure {
|
||||
GCClosure cclosure;
|
||||
ofono_watch_cb_t cb;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#define SIGNAL_MODEM_CHANGED_NAME "ofono-watch-modem-changed"
|
||||
#define SIGNAL_ONLINE_CHANGED_NAME "ofono-watch-online-changed"
|
||||
#define SIGNAL_SIM_CHANGED_NAME "ofono-watch-sim-changed"
|
||||
#define SIGNAL_SIM_STATE_CHANGED_NAME "ofono-watch-sim-state-changed"
|
||||
#define SIGNAL_ICCID_CHANGED_NAME "ofono-watch-iccid-changed"
|
||||
#define SIGNAL_IMSI_CHANGED_NAME "ofono-watch-imsi-changed"
|
||||
#define SIGNAL_SPN_CHANGED_NAME "ofono-watch-spn-changed"
|
||||
#define SIGNAL_NETREG_CHANGED_NAME "ofono-watch-netreg-changed"
|
||||
|
||||
static guint fake_ofono_watch_signals[FAKE_WATCH_SIGNAL_COUNT] = { 0 };
|
||||
static GHashTable *fake_ofono_watch_table = NULL;
|
||||
|
||||
G_DEFINE_TYPE(FakeOfonoWatch, fake_ofono_watch, G_TYPE_OBJECT)
|
||||
#define FAKE_OFONO_WATCH_TYPE (fake_ofono_watch_get_type())
|
||||
#define FAKE_OFONO_WATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||
FAKE_OFONO_WATCH_TYPE, FakeOfonoWatch))
|
||||
|
||||
#define NEW_SIGNAL(klass,name) \
|
||||
fake_ofono_watch_signals[FAKE_WATCH_SIGNAL_##name##_CHANGED] = \
|
||||
g_signal_new(SIGNAL_##name##_CHANGED_NAME, \
|
||||
G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, \
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 0)
|
||||
|
||||
#define DBG_(obj,fmt,args...) DBG("%s " fmt, (obj)->path+1, ##args)
|
||||
|
||||
static inline struct fake_ofono_watch *fake_ofono_watch_cast
|
||||
(struct ofono_watch *watch)
|
||||
{
|
||||
return watch ?
|
||||
FAKE_OFONO_WATCH(G_CAST(watch, struct fake_ofono_watch, pub)) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
static inline int fake_ofono_watch_signal_bit(enum fake_watch_signal id)
|
||||
{
|
||||
return (1 << id);
|
||||
}
|
||||
|
||||
static inline void fake_ofono_watch_signal_emit(struct fake_ofono_watch *self,
|
||||
enum fake_watch_signal id)
|
||||
{
|
||||
self->queued_signals &= ~fake_ofono_watch_signal_bit(id);
|
||||
g_signal_emit(self, fake_ofono_watch_signals[id], 0);
|
||||
}
|
||||
|
||||
void fake_watch_signal_queue(struct ofono_watch *watch,
|
||||
enum fake_watch_signal id)
|
||||
{
|
||||
struct fake_ofono_watch *self = fake_ofono_watch_cast(watch);
|
||||
|
||||
self->queued_signals |= fake_ofono_watch_signal_bit(id);
|
||||
}
|
||||
|
||||
void fake_watch_emit_queued_signals(struct ofono_watch *watch)
|
||||
{
|
||||
struct fake_ofono_watch *self = fake_ofono_watch_cast(watch);
|
||||
int i;
|
||||
|
||||
for (i = 0; self->queued_signals && i < FAKE_WATCH_SIGNAL_COUNT; i++) {
|
||||
if (self->queued_signals & fake_ofono_watch_signal_bit(i)) {
|
||||
fake_ofono_watch_signal_emit(self, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fake_watch_set_ofono_iccid(struct ofono_watch *watch, const char *iccid)
|
||||
{
|
||||
struct fake_ofono_watch *self = fake_ofono_watch_cast(watch);
|
||||
|
||||
if (g_strcmp0(self->iccid, iccid)) {
|
||||
g_free(self->iccid);
|
||||
watch->iccid = self->iccid = g_strdup(iccid);
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_ICCID_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
void fake_watch_set_ofono_imsi(struct ofono_watch *watch, const char *imsi)
|
||||
{
|
||||
struct fake_ofono_watch *self = fake_ofono_watch_cast(watch);
|
||||
|
||||
if (g_strcmp0(self->imsi, imsi)) {
|
||||
g_free(self->imsi);
|
||||
watch->imsi = self->imsi = g_strdup(imsi);
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_IMSI_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
void fake_watch_set_ofono_spn(struct ofono_watch *watch, const char *spn)
|
||||
{
|
||||
struct fake_ofono_watch *self = fake_ofono_watch_cast(watch);
|
||||
|
||||
if (g_strcmp0(self->spn, spn)) {
|
||||
g_free(self->spn);
|
||||
watch->spn = self->spn = g_strdup(spn);
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_SPN_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
void fake_watch_set_ofono_sim(struct ofono_watch *watch,
|
||||
struct ofono_sim *sim)
|
||||
{
|
||||
if (watch->sim != sim) {
|
||||
watch->sim = sim;
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_SIM_CHANGED);
|
||||
if (!sim) {
|
||||
fake_watch_set_ofono_iccid(watch, NULL);
|
||||
fake_watch_set_ofono_imsi(watch, NULL);
|
||||
fake_watch_set_ofono_spn(watch, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fake_watch_set_ofono_netreg(struct ofono_watch *watch,
|
||||
struct ofono_netreg *netreg)
|
||||
{
|
||||
if (watch->netreg != netreg) {
|
||||
watch->netreg = netreg;
|
||||
fake_watch_signal_queue(watch,
|
||||
FAKE_WATCH_SIGNAL_NETREG_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void fake_ofono_watch_initialize(struct fake_ofono_watch *self,
|
||||
const char *path)
|
||||
{
|
||||
self->pub.path = self->path = g_strdup(path);
|
||||
}
|
||||
|
||||
static void fake_ofono_watch_destroyed(gpointer key, GObject *obj)
|
||||
{
|
||||
GASSERT(fake_ofono_watch_table);
|
||||
DBG("%s", (char*)key);
|
||||
if (fake_ofono_watch_table) {
|
||||
GASSERT(g_hash_table_lookup(fake_ofono_watch_table,key) == obj);
|
||||
g_hash_table_remove(fake_ofono_watch_table, key);
|
||||
if (g_hash_table_size(fake_ofono_watch_table) == 0) {
|
||||
g_hash_table_unref(fake_ofono_watch_table);
|
||||
fake_ofono_watch_table = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ofono_watch *ofono_watch_new(const char *path)
|
||||
{
|
||||
if (path) {
|
||||
struct fake_ofono_watch *self = NULL;
|
||||
|
||||
if (fake_ofono_watch_table) {
|
||||
self = g_hash_table_lookup(fake_ofono_watch_table,
|
||||
path);
|
||||
}
|
||||
if (self) {
|
||||
g_object_ref(self);
|
||||
} else {
|
||||
char *key = g_strdup(path);
|
||||
|
||||
self = g_object_new(FAKE_OFONO_WATCH_TYPE, NULL);
|
||||
fake_ofono_watch_initialize(self, path);
|
||||
if (!fake_ofono_watch_table) {
|
||||
/* Create the table on demand */
|
||||
fake_ofono_watch_table =
|
||||
g_hash_table_new_full(g_str_hash,
|
||||
g_str_equal, g_free, NULL);
|
||||
}
|
||||
g_hash_table_replace(fake_ofono_watch_table, key, self);
|
||||
g_object_weak_ref(G_OBJECT(self),
|
||||
fake_ofono_watch_destroyed, key);
|
||||
DBG_(self, "created");
|
||||
}
|
||||
return &self->pub;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ofono_watch *ofono_watch_ref(struct ofono_watch *self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_ref(fake_ofono_watch_cast(self));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void ofono_watch_unref(struct ofono_watch *self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_unref(fake_ofono_watch_cast(self));
|
||||
}
|
||||
}
|
||||
|
||||
static void fake_watch_signal_cb(struct fake_ofono_watch *source,
|
||||
struct fake_ofono_watch_closure *closure)
|
||||
{
|
||||
closure->cb(&source->pub, closure->user_data);
|
||||
}
|
||||
|
||||
static unsigned long fake_watch_add_signal_handler(struct ofono_watch *watch,
|
||||
enum fake_watch_signal signal, ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
if (watch && cb) {
|
||||
struct fake_ofono_watch *self = fake_ofono_watch_cast(watch);
|
||||
struct fake_ofono_watch_closure *closure =
|
||||
(struct fake_ofono_watch_closure *)g_closure_new_simple
|
||||
(sizeof(struct fake_ofono_watch_closure), NULL);
|
||||
|
||||
closure->cclosure.closure.data = closure;
|
||||
closure->cclosure.callback = G_CALLBACK(fake_watch_signal_cb);
|
||||
closure->cb = cb;
|
||||
closure->user_data = user_data;
|
||||
|
||||
return g_signal_connect_closure_by_id(self,
|
||||
fake_ofono_watch_signals[signal], 0,
|
||||
&closure->cclosure.closure, FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_modem_changed_handler(struct ofono_watch *watch,
|
||||
ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_MODEM_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_online_changed_handler(struct ofono_watch *watch,
|
||||
ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_ONLINE_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_sim_changed_handler(struct ofono_watch *watch,
|
||||
ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_SIM_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_sim_state_changed_handler
|
||||
(struct ofono_watch *watch, ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_iccid_changed_handler(struct ofono_watch *watch,
|
||||
ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_ICCID_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_imsi_changed_handler(struct ofono_watch *watch,
|
||||
ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_IMSI_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_spn_changed_handler(struct ofono_watch *watch,
|
||||
ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_SPN_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
unsigned long ofono_watch_add_netreg_changed_handler(struct ofono_watch *watch,
|
||||
ofono_watch_cb_t cb, void *user_data)
|
||||
{
|
||||
return fake_watch_add_signal_handler(watch,
|
||||
FAKE_WATCH_SIGNAL_NETREG_CHANGED, cb, user_data);
|
||||
}
|
||||
|
||||
void ofono_watch_remove_handler(struct ofono_watch *watch, unsigned long id)
|
||||
{
|
||||
if (watch && id) {
|
||||
g_signal_handler_disconnect(fake_ofono_watch_cast(watch), id);
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_watch_remove_handlers(struct ofono_watch *watch, unsigned long *ids,
|
||||
unsigned int count)
|
||||
{
|
||||
gutil_disconnect_handlers(fake_ofono_watch_cast(watch), ids, count);
|
||||
}
|
||||
|
||||
static void fake_ofono_watch_init(struct fake_ofono_watch *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void fake_ofono_watch_finalize(GObject *object)
|
||||
{
|
||||
struct fake_ofono_watch *self = FAKE_OFONO_WATCH(object);
|
||||
|
||||
g_free(self->path);
|
||||
g_free(self->iccid);
|
||||
g_free(self->imsi);
|
||||
g_free(self->spn);
|
||||
G_OBJECT_CLASS(fake_ofono_watch_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void fake_ofono_watch_class_init(FakeOfonoWatchClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = fake_ofono_watch_finalize;
|
||||
NEW_SIGNAL(klass, MODEM);
|
||||
NEW_SIGNAL(klass, ONLINE);
|
||||
NEW_SIGNAL(klass, SIM);
|
||||
NEW_SIGNAL(klass, SIM_STATE);
|
||||
NEW_SIGNAL(klass, ICCID);
|
||||
NEW_SIGNAL(klass, IMSI);
|
||||
NEW_SIGNAL(klass, SPN);
|
||||
NEW_SIGNAL(klass, NETREG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
50
ofono/unit/fake_watch.h
Normal file
50
ofono/unit/fake_watch.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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
|
||||
* 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 FAKE_WATCH_H
|
||||
#define FAKE_WATCH_H
|
||||
|
||||
#include <ofono/watch.h>
|
||||
|
||||
enum fake_watch_signal {
|
||||
FAKE_WATCH_SIGNAL_MODEM_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_ONLINE_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_SIM_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_ICCID_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_IMSI_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_SPN_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_NETREG_CHANGED,
|
||||
FAKE_WATCH_SIGNAL_COUNT
|
||||
};
|
||||
|
||||
void fake_watch_signal_queue(struct ofono_watch *w, enum fake_watch_signal id);
|
||||
void fake_watch_emit_queued_signals(struct ofono_watch *w);
|
||||
void fake_watch_set_ofono_sim(struct ofono_watch *w, struct ofono_sim *sim);
|
||||
void fake_watch_set_ofono_iccid(struct ofono_watch *w, const char *iccid);
|
||||
void fake_watch_set_ofono_imsi(struct ofono_watch *w, const char *imsi);
|
||||
void fake_watch_set_ofono_spn(struct ofono_watch *w, const char *spn);
|
||||
void fake_watch_set_ofono_netreg(struct ofono_watch *w,
|
||||
struct ofono_netreg *netreg);
|
||||
|
||||
#endif /* FAKE_WATCH_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
191
ofono/unit/test-dbus-access.c
Normal file
191
ofono/unit/test-dbus-access.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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 "ofono.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
static enum ofono_dbus_access dontcare_method_access(const char *sender,
|
||||
enum ofono_dbus_access_intf intf, int method, const char *arg)
|
||||
{
|
||||
return OFONO_DBUS_ACCESS_DONT_CARE;
|
||||
}
|
||||
static enum ofono_dbus_access allow_method_access(const char *sender,
|
||||
enum ofono_dbus_access_intf intf, int method, const char *arg)
|
||||
{
|
||||
return OFONO_DBUS_ACCESS_ALLOW;
|
||||
}
|
||||
static enum ofono_dbus_access deny_method_access(const char *sender,
|
||||
enum ofono_dbus_access_intf intf, int method, const char *arg)
|
||||
{
|
||||
return OFONO_DBUS_ACCESS_DENY;
|
||||
}
|
||||
|
||||
struct ofono_dbus_access_plugin access_inval;
|
||||
struct ofono_dbus_access_plugin access_dontcare = {
|
||||
.name = "DontCare",
|
||||
.priority = OFONO_DBUS_ACCESS_PRIORITY_LOW,
|
||||
.method_access = dontcare_method_access
|
||||
};
|
||||
struct ofono_dbus_access_plugin access_allow = {
|
||||
.name = "Allow",
|
||||
.priority = OFONO_DBUS_ACCESS_PRIORITY_DEFAULT,
|
||||
.method_access = allow_method_access
|
||||
};
|
||||
struct ofono_dbus_access_plugin access_deny = {
|
||||
.name = "Deny",
|
||||
.priority = OFONO_DBUS_ACCESS_PRIORITY_LOW,
|
||||
.method_access = deny_method_access
|
||||
};
|
||||
|
||||
/*==========================================================================*
|
||||
* Tests
|
||||
*==========================================================================*/
|
||||
|
||||
static void test_intf_name()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Valid interface ids must have names */
|
||||
for (i = 0; i < OFONO_DBUS_ACCESS_INTF_COUNT; i++) {
|
||||
g_assert(ofono_dbus_access_intf_name(i));
|
||||
}
|
||||
/* And the invalid ones must have no names */
|
||||
g_assert(!ofono_dbus_access_intf_name(-1));
|
||||
g_assert(!ofono_dbus_access_intf_name(i));
|
||||
/* An no method names too */
|
||||
g_assert(!ofono_dbus_access_method_name(-1, 0));
|
||||
g_assert(!ofono_dbus_access_method_name(i, 0));
|
||||
}
|
||||
|
||||
struct test_method_name_data {
|
||||
enum ofono_dbus_access_intf intf;
|
||||
int n_methods;
|
||||
};
|
||||
|
||||
static const struct test_method_name_data method_name_tests[] = {
|
||||
{
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGE,
|
||||
OFONO_DBUS_ACCESS_MESSAGE_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGEMGR,
|
||||
OFONO_DBUS_ACCESS_MESSAGEMGR_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALL,
|
||||
OFONO_DBUS_ACCESS_VOICECALL_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_CONNCTX,
|
||||
OFONO_DBUS_ACCESS_CONNCTX_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_CONNMGR,
|
||||
OFONO_DBUS_ACCESS_CONNMGR_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_SIMMGR,
|
||||
OFONO_DBUS_ACCESS_SIMMGR_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_MODEM,
|
||||
OFONO_DBUS_ACCESS_MODEM_METHOD_COUNT
|
||||
},{
|
||||
OFONO_DBUS_ACCESS_INTF_RADIOSETTINGS,
|
||||
OFONO_DBUS_ACCESS_RADIOSETTINGS_METHOD_COUNT
|
||||
}
|
||||
};
|
||||
|
||||
static void test_method_name(gconstpointer test_data)
|
||||
{
|
||||
const struct test_method_name_data *test = test_data;
|
||||
int i;
|
||||
|
||||
/* Valid method ids must have names */
|
||||
for (i = 0; i < test->n_methods; i++) {
|
||||
g_assert(ofono_dbus_access_method_name(test->intf, i));
|
||||
}
|
||||
/* And the invalid ones must have no names */
|
||||
g_assert(!ofono_dbus_access_method_name(test->intf, -1));
|
||||
g_assert(!ofono_dbus_access_method_name(test->intf, i));
|
||||
}
|
||||
|
||||
G_STATIC_ASSERT(G_N_ELEMENTS(method_name_tests)==OFONO_DBUS_ACCESS_INTF_COUNT);
|
||||
|
||||
static void test_register()
|
||||
{
|
||||
g_assert(ofono_dbus_access_plugin_register(NULL) == -EINVAL);
|
||||
g_assert(ofono_dbus_access_plugin_register(&access_inval) == -EINVAL);
|
||||
ofono_dbus_access_plugin_unregister(NULL);
|
||||
|
||||
/* Plugin won't be registered more than once */
|
||||
g_assert(!ofono_dbus_access_plugin_register(&access_deny));
|
||||
g_assert(ofono_dbus_access_plugin_register(&access_deny) == -EALREADY);
|
||||
|
||||
/* Allow has higher priority */
|
||||
g_assert(!ofono_dbus_access_plugin_register(&access_allow));
|
||||
g_assert(__ofono_dbus_access_method_allowed(":1.0", 0, 1, NULL));
|
||||
ofono_dbus_access_plugin_unregister(&access_deny);
|
||||
ofono_dbus_access_plugin_unregister(&access_allow);
|
||||
|
||||
/* Allow has higher priority */
|
||||
g_assert(!ofono_dbus_access_plugin_register(&access_allow));
|
||||
g_assert(!ofono_dbus_access_plugin_register(&access_deny));
|
||||
g_assert(__ofono_dbus_access_method_allowed(":1.0", 0, 1, NULL));
|
||||
ofono_dbus_access_plugin_unregister(&access_deny);
|
||||
ofono_dbus_access_plugin_unregister(&access_allow);
|
||||
|
||||
/* Deny wins here */
|
||||
g_assert(!ofono_dbus_access_plugin_register(&access_dontcare));
|
||||
g_assert(!ofono_dbus_access_plugin_register(&access_deny));
|
||||
g_assert(!__ofono_dbus_access_method_allowed(":1.0", 0, 1, NULL));
|
||||
ofono_dbus_access_plugin_unregister(&access_deny);
|
||||
ofono_dbus_access_plugin_unregister(&access_dontcare);
|
||||
|
||||
/* DontCare will allow everything */
|
||||
g_assert(!ofono_dbus_access_plugin_register(&access_dontcare));
|
||||
g_assert(__ofono_dbus_access_method_allowed(":1.0", 0, 1, NULL));
|
||||
ofono_dbus_access_plugin_unregister(&access_dontcare);
|
||||
}
|
||||
|
||||
#define TEST_(test) "/dbus-access/" test
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
__ofono_log_init("test-dbus-access", g_test_verbose() ? "*" : NULL,
|
||||
FALSE, FALSE);
|
||||
|
||||
g_test_add_func(TEST_("intf_name"), test_intf_name);
|
||||
for (i = 0; i < G_N_ELEMENTS(method_name_tests); i++) {
|
||||
char* name = g_strdup_printf(TEST_("method_name/%d"), i + 1);
|
||||
const struct test_method_name_data *test =
|
||||
method_name_tests + i;
|
||||
|
||||
g_test_add_data_func(name, test, test_method_name);
|
||||
g_free(name);
|
||||
}
|
||||
g_test_add_func(TEST_("register"), test_register);
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -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
|
||||
@@ -18,7 +18,11 @@
|
||||
#include "ofono.h"
|
||||
#include "common.h"
|
||||
|
||||
void test_parse_tech(void)
|
||||
#define RIL_PROTO_IP_STR "IP"
|
||||
#define RIL_PROTO_IPV6_STR "IPV6"
|
||||
#define RIL_PROTO_IPV4V6_STR "IPV4V6"
|
||||
|
||||
static void test_parse_tech(void)
|
||||
{
|
||||
int tech = 0;
|
||||
|
||||
@@ -51,7 +55,7 @@ void test_parse_tech(void)
|
||||
g_assert(tech == RADIO_TECH_LTE);
|
||||
}
|
||||
|
||||
void test_parse_mcc_mnc(void)
|
||||
static void test_parse_mcc_mnc(void)
|
||||
{
|
||||
struct ofono_network_operator op;
|
||||
|
||||
@@ -81,7 +85,45 @@ void test_parse_mcc_mnc(void)
|
||||
g_assert(!op.tech);
|
||||
}
|
||||
|
||||
void test_strings(void)
|
||||
static void test_protocol_from_ofono(void)
|
||||
{
|
||||
g_assert(!g_strcmp0(ril_protocol_from_ofono(OFONO_GPRS_PROTO_IP),
|
||||
RIL_PROTO_IP_STR));
|
||||
g_assert(!g_strcmp0(ril_protocol_from_ofono(OFONO_GPRS_PROTO_IPV6),
|
||||
RIL_PROTO_IPV6_STR));
|
||||
g_assert(!g_strcmp0(ril_protocol_from_ofono(OFONO_GPRS_PROTO_IPV4V6),
|
||||
RIL_PROTO_IPV4V6_STR));
|
||||
g_assert(!ril_protocol_from_ofono((enum ofono_gprs_proto)-1));
|
||||
}
|
||||
|
||||
static void test_protocol_to_ofono(void)
|
||||
{
|
||||
g_assert(ril_protocol_to_ofono(NULL) < 0);
|
||||
g_assert(ril_protocol_to_ofono("") < 0);
|
||||
g_assert(ril_protocol_to_ofono("ip") < 0);
|
||||
g_assert(ril_protocol_to_ofono(RIL_PROTO_IP_STR) ==
|
||||
OFONO_GPRS_PROTO_IP);
|
||||
g_assert(ril_protocol_to_ofono(RIL_PROTO_IPV6_STR) ==
|
||||
OFONO_GPRS_PROTO_IPV6);
|
||||
g_assert(ril_protocol_to_ofono(RIL_PROTO_IPV4V6_STR) ==
|
||||
OFONO_GPRS_PROTO_IPV4V6);
|
||||
}
|
||||
|
||||
static void test_auth_method(void)
|
||||
{
|
||||
g_assert(ril_auth_method_from_ofono(OFONO_GPRS_AUTH_METHOD_NONE) ==
|
||||
RIL_AUTH_NONE);
|
||||
g_assert(ril_auth_method_from_ofono(OFONO_GPRS_AUTH_METHOD_CHAP) ==
|
||||
RIL_AUTH_CHAP);
|
||||
g_assert(ril_auth_method_from_ofono(OFONO_GPRS_AUTH_METHOD_PAP) ==
|
||||
RIL_AUTH_PAP);
|
||||
g_assert(ril_auth_method_from_ofono(OFONO_GPRS_AUTH_METHOD_ANY) ==
|
||||
RIL_AUTH_BOTH);
|
||||
g_assert(ril_auth_method_from_ofono((enum ofono_gprs_auth_method)-1) ==
|
||||
RIL_AUTH_BOTH);
|
||||
}
|
||||
|
||||
static void test_strings(void)
|
||||
{
|
||||
g_assert(!g_strcmp0(ril_error_to_string(RIL_E_SUCCESS), "OK"));
|
||||
g_assert(!g_strcmp0(ril_error_to_string(2147483647), "2147483647"));
|
||||
@@ -107,6 +149,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
g_test_add_func(TEST_("parse_tech"), test_parse_tech);
|
||||
g_test_add_func(TEST_("parse_mcc_mnc"), test_parse_mcc_mnc);
|
||||
g_test_add_func(TEST_("protocol_from_ofono"), test_protocol_from_ofono);
|
||||
g_test_add_func(TEST_("protocol_to_ofono"), test_protocol_to_ofono);
|
||||
g_test_add_func(TEST_("auth_method"), test_auth_method);
|
||||
g_test_add_func(TEST_("strings"), test_strings);
|
||||
|
||||
return g_test_run();
|
||||
|
||||
394
ofono/unit/test-ril_vendor.c
Normal file
394
ofono/unit/test-ril_vendor.c
Normal file
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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
|
||||
* 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 "drivers/ril/ril_vendor.h"
|
||||
#include "drivers/ril/ril_vendor_impl.h"
|
||||
#include "drivers/ril/ril_network.h"
|
||||
#include "drivers/ril/ril_data.h"
|
||||
#include "drivers/ril/ril_log.h"
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
#include <grilio_request.h>
|
||||
#include <grilio_parser.h>
|
||||
|
||||
GLOG_MODULE_DEFINE("ril");
|
||||
|
||||
/* Stubs */
|
||||
typedef struct ril_network TestNetwork;
|
||||
typedef GObjectClass TestNetworkClass;
|
||||
static void test_network_init(TestNetwork *self) {}
|
||||
static void test_network_class_init(TestNetworkClass *klass) {}
|
||||
G_DEFINE_TYPE(TestNetwork, test_network, G_TYPE_OBJECT)
|
||||
|
||||
void ril_network_query_registration_state(struct ril_network *network)
|
||||
{
|
||||
}
|
||||
|
||||
const struct ofono_gprs_primary_context *ofono_gprs_context_settings_by_type
|
||||
(struct ofono_gprs *gprs, enum ofono_gprs_context_type type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Test vendor objects and drivers */
|
||||
|
||||
typedef RilVendor TestVendor;
|
||||
typedef RilVendorClass TestVendorClass;
|
||||
static void test_vendor_init(TestVendor *self) {}
|
||||
static void test_vendor_class_init(TestVendorClass* klass) {}
|
||||
static const struct ril_vendor_defaults test_defaults = { .enable_cbs = TRUE };
|
||||
G_DEFINE_TYPE(TestVendor, test_vendor, RIL_VENDOR_TYPE)
|
||||
|
||||
static void test_driver_get_defaults(struct ril_vendor_defaults *defaults)
|
||||
{
|
||||
memcpy(defaults, &test_defaults, sizeof(*defaults));
|
||||
}
|
||||
|
||||
static RilVendor *test_driver_create_vendor(const void *driver_data,
|
||||
GRilIoChannel *io, const char *path,
|
||||
const struct ril_slot_config *config)
|
||||
{
|
||||
TestVendor *self = g_object_new(test_vendor_get_type(), NULL);
|
||||
|
||||
ril_vendor_init_base(self, io);
|
||||
return self;
|
||||
}
|
||||
|
||||
RIL_VENDOR_DRIVER_DEFINE(test_driver) {
|
||||
.name = "test",
|
||||
.get_defaults = test_driver_get_defaults,
|
||||
.create_vendor = test_driver_create_vendor
|
||||
};
|
||||
|
||||
RIL_VENDOR_DRIVER_DEFINE(dummy_driver) { .name = "dummy" };
|
||||
|
||||
/* Tests */
|
||||
|
||||
static void test_null(void)
|
||||
{
|
||||
ril_vendor_unref(NULL);
|
||||
ril_vendor_set_network(NULL, NULL);
|
||||
ril_vendor_data_call_parse(NULL, NULL, 0, NULL);
|
||||
ril_vendor_get_defaults(NULL, NULL);
|
||||
g_assert(!ril_vendor_find_driver(NULL));
|
||||
g_assert(!ril_vendor_create(NULL, NULL, NULL, NULL));
|
||||
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,
|
||||
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)
|
||||
{
|
||||
const struct ril_vendor_driver *driver;
|
||||
struct ril_vendor_defaults defaults;
|
||||
|
||||
/* This one exists and has all the callbacks */
|
||||
driver = ril_vendor_find_driver(test_driver.name);
|
||||
g_assert(driver);
|
||||
memset(&defaults, 0, sizeof(defaults));
|
||||
ril_vendor_get_defaults(driver, &defaults);
|
||||
g_assert(!memcmp(&defaults, &test_defaults, sizeof(defaults)));
|
||||
|
||||
/* This one has no callbacks at all */
|
||||
driver = ril_vendor_find_driver(dummy_driver.name);
|
||||
g_assert(driver);
|
||||
memset(&defaults, 0, sizeof(defaults));
|
||||
g_assert(!ril_vendor_create(driver, NULL, NULL, NULL));
|
||||
ril_vendor_get_defaults(driver, &defaults);
|
||||
|
||||
/* And this one doesn't exist */
|
||||
g_assert(!ril_vendor_find_driver("no such driver"));
|
||||
}
|
||||
|
||||
static void test_base(void)
|
||||
{
|
||||
TestNetwork *network = g_object_new(test_network_get_type(), NULL);
|
||||
const struct ril_vendor_driver *driver;
|
||||
struct ril_vendor *base;
|
||||
|
||||
/* Create test vendor which does nothing but extends the base */
|
||||
driver = ril_vendor_find_driver(test_driver.name);
|
||||
g_assert(driver);
|
||||
base = ril_vendor_create(driver, NULL, NULL, NULL);
|
||||
ril_vendor_set_network(base, NULL);
|
||||
ril_vendor_set_network(base, network);
|
||||
ril_vendor_set_network(base, NULL);
|
||||
ril_vendor_set_network(base, network);
|
||||
|
||||
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,
|
||||
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);
|
||||
ril_vendor_unref(base);
|
||||
ril_vendor_unref(base);
|
||||
g_object_unref(network);
|
||||
}
|
||||
|
||||
static void test_mtk(void)
|
||||
{
|
||||
TestNetwork *network = g_object_new(test_network_get_type(), NULL);
|
||||
const struct ril_vendor_driver *driver = ril_vendor_find_driver("mtk");
|
||||
struct ril_vendor_defaults defaults;
|
||||
struct ril_slot_config config;
|
||||
struct ril_vendor *mtk;
|
||||
|
||||
g_assert(driver);
|
||||
memset(&defaults, 0, sizeof(defaults));
|
||||
memset(&config, 0, sizeof(config));
|
||||
ril_vendor_get_defaults(driver, &defaults);
|
||||
mtk = ril_vendor_create(driver, NULL, NULL, &config);
|
||||
g_assert(mtk);
|
||||
|
||||
/* Freeing the network clears vendor's weak pointer */
|
||||
ril_vendor_set_network(mtk, network);
|
||||
g_object_unref(network);
|
||||
g_assert(!ril_vendor_request_to_string(mtk, 0));
|
||||
g_assert(!ril_vendor_event_to_string(mtk, 0));
|
||||
ril_vendor_unref(mtk);
|
||||
}
|
||||
|
||||
static const char *MTK_RESUME_REGISTRATION="MTK_RESUME_REGISTRATION";
|
||||
static const char *MTK_SET_CALL_INDICATION="MTK_SET_CALL_INDICATION";
|
||||
static const char *MTK_PS_NETWORK_STATE_CHANGED="MTK_PS_NETWORK_STATE_CHANGED";
|
||||
static const char *MTK_REGISTRATION_SUSPENDED="MTK_REGISTRATION_SUSPENDED";
|
||||
static const char *MTK_SET_ATTACH_APN="MTK_SET_ATTACH_APN";
|
||||
static const char *MTK_INCOMING_CALL_INDICATION="MTK_INCOMING_CALL_INDICATION";
|
||||
|
||||
static void test_mtk1(void)
|
||||
{
|
||||
const struct ril_vendor_driver *driver = ril_vendor_find_driver("mtk1");
|
||||
struct ril_slot_config config;
|
||||
struct ril_vendor *mtk1;
|
||||
GRilIoRequest* req;
|
||||
|
||||
g_assert(driver);
|
||||
memset(&config, 0, sizeof(config));
|
||||
mtk1 = ril_vendor_create(driver, NULL, NULL, &config);
|
||||
g_assert(mtk1);
|
||||
|
||||
g_assert(!g_strcmp0(ril_vendor_request_to_string(mtk1, 2050),
|
||||
MTK_RESUME_REGISTRATION));
|
||||
g_assert(!g_strcmp0(ril_vendor_request_to_string(mtk1, 2065),
|
||||
MTK_SET_CALL_INDICATION));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk1, 3012),
|
||||
MTK_PS_NETWORK_STATE_CHANGED));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk1, 3021),
|
||||
MTK_REGISTRATION_SUSPENDED));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk1, 3065),
|
||||
MTK_SET_ATTACH_APN));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk1, 3037),
|
||||
MTK_INCOMING_CALL_INDICATION));
|
||||
|
||||
/* mtk1 doesn't parse data calls */
|
||||
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, "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, RIL_DATA_PROFILE_DEFAULT,
|
||||
"apn", "username", "password", RIL_AUTH_NONE, "IP");
|
||||
grilio_request_unref(req);
|
||||
|
||||
ril_vendor_unref(mtk1);
|
||||
}
|
||||
|
||||
static void test_mtk2(void)
|
||||
{
|
||||
static const guint8 noprot[] = {
|
||||
0x00, 0x00, 0x00, 0x00, /* status */
|
||||
0x00, 0x00, 0x00, 0x00, /* retry_time */
|
||||
0x00, 0x00, 0x00, 0x00, /* cid */
|
||||
0x02, 0x00, 0x00, 0x00, /* active */
|
||||
0x00, 0x05, 0x00, 0x00 /* mtu */
|
||||
};
|
||||
static const guint8 noifname[] = {
|
||||
0x00, 0x00, 0x00, 0x00, /* status */
|
||||
0x00, 0x00, 0x00, 0x00, /* retry_time */
|
||||
0x00, 0x00, 0x00, 0x00, /* cid */
|
||||
0x02, 0x00, 0x00, 0x00, /* active */
|
||||
0x00, 0x05, 0x00, 0x00, /* mtu */
|
||||
/* "IP" */
|
||||
0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static const guint8 noaddr[] = {
|
||||
0x00, 0x00, 0x00, 0x00, /* status */
|
||||
0x00, 0x00, 0x00, 0x00, /* retry_time */
|
||||
0x00, 0x00, 0x00, 0x00, /* cid */
|
||||
0x02, 0x00, 0x00, 0x00, /* active */
|
||||
0x00, 0x05, 0x00, 0x00, /* mtu */
|
||||
/* "IP" */
|
||||
0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
/* "ccmni0" */
|
||||
0x06, 0x00, 0x00, 0x00, 0x63, 0x00, 0x63, 0x00,
|
||||
0x6d, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static const guint8 datacall[] = {
|
||||
0x00, 0x00, 0x00, 0x00, /* status */
|
||||
0x00, 0x00, 0x00, 0x00, /* retry_time */
|
||||
0x00, 0x00, 0x00, 0x00, /* cid */
|
||||
0x02, 0x00, 0x00, 0x00, /* active */
|
||||
0x00, 0x05, 0x00, 0x00, /* mtu */
|
||||
/* "IP" */
|
||||
0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
/* "ccmni0" */
|
||||
0x06, 0x00, 0x00, 0x00, 0x63, 0x00, 0x63, 0x00,
|
||||
0x6d, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
/* "10.236.123.155" */
|
||||
0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
|
||||
0x2e, 0x00, 0x32, 0x00, 0x33, 0x00, 0x36, 0x00,
|
||||
0x2e, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00,
|
||||
0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x35, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
/* "217.118.66.243 217.118.66.244" */
|
||||
0x1d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x31, 0x00,
|
||||
0x37, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x31, 0x00,
|
||||
0x38, 0x00, 0x2e, 0x00, 0x36, 0x00, 0x36, 0x00,
|
||||
0x2e, 0x00, 0x32, 0x00, 0x34, 0x00, 0x33, 0x00,
|
||||
0x20, 0x00, 0x32, 0x00, 0x31, 0x00, 0x37, 0x00,
|
||||
0x2e, 0x00, 0x31, 0x00, 0x31, 0x00, 0x38, 0x00,
|
||||
0x2e, 0x00, 0x36, 0x00, 0x36, 0x00, 0x2e, 0x00,
|
||||
0x32, 0x00, 0x34, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
/* "10.236.123.155" */
|
||||
0x0e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00,
|
||||
0x2e, 0x00, 0x32, 0x00, 0x33, 0x00, 0x36, 0x00,
|
||||
0x2e, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00,
|
||||
0x2e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x35, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
/* whatever... */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const struct ril_vendor_driver *driver = ril_vendor_find_driver("mtk2");
|
||||
struct ril_slot_config config;
|
||||
struct ril_data_call call;
|
||||
struct ril_vendor *mtk2;
|
||||
GRilIoParser rilp;
|
||||
GRilIoRequest* req;
|
||||
|
||||
g_assert(driver);
|
||||
memset(&config, 0, sizeof(config));
|
||||
mtk2 = ril_vendor_create(driver, NULL, NULL, &config);
|
||||
g_assert(mtk2);
|
||||
|
||||
g_assert(!g_strcmp0(ril_vendor_request_to_string(mtk2, 2065),
|
||||
MTK_RESUME_REGISTRATION));
|
||||
g_assert(!g_strcmp0(ril_vendor_request_to_string(mtk2, 2086),
|
||||
MTK_SET_CALL_INDICATION));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk2, 3015),
|
||||
MTK_PS_NETWORK_STATE_CHANGED));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk2, 3024),
|
||||
MTK_REGISTRATION_SUSPENDED));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk2, 3073),
|
||||
MTK_SET_ATTACH_APN));
|
||||
g_assert(!g_strcmp0(ril_vendor_event_to_string(mtk2, 3042),
|
||||
MTK_INCOMING_CALL_INDICATION));
|
||||
|
||||
/* Build RIL_REQUEST_SET_INITIAL_ATTACH_APN */
|
||||
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, RIL_DATA_PROFILE_DEFAULT,
|
||||
"apn", "username", "password", RIL_AUTH_NONE, "IP");
|
||||
grilio_request_unref(req);
|
||||
|
||||
/* Parse data call (version < 11) */
|
||||
memset(&call, 0, sizeof(call));
|
||||
memset(&rilp, 0, sizeof(rilp));
|
||||
g_assert(!ril_vendor_data_call_parse(mtk2, &call, 11, &rilp));
|
||||
|
||||
memset(&call, 0, sizeof(call));
|
||||
grilio_parser_init(&rilp, noprot, sizeof(noprot));
|
||||
g_assert(!ril_vendor_data_call_parse(mtk2, &call, 10, &rilp));
|
||||
|
||||
memset(&call, 0, sizeof(call));
|
||||
grilio_parser_init(&rilp, noifname, sizeof(noifname));
|
||||
g_assert(!ril_vendor_data_call_parse(mtk2, &call, 10, &rilp));
|
||||
|
||||
memset(&call, 0, sizeof(call));
|
||||
grilio_parser_init(&rilp, noaddr, sizeof(noaddr));
|
||||
g_assert(!ril_vendor_data_call_parse(mtk2, &call, 10, &rilp));
|
||||
g_free(call.ifname);
|
||||
|
||||
grilio_parser_init(&rilp, datacall, sizeof(datacall));
|
||||
g_assert(ril_vendor_data_call_parse(mtk2, &call, 10, &rilp));
|
||||
g_assert(call.active == RIL_DATA_CALL_ACTIVE);
|
||||
g_assert(call.mtu == 1280);
|
||||
g_assert(call.prot == OFONO_GPRS_PROTO_IP);
|
||||
g_assert(!g_strcmp0(call.ifname, "ccmni0"));
|
||||
g_assert(!g_strcmp0(call.dnses[0], "217.118.66.243"));
|
||||
g_assert(!g_strcmp0(call.dnses[1], "217.118.66.244"));
|
||||
g_assert(!call.dnses[2]);
|
||||
g_assert(!g_strcmp0(call.gateways[0], "10.236.123.155"));
|
||||
g_assert(!call.gateways[1]);
|
||||
g_assert(!g_strcmp0(call.addresses[0], "10.236.123.155"));
|
||||
g_assert(!call.addresses[1]);
|
||||
g_free(call.ifname);
|
||||
g_strfreev(call.dnses);
|
||||
g_strfreev(call.gateways);
|
||||
g_strfreev(call.addresses);
|
||||
|
||||
ril_vendor_unref(mtk2);
|
||||
}
|
||||
|
||||
#define TEST_(name) "/ril_vendor/" name
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
__ofono_log_init("test-ril_vendor",
|
||||
g_test_verbose() ? "*" : NULL,
|
||||
FALSE, FALSE);
|
||||
|
||||
g_test_add_func(TEST_("null"), test_null);
|
||||
g_test_add_func(TEST_("drivers"), test_drivers);
|
||||
g_test_add_func(TEST_("base"), test_base);
|
||||
g_test_add_func(TEST_("mtk"), test_mtk);
|
||||
g_test_add_func(TEST_("mtk1"), test_mtk1);
|
||||
g_test_add_func(TEST_("mtk2"), test_mtk2);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
302
ofono/unit/test-sailfish_access.c
Normal file
302
ofono/unit/test-sailfish_access.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* 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 "ofono.h"
|
||||
|
||||
#include <dbusaccess_peer.h>
|
||||
#include <dbusaccess_policy.h>
|
||||
#include <dbusaccess_system.h>
|
||||
|
||||
#include <gutil_idlepool.h>
|
||||
#include <gutil_log.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
static GUtilIdlePool* peer_pool;
|
||||
|
||||
extern struct ofono_plugin_desc __ofono_builtin_sailfish_access;
|
||||
extern const char *sailfish_access_config_file;
|
||||
|
||||
#define TMP_DIR_TEMPLATE "test-sailfish_access-XXXXXX"
|
||||
|
||||
#define ROOT_SENDER ":1.100"
|
||||
#define PRIVILEGED_SENDER ":1.200"
|
||||
#define NON_PRIVILEGED_SENDER ":1.300"
|
||||
#define INVALID_SENDER ":1.400"
|
||||
|
||||
#define NEMO_UID (100000)
|
||||
#define NEMO_GID (100000)
|
||||
#define PRIVILEGED_GID (996)
|
||||
#define SAILFISH_RADIO_GID (997)
|
||||
|
||||
/*==========================================================================*
|
||||
* Stubs
|
||||
*==========================================================================*/
|
||||
|
||||
DAPeer *da_peer_get(DA_BUS bus, const char *name)
|
||||
{
|
||||
if (name && g_strcmp0(name, INVALID_SENDER)) {
|
||||
gsize len = strlen(name);
|
||||
DAPeer *peer = g_malloc0(sizeof(DAPeer) + len + 1);
|
||||
char *buf = (char*)(peer + 1);
|
||||
strcpy(buf, name);
|
||||
peer->name = buf;
|
||||
gutil_idle_pool_add(peer_pool, peer, g_free);
|
||||
if (!strcmp(name, PRIVILEGED_SENDER)) {
|
||||
peer->cred.euid = NEMO_UID;
|
||||
peer->cred.egid = PRIVILEGED_GID;
|
||||
} else if (strcmp(name, ROOT_SENDER)) {
|
||||
peer->cred.euid = NEMO_UID;
|
||||
peer->cred.egid = NEMO_GID;
|
||||
}
|
||||
return peer;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void da_peer_flush(DA_BUS bus, const char *name)
|
||||
{
|
||||
gutil_idle_pool_drain(peer_pool);
|
||||
}
|
||||
|
||||
/*
|
||||
* The build environment doesn't necessarily have these users and groups.
|
||||
* And yet, sailfish access plugin depends on those.
|
||||
*/
|
||||
|
||||
int da_system_uid(const char *user)
|
||||
{
|
||||
if (!g_strcmp0(user, "nemo")) {
|
||||
return NEMO_UID;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int da_system_gid(const char *group)
|
||||
{
|
||||
if (!g_strcmp0(group, "sailfish-radio")) {
|
||||
return SAILFISH_RADIO_GID;
|
||||
} else if (!g_strcmp0(group, "privileged")) {
|
||||
return PRIVILEGED_GID;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Tests
|
||||
*==========================================================================*/
|
||||
|
||||
static void test_register()
|
||||
{
|
||||
g_assert(__ofono_builtin_sailfish_access.init() == 0);
|
||||
g_assert(__ofono_builtin_sailfish_access.init() == -EALREADY);
|
||||
__ofono_builtin_sailfish_access.exit();
|
||||
__ofono_builtin_sailfish_access.exit();
|
||||
}
|
||||
|
||||
static void test_default()
|
||||
{
|
||||
const char *default_config_file = sailfish_access_config_file;
|
||||
|
||||
sailfish_access_config_file = "/no such file";
|
||||
g_assert(__ofono_builtin_sailfish_access.init() == 0);
|
||||
|
||||
/* root and privileged are allowed to Dial by default */
|
||||
g_assert(__ofono_dbus_access_method_allowed(ROOT_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL, NULL));
|
||||
g_assert(__ofono_dbus_access_method_allowed(PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL, NULL));
|
||||
|
||||
/* Non-privileged and unknown users are not */
|
||||
g_assert(!__ofono_dbus_access_method_allowed(NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL, NULL));
|
||||
g_assert(!__ofono_dbus_access_method_allowed(INVALID_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL, NULL));
|
||||
|
||||
/* Unknown interfaces/methods are allowed */
|
||||
g_assert(__ofono_dbus_access_method_allowed(NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_COUNT, 0, NULL));
|
||||
g_assert(__ofono_dbus_access_method_allowed(NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGE, -1, NULL));
|
||||
g_assert(__ofono_dbus_access_method_allowed(NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_MESSAGE,
|
||||
OFONO_DBUS_ACCESS_MESSAGE_METHOD_COUNT, NULL));
|
||||
|
||||
__ofono_builtin_sailfish_access.exit();
|
||||
|
||||
/* Restore the defaults */
|
||||
sailfish_access_config_file = default_config_file;
|
||||
}
|
||||
|
||||
struct test_config_data {
|
||||
gboolean allowed;
|
||||
const char *sender;
|
||||
enum ofono_dbus_access_intf intf;
|
||||
int method;
|
||||
const char *config;
|
||||
};
|
||||
|
||||
static const struct test_config_data config_tests [] = {
|
||||
{
|
||||
TRUE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALL,
|
||||
OFONO_DBUS_ACCESS_VOICECALL_HANGUP,
|
||||
"[org.ofono.VoiceCall]\n"
|
||||
"Hangup = " DA_POLICY_VERSION "; * = allow \n"
|
||||
},{
|
||||
FALSE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALL,
|
||||
OFONO_DBUS_ACCESS_VOICECALL_HANGUP,
|
||||
"[org.ofono.VoiceCall]\n"
|
||||
"Hangup = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"=========" /* Invalid key file */
|
||||
},{
|
||||
FALSE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL,
|
||||
"[Common]\n"
|
||||
"DefaultAccess = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"Dial = " DA_POLICY_VERSION "; * = deny\n"
|
||||
"group(privileged) = allow\n"
|
||||
},{
|
||||
TRUE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_TRANSFER,
|
||||
"[Common]\n"
|
||||
"DefaultAccess = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"Dial = " DA_POLICY_VERSION "; * = deny; "
|
||||
"group(privileged) = allow \n"
|
||||
},{
|
||||
TRUE, PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL,
|
||||
"[Common]\n"
|
||||
"DefaultAccess = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"Dial = " DA_POLICY_VERSION "; * = deny; "
|
||||
"group(privileged) = allow \n"
|
||||
},{
|
||||
TRUE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL,
|
||||
"[Common]\n"
|
||||
"DefaultAccess = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"* = invalid"
|
||||
},{
|
||||
FALSE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL,
|
||||
"[Common]\n"
|
||||
"DefaultAccess = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"* = " DA_POLICY_VERSION "; * = deny \n" /* <= Applied */
|
||||
},{
|
||||
TRUE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALL,
|
||||
OFONO_DBUS_ACCESS_VOICECALL_HANGUP,
|
||||
"[Common]\n" /* DefaultAccess gets applied */
|
||||
"DefaultAccess = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"* = " DA_POLICY_VERSION "; * = deny \n"
|
||||
},{
|
||||
TRUE, NON_PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL,
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"* = " DA_POLICY_VERSION "; * = allow \n" /* <= Applied */
|
||||
"Dial = invalid \n"
|
||||
},{
|
||||
FALSE, PRIVILEGED_SENDER,
|
||||
OFONO_DBUS_ACCESS_INTF_VOICECALLMGR,
|
||||
OFONO_DBUS_ACCESS_VOICECALLMGR_DIAL,
|
||||
"[org.ofono.VoiceCallManager]\n"
|
||||
"* = " DA_POLICY_VERSION "; * = allow \n"
|
||||
"Dial = " DA_POLICY_VERSION "; * = deny \n" /* <= Applied */
|
||||
}
|
||||
};
|
||||
|
||||
static void test_config(gconstpointer test_data)
|
||||
{
|
||||
const struct test_config_data *test = test_data;
|
||||
const char *default_config_file = sailfish_access_config_file;
|
||||
char *dir = g_dir_make_tmp(TMP_DIR_TEMPLATE, NULL);
|
||||
char *file = g_strconcat(dir, "/test.conf", NULL);
|
||||
|
||||
/* Write temporary config file */
|
||||
sailfish_access_config_file = file;
|
||||
g_assert(g_file_set_contents(file, test->config, -1, NULL));
|
||||
|
||||
g_assert(__ofono_builtin_sailfish_access.init() == 0);
|
||||
g_assert(__ofono_dbus_access_method_allowed(test->sender,
|
||||
test->intf, test->method, NULL) == test->allowed);
|
||||
__ofono_builtin_sailfish_access.exit();
|
||||
|
||||
/* Restore the defaults */
|
||||
sailfish_access_config_file = default_config_file;
|
||||
|
||||
remove(file);
|
||||
remove(dir);
|
||||
|
||||
g_free(file);
|
||||
g_free(dir);
|
||||
}
|
||||
|
||||
#define TEST_(test) "/sailfish_access/" test
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
peer_pool = gutil_idle_pool_new();
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
gutil_log_timestamp = FALSE;
|
||||
gutil_log_default.level = g_test_verbose() ?
|
||||
GLOG_LEVEL_VERBOSE : GLOG_LEVEL_NONE;
|
||||
__ofono_log_init("test-sailfish_access",
|
||||
g_test_verbose() ? "*" : NULL,
|
||||
FALSE, FALSE);
|
||||
|
||||
g_test_add_func(TEST_("register"), test_register);
|
||||
g_test_add_func(TEST_("default"), test_default);
|
||||
for (i = 0; i < G_N_ELEMENTS(config_tests); i++) {
|
||||
char* name = g_strdup_printf(TEST_("config/%d"), i + 1);
|
||||
const struct test_config_data *test = config_tests + i;
|
||||
|
||||
g_test_add_data_func(name, test, test_config);
|
||||
g_free(name);
|
||||
}
|
||||
ret = g_test_run();
|
||||
gutil_idle_pool_unref(peer_pool);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -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 ==== */
|
||||
|
||||
@@ -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
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "sailfish_sim_info.h"
|
||||
#include "sailfish_manager_dbus.h"
|
||||
#include "fake_sailfish_watch.h"
|
||||
#include "fake_watch.h"
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include "ofono.h"
|
||||
@@ -610,7 +610,7 @@ static gboolean test_sync_start_done(gpointer user_data)
|
||||
{
|
||||
test_slot_manager *sm = user_data;
|
||||
test_slot *s = sm->slot;
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct sailfish_manager *m = fake_sailfish_manager_dbus.m;
|
||||
struct ofono_modem modem;
|
||||
char **slots;
|
||||
@@ -625,18 +625,18 @@ static gboolean test_sync_start_done(gpointer user_data)
|
||||
memset(&modem, 0, sizeof(modem));
|
||||
w->modem = &modem;
|
||||
w->online = TRUE;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
sailfish_manager_set_cell_info(s->handle, NULL);
|
||||
sailfish_manager_set_cell_info(s->handle, &fake_sailfish_cell_info);
|
||||
|
||||
w->modem = NULL;
|
||||
w->online = FALSE;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
sailfish_manager_set_cell_info(s->handle, NULL);
|
||||
g_assert(!fake_sailfish_cell_info_ref_count);
|
||||
@@ -708,7 +708,7 @@ static gboolean test_sync_start_done(gpointer user_data)
|
||||
fake_sailfish_manager_dbus.fn_block_changed =
|
||||
test_quit_loop_when_unblocked;
|
||||
|
||||
sailfish_watch_unref(w);
|
||||
ofono_watch_unref(w);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@@ -885,7 +885,7 @@ static gboolean test_voice_sim_done(gpointer user_data)
|
||||
test_slot_manager *sm = user_data;
|
||||
test_slot *s = sm->slot;
|
||||
struct sailfish_manager *m = fake_sailfish_manager_dbus.m;
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct ofono_sim sim;
|
||||
|
||||
memset(&sim, 0, sizeof(sim));
|
||||
@@ -899,10 +899,10 @@ static gboolean test_voice_sim_done(gpointer user_data)
|
||||
g_assert(!m->default_voice_path);
|
||||
|
||||
/* Once IMSI is known, default voice modem will point to this slot */
|
||||
fake_sailfish_watch_set_ofono_sim(w, &sim);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_sim(w, &sim);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
g_assert(!m->default_voice_imsi);
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH));
|
||||
@@ -919,16 +919,16 @@ static gboolean test_voice_sim_done(gpointer user_data)
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH));
|
||||
|
||||
/* Remove the SIM */
|
||||
fake_sailfish_watch_set_ofono_iccid(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_spn(w, NULL);
|
||||
fake_watch_set_ofono_iccid(w, NULL);
|
||||
fake_watch_set_ofono_imsi(w, NULL);
|
||||
fake_watch_set_ofono_spn(w, NULL);
|
||||
sailfish_manager_set_sim_state(s->handle, SAILFISH_SIM_STATE_ABSENT);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!m->slots[0]->sim_present);
|
||||
g_assert(!g_strcmp0(m->default_voice_imsi, TEST_IMSI));
|
||||
g_assert(!m->default_voice_path);
|
||||
|
||||
sailfish_watch_unref(w);
|
||||
ofono_watch_unref(w);
|
||||
g_main_loop_quit(test_loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -977,7 +977,7 @@ static gboolean test_data_sim_done(gpointer user_data)
|
||||
test_slot_manager *sm = user_data;
|
||||
test_slot *s = sm->slot;
|
||||
struct sailfish_manager *m = fake_sailfish_manager_dbus.m;
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct ofono_modem modem;
|
||||
struct ofono_sim sim;
|
||||
|
||||
@@ -995,10 +995,10 @@ static gboolean test_data_sim_done(gpointer user_data)
|
||||
g_assert(!m->default_data_path);
|
||||
|
||||
/* Once IMSI is known, default voice modem will point to this slot */
|
||||
fake_sailfish_watch_set_ofono_sim(w, &sim);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_sim(w, &sim);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH));
|
||||
g_assert(!m->default_data_path); /* No default data slot */
|
||||
@@ -1011,9 +1011,9 @@ static gboolean test_data_sim_done(gpointer user_data)
|
||||
/* Set modem online */
|
||||
w->modem = &modem;
|
||||
w->online = TRUE;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
/* Now is should point to our slot */
|
||||
g_assert(!g_strcmp0(m->default_data_path, TEST_PATH));
|
||||
|
||||
@@ -1023,19 +1023,19 @@ static gboolean test_data_sim_done(gpointer user_data)
|
||||
g_assert(!m->default_data_path);
|
||||
|
||||
/* Switch the SIM */
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI_1);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI_1);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(m->default_data_path, TEST_PATH));
|
||||
|
||||
/* Remove the SIM */
|
||||
fake_sailfish_watch_set_ofono_sim(w, NULL);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_sim(w, NULL);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
sailfish_manager_set_sim_state(s->handle, SAILFISH_SIM_STATE_ABSENT);
|
||||
g_assert(!m->slots[0]->sim_present);
|
||||
g_assert(!g_strcmp0(m->default_data_imsi, TEST_IMSI_1));
|
||||
g_assert(!m->default_data_path);
|
||||
|
||||
sailfish_watch_unref(w);
|
||||
ofono_watch_unref(w);
|
||||
g_main_loop_quit(test_loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -1085,7 +1085,7 @@ static gboolean test_mms_sim_done(gpointer user_data)
|
||||
test_slot_manager *sm = user_data;
|
||||
test_slot *s = sm->slot;
|
||||
struct sailfish_manager *m = fake_sailfish_manager_dbus.m;
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct ofono_modem modem;
|
||||
struct ofono_sim sim;
|
||||
|
||||
@@ -1107,12 +1107,12 @@ static gboolean test_mms_sim_done(gpointer user_data)
|
||||
/* Make the test slot the default data modem */
|
||||
w->modem = &modem;
|
||||
w->online = TRUE;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_sim(w, &sim);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_watch_set_ofono_sim(w, &sim);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
/* Data SIM gets automatically selected on a single-SIM phone */
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH));
|
||||
@@ -1151,7 +1151,7 @@ static gboolean test_mms_sim_done(gpointer user_data)
|
||||
g_assert(!m->mms_imsi);
|
||||
g_assert(!m->mms_path);
|
||||
|
||||
sailfish_watch_unref(w);
|
||||
ofono_watch_unref(w);
|
||||
g_main_loop_quit(test_loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -1203,8 +1203,8 @@ static gboolean test_multisim_done(gpointer user_data)
|
||||
test_slot *s = sm->slot;
|
||||
test_slot *s2 = sm->slot2;
|
||||
struct sailfish_manager *m = fake_sailfish_manager_dbus.m;
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct sailfish_watch *w2 = sailfish_watch_new(TEST_PATH_1);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w2 = ofono_watch_new(TEST_PATH_1);
|
||||
struct ofono_modem modem;
|
||||
struct ofono_sim sim;
|
||||
struct ofono_sim sim2;
|
||||
@@ -1219,21 +1219,21 @@ static gboolean test_multisim_done(gpointer user_data)
|
||||
/* Assign IMSI to the SIMs */
|
||||
w->modem = &modem;
|
||||
w->online = TRUE;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_sim(w, &sim);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_watch_set_ofono_sim(w, &sim);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
w2->modem = &modem;
|
||||
w2->online = TRUE;
|
||||
fake_sailfish_watch_signal_queue(w2, WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w2, WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_sim(w2, &sim2);
|
||||
fake_sailfish_watch_set_ofono_iccid(w2, TEST_ICCID_1);
|
||||
fake_sailfish_watch_set_ofono_imsi(w2, TEST_IMSI_1);
|
||||
fake_sailfish_watch_emit_queued_signals(w2);
|
||||
fake_watch_signal_queue(w2, FAKE_WATCH_SIGNAL_ONLINE_CHANGED);
|
||||
fake_watch_signal_queue(w2, FAKE_WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_watch_set_ofono_sim(w2, &sim2);
|
||||
fake_watch_set_ofono_iccid(w2, TEST_ICCID_1);
|
||||
fake_watch_set_ofono_imsi(w2, TEST_IMSI_1);
|
||||
fake_watch_emit_queued_signals(w2);
|
||||
|
||||
/* No automatic data SIM selection on a multisim phone */
|
||||
g_assert(s->data_role == SAILFISH_DATA_ROLE_NONE);
|
||||
@@ -1284,8 +1284,8 @@ static gboolean test_multisim_done(gpointer user_data)
|
||||
g_assert(!m->mms_path);
|
||||
g_assert(!m->mms_imsi);
|
||||
|
||||
sailfish_watch_unref(w);
|
||||
sailfish_watch_unref(w2);
|
||||
ofono_watch_unref(w);
|
||||
ofono_watch_unref(w2);
|
||||
g_main_loop_quit(test_loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -1351,8 +1351,8 @@ static void test_multisim(void)
|
||||
|
||||
static void test_storage_init(test_slot_manager *sm)
|
||||
{
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct sailfish_watch *w2 = sailfish_watch_new(TEST_PATH_1);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w2 = ofono_watch_new(TEST_PATH_1);
|
||||
struct ofono_sim sim;
|
||||
struct ofono_sim sim2;
|
||||
|
||||
@@ -1363,18 +1363,18 @@ static void test_storage_init(test_slot_manager *sm)
|
||||
sim2 = sim;
|
||||
|
||||
/* Assign IMSI to the SIMs */
|
||||
fake_sailfish_watch_set_ofono_sim(w, &sim);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_sim(w, &sim);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
fake_sailfish_watch_set_ofono_sim(w2, &sim2);
|
||||
fake_sailfish_watch_set_ofono_iccid(w2, TEST_ICCID_1);
|
||||
fake_sailfish_watch_set_ofono_imsi(w2, TEST_IMSI_1);
|
||||
fake_sailfish_watch_emit_queued_signals(w2);
|
||||
fake_watch_set_ofono_sim(w2, &sim2);
|
||||
fake_watch_set_ofono_iccid(w2, TEST_ICCID_1);
|
||||
fake_watch_set_ofono_imsi(w2, TEST_IMSI_1);
|
||||
fake_watch_emit_queued_signals(w2);
|
||||
|
||||
sailfish_watch_unref(w);
|
||||
sailfish_watch_unref(w2);
|
||||
ofono_watch_unref(w);
|
||||
ofono_watch_unref(w2);
|
||||
}
|
||||
|
||||
static void test_storage_add_slots(test_slot_manager *sm)
|
||||
|
||||
@@ -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
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "sailfish_sim_info.h"
|
||||
#include "fake_sailfish_watch.h"
|
||||
#include "fake_watch.h"
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include "ofono.h"
|
||||
@@ -173,17 +173,17 @@ static void netreg_notify_status_watches(struct ofono_netreg *netreg)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_remove_sim(struct ofono_sim* sim, struct sailfish_watch *watch)
|
||||
static void test_remove_sim(struct ofono_sim* sim, struct ofono_watch *watch)
|
||||
{
|
||||
sim->mcc = NULL;
|
||||
sim->mnc = NULL;
|
||||
sim->state = OFONO_SIM_STATE_NOT_PRESENT;
|
||||
fake_sailfish_watch_signal_queue(watch, WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(watch, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(watch, NULL);
|
||||
fake_sailfish_watch_set_ofono_imsi(watch, NULL);
|
||||
fake_sailfish_watch_set_ofono_spn(watch, NULL);
|
||||
fake_sailfish_watch_emit_queued_signals(watch);
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_set_ofono_iccid(watch, NULL);
|
||||
fake_watch_set_ofono_imsi(watch, NULL);
|
||||
fake_watch_set_ofono_spn(watch, NULL);
|
||||
fake_watch_emit_queued_signals(watch);
|
||||
}
|
||||
|
||||
/* Test cases */
|
||||
@@ -222,7 +222,7 @@ static void test_signal_count_cb(struct sailfish_sim_info *si, void *data)
|
||||
static void test_cache(void)
|
||||
{
|
||||
struct sailfish_sim_info *si;
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct ofono_sim sim;
|
||||
struct stat st;
|
||||
gulong id[SIM_INFO_SIGNAL_COUNT];
|
||||
@@ -248,8 +248,8 @@ static void test_cache(void)
|
||||
test_signal_count_cb, count +
|
||||
SIM_INFO_SIGNAL_SPN_CHANGED);
|
||||
|
||||
fake_sailfish_watch_set_ofono_sim(w, &sim);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_sim(w, &sim);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
@@ -257,8 +257,8 @@ static void test_cache(void)
|
||||
g_assert(!si->imsi);
|
||||
g_assert(!si->spn);
|
||||
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->iccid, TEST_ICCID));
|
||||
g_assert(count[SIM_INFO_SIGNAL_ICCID_CHANGED] == 1);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
@@ -266,8 +266,8 @@ static void test_cache(void)
|
||||
g_assert(stat(ICCID_MAP, &st) < 0);
|
||||
count[SIM_INFO_SIGNAL_ICCID_CHANGED] = 0;
|
||||
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->imsi, TEST_IMSI));
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
@@ -283,9 +283,9 @@ static void test_cache(void)
|
||||
sim.mcc = TEST_MCC;
|
||||
sim.mnc = TEST_MNC;
|
||||
sim.state = OFONO_SIM_STATE_READY;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->spn, TEST_DEFAULT_SPN));
|
||||
g_assert(count[SIM_INFO_SIGNAL_SPN_CHANGED] == 1);
|
||||
count[SIM_INFO_SIGNAL_SPN_CHANGED] = 0;
|
||||
@@ -301,8 +301,8 @@ static void test_cache(void)
|
||||
memset(count, 0, sizeof(count));
|
||||
|
||||
sim.state = OFONO_SIM_STATE_INSERTED;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
@@ -310,9 +310,9 @@ static void test_cache(void)
|
||||
sim.mcc = TEST_MCC;
|
||||
sim.mnc = TEST_MNC;
|
||||
sim.state = OFONO_SIM_STATE_READY;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
/* IMSI gets loaded from the cache file */
|
||||
g_assert(!g_strcmp0(si->iccid, TEST_ICCID));
|
||||
@@ -324,8 +324,8 @@ static void test_cache(void)
|
||||
memset(count, 0, sizeof(count));
|
||||
|
||||
/* Replace default SPN with the real one */
|
||||
fake_sailfish_watch_set_ofono_spn(w, TEST_SPN);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_spn(w, TEST_SPN);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->spn, TEST_SPN));
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
@@ -336,19 +336,19 @@ static void test_cache(void)
|
||||
g_assert(S_ISREG(st.st_mode));
|
||||
|
||||
/* Stray events have no effect */
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SPN_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ICCID_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SPN_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_ICCID_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
|
||||
/* Empty SPN and IMSI are ignored too */
|
||||
fake_sailfish_watch_set_ofono_imsi(w, "");
|
||||
fake_sailfish_watch_set_ofono_spn(w, "");
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_imsi(w, "");
|
||||
fake_watch_set_ofono_spn(w, "");
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
@@ -367,10 +367,10 @@ static void test_cache(void)
|
||||
sim.mcc = NULL;
|
||||
sim.mnc = NULL;
|
||||
sim.state = OFONO_SIM_STATE_INSERTED;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ICCID_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_ICCID_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->iccid, TEST_ICCID));
|
||||
g_assert(!g_strcmp0(si->imsi, TEST_IMSI));
|
||||
g_assert(!g_strcmp0(si->spn, TEST_SPN));
|
||||
@@ -390,8 +390,8 @@ static void test_cache(void)
|
||||
memset(count, 0, sizeof(count));
|
||||
|
||||
sim.state = OFONO_SIM_STATE_INSERTED;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
@@ -399,11 +399,11 @@ static void test_cache(void)
|
||||
sim.mcc = TEST_MCC;
|
||||
sim.mnc = TEST_MNC;
|
||||
sim.state = OFONO_SIM_STATE_READY;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID_1);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI_1);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID_1);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI_1);
|
||||
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->iccid, TEST_ICCID_1));
|
||||
g_assert(!g_strcmp0(si->imsi, TEST_IMSI_1));
|
||||
g_assert(!g_strcmp0(si->spn, TEST_DEFAULT_SPN));
|
||||
@@ -417,17 +417,17 @@ static void test_cache(void)
|
||||
memset(count, 0, sizeof(count));
|
||||
|
||||
sim.state = OFONO_SIM_STATE_INSERTED;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
sim.mcc = TEST_MCC;
|
||||
sim.mnc = TEST_MNC;
|
||||
sim.state = OFONO_SIM_STATE_READY;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->iccid, TEST_ICCID));
|
||||
g_assert(!g_strcmp0(si->imsi, TEST_IMSI));
|
||||
g_assert(!g_strcmp0(si->spn, TEST_SPN));
|
||||
@@ -442,12 +442,12 @@ static void test_cache(void)
|
||||
sim.mcc = NULL;
|
||||
sim.mnc = NULL;
|
||||
sim.state = OFONO_SIM_STATE_NOT_PRESENT;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_spn(w, NULL);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_watch_signal_queue(w, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_set_ofono_iccid(w, NULL);
|
||||
fake_watch_set_ofono_imsi(w, NULL);
|
||||
fake_watch_set_ofono_spn(w, NULL);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(count[SIM_INFO_SIGNAL_ICCID_CHANGED] == 1);
|
||||
g_assert(count[SIM_INFO_SIGNAL_IMSI_CHANGED] == 1);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]); /* removed ^ */
|
||||
@@ -455,13 +455,13 @@ static void test_cache(void)
|
||||
|
||||
sailfish_sim_info_remove_handlers(si, id, G_N_ELEMENTS(id));
|
||||
sailfish_sim_info_unref(si);
|
||||
sailfish_watch_unref(w);
|
||||
ofono_watch_unref(w);
|
||||
}
|
||||
|
||||
static void test_netreg(void)
|
||||
{
|
||||
struct sailfish_sim_info *si;
|
||||
struct sailfish_watch *w = sailfish_watch_new(TEST_PATH);
|
||||
struct ofono_watch *w = ofono_watch_new(TEST_PATH);
|
||||
struct ofono_sim sim;
|
||||
struct ofono_netreg netreg;
|
||||
struct stat st;
|
||||
@@ -496,10 +496,10 @@ static void test_netreg(void)
|
||||
test_signal_count_cb, count +
|
||||
SIM_INFO_SIGNAL_SPN_CHANGED);
|
||||
|
||||
fake_sailfish_watch_set_ofono_sim(w, &sim);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_sim(w, &sim);
|
||||
fake_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_watch_set_ofono_imsi(w, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->iccid, TEST_ICCID));
|
||||
g_assert(!g_strcmp0(si->imsi, TEST_IMSI));
|
||||
g_assert(!g_strcmp0(si->spn, TEST_DEFAULT_SPN));
|
||||
@@ -513,8 +513,8 @@ static void test_netreg(void)
|
||||
/* Default SPN doesn't get cached */
|
||||
g_assert(stat(SIM_CACHE, &st) < 0);
|
||||
|
||||
fake_sailfish_watch_set_ofono_netreg(w, &netreg);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_netreg(w, &netreg);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
@@ -531,13 +531,13 @@ static void test_netreg(void)
|
||||
g_assert(stat(SIM_CACHE, &st) == 0);
|
||||
g_assert(S_ISREG(st.st_mode));
|
||||
|
||||
fake_sailfish_watch_set_ofono_netreg(w, NULL);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_watch_set_ofono_netreg(w, NULL);
|
||||
fake_watch_emit_queued_signals(w);
|
||||
|
||||
__ofono_watchlist_free(netreg.status_watches);
|
||||
sailfish_sim_info_remove_handlers(si, id, G_N_ELEMENTS(id));
|
||||
sailfish_sim_info_unref(si);
|
||||
sailfish_watch_unref(w);
|
||||
ofono_watch_unref(w);
|
||||
}
|
||||
|
||||
#define TEST_(name) "/sailfish_sim_info/" name
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 Jolla Ltd.
|
||||
* Copyright (C) 2018-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
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "test-dbus.h"
|
||||
#include "fake_sailfish_watch.h"
|
||||
#include "fake_watch.h"
|
||||
|
||||
#include "sailfish_sim_info.h"
|
||||
|
||||
@@ -242,7 +242,7 @@ struct test_get_all_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_sim_info_dbus *dbus;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
const char *iccid;
|
||||
};
|
||||
|
||||
@@ -310,14 +310,14 @@ static void test_get_all1(void)
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_all1_start;
|
||||
test.watch = sailfish_watch_new(test.modem.path);
|
||||
test.watch = ofono_watch_new(test.modem.path);
|
||||
test.watch->modem = &test.modem;
|
||||
test.iccid = "";
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
sailfish_watch_unref(test.watch);
|
||||
ofono_watch_unref(test.watch);
|
||||
sailfish_sim_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
@@ -333,18 +333,18 @@ static void test_get_all2_start(struct test_dbus_context *context)
|
||||
struct test_get_all_data *test =
|
||||
G_CAST(context, struct test_get_all_data, context);
|
||||
const char *path = test->modem.path;
|
||||
struct sailfish_watch *watch = test->watch;
|
||||
struct ofono_watch *watch = test->watch;
|
||||
|
||||
DBG("");
|
||||
test->dbus = sailfish_sim_info_dbus_new_path(path);
|
||||
g_assert(test->dbus);
|
||||
|
||||
/* Tell sailfish_watch that we have a modem */
|
||||
/* Tell ofono_watch that we have a modem */
|
||||
test->watch->modem = &test->modem;
|
||||
fake_sailfish_watch_set_ofono_sim(watch, &test->modem.sim);
|
||||
fake_sailfish_watch_set_ofono_iccid(watch, test->iccid);
|
||||
fake_sailfish_watch_signal_queue(watch, WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(watch);
|
||||
fake_watch_set_ofono_sim(watch, &test->modem.sim);
|
||||
fake_watch_set_ofono_iccid(watch, test->iccid);
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_MODEM_CHANGED);
|
||||
fake_watch_emit_queued_signals(watch);
|
||||
|
||||
test_submit_get_all_call(test, test_get_all_reply);
|
||||
}
|
||||
@@ -358,7 +358,7 @@ static void test_get_all2(void)
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_all2_start;
|
||||
test.watch = sailfish_watch_new(test.modem.path);
|
||||
test.watch = ofono_watch_new(test.modem.path);
|
||||
test.iccid = TEST_ICCID;
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
@@ -368,7 +368,7 @@ static void test_get_all2(void)
|
||||
g_assert(test_dbus_find_signal(&test.context, test.modem.path,
|
||||
SIM_INFO_DBUS_INTERFACE, SIM_INFO_DBUS_ICCID_CHANGED_SIGNAL));
|
||||
|
||||
sailfish_watch_unref(test.watch);
|
||||
ofono_watch_unref(test.watch);
|
||||
sailfish_sim_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
@@ -448,7 +448,7 @@ struct test_get_iccid_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_sim_info_dbus *dbus;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
const char *iccid;
|
||||
const char *result;
|
||||
};
|
||||
@@ -474,8 +474,8 @@ static void test_get_iccid_start(struct test_dbus_context *context)
|
||||
|
||||
DBG("");
|
||||
test->dbus = sailfish_sim_info_dbus_new_path(path);
|
||||
fake_sailfish_watch_set_ofono_iccid(test->watch, test->iccid);
|
||||
fake_sailfish_watch_emit_queued_signals(test->watch);
|
||||
fake_watch_set_ofono_iccid(test->watch, test->iccid);
|
||||
fake_watch_emit_queued_signals(test->watch);
|
||||
g_assert(test->dbus);
|
||||
|
||||
msg = dbus_message_new_method_call(NULL, test->modem.path,
|
||||
@@ -497,10 +497,10 @@ static void test_get_iccid(const char *init_iccid, const char *set_iccid,
|
||||
test.result = result;
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_iccid_start;
|
||||
test.watch = sailfish_watch_new(test.modem.path);
|
||||
test.watch = ofono_watch_new(test.modem.path);
|
||||
test.watch->modem = &test.modem;
|
||||
fake_sailfish_watch_set_ofono_iccid(test.watch, init_iccid);
|
||||
fake_sailfish_watch_emit_queued_signals(test.watch);
|
||||
fake_watch_set_ofono_iccid(test.watch, init_iccid);
|
||||
fake_watch_emit_queued_signals(test.watch);
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
@@ -509,7 +509,7 @@ static void test_get_iccid(const char *init_iccid, const char *set_iccid,
|
||||
g_assert(test_dbus_find_signal(&test.context, test.modem.path,
|
||||
SIM_INFO_DBUS_INTERFACE, SIM_INFO_DBUS_ICCID_CHANGED_SIGNAL));
|
||||
|
||||
sailfish_watch_unref(test.watch);
|
||||
ofono_watch_unref(test.watch);
|
||||
sailfish_sim_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
@@ -535,7 +535,7 @@ struct test_get_string_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_sim_info_dbus *dbus;
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
const char *method;
|
||||
const char *result;
|
||||
};
|
||||
@@ -559,16 +559,16 @@ static void test_get_string_start(struct test_dbus_context *context)
|
||||
G_CAST(context, struct test_get_string_data, context);
|
||||
const char *path = test->modem.path;
|
||||
struct ofono_sim *sim = &test->modem.sim;
|
||||
struct sailfish_watch *watch = test->watch;
|
||||
struct ofono_watch *watch = test->watch;
|
||||
|
||||
DBG("%s", test->method);
|
||||
test->dbus = sailfish_sim_info_dbus_new_path(path);
|
||||
sim->mcc = TEST_MCC;
|
||||
sim->mnc = TEST_MNC;
|
||||
sim->state = OFONO_SIM_STATE_READY;
|
||||
fake_sailfish_watch_signal_queue(watch, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_imsi(watch, TEST_IMSI);
|
||||
fake_sailfish_watch_emit_queued_signals(watch);
|
||||
fake_watch_signal_queue(watch, FAKE_WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_watch_set_ofono_imsi(watch, TEST_IMSI);
|
||||
fake_watch_emit_queued_signals(watch);
|
||||
g_assert(test->dbus);
|
||||
|
||||
msg = dbus_message_new_method_call(NULL, test->modem.path,
|
||||
@@ -590,11 +590,11 @@ static void test_get_string(const char *method, const char *result)
|
||||
test.result = result;
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_string_start;
|
||||
test.watch = sailfish_watch_new(test.modem.path);
|
||||
test.watch = ofono_watch_new(test.modem.path);
|
||||
test.watch->modem = &test.modem;
|
||||
fake_sailfish_watch_set_ofono_iccid(test.watch, TEST_ICCID);
|
||||
fake_sailfish_watch_set_ofono_sim(test.watch, &test.modem.sim);
|
||||
fake_sailfish_watch_emit_queued_signals(test.watch);
|
||||
fake_watch_set_ofono_iccid(test.watch, TEST_ICCID);
|
||||
fake_watch_set_ofono_sim(test.watch, &test.modem.sim);
|
||||
fake_watch_emit_queued_signals(test.watch);
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
@@ -605,7 +605,7 @@ static void test_get_string(const char *method, const char *result)
|
||||
g_assert(test_dbus_find_signal(&test.context, test.modem.path,
|
||||
SIM_INFO_DBUS_INTERFACE, SIM_INFO_DBUS_SPN_CHANGED_SIGNAL));
|
||||
|
||||
sailfish_watch_unref(test.watch);
|
||||
ofono_watch_unref(test.watch);
|
||||
sailfish_sim_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 Jolla Ltd.
|
||||
* Copyright (C) 2018-2019 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -13,7 +13,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <sailfish_watch.h>
|
||||
#include "watch_p.h"
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
@@ -27,6 +27,9 @@ static struct ofono_watchlist *g_modemwatches = NULL;
|
||||
#define TEST_ICCID "0000000000000000000"
|
||||
#define TEST_IMSI "244120000000000"
|
||||
#define TEST_SPN "Test"
|
||||
#define TEST_MCC "244"
|
||||
#define TEST_MNC "12"
|
||||
#define TEST_NAME "Test"
|
||||
|
||||
/* Fake ofono_atom */
|
||||
|
||||
@@ -42,12 +45,44 @@ void *__ofono_atom_get_data(struct ofono_atom *atom)
|
||||
return atom->data;
|
||||
}
|
||||
|
||||
/* Fake ofono_gprs */
|
||||
|
||||
struct ofono_gprs {
|
||||
struct ofono_atom atom;
|
||||
enum ofono_gprs_context_type type;
|
||||
const struct ofono_gprs_primary_context *settings;
|
||||
};
|
||||
|
||||
/* Fake ofono_netreg */
|
||||
|
||||
struct ofono_netreg {
|
||||
struct ofono_atom atom;
|
||||
enum ofono_netreg_status status;
|
||||
const char *mcc;
|
||||
const char *mnc;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
int ofono_netreg_get_status(struct ofono_netreg *netreg)
|
||||
{
|
||||
return netreg ? netreg->status : OFONO_NETREG_STATUS_NONE;
|
||||
}
|
||||
|
||||
const char *ofono_netreg_get_mcc(struct ofono_netreg *netreg)
|
||||
{
|
||||
return netreg ? netreg->mcc : NULL;
|
||||
}
|
||||
|
||||
const char *ofono_netreg_get_mnc(struct ofono_netreg *netreg)
|
||||
{
|
||||
return netreg ? netreg->mnc : NULL;
|
||||
}
|
||||
|
||||
const char *ofono_netreg_get_name(struct ofono_netreg *netreg)
|
||||
{
|
||||
return netreg ? netreg->name : NULL;
|
||||
}
|
||||
|
||||
/* Fake ofono_sim */
|
||||
|
||||
struct ofono_sim {
|
||||
@@ -209,6 +244,7 @@ struct ofono_modem {
|
||||
struct ofono_watchlist *online_watches;
|
||||
struct ofono_sim sim;
|
||||
struct ofono_netreg netreg;
|
||||
struct ofono_gprs gprs;
|
||||
};
|
||||
|
||||
struct atom_watch {
|
||||
@@ -381,6 +417,7 @@ static void test_modem_unregister_atom(struct ofono_modem *modem,
|
||||
static void test_modem_init1(struct ofono_modem *modem, const char *path)
|
||||
{
|
||||
struct ofono_netreg *netreg = &modem->netreg;
|
||||
struct ofono_gprs *gprs = &modem->gprs;
|
||||
struct ofono_sim *sim = &modem->sim;
|
||||
|
||||
/* Assume that the structure has been zero-initialized */
|
||||
@@ -392,6 +429,10 @@ static void test_modem_init1(struct ofono_modem *modem, const char *path)
|
||||
netreg->atom.modem = modem;
|
||||
netreg->atom.data = netreg;
|
||||
|
||||
gprs->atom.type = OFONO_ATOM_TYPE_GPRS;
|
||||
gprs->atom.modem = modem;
|
||||
gprs->atom.data = gprs;
|
||||
|
||||
sim->atom.type = OFONO_ATOM_TYPE_SIM;
|
||||
sim->atom.modem = modem;
|
||||
sim->atom.data = sim;
|
||||
@@ -427,7 +468,7 @@ static void test_modem_shutdown(struct ofono_modem *modem)
|
||||
__ofono_watchlist_free(modem->online_watches);
|
||||
}
|
||||
|
||||
static void test_inc_cb(struct sailfish_watch *watch, void *user_data)
|
||||
static void test_inc_cb(struct ofono_watch *watch, void *user_data)
|
||||
{
|
||||
(*((int *)user_data))++;
|
||||
}
|
||||
@@ -436,25 +477,39 @@ static void test_inc_cb(struct sailfish_watch *watch, void *user_data)
|
||||
|
||||
static void test_basic(void)
|
||||
{
|
||||
struct sailfish_watch *watch;
|
||||
struct sailfish_watch *watch1;
|
||||
struct ofono_watch *watch;
|
||||
struct ofono_watch *watch1;
|
||||
struct ofono_modem modem, modem1;
|
||||
unsigned long id = 0;
|
||||
|
||||
/* NULL resistance */
|
||||
g_assert(!sailfish_watch_new(NULL));
|
||||
g_assert(!sailfish_watch_ref(NULL));
|
||||
sailfish_watch_unref(NULL);
|
||||
g_assert(!sailfish_watch_add_modem_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_online_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_sim_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_sim_state_changed_handler(NULL, NULL,
|
||||
g_assert(!ofono_watch_new(NULL));
|
||||
g_assert(!ofono_watch_ref(NULL));
|
||||
ofono_watch_unref(NULL);
|
||||
g_assert(!ofono_watch_add_modem_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_online_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_sim_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_sim_state_changed_handler(NULL, NULL,
|
||||
NULL));
|
||||
g_assert(!sailfish_watch_add_iccid_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_imsi_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_spn_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_netreg_changed_handler(NULL, NULL, NULL));
|
||||
sailfish_watch_remove_handler(NULL, 0);
|
||||
sailfish_watch_remove_handlers(NULL, NULL, 0);
|
||||
g_assert(!ofono_watch_add_iccid_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_imsi_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_spn_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_netreg_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_reg_status_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_reg_mcc_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_reg_mnc_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_reg_name_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_gprs_changed_handler(NULL, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_gprs_settings_changed_handler(NULL,
|
||||
NULL, NULL));
|
||||
ofono_watch_remove_handler(NULL, 0);
|
||||
ofono_watch_remove_handlers(NULL, NULL, 0);
|
||||
__ofono_watch_netreg_changed(NULL);
|
||||
__ofono_watch_netreg_changed(TEST_PATH);
|
||||
__ofono_watch_gprs_settings_changed
|
||||
(NULL, OFONO_GPRS_CONTEXT_TYPE_ANY, NULL);
|
||||
__ofono_watch_gprs_settings_changed
|
||||
(TEST_PATH, OFONO_GPRS_CONTEXT_TYPE_ANY, NULL);
|
||||
|
||||
/* Instance caching */
|
||||
memset(&modem, 0, sizeof(modem));
|
||||
@@ -462,8 +517,8 @@ static void test_basic(void)
|
||||
__ofono_modemwatch_init();
|
||||
test_modem_init1(&modem, TEST_PATH);
|
||||
|
||||
watch = sailfish_watch_new(TEST_PATH);
|
||||
watch1 = sailfish_watch_new(TEST_PATH_1);
|
||||
watch = ofono_watch_new(TEST_PATH);
|
||||
watch1 = ofono_watch_new(TEST_PATH_1);
|
||||
|
||||
/* The second modem is added after the watch is created */
|
||||
test_modem_init1(&modem1, TEST_PATH_1);
|
||||
@@ -475,28 +530,32 @@ static void test_basic(void)
|
||||
g_assert(watch1);
|
||||
g_assert(watch->modem == &modem);
|
||||
g_assert(watch1->modem == &modem1);
|
||||
g_assert(sailfish_watch_new(TEST_PATH) == watch);
|
||||
g_assert(sailfish_watch_new(TEST_PATH_1) == watch1);
|
||||
sailfish_watch_unref(watch);
|
||||
sailfish_watch_unref(watch1);
|
||||
g_assert(ofono_watch_new(TEST_PATH) == watch);
|
||||
g_assert(ofono_watch_new(TEST_PATH_1) == watch1);
|
||||
g_assert(ofono_watch_ref(watch) == watch);
|
||||
ofono_watch_unref(watch);
|
||||
ofono_watch_unref(watch);
|
||||
ofono_watch_unref(watch1);
|
||||
|
||||
/* More NULLs and zeros */
|
||||
g_assert(!sailfish_watch_add_modem_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_online_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_sim_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_sim_state_changed_handler(watch, NULL,
|
||||
g_assert(!ofono_watch_add_modem_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_online_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_sim_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_sim_state_changed_handler(watch, NULL,
|
||||
NULL));
|
||||
g_assert(!sailfish_watch_add_iccid_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_imsi_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_spn_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!sailfish_watch_add_netreg_changed_handler(watch, NULL, NULL));
|
||||
sailfish_watch_remove_handler(watch, 0);
|
||||
sailfish_watch_remove_handlers(watch, NULL, 0);
|
||||
g_assert(!ofono_watch_add_iccid_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_imsi_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_spn_changed_handler(watch, NULL, NULL));
|
||||
g_assert(!ofono_watch_add_netreg_changed_handler(watch, NULL, NULL));
|
||||
ofono_watch_remove_handler(watch, 0);
|
||||
ofono_watch_remove_handlers(watch, NULL, 0);
|
||||
ofono_watch_remove_handlers(watch, &id, 0);
|
||||
ofono_watch_remove_handlers(watch, &id, 1);
|
||||
|
||||
/* The first modem is removed when the watch is still alive */
|
||||
test_modem_shutdown(&modem);
|
||||
sailfish_watch_unref(watch);
|
||||
sailfish_watch_unref(watch1);
|
||||
ofono_watch_unref(watch);
|
||||
ofono_watch_unref(watch1);
|
||||
test_modem_shutdown(&modem1);
|
||||
__ofono_modemwatch_cleanup();
|
||||
}
|
||||
@@ -505,22 +564,22 @@ static void test_basic(void)
|
||||
|
||||
static void test_modem(void)
|
||||
{
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
struct ofono_modem modem;
|
||||
gulong id;
|
||||
int n = 0;
|
||||
|
||||
__ofono_modemwatch_init();
|
||||
watch = sailfish_watch_new(TEST_PATH);
|
||||
watch = ofono_watch_new(TEST_PATH);
|
||||
|
||||
id = sailfish_watch_add_modem_changed_handler(watch, test_inc_cb, &n);
|
||||
id = ofono_watch_add_modem_changed_handler(watch, test_inc_cb, &n);
|
||||
g_assert(id);
|
||||
memset(&modem, 0, sizeof(modem));
|
||||
test_modem_init(&modem);
|
||||
g_assert(n == 1);
|
||||
|
||||
sailfish_watch_remove_handler(watch, id);
|
||||
sailfish_watch_unref(watch);
|
||||
ofono_watch_remove_handler(watch, id);
|
||||
ofono_watch_unref(watch);
|
||||
test_modem_shutdown(&modem);
|
||||
__ofono_modemwatch_cleanup();
|
||||
}
|
||||
@@ -529,7 +588,7 @@ static void test_modem(void)
|
||||
|
||||
static void test_online(void)
|
||||
{
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
struct ofono_modem modem;
|
||||
gulong id;
|
||||
int n = 0;
|
||||
@@ -537,11 +596,11 @@ static void test_online(void)
|
||||
memset(&modem, 0, sizeof(modem));
|
||||
__ofono_modemwatch_init();
|
||||
test_modem_init(&modem);
|
||||
watch = sailfish_watch_new(TEST_PATH);
|
||||
watch = ofono_watch_new(TEST_PATH);
|
||||
g_assert(!watch->online);
|
||||
|
||||
modem.online = TRUE;
|
||||
id = sailfish_watch_add_online_changed_handler(watch, test_inc_cb, &n);
|
||||
id = ofono_watch_add_online_changed_handler(watch, test_inc_cb, &n);
|
||||
notify_online_watches(&modem);
|
||||
g_assert(watch->online);
|
||||
g_assert(n == 1);
|
||||
@@ -552,8 +611,8 @@ static void test_online(void)
|
||||
g_assert(!watch->online);
|
||||
g_assert(n == 2);
|
||||
|
||||
sailfish_watch_remove_handler(watch, id);
|
||||
sailfish_watch_unref(watch);
|
||||
ofono_watch_remove_handler(watch, id);
|
||||
ofono_watch_unref(watch);
|
||||
__ofono_modemwatch_cleanup();
|
||||
}
|
||||
|
||||
@@ -561,36 +620,169 @@ static void test_online(void)
|
||||
|
||||
static void test_netreg(void)
|
||||
{
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
struct ofono_modem modem;
|
||||
gulong id;
|
||||
int n = 0;
|
||||
struct ofono_netreg *netreg = &modem.netreg;
|
||||
gulong id[5];
|
||||
int n[G_N_ELEMENTS(id)];
|
||||
|
||||
#define NETREG 0
|
||||
#define REG_STATUS 1
|
||||
#define REG_MCC 2
|
||||
#define REG_MNC 3
|
||||
#define REG_NAME 4
|
||||
|
||||
__ofono_watch_netreg_changed(TEST_PATH); /* No effect (yet) */
|
||||
|
||||
memset(&modem, 0, sizeof(modem));
|
||||
__ofono_modemwatch_init();
|
||||
test_modem_init(&modem);
|
||||
watch = sailfish_watch_new(TEST_PATH);
|
||||
watch = ofono_watch_new(TEST_PATH);
|
||||
g_assert(!watch->netreg);
|
||||
|
||||
id = sailfish_watch_add_netreg_changed_handler(watch, test_inc_cb, &n);
|
||||
test_modem_register_atom(&modem, &modem.netreg.atom);
|
||||
g_assert(watch->netreg == &modem.netreg);
|
||||
g_assert(n == 1);
|
||||
memset(id, 0, sizeof(id));
|
||||
memset(n, 0, sizeof(n));
|
||||
id[NETREG] = ofono_watch_add_netreg_changed_handler
|
||||
(watch, test_inc_cb, n + NETREG);
|
||||
id[REG_STATUS] = ofono_watch_add_reg_status_changed_handler
|
||||
(watch, test_inc_cb, n + REG_STATUS);
|
||||
id[REG_MCC] = ofono_watch_add_reg_mcc_changed_handler
|
||||
(watch, test_inc_cb, n + REG_MCC);
|
||||
id[REG_MNC] = ofono_watch_add_reg_mnc_changed_handler
|
||||
(watch, test_inc_cb, n + REG_MNC);
|
||||
id[REG_NAME] = ofono_watch_add_reg_name_changed_handler
|
||||
(watch, test_inc_cb, n + REG_NAME);
|
||||
test_modem_register_atom(&modem, &netreg->atom);
|
||||
g_assert(watch->netreg == netreg);
|
||||
g_assert(watch->reg_status == netreg->status);
|
||||
g_assert(n[NETREG] == 1);
|
||||
g_assert(n[REG_STATUS] == 1);
|
||||
n[NETREG] = 0;
|
||||
n[REG_STATUS] = 0;
|
||||
|
||||
test_modem_unregister_atom(&modem, &modem.netreg.atom);
|
||||
netreg->status++;
|
||||
__ofono_watch_netreg_changed(TEST_PATH);
|
||||
g_assert(watch->reg_status == netreg->status);
|
||||
g_assert(n[REG_STATUS] == 1);
|
||||
n[REG_STATUS] = 0;
|
||||
|
||||
netreg->mcc = TEST_MCC;
|
||||
netreg->mnc = TEST_MNC;
|
||||
netreg->name = TEST_NAME;
|
||||
__ofono_watch_netreg_changed(TEST_PATH);
|
||||
__ofono_watch_netreg_changed(TEST_PATH); /* This one has no effect */
|
||||
__ofono_watch_netreg_changed(TEST_PATH_1); /* This one too */
|
||||
g_assert(!n[REG_STATUS]);
|
||||
g_assert(n[REG_MCC] == 1);
|
||||
g_assert(n[REG_MNC] == 1);
|
||||
g_assert(n[REG_NAME] == 1);
|
||||
g_assert(!g_strcmp0(watch->reg_mcc, netreg->mcc));
|
||||
g_assert(!g_strcmp0(watch->reg_mnc, netreg->mnc));
|
||||
g_assert(!g_strcmp0(watch->reg_name, netreg->name));
|
||||
n[REG_MCC] = 0;
|
||||
n[REG_MNC] = 0;
|
||||
n[REG_NAME] = 0;
|
||||
|
||||
test_modem_unregister_atom(&modem, &netreg->atom);
|
||||
g_assert(!watch->netreg);
|
||||
g_assert(n == 2);
|
||||
g_assert(watch->reg_status == OFONO_NETREG_STATUS_NONE);
|
||||
g_assert(!watch->reg_mcc);
|
||||
g_assert(!watch->reg_mnc);
|
||||
g_assert(!watch->reg_name);
|
||||
g_assert(n[NETREG] == 1);
|
||||
g_assert(n[REG_STATUS] == 1);
|
||||
g_assert(n[REG_MCC] == 1);
|
||||
g_assert(n[REG_MNC] == 1);
|
||||
g_assert(n[REG_NAME] == 1);
|
||||
memset(n, 0, sizeof(n));
|
||||
|
||||
test_modem_register_atom(&modem, &modem.netreg.atom);
|
||||
g_assert(watch->netreg == &modem.netreg);
|
||||
g_assert(n == 3);
|
||||
netreg->mcc = NULL;
|
||||
netreg->mnc = NULL;
|
||||
netreg->name = NULL;
|
||||
|
||||
test_modem_register_atom(&modem, &netreg->atom);
|
||||
g_assert(watch->netreg == netreg);
|
||||
g_assert(watch->reg_status == netreg->status);
|
||||
g_assert(n[NETREG] == 1);
|
||||
g_assert(n[REG_STATUS] == 1);
|
||||
n[NETREG] = 0;
|
||||
n[REG_STATUS] = 0;
|
||||
|
||||
test_modem_shutdown(&modem);
|
||||
g_assert(!watch->netreg);
|
||||
g_assert(watch->reg_status == OFONO_NETREG_STATUS_NONE);
|
||||
g_assert(n[NETREG] == 1);
|
||||
g_assert(n[REG_STATUS] == 1);
|
||||
g_assert(!n[REG_MCC]);
|
||||
g_assert(!n[REG_MNC]);
|
||||
g_assert(!n[REG_NAME]);
|
||||
|
||||
ofono_watch_remove_all_handlers(watch, id);
|
||||
ofono_watch_unref(watch);
|
||||
__ofono_modemwatch_cleanup();
|
||||
}
|
||||
|
||||
/* ==== gprs ==== */
|
||||
|
||||
static void test_gprs_settings_cb(struct ofono_watch *watch,
|
||||
enum ofono_gprs_context_type type,
|
||||
const struct ofono_gprs_primary_context *settings,
|
||||
void *user_data)
|
||||
{
|
||||
struct ofono_gprs *gprs = user_data;
|
||||
|
||||
g_assert(gprs == watch->gprs);
|
||||
gprs->type = type;
|
||||
gprs->settings = settings;
|
||||
}
|
||||
|
||||
static void test_gprs(void)
|
||||
{
|
||||
struct ofono_watch *watch;
|
||||
struct ofono_modem modem;
|
||||
struct ofono_gprs *gprs = &modem.gprs;
|
||||
struct ofono_gprs_primary_context settings;
|
||||
gulong ids[2];
|
||||
int n = 0;
|
||||
|
||||
__ofono_modemwatch_init();
|
||||
memset(&modem, 0, sizeof(modem));
|
||||
test_modem_init(&modem);
|
||||
watch = ofono_watch_new(TEST_PATH);
|
||||
g_assert(!watch->gprs);
|
||||
|
||||
ids[0] = ofono_watch_add_gprs_changed_handler(watch, test_inc_cb, &n);
|
||||
ids[1] = ofono_watch_add_gprs_settings_changed_handler(watch,
|
||||
test_gprs_settings_cb, gprs);
|
||||
|
||||
test_modem_register_atom(&modem, &gprs->atom);
|
||||
g_assert(watch->gprs == gprs);
|
||||
g_assert(n == 1);
|
||||
test_modem_register_atom(&modem, &gprs->atom); /* No effect */
|
||||
g_assert(n == 1);
|
||||
|
||||
test_modem_unregister_atom(&modem, &gprs->atom);
|
||||
g_assert(!watch->gprs);
|
||||
g_assert(n == 2);
|
||||
|
||||
test_modem_register_atom(&modem, &gprs->atom);
|
||||
g_assert(watch->gprs == gprs);
|
||||
g_assert(n == 3);
|
||||
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
__ofono_watch_gprs_settings_changed(TEST_PATH,
|
||||
OFONO_GPRS_CONTEXT_TYPE_INTERNET, &settings);
|
||||
__ofono_watch_gprs_settings_changed(TEST_PATH_1, /* No effect */
|
||||
OFONO_GPRS_CONTEXT_TYPE_ANY, NULL);
|
||||
g_assert(gprs->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET);
|
||||
g_assert(gprs->settings == &settings);
|
||||
|
||||
test_modem_shutdown(&modem);
|
||||
g_assert(!watch->gprs);
|
||||
g_assert(n == 4);
|
||||
|
||||
sailfish_watch_remove_handler(watch, id);
|
||||
sailfish_watch_unref(watch);
|
||||
ofono_watch_remove_all_handlers(watch, ids);
|
||||
ofono_watch_unref(watch);
|
||||
__ofono_modemwatch_cleanup();
|
||||
}
|
||||
|
||||
@@ -598,7 +790,7 @@ static void test_netreg(void)
|
||||
|
||||
static void test_sim(void)
|
||||
{
|
||||
struct sailfish_watch *watch;
|
||||
struct ofono_watch *watch;
|
||||
struct ofono_modem modem;
|
||||
struct ofono_sim *sim = &modem.sim;
|
||||
gulong id[4];
|
||||
@@ -612,20 +804,20 @@ static void test_sim(void)
|
||||
memset(&modem, 0, sizeof(modem));
|
||||
__ofono_modemwatch_init();
|
||||
test_modem_init(&modem);
|
||||
watch = sailfish_watch_new(TEST_PATH);
|
||||
watch = ofono_watch_new(TEST_PATH);
|
||||
g_assert(!watch->iccid);
|
||||
g_assert(!watch->imsi);
|
||||
g_assert(!watch->spn);
|
||||
|
||||
memset(id, 0, sizeof(id));
|
||||
memset(n, 0, sizeof(n));
|
||||
id[SIM] = sailfish_watch_add_sim_changed_handler(watch,
|
||||
id[SIM] = ofono_watch_add_sim_changed_handler(watch,
|
||||
test_inc_cb, n + SIM);
|
||||
id[ICCID] = sailfish_watch_add_iccid_changed_handler(watch,
|
||||
id[ICCID] = ofono_watch_add_iccid_changed_handler(watch,
|
||||
test_inc_cb, n + ICCID);
|
||||
id[IMSI] = sailfish_watch_add_imsi_changed_handler(watch,
|
||||
id[IMSI] = ofono_watch_add_imsi_changed_handler(watch,
|
||||
test_inc_cb, n + IMSI);
|
||||
id[SPN] = sailfish_watch_add_spn_changed_handler(watch,
|
||||
id[SPN] = ofono_watch_add_spn_changed_handler(watch,
|
||||
test_inc_cb, n + SPN);
|
||||
test_modem_register_atom(&modem, &modem.sim.atom);
|
||||
g_assert(watch->sim == &modem.sim);
|
||||
@@ -673,13 +865,13 @@ static void test_sim(void)
|
||||
g_assert(!watch->sim);
|
||||
g_assert(n[SIM] == 2);
|
||||
|
||||
sailfish_watch_remove_all_handlers(watch, id);
|
||||
sailfish_watch_unref(watch);
|
||||
ofono_watch_remove_all_handlers(watch, id);
|
||||
ofono_watch_unref(watch);
|
||||
test_modem_shutdown(&modem);
|
||||
__ofono_modemwatch_cleanup();
|
||||
}
|
||||
|
||||
#define TEST_(name) "/sailfish_watch/" name
|
||||
#define TEST_(name) "/ofono_watch/" name
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -688,14 +880,14 @@ int main(int argc, char *argv[])
|
||||
gutil_log_timestamp = FALSE;
|
||||
gutil_log_default.level = g_test_verbose() ?
|
||||
GLOG_LEVEL_VERBOSE : GLOG_LEVEL_NONE;
|
||||
__ofono_log_init("test-sailfish_watch",
|
||||
g_test_verbose() ? "*" : NULL,
|
||||
FALSE, FALSE);
|
||||
__ofono_log_init("test-ofono_watch", g_test_verbose() ? "*" : NULL,
|
||||
FALSE, FALSE);
|
||||
|
||||
g_test_add_func(TEST_("basic"), test_basic);
|
||||
g_test_add_func(TEST_("modem"), test_modem);
|
||||
g_test_add_func(TEST_("online"), test_online);
|
||||
g_test_add_func(TEST_("netreg"), test_netreg);
|
||||
g_test_add_func(TEST_("gprs"), test_gprs);
|
||||
g_test_add_func(TEST_("sim"), test_sim);
|
||||
|
||||
return g_test_run();
|
||||
@@ -1,30 +1,39 @@
|
||||
Name: ofono
|
||||
|
||||
Summary: Open Source Telephony
|
||||
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
|
||||
Requires(postun): systemd
|
||||
|
||||
# license macro requires reasonably fresh rpm
|
||||
BuildRequires: rpm >= 4.11
|
||||
BuildRequires: pkgconfig(dbus-1)
|
||||
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
|
||||
BuildRequires: automake
|
||||
@@ -61,6 +70,14 @@ Provides: ofono-configs
|
||||
%description configs-mer
|
||||
This package provides default configs for ofono
|
||||
|
||||
%package doc
|
||||
Summary: Documentation for %{name}
|
||||
Group: Documentation
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
%description doc
|
||||
Man pages for %{name}.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}-%{version}/%{name}
|
||||
|
||||
@@ -77,6 +94,7 @@ autoreconf --force --install
|
||||
--enable-sailfish-provision \
|
||||
--enable-sailfish-pushforwarder \
|
||||
--enable-sailfish-rilmodem \
|
||||
--enable-sailfish-access \
|
||||
--disable-add-remove-context \
|
||||
--disable-isimodem \
|
||||
--disable-qmimodem \
|
||||
@@ -84,7 +102,6 @@ autoreconf --force --install
|
||||
|
||||
make %{_smp_mflags}
|
||||
|
||||
|
||||
%check
|
||||
# run unit tests
|
||||
make check
|
||||
@@ -98,6 +115,10 @@ mkdir -p %{buildroot}/%{_lib}/systemd/system/network.target.wants
|
||||
mkdir -p %{buildroot}/var/lib/ofono
|
||||
ln -s ../ofono.service %{buildroot}/%{_lib}/systemd/system/network.target.wants/ofono.service
|
||||
|
||||
mkdir -p %{buildroot}%{_docdir}/%{name}-%{version}
|
||||
install -m0644 -t %{buildroot}%{_docdir}/%{name}-%{version} \
|
||||
ChangeLog AUTHORS README
|
||||
|
||||
%preun
|
||||
if [ "$1" -eq 0 ]; then
|
||||
systemctl stop ofono.service ||:
|
||||
@@ -115,7 +136,7 @@ systemctl daemon-reload ||:
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc COPYING ChangeLog AUTHORS README
|
||||
%license COPYING
|
||||
%config %{_sysconfdir}/dbus-1/system.d/*.conf
|
||||
%{_sbindir}/*
|
||||
/%{_lib}/systemd/system/network.target.wants/ofono.service
|
||||
@@ -124,7 +145,6 @@ systemctl daemon-reload ||:
|
||||
%dir %{_sysconfdir}/ofono/push_forwarder.d
|
||||
# This file is part of phonesim and not needed with ofono.
|
||||
%exclude %{_sysconfdir}/ofono/phonesim.conf
|
||||
%doc /usr/share/man/man8/ofonod.8.gz
|
||||
%dir %attr(775,radio,radio) /var/lib/ofono
|
||||
|
||||
%files devel
|
||||
@@ -139,3 +159,8 @@ systemctl daemon-reload ||:
|
||||
%files configs-mer
|
||||
%defattr(-,root,root,-)
|
||||
%config /etc/ofono/ril_subscription.conf
|
||||
|
||||
%files doc
|
||||
%defattr(-,root,root,-)
|
||||
%{_mandir}/man8/%{name}d.*
|
||||
%{_docdir}/%{name}-%{version}
|
||||
|
||||
Reference in New Issue
Block a user