mirror of
https://github.com/sailfishos/ofono
synced 2025-11-24 03:19:44 +08:00
Compare commits
1 Commits
mer/1.23+g
...
upgrade-3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
153eb3a4f3 |
3
ofono/.gitignore
vendored
3
ofono/.gitignore
vendored
@@ -48,7 +48,6 @@ unit/test-dbus-access
|
|||||||
unit/test-dbus-queue
|
unit/test-dbus-queue
|
||||||
unit/test-gprs-filter
|
unit/test-gprs-filter
|
||||||
unit/test-ril_config
|
unit/test-ril_config
|
||||||
unit/test-ril_ecclist
|
|
||||||
unit/test-ril_util
|
unit/test-ril_util
|
||||||
unit/test-ril_vendor
|
unit/test-ril_vendor
|
||||||
unit/test-ril-transport
|
unit/test-ril-transport
|
||||||
@@ -62,13 +61,11 @@ unit/test-sailfish_cell_info_dbus
|
|||||||
unit/test-sailfish_manager
|
unit/test-sailfish_manager
|
||||||
unit/test-sailfish_sim_info
|
unit/test-sailfish_sim_info
|
||||||
unit/test-sailfish_sim_info_dbus
|
unit/test-sailfish_sim_info_dbus
|
||||||
unit/test-config
|
|
||||||
unit/test-watch
|
unit/test-watch
|
||||||
unit/test-sms-filter
|
unit/test-sms-filter
|
||||||
unit/test-voicecall-filter
|
unit/test-voicecall-filter
|
||||||
unit/test-*.log
|
unit/test-*.log
|
||||||
unit/test-*.trs
|
unit/test-*.trs
|
||||||
unit/test-mbim
|
|
||||||
|
|
||||||
unit/test-grilreply
|
unit/test-grilreply
|
||||||
unit/test-grilrequest
|
unit/test-grilrequest
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ Antara Borwankar <antara.borwankar@gmail.com>
|
|||||||
Martin Chaplet <m.chaplet@kerlink.fr>
|
Martin Chaplet <m.chaplet@kerlink.fr>
|
||||||
Suman Mallela <suman.m@intel.com>
|
Suman Mallela <suman.m@intel.com>
|
||||||
Rajagopal Aravindan <rajagopalx.aravindan@intel.com>
|
Rajagopal Aravindan <rajagopalx.aravindan@intel.com>
|
||||||
Ankit Navik <ankit.p.navik@intel.com>
|
|
||||||
Antoine Aubert <a.aubert@overkiz.com>
|
Antoine Aubert <a.aubert@overkiz.com>
|
||||||
Djalal Harouni <djalal@endocode.com>
|
Djalal Harouni <djalal@endocode.com>
|
||||||
Christophe Ronco <c.ronco@kerlink.fr>
|
Christophe Ronco <c.ronco@kerlink.fr>
|
||||||
@@ -127,6 +126,3 @@ Jonas Bonn <jonas@southpole.se>
|
|||||||
Matthijs Kooijman <matthijs@stdin.nl>
|
Matthijs Kooijman <matthijs@stdin.nl>
|
||||||
Clayton Craft <clayton@craftyguy.net>
|
Clayton Craft <clayton@craftyguy.net>
|
||||||
Joey Hewitt <joey@joeyhewitt.com>
|
Joey Hewitt <joey@joeyhewitt.com>
|
||||||
Richard Röjfors <richard.rojfors@gmail.com>
|
|
||||||
Philippe De Swert <philippe.deswert@nomovok.com>
|
|
||||||
Gabriel Lucas <gabriel.lucas@smile.fr>
|
|
||||||
|
|||||||
@@ -1,21 +1,3 @@
|
|||||||
ver 1.23:
|
|
||||||
Fix issue with handling SIM AID sessions.
|
|
||||||
Add support for QMI LTE bearer handling.
|
|
||||||
Add support for memory location dialing.
|
|
||||||
|
|
||||||
ver 1.22:
|
|
||||||
Fix issue with GPIO handling and Nokia modems.
|
|
||||||
Fix issue with SIM state callback and AT modems.
|
|
||||||
Fix issue with data mode and DCD for U-Blox modems.
|
|
||||||
Fix issue with SMS receive on QMI based Quectel EC21.
|
|
||||||
Fix issue with HFP support and last call dialed request.
|
|
||||||
Fix issue with PIM retires handling and Gemalto modems.
|
|
||||||
Fix issue with atom registration and SIM state handling.
|
|
||||||
Add support for handling SIM card AID session management.
|
|
||||||
Add support for handling GSM/UMTS and IMS authentication.
|
|
||||||
Add support for IP Multimedia Subsystem (IMS) atom.
|
|
||||||
Add support for MBIM based modems.
|
|
||||||
|
|
||||||
ver 1.21:
|
ver 1.21:
|
||||||
Fix issue with USSD notification received handling.
|
Fix issue with USSD notification received handling.
|
||||||
Fix issue with crashing SIM filesystem notifications.
|
Fix issue with crashing SIM filesystem notifications.
|
||||||
|
|||||||
@@ -26,12 +26,17 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
|
|||||||
include/sms-filter.h include/gprs-filter.h \
|
include/sms-filter.h include/gprs-filter.h \
|
||||||
include/voicecall-filter.h include/dbus-access.h \
|
include/voicecall-filter.h include/dbus-access.h \
|
||||||
include/ril-constants.h include/ril-transport.h \
|
include/ril-constants.h include/ril-transport.h \
|
||||||
include/watch.h gdbus/gdbus.h \
|
include/netmon.h include/lte.h \
|
||||||
include/netmon.h include/lte.h include/ims.h \
|
include/storage.h include/watch.h \
|
||||||
include/storage.h
|
gdbus/gdbus.h
|
||||||
|
|
||||||
nodist_pkginclude_HEADERS = include/version.h
|
nodist_pkginclude_HEADERS = include/version.h
|
||||||
|
|
||||||
|
if SAILFISH_MANAGER
|
||||||
|
nodist_pkginclude_HEADERS += include/sailfish_cell_info.h \
|
||||||
|
include/sailfish_manager.h
|
||||||
|
endif
|
||||||
|
|
||||||
local_headers = $(foreach file,$(pkginclude_HEADERS) \
|
local_headers = $(foreach file,$(pkginclude_HEADERS) \
|
||||||
$(nodist_pkginclude_HEADERS), \
|
$(nodist_pkginclude_HEADERS), \
|
||||||
include/ofono/$(notdir $(file)))
|
include/ofono/$(notdir $(file)))
|
||||||
@@ -63,7 +68,7 @@ endif
|
|||||||
builtin_modules =
|
builtin_modules =
|
||||||
builtin_sources =
|
builtin_sources =
|
||||||
builtin_libadd =
|
builtin_libadd =
|
||||||
builtin_cflags = -DSAILFISH_OS
|
builtin_cflags =
|
||||||
|
|
||||||
noinst_LTLIBRARIES += gdbus/libgdbus-internal.la
|
noinst_LTLIBRARIES += gdbus/libgdbus-internal.la
|
||||||
|
|
||||||
@@ -145,14 +150,9 @@ builtin_sources += drivers/ril/ril_call_barring.c \
|
|||||||
drivers/ril/ril_call_volume.c \
|
drivers/ril/ril_call_volume.c \
|
||||||
drivers/ril/ril_cell_info.c \
|
drivers/ril/ril_cell_info.c \
|
||||||
drivers/ril/ril_config.c \
|
drivers/ril/ril_config.c \
|
||||||
drivers/ril/ril_connman.c \
|
|
||||||
drivers/ril/ril_cbs.c \
|
drivers/ril/ril_cbs.c \
|
||||||
drivers/ril/ril_data.c \
|
drivers/ril/ril_data.c \
|
||||||
drivers/ril/ril_devinfo.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_ecclist.c \
|
||||||
drivers/ril/ril_gprs.c \
|
drivers/ril/ril_gprs.c \
|
||||||
drivers/ril/ril_gprs_context.c \
|
drivers/ril/ril_gprs_context.c \
|
||||||
@@ -288,8 +288,7 @@ qmi_sources = drivers/qmimodem/qmi.h drivers/qmimodem/qmi.c \
|
|||||||
drivers/qmimodem/wds.h \
|
drivers/qmimodem/wds.h \
|
||||||
drivers/qmimodem/pds.h \
|
drivers/qmimodem/pds.h \
|
||||||
drivers/qmimodem/common.h \
|
drivers/qmimodem/common.h \
|
||||||
drivers/qmimodem/wda.h \
|
drivers/qmimodem/wda.h
|
||||||
drivers/qmimodem/voice.h
|
|
||||||
|
|
||||||
builtin_modules += qmimodem
|
builtin_modules += qmimodem
|
||||||
builtin_sources += $(qmi_sources) \
|
builtin_sources += $(qmi_sources) \
|
||||||
@@ -305,7 +304,6 @@ builtin_sources += $(qmi_sources) \
|
|||||||
drivers/qmimodem/ussd.c \
|
drivers/qmimodem/ussd.c \
|
||||||
drivers/qmimodem/gprs.c \
|
drivers/qmimodem/gprs.c \
|
||||||
drivers/qmimodem/gprs-context.c \
|
drivers/qmimodem/gprs-context.c \
|
||||||
drivers/qmimodem/lte.c \
|
|
||||||
drivers/qmimodem/radio-settings.c \
|
drivers/qmimodem/radio-settings.c \
|
||||||
drivers/qmimodem/location-reporting.c \
|
drivers/qmimodem/location-reporting.c \
|
||||||
drivers/qmimodem/netmon.c
|
drivers/qmimodem/netmon.c
|
||||||
@@ -338,6 +336,7 @@ builtin_sources += drivers/atmodem/atmodem.h \
|
|||||||
drivers/atmodem/atutil.c \
|
drivers/atmodem/atutil.c \
|
||||||
drivers/atmodem/gprs.c \
|
drivers/atmodem/gprs.c \
|
||||||
drivers/atmodem/gprs-context.c \
|
drivers/atmodem/gprs-context.c \
|
||||||
|
drivers/atmodem/sim-auth.c \
|
||||||
drivers/atmodem/gnss.c \
|
drivers/atmodem/gnss.c \
|
||||||
drivers/atmodem/lte.c
|
drivers/atmodem/lte.c
|
||||||
|
|
||||||
@@ -474,8 +473,7 @@ builtin_modules += xmm7modem
|
|||||||
builtin_sources += drivers/atmodem/atutil.h \
|
builtin_sources += drivers/atmodem/atutil.h \
|
||||||
drivers/xmm7modem/xmm7modem.h \
|
drivers/xmm7modem/xmm7modem.h \
|
||||||
drivers/xmm7modem/xmm7modem.c \
|
drivers/xmm7modem/xmm7modem.c \
|
||||||
drivers/xmm7modem/radio-settings.c \
|
drivers/xmm7modem/radio-settings.c
|
||||||
drivers/xmm7modem/ims.c
|
|
||||||
|
|
||||||
if PHONESIM
|
if PHONESIM
|
||||||
builtin_modules += phonesim
|
builtin_modules += phonesim
|
||||||
@@ -571,6 +569,9 @@ builtin_sources += plugins/samsung.c
|
|||||||
builtin_modules += sim900
|
builtin_modules += sim900
|
||||||
builtin_sources += plugins/sim900.c
|
builtin_sources += plugins/sim900.c
|
||||||
|
|
||||||
|
builtin_modules += connman
|
||||||
|
builtin_sources += plugins/connman.c
|
||||||
|
|
||||||
builtin_modules += telit
|
builtin_modules += telit
|
||||||
builtin_sources += plugins/telit.c
|
builtin_sources += plugins/telit.c
|
||||||
|
|
||||||
@@ -713,36 +714,6 @@ builtin_sources += plugins/smshistory.c
|
|||||||
builtin_modules += allowed_apns
|
builtin_modules += allowed_apns
|
||||||
builtin_sources += plugins/allowed-apns.c
|
builtin_sources += plugins/allowed-apns.c
|
||||||
|
|
||||||
if ELL
|
|
||||||
builtin_cflags += @ELL_CFLAGS@
|
|
||||||
builtin_libadd += @ELL_LIBS@
|
|
||||||
|
|
||||||
if MBIMMODEM
|
|
||||||
mbim_sources = drivers/mbimmodem/mbim.h \
|
|
||||||
drivers/mbimmodem/mbim.c \
|
|
||||||
drivers/mbimmodem/mbim-desc.h \
|
|
||||||
drivers/mbimmodem/mbim-desc.c \
|
|
||||||
drivers/mbimmodem/mbim-message.h \
|
|
||||||
drivers/mbimmodem/mbim-message.c
|
|
||||||
|
|
||||||
builtin_modules += mbimmodem
|
|
||||||
builtin_sources += $(mbim_sources) \
|
|
||||||
drivers/mbimmodem/util.h \
|
|
||||||
drivers/mbimmodem/util.c \
|
|
||||||
drivers/mbimmodem/mbimmodem.h \
|
|
||||||
drivers/mbimmodem/mbimmodem.c \
|
|
||||||
drivers/mbimmodem/devinfo.c \
|
|
||||||
drivers/mbimmodem/sim.c \
|
|
||||||
drivers/mbimmodem/network-registration.c \
|
|
||||||
drivers/mbimmodem/sms.c \
|
|
||||||
drivers/mbimmodem/gprs.c \
|
|
||||||
drivers/mbimmodem/gprs-context.c
|
|
||||||
|
|
||||||
builtin_modules += mbim
|
|
||||||
builtin_sources += plugins/mbim.c
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
sbin_PROGRAMS = src/ofonod
|
sbin_PROGRAMS = src/ofonod
|
||||||
|
|
||||||
src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
|
src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
|
||||||
@@ -773,10 +744,10 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
|
|||||||
src/handsfree-audio.c src/bluetooth.h \
|
src/handsfree-audio.c src/bluetooth.h \
|
||||||
src/sim-mnclength.c src/voicecallagent.c \
|
src/sim-mnclength.c src/voicecallagent.c \
|
||||||
src/sms-filter.c src/gprs-filter.c \
|
src/sms-filter.c src/gprs-filter.c \
|
||||||
src/dbus-queue.c src/dbus-access.c src/config.c \
|
src/dbus-queue.c src/dbus-access.c \
|
||||||
src/voicecall-filter.c src/ril-transport.c \
|
src/voicecall-filter.c src/ril-transport.c \
|
||||||
src/hfp.h src/siri.c src/watchlist.c \
|
src/hfp.h src/siri.c src/watchlist.c \
|
||||||
src/netmon.c src/lte.c src/ims.c \
|
src/netmon.c src/lte.c \
|
||||||
src/netmonagent.c src/netmonagent.h
|
src/netmonagent.c src/netmonagent.h
|
||||||
|
|
||||||
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
||||||
@@ -804,8 +775,7 @@ AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ $(builtin_cflags) \
|
|||||||
|
|
||||||
AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/src \
|
AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/src \
|
||||||
-I$(srcdir)/gdbus -I$(srcdir)/gisi -I$(srcdir)/gatchat \
|
-I$(srcdir)/gdbus -I$(srcdir)/gisi -I$(srcdir)/gatchat \
|
||||||
-I$(srcdir)/btio -I$(srcdir)/gril \
|
-I$(srcdir)/btio -I$(srcdir)/gril
|
||||||
-I$(srcdir)/plugins/sailfish_manager
|
|
||||||
|
|
||||||
doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
|
doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
|
||||||
doc/manager-api.txt doc/modem-api.txt doc/network-api.txt \
|
doc/manager-api.txt doc/modem-api.txt doc/network-api.txt \
|
||||||
@@ -829,8 +799,7 @@ doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
|
|||||||
doc/networkmonitor-api.txt \
|
doc/networkmonitor-api.txt \
|
||||||
doc/allowed-apns-api.txt \
|
doc/allowed-apns-api.txt \
|
||||||
doc/lte-api.txt \
|
doc/lte-api.txt \
|
||||||
doc/cinterion-hardware-monitor-api.txt \
|
doc/cinterion-hardware-monitor-api.txt
|
||||||
doc/ims-api.txt
|
|
||||||
|
|
||||||
|
|
||||||
test_scripts = test/backtrace \
|
test_scripts = test/backtrace \
|
||||||
@@ -939,10 +908,7 @@ test_scripts = test/backtrace \
|
|||||||
test/enable-throttling \
|
test/enable-throttling \
|
||||||
test/disable-throttling \
|
test/disable-throttling \
|
||||||
test/set-lte-property \
|
test/set-lte-property \
|
||||||
test/test-serving-cell-info \
|
test/test-serving-cell-info
|
||||||
test/ims-register \
|
|
||||||
test/ims-unregister \
|
|
||||||
test/list-applications
|
|
||||||
|
|
||||||
|
|
||||||
if TEST
|
if TEST
|
||||||
@@ -969,7 +935,8 @@ if SAILFISH_MANAGER
|
|||||||
|
|
||||||
unit_test_sailfish_cell_info_SOURCES = unit/test-sailfish_cell_info.c \
|
unit_test_sailfish_cell_info_SOURCES = unit/test-sailfish_cell_info.c \
|
||||||
plugins/sailfish_manager/sailfish_cell_info.c
|
plugins/sailfish_manager/sailfish_cell_info.c
|
||||||
unit_test_sailfish_cell_info_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT)
|
unit_test_sailfish_cell_info_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||||
|
-Iplugins/sailfish_manager
|
||||||
unit_test_sailfish_cell_info_LDADD = @GLIB_LIBS@ -ldl
|
unit_test_sailfish_cell_info_LDADD = @GLIB_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_sailfish_cell_info_OBJECTS)
|
unit_objects += $(unit_test_sailfish_cell_info_OBJECTS)
|
||||||
unit_tests += unit/test-sailfish_cell_info
|
unit_tests += unit/test-sailfish_cell_info
|
||||||
@@ -982,7 +949,7 @@ unit_test_sailfish_cell_info_dbus_SOURCES = unit/test-dbus.c \
|
|||||||
gdbus/object.c \
|
gdbus/object.c \
|
||||||
src/dbus.c src/log.c
|
src/dbus.c src/log.c
|
||||||
unit_test_sailfish_cell_info_dbus_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
unit_test_sailfish_cell_info_dbus_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||||
@DBUS_GLIB_CFLAGS@
|
@DBUS_GLIB_CFLAGS@ -Iplugins/sailfish_manager
|
||||||
unit_test_sailfish_cell_info_dbus_LDADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@ -ldl
|
unit_test_sailfish_cell_info_dbus_LDADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_sailfish_cell_info_dbus_OBJECTS)
|
unit_objects += $(unit_test_sailfish_cell_info_dbus_OBJECTS)
|
||||||
unit_tests += unit/test-sailfish_cell_info_dbus
|
unit_tests += unit/test-sailfish_cell_info_dbus
|
||||||
@@ -992,7 +959,7 @@ unit_test_sailfish_sim_info_SOURCES = unit/test-sailfish_sim_info.c \
|
|||||||
plugins/sailfish_manager/sailfish_sim_info.c \
|
plugins/sailfish_manager/sailfish_sim_info.c \
|
||||||
src/storage.c src/watchlist.c src/log.c
|
src/storage.c src/watchlist.c src/log.c
|
||||||
unit_test_sailfish_sim_info_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS) \
|
unit_test_sailfish_sim_info_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS) \
|
||||||
-DSTORAGEDIR='"/tmp/ofono"'
|
-DSTORAGEDIR='"/tmp/ofono"' -Iplugins/sailfish_manager
|
||||||
unit_test_sailfish_sim_info_LDADD = @GLIB_LIBS@ -ldl
|
unit_test_sailfish_sim_info_LDADD = @GLIB_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_sailfish_sim_info_OBJECTS)
|
unit_objects += $(unit_test_sailfish_sim_info_OBJECTS)
|
||||||
unit_tests += unit/test-sailfish_sim_info
|
unit_tests += unit/test-sailfish_sim_info
|
||||||
@@ -1004,7 +971,8 @@ unit_test_sailfish_sim_info_dbus_SOURCES = unit/test-sailfish_sim_info_dbus.c \
|
|||||||
gdbus/object.c \
|
gdbus/object.c \
|
||||||
src/dbus.c src/storage.c src/watchlist.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) \
|
unit_test_sailfish_sim_info_dbus_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS) \
|
||||||
@DBUS_GLIB_CFLAGS@ -DSTORAGEDIR='"/tmp/ofono"'
|
@DBUS_GLIB_CFLAGS@ -DSTORAGEDIR='"/tmp/ofono"' \
|
||||||
|
-Iplugins/sailfish_manager
|
||||||
unit_test_sailfish_sim_info_dbus_LDADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@ -ldl
|
unit_test_sailfish_sim_info_dbus_LDADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_sailfish_sim_info_dbus_OBJECTS)
|
unit_objects += $(unit_test_sailfish_sim_info_dbus_OBJECTS)
|
||||||
unit_tests += unit/test-sailfish_sim_info_dbus
|
unit_tests += unit/test-sailfish_sim_info_dbus
|
||||||
@@ -1016,7 +984,7 @@ unit_test_sailfish_manager_SOURCES = unit/test-sailfish_manager.c \
|
|||||||
plugins/sailfish_manager/sailfish_sim_info.c \
|
plugins/sailfish_manager/sailfish_sim_info.c \
|
||||||
src/storage.c src/log.c
|
src/storage.c src/log.c
|
||||||
unit_test_sailfish_manager_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
unit_test_sailfish_manager_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||||
-DSTORAGEDIR='"/tmp/ofono"'
|
-DSTORAGEDIR='"/tmp/ofono"' -Iplugins/sailfish_manager
|
||||||
unit_test_sailfish_manager_LDADD = @GLIB_LIBS@ -ldl
|
unit_test_sailfish_manager_LDADD = @GLIB_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_sailfish_manager_OBJECTS)
|
unit_objects += $(unit_test_sailfish_manager_OBJECTS)
|
||||||
unit_tests += unit/test-sailfish_manager
|
unit_tests += unit/test-sailfish_manager
|
||||||
@@ -1024,20 +992,13 @@ unit_tests += unit/test-sailfish_manager
|
|||||||
unit_test_watch_SOURCES = unit/test-watch.c src/watch.c \
|
unit_test_watch_SOURCES = unit/test-watch.c src/watch.c \
|
||||||
src/log.c src/watchlist.c
|
src/log.c src/watchlist.c
|
||||||
unit_test_watch_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
unit_test_watch_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||||
-DSTORAGEDIR='"/tmp/ofono"'
|
-DSTORAGEDIR='"/tmp/ofono"' -Iplugins/sailfish_manager
|
||||||
unit_test_watch_LDADD = @GLIB_LIBS@ -ldl
|
unit_test_watch_LDADD = @GLIB_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_watch_OBJECTS)
|
unit_objects += $(unit_test_watch_OBJECTS)
|
||||||
unit_tests += unit/test-watch
|
unit_tests += unit/test-watch
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
unit_test_config_SOURCES = unit/test-config.c drivers/ril/ril_util.c \
|
|
||||||
src/config.c src/log.c
|
|
||||||
unit_test_config_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
|
|
||||||
unit_test_config_LDADD = @GLIB_LIBS@ -ldl
|
|
||||||
unit_objects += $(unit_test_config_OBJECTS)
|
|
||||||
unit_tests += unit/test-config
|
|
||||||
|
|
||||||
if SAILFISH_ACCESS
|
if SAILFISH_ACCESS
|
||||||
unit_test_sailfish_access_SOURCES = unit/test-sailfish_access.c \
|
unit_test_sailfish_access_SOURCES = unit/test-sailfish_access.c \
|
||||||
plugins/sailfish_access.c src/dbus-access.c src/log.c
|
plugins/sailfish_access.c src/dbus-access.c src/log.c
|
||||||
@@ -1064,13 +1025,6 @@ unit_test_ril_config_LDADD = @GLIB_LIBS@ -ldl
|
|||||||
unit_objects += $(unit_test_ril_config_OBJECTS)
|
unit_objects += $(unit_test_ril_config_OBJECTS)
|
||||||
unit_tests += unit/test-ril_config
|
unit_tests += unit/test-ril_config
|
||||||
|
|
||||||
unit_test_ril_ecclist_SOURCES = unit/test-ril_ecclist.c \
|
|
||||||
drivers/ril/ril_ecclist.c src/log.c
|
|
||||||
unit_test_ril_ecclist_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
|
|
||||||
unit_test_ril_ecclist_LDADD = @GLIB_LIBS@ -ldl
|
|
||||||
unit_objects += $(unit_test_ril_ecclist_OBJECTS)
|
|
||||||
unit_tests += unit/test-ril_ecclist
|
|
||||||
|
|
||||||
unit_test_ril_util_SOURCES = unit/test-ril_util.c drivers/ril/ril_util.c \
|
unit_test_ril_util_SOURCES = unit/test-ril_util.c drivers/ril/ril_util.c \
|
||||||
src/log.c
|
src/log.c
|
||||||
unit_test_ril_util_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
|
unit_test_ril_util_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
|
||||||
@@ -1096,13 +1050,6 @@ unit_tests += unit/test-rilmodem-cs \
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ELL
|
|
||||||
if MBIMMODEM
|
|
||||||
unit_tests += unit/test-mbim
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
noinst_PROGRAMS = $(unit_tests) \
|
noinst_PROGRAMS = $(unit_tests) \
|
||||||
unit/test-sms-root unit/test-mux unit/test-caif
|
unit/test-sms-root unit/test-mux unit/test-caif
|
||||||
|
|
||||||
@@ -1245,12 +1192,6 @@ unit_test_rilmodem_gprs_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
|||||||
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
|
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_rilmodem_gprs_OBJECTS)
|
unit_objects += $(unit_test_rilmodem_gprs_OBJECTS)
|
||||||
|
|
||||||
unit_test_mbim_SOURCES = unit/test-mbim.c \
|
|
||||||
drivers/mbimmodem/mbim-message.c \
|
|
||||||
drivers/mbimmodem/mbim.c
|
|
||||||
unit_test_mbim_LDADD = @ELL_LIBS@
|
|
||||||
unit_objects += $(unit_test_mbim_OBJECTS)
|
|
||||||
|
|
||||||
TESTS = $(unit_tests)
|
TESTS = $(unit_tests)
|
||||||
|
|
||||||
if TOOLS
|
if TOOLS
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.60)
|
AC_PREREQ(2.60)
|
||||||
AC_INIT(ofono, 1.23)
|
AC_INIT(ofono, 1.21)
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
|
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
|
||||||
AC_CONFIG_HEADERS(config.h)
|
AC_CONFIG_HEADERS(config.h)
|
||||||
@@ -183,19 +183,17 @@ AC_ARG_ENABLE(sailfish-rilmodem, AC_HELP_STRING([--enable-sailfish-rilmodem],
|
|||||||
[enable_sailfish_rilmodem="no"])
|
[enable_sailfish_rilmodem="no"])
|
||||||
AM_CONDITIONAL(SAILFISH_RILMODEM, test "${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
|
if (test "${enable_sailfish_rilmodem}" = "yes"); then
|
||||||
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.35, dummy=yes,
|
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.25, dummy=yes,
|
||||||
AC_MSG_ERROR(libgrilio >= 1.0.35 is required))
|
AC_MSG_ERROR(libgrilio >= 1.0.25 is required))
|
||||||
PKG_CHECK_MODULES(LIBMCE, libmce-glib >= 1.0.6, dummy=yes,
|
PKG_CHECK_MODULES(GLIBUTIL, libglibutil >= 1.0.30, dummy=yes,
|
||||||
AC_MSG_ERROR(libmce-glib >= 1.0.6 is required))
|
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))
|
||||||
CFLAGS="$CFLAGS $GRILIO_CFLAGS $LIBMCE_CFLAGS"
|
CFLAGS="$CFLAGS $GRILIO_CFLAGS $LIBMCE_CFLAGS"
|
||||||
LIBS="$LIBS $GRILIO_LIBS $LIBMCE_LIBS"
|
LIBS="$LIBS $GRILIO_LIBS $LIBMCE_LIBS"
|
||||||
enable_sailfish_manager=yes
|
enable_sailfish_manager=yes
|
||||||
|
need_glibutil=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(sailfish-manager,
|
AC_ARG_ENABLE(sailfish-manager,
|
||||||
@@ -204,10 +202,12 @@ AC_ARG_ENABLE(sailfish-manager,
|
|||||||
[enable_sailfish_manager=${enableval}])
|
[enable_sailfish_manager=${enableval}])
|
||||||
AM_CONDITIONAL(SAILFISH_MANAGER, test "${enable_sailfish_manager}" = "yes")
|
AM_CONDITIONAL(SAILFISH_MANAGER, test "${enable_sailfish_manager}" = "yes")
|
||||||
|
|
||||||
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1, dummy=yes,
|
if (test "${enable_sailfish_manager}" = "yes"); then
|
||||||
AC_MSG_ERROR(dbus-glib is required by unit tests))
|
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1, dummy=yes,
|
||||||
AC_SUBST(DBUS_GLIB_CFLAGS)
|
AC_MSG_ERROR(dbus-glib is required by unit tests))
|
||||||
AC_SUBST(DBUS_GLIB_LIBS)
|
AC_SUBST(DBUS_GLIB_CFLAGS)
|
||||||
|
AC_SUBST(DBUS_GLIB_LIBS)
|
||||||
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(add-remove-context, AC_HELP_STRING([--disable-add-remove-context],
|
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]), [
|
[don't allow to add or remove connection context over D-Bus]), [
|
||||||
@@ -292,25 +292,6 @@ AC_ARG_ENABLE(upower, AC_HELP_STRING([--disable-upower],
|
|||||||
[enable_upower=${enableval}])
|
[enable_upower=${enableval}])
|
||||||
AM_CONDITIONAL(UPOWER, test "${enable_power}" != "no")
|
AM_CONDITIONAL(UPOWER, test "${enable_power}" != "no")
|
||||||
|
|
||||||
AC_ARG_ENABLE(mbimmodem, AC_HELP_STRING([--enable-mbimmodem],
|
|
||||||
[enable MBIM based modem support]),
|
|
||||||
[enable_mbimmodem=${enableval}])
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(ell, AC_HELP_STRING([--enable-ell],
|
|
||||||
[enable support for ell]),
|
|
||||||
[enable_ell=${enableval}])
|
|
||||||
|
|
||||||
if (test "${enable_ell}" = "yes"); then
|
|
||||||
AC_DEFINE(HAVE_ELL, 1, [Defined if Ell is enabled])
|
|
||||||
PKG_CHECK_MODULES(ELL, ell >= 0.2, dummy=yes,
|
|
||||||
AC_MSG_ERROR(ell library >= 0.2 is required))
|
|
||||||
AC_SUBST(ELL_CFLAGS)
|
|
||||||
AC_SUBST(ELL_LIBS)
|
|
||||||
fi
|
|
||||||
|
|
||||||
AM_CONDITIONAL(MBIMMODEM, test "${enable_ell}" != "no" && test "${enable_mbimmodem}" = "yes")
|
|
||||||
AM_CONDITIONAL(ELL, test "${enable_ell}" != "no")
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
|
AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
|
||||||
[do not install configuration and data files]),
|
[do not install configuration and data files]),
|
||||||
[enable_datafiles=${enableval}])
|
[enable_datafiles=${enableval}])
|
||||||
@@ -322,10 +303,13 @@ AC_ARG_ENABLE(sailfish-pushforwarder, AC_HELP_STRING([--enable-sailfish-pushforw
|
|||||||
[enable_sailfish_pushforwarder="no"])
|
[enable_sailfish_pushforwarder="no"])
|
||||||
AM_CONDITIONAL(SAILFISH_PUSHFORWARDER, test "${enable_sailfish_pushforwarder}" != "no")
|
AM_CONDITIONAL(SAILFISH_PUSHFORWARDER, test "${enable_sailfish_pushforwarder}" != "no")
|
||||||
if (test "${enable_sailfish_pushforwarder}" != "no"); then
|
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,
|
PKG_CHECK_MODULES(WSPCODEC, libwspcodec >= 2.0, dummy=yes,
|
||||||
AC_MSG_ERROR(WSP decoder is required))
|
AC_MSG_ERROR(WSP decoder is required))
|
||||||
CFLAGS="$CFLAGS $WSPCODEC_CFLAGS"
|
CFLAGS="$CFLAGS $WSPCODEC_CFLAGS"
|
||||||
LIBS="$LIBS $WSPCODEC_LIBS"
|
LIBS="$LIBS $WSPCODEC_LIBS"
|
||||||
|
need_glibutil=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(sailfish-access, AC_HELP_STRING([--enable-sailfish-access],
|
AC_ARG_ENABLE(sailfish-access, AC_HELP_STRING([--enable-sailfish-access],
|
||||||
@@ -353,6 +337,11 @@ if (test "${enable_sailfish_debuglog}" = "yes"); then
|
|||||||
LIBS="$LIBS $DBUSLOG_LIBS"
|
LIBS="$LIBS $DBUSLOG_LIBS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if (test "${need_glibutil}" = "yes"); then
|
||||||
|
CFLAGS="$CFLAGS $GLIBUTIL_CFLAGS"
|
||||||
|
LIBS="$LIBS $GLIBUTIL_LIBS"
|
||||||
|
fi
|
||||||
|
|
||||||
if (test "${prefix}" = "NONE"); then
|
if (test "${prefix}" = "NONE"); then
|
||||||
dnl no prefix and no localstatedir, so default to /var
|
dnl no prefix and no localstatedir, so default to /var
|
||||||
if (test "$localstatedir" = '${prefix}/var'); then
|
if (test "$localstatedir" = '${prefix}/var'); then
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
IpMultimediaSystem Hierarchy
|
|
||||||
============================
|
|
||||||
|
|
||||||
Service org.ofono
|
|
||||||
Interface org.ofono.IpMultimediaSystem
|
|
||||||
Object path [variable prefix]/{modem0,modem1,...}
|
|
||||||
|
|
||||||
Methods dict GetProperties()
|
|
||||||
|
|
||||||
Returns all IpMultimediaSystem configuration properties.
|
|
||||||
|
|
||||||
void SetProperty(string property, variant value)
|
|
||||||
|
|
||||||
Changes the value of the specified property. Only
|
|
||||||
properties that are listed as readwrite are
|
|
||||||
changeable. On success a PropertyChanged signal
|
|
||||||
will be emitted.
|
|
||||||
|
|
||||||
Possible Errors: [service].Error.InProgress
|
|
||||||
[service].Error.InvalidArguments
|
|
||||||
[service].Error.Failed
|
|
||||||
|
|
||||||
void Register()
|
|
||||||
|
|
||||||
Attempts to register to IMS. A successful method return
|
|
||||||
indicates that the registration process could be
|
|
||||||
initiated successfully. The actual registration state
|
|
||||||
will be reflected by the 'Registered' property.
|
|
||||||
|
|
||||||
Possible Errors: [service].Error.InProgress
|
|
||||||
[service].Error.NotImplemented
|
|
||||||
|
|
||||||
void Unregister()
|
|
||||||
|
|
||||||
Attempts to unregister from IMS. A successful method
|
|
||||||
return indicates that the unregistration process could
|
|
||||||
be initiated successfully. The actual unregistration
|
|
||||||
state will be reflected by the 'Registered' property.
|
|
||||||
|
|
||||||
Possible Errors: [service].Error.InProgress
|
|
||||||
[service].Error.NotImplemented
|
|
||||||
|
|
||||||
Signals PropertyChanged(string property, variant value)
|
|
||||||
|
|
||||||
This signal indicates a changed value of the given
|
|
||||||
property.
|
|
||||||
|
|
||||||
Properties boolean Registered [readonly]
|
|
||||||
|
|
||||||
Contains the current IMS registration state.
|
|
||||||
|
|
||||||
boolean VoiceCapable [readonly, optional]
|
|
||||||
|
|
||||||
Boolean representing whether voice call transfer over
|
|
||||||
RTP (IMS) is available.
|
|
||||||
|
|
||||||
boolean SmsCapable [readonly, optional]
|
|
||||||
|
|
||||||
Boolean representing whether SMS-over-IMS is available.
|
|
||||||
@@ -95,13 +95,6 @@ Properties boolean Powered [readwrite]
|
|||||||
String representing the software version number of the
|
String representing the software version number of the
|
||||||
modem device.
|
modem device.
|
||||||
|
|
||||||
string SystemPath [readonly, optional]
|
|
||||||
|
|
||||||
String representing the system path for the modem
|
|
||||||
device.
|
|
||||||
For modems detected by udev events, this corresponds to
|
|
||||||
the modem sysfs path.
|
|
||||||
|
|
||||||
array{string} Features [readonly]
|
array{string} Features [readonly]
|
||||||
|
|
||||||
List of currently enabled features. It uses simple
|
List of currently enabled features. It uses simple
|
||||||
@@ -134,8 +127,6 @@ Properties boolean Powered [readwrite]
|
|||||||
org.ofono.CallVolume
|
org.ofono.CallVolume
|
||||||
org.ofono.CellBroadcast
|
org.ofono.CellBroadcast
|
||||||
org.ofono.Handsfree
|
org.ofono.Handsfree
|
||||||
org.ofono.IpMultimediaSystem
|
|
||||||
org.ofono.LongTermEvolution
|
|
||||||
org.ofono.LocationReporting
|
org.ofono.LocationReporting
|
||||||
org.ofono.MessageManager
|
org.ofono.MessageManager
|
||||||
org.ofono.MessageWaiting
|
org.ofono.MessageWaiting
|
||||||
|
|||||||
@@ -200,8 +200,3 @@ Properties boolean Present [readonly]
|
|||||||
might have changed the retry counters, i.e. calls to
|
might have changed the retry counters, i.e. calls to
|
||||||
ChangePin(), EnterPin(), ResetPin() LockPin(),
|
ChangePin(), EnterPin(), ResetPin() LockPin(),
|
||||||
UnlockPin().
|
UnlockPin().
|
||||||
|
|
||||||
string ImsPrivateIdentity [readonly, optional]
|
|
||||||
|
|
||||||
Contains the SIM's ImsPrivateIdentity, read from the
|
|
||||||
ISIM.
|
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
SimAuthentication heiarchy [experimental]
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
Service org.ofono
|
|
||||||
Interface org.ofono.SimAuthentication
|
|
||||||
Object path [variable prefix]/{modem0,modem1,...}
|
|
||||||
|
|
||||||
Methods array{object,dict} GetApplications()
|
|
||||||
|
|
||||||
Get an array of all SIM applications found during
|
|
||||||
discovery. In the format "a{oa{sv}}" where 'o' is
|
|
||||||
the object path for the application e.g.
|
|
||||||
|
|
||||||
o = "/modem1/A0000000871004FFFFFFFF8906190000"
|
|
||||||
|
|
||||||
Each dictionary will contain 'Type' e.g. 'Ims' and
|
|
||||||
'Name' e.g. 'ISim'
|
|
||||||
|
|
||||||
For each application there will be a corresponding
|
|
||||||
object that matches the path (o). The type will
|
|
||||||
signify which interfaces are under that object (below).
|
|
||||||
|
|
||||||
type = Umts --> org.ofono.USimApplication
|
|
||||||
type = Ims --> org.ofono.ISimApplication
|
|
||||||
|
|
||||||
SimAuth USIM application heiarchy [experimental]
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
Service org.ofono
|
|
||||||
Interface org.ofono.USimApplication
|
|
||||||
Object path [variable prefix]/{modem0,modem1,...}/{AID name}
|
|
||||||
|
|
||||||
Methods dict GetProperties()
|
|
||||||
|
|
||||||
Returns properties for the USimApplication. See
|
|
||||||
properties section for available properties.
|
|
||||||
|
|
||||||
array{dict{string, array{byte}}}
|
|
||||||
GsmAuthenticate(array{array{byte}} rands)
|
|
||||||
|
|
||||||
Run the USIM application GSM AUTHENTICATE algorithm
|
|
||||||
with N random challenges 'rands'. This should be an
|
|
||||||
array of an array of bytes ("aay"). The number of
|
|
||||||
random challenges is limited to a maximum of 3.
|
|
||||||
|
|
||||||
Returns the derived Kc/SRES values as an array of
|
|
||||||
dictionaries. The index of each dictionary matches
|
|
||||||
the index of the rand value in the method call. The
|
|
||||||
keys for each dictionary are "Kc" and "SRES" and both
|
|
||||||
are arrays of bytes.
|
|
||||||
|
|
||||||
Possible Errors:
|
|
||||||
[service].Error.NotSupported
|
|
||||||
[service].Error.Busy
|
|
||||||
|
|
||||||
dict{string, array{byte}}
|
|
||||||
UmtsAuthenticate(array{byte} rand, array{byte} autn)
|
|
||||||
|
|
||||||
Run the UMTS AUTHENTICATE algorithm in the 3G
|
|
||||||
context with 'rand' and 'autn'. A dictionary will be
|
|
||||||
returned containing 'RES', 'CK', 'IK' and possibly
|
|
||||||
'Kc' if service 27 is available. If there was a
|
|
||||||
sync error 'AUTS' will be returned.
|
|
||||||
|
|
||||||
Possible Errors: [service].Error.NotSupported
|
|
||||||
|
|
||||||
Properties string Type [readonly]
|
|
||||||
|
|
||||||
Type of application: 'Umts'
|
|
||||||
|
|
||||||
string Name [readonly]
|
|
||||||
|
|
||||||
Human readable name: 'USim'
|
|
||||||
|
|
||||||
SimAuth ISIM application heiarchy [experimental]
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
Service org.ofono
|
|
||||||
Interface org.ofono.ISimApplication
|
|
||||||
Object [variable prefix]/{modem0,modem1,...}/{AID name}
|
|
||||||
|
|
||||||
Methods dict GetProperties()
|
|
||||||
|
|
||||||
Returns properties for the ISimApplication. See
|
|
||||||
the properties section for available properties.
|
|
||||||
|
|
||||||
dict{string, array{byte}
|
|
||||||
ImsAuthenticate(array{byte} rand, array{byte} autn)
|
|
||||||
|
|
||||||
Run the UMTS AUTHENTICATE algorithm in the IMS
|
|
||||||
context with 'rand' and 'autn'. A dictionary will be
|
|
||||||
returned containing 'RES', 'CK', 'IK' and possibly
|
|
||||||
'Kc' if service 27 is available. If there was a
|
|
||||||
sync error 'AUTS' will be returned.
|
|
||||||
|
|
||||||
Possible Errors: [service].Error.NotSupported
|
|
||||||
|
|
||||||
Properties string Type [readonly]
|
|
||||||
|
|
||||||
Type of application: 'Ims'
|
|
||||||
|
|
||||||
string Name [readonly]
|
|
||||||
|
|
||||||
Human readable name: 'ISim'
|
|
||||||
@@ -59,27 +59,6 @@ Methods dict GetProperties()
|
|||||||
[service].Error.NotImplemented
|
[service].Error.NotImplemented
|
||||||
[service].Error.Failed
|
[service].Error.Failed
|
||||||
|
|
||||||
object DialLast()
|
|
||||||
|
|
||||||
Initiates a new outgoing call to the last dialled number.
|
|
||||||
|
|
||||||
Possible Errors: [service].Error.InProgress
|
|
||||||
[service].Error.InvalidArguments
|
|
||||||
[service].Error.InvalidFormat
|
|
||||||
[service].Error.NotImplemented
|
|
||||||
[service].Error.Failed
|
|
||||||
|
|
||||||
object DialMemory(string memory position, string hide_callerid)
|
|
||||||
|
|
||||||
Initiates a new outgoing call to the number in the given memory
|
|
||||||
position/favourite. For callerid see the Dial method.
|
|
||||||
|
|
||||||
Possible Errors: [service].Error.InProgress
|
|
||||||
[service].Error.InvalidArguments
|
|
||||||
[service].Error.InvalidFormat
|
|
||||||
[service].Error.NotImplemented
|
|
||||||
[service].Error.Failed
|
|
||||||
|
|
||||||
void Transfer()
|
void Transfer()
|
||||||
|
|
||||||
Joins the currently Active (or Outgoing, depending
|
Joins the currently Active (or Outgoing, depending
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ static int atmodem_init(void)
|
|||||||
at_call_volume_init();
|
at_call_volume_init();
|
||||||
at_gprs_init();
|
at_gprs_init();
|
||||||
at_gprs_context_init();
|
at_gprs_context_init();
|
||||||
|
at_sim_auth_init();
|
||||||
at_gnss_init();
|
at_gnss_init();
|
||||||
at_lte_init();
|
at_lte_init();
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ static int atmodem_init(void)
|
|||||||
|
|
||||||
static void atmodem_exit(void)
|
static void atmodem_exit(void)
|
||||||
{
|
{
|
||||||
|
at_sim_auth_exit();
|
||||||
at_stk_exit();
|
at_stk_exit();
|
||||||
at_sim_exit();
|
at_sim_exit();
|
||||||
at_sms_exit();
|
at_sms_exit();
|
||||||
|
|||||||
164
ofono/drivers/atmodem/sim-auth.c
Normal file
164
ofono/drivers/atmodem/sim-auth.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <ofono/modem.h>
|
||||||
|
#include <ofono/sim-auth.h>
|
||||||
|
|
||||||
|
#include "gatchat.h"
|
||||||
|
#include "gatresult.h"
|
||||||
|
#include "simutil.h"
|
||||||
|
#include "vendor.h"
|
||||||
|
|
||||||
|
#include "atmodem.h"
|
||||||
|
|
||||||
|
struct sim_auth_data {
|
||||||
|
GAtChat *chat;
|
||||||
|
unsigned int vendor;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *cuad_prefix[] = { "+CUAD:", NULL };
|
||||||
|
|
||||||
|
static void at_discover_apps_cb(gboolean ok, GAtResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
GAtResultIter iter;
|
||||||
|
ofono_sim_list_apps_cb_t cb = cbd->cb;
|
||||||
|
struct ofono_error error;
|
||||||
|
const unsigned char *dataobj;
|
||||||
|
gint linelen;
|
||||||
|
unsigned char *buffer;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
decode_at_error(&error, g_at_result_final_response(result));
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
cb(&error, NULL, 0, cbd->data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_at_result_iter_init(&iter, result);
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
while (g_at_result_iter_next(&iter, "+CUAD:")) {
|
||||||
|
if (!g_at_result_iter_next_hexstring(&iter, NULL, &linelen))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
len += linelen;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_at_result_iter_init(&iter, result);
|
||||||
|
|
||||||
|
buffer = g_malloc(len);
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
while (g_at_result_iter_next(&iter, "+CUAD:")) {
|
||||||
|
g_at_result_iter_next_hexstring(&iter, &dataobj, &linelen);
|
||||||
|
memcpy(buffer + len, dataobj, linelen);
|
||||||
|
len += linelen;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(&error, buffer, len, cbd->data);
|
||||||
|
|
||||||
|
g_free(buffer);
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void at_discover_apps(struct ofono_sim_auth *sa,
|
||||||
|
ofono_sim_list_apps_cb_t cb,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct sim_auth_data *sad = ofono_sim_auth_get_data(sa);
|
||||||
|
struct cb_data *cbd = cb_data_new(cb, data);
|
||||||
|
|
||||||
|
if (g_at_chat_send(sad->chat, "AT+CUAD", cuad_prefix,
|
||||||
|
at_discover_apps_cb, cbd, g_free) > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free(cbd);
|
||||||
|
|
||||||
|
CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean at_sim_auth_register(gpointer user)
|
||||||
|
{
|
||||||
|
struct ofono_sim_auth *sa = user;
|
||||||
|
|
||||||
|
ofono_sim_auth_register(sa);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int at_sim_auth_probe(struct ofono_sim_auth *sa, unsigned int vendor,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
GAtChat *chat = data;
|
||||||
|
struct sim_auth_data *sad;
|
||||||
|
|
||||||
|
sad = g_new0(struct sim_auth_data, 1);
|
||||||
|
sad->chat = g_at_chat_clone(chat);
|
||||||
|
sad->vendor = vendor;
|
||||||
|
|
||||||
|
ofono_sim_auth_set_data(sa, sad);
|
||||||
|
g_idle_add(at_sim_auth_register, sa);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void at_sim_auth_remove(struct ofono_sim_auth *sa)
|
||||||
|
{
|
||||||
|
struct sim_auth_data *sad = ofono_sim_auth_get_data(sa);
|
||||||
|
|
||||||
|
g_idle_remove_by_data(sa);
|
||||||
|
ofono_sim_auth_set_data(sa, NULL);
|
||||||
|
|
||||||
|
g_at_chat_unref(sad->chat);
|
||||||
|
g_free(sad);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ofono_sim_auth_driver driver = {
|
||||||
|
.name = "atmodem",
|
||||||
|
.probe = at_sim_auth_probe,
|
||||||
|
.remove = at_sim_auth_remove,
|
||||||
|
.list_apps = at_discover_apps,
|
||||||
|
};
|
||||||
|
|
||||||
|
void at_sim_auth_init(void)
|
||||||
|
{
|
||||||
|
ofono_sim_auth_driver_register(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void at_sim_auth_exit(void)
|
||||||
|
{
|
||||||
|
ofono_sim_auth_driver_unregister(&driver);
|
||||||
|
}
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
#include "gatresult.h"
|
#include "gatresult.h"
|
||||||
#include "simutil.h"
|
#include "simutil.h"
|
||||||
#include "vendor.h"
|
#include "vendor.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include "atmodem.h"
|
#include "atmodem.h"
|
||||||
|
|
||||||
@@ -51,6 +50,7 @@
|
|||||||
struct sim_data {
|
struct sim_data {
|
||||||
GAtChat *chat;
|
GAtChat *chat;
|
||||||
unsigned int vendor;
|
unsigned int vendor;
|
||||||
|
guint ready_id;
|
||||||
guint passwd_type_mask;
|
guint passwd_type_mask;
|
||||||
struct at_util_sim_state_query *sim_state_query;
|
struct at_util_sim_state_query *sim_state_query;
|
||||||
};
|
};
|
||||||
@@ -65,36 +65,14 @@ static const char *pinnum_prefix[] = { "%PINNUM:", NULL };
|
|||||||
static const char *oercn_prefix[] = { "_OERCN:", NULL };
|
static const char *oercn_prefix[] = { "_OERCN:", NULL };
|
||||||
static const char *cpinr_prefixes[] = { "+CPINR:", "+CPINRE:", NULL };
|
static const char *cpinr_prefixes[] = { "+CPINR:", "+CPINRE:", NULL };
|
||||||
static const char *epin_prefix[] = { "*EPIN:", NULL };
|
static const char *epin_prefix[] = { "*EPIN:", NULL };
|
||||||
static const char *simcom_spic_prefix[] = { "+SPIC:", NULL };
|
static const char *spic_prefix[] = { "+SPIC:", NULL };
|
||||||
static const char *cinterion_spic_prefix[] = { "^SPIC:", NULL };
|
|
||||||
static const char *pct_prefix[] = { "#PCT:", NULL };
|
static const char *pct_prefix[] = { "#PCT:", NULL };
|
||||||
static const char *pnnm_prefix[] = { "+PNNM:", NULL };
|
static const char *pnnm_prefix[] = { "+PNNM:", NULL };
|
||||||
static const char *qpinc_prefix[] = { "+QPINC:", NULL };
|
static const char *qpinc_prefix[] = { "+QPINC:", NULL };
|
||||||
static const char *upincnt_prefix[] = { "+UPINCNT:", NULL };
|
static const char *upincnt_prefix[] = { "+UPINCNT:", NULL };
|
||||||
static const char *cuad_prefix[] = { "+CUAD:", NULL };
|
|
||||||
static const char *ccho_prefix[] = { "+CCHO:", NULL };
|
|
||||||
static const char *crla_prefix[] = { "+CRLA:", NULL };
|
|
||||||
static const char *cgla_prefix[] = { "+CGLA:", NULL };
|
|
||||||
static const char *none_prefix[] = { NULL };
|
static const char *none_prefix[] = { NULL };
|
||||||
|
|
||||||
static void append_file_path(char *buf, const unsigned char *path,
|
static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
unsigned int path_len)
|
|
||||||
{
|
|
||||||
if (path_len > 0) {
|
|
||||||
*buf++ = ',';
|
|
||||||
*buf++ = ',';
|
|
||||||
*buf++ = '\"';
|
|
||||||
|
|
||||||
for (; path_len; path_len--)
|
|
||||||
buf += sprintf(buf, "%02hhX", *path++);
|
|
||||||
|
|
||||||
*buf++ = '\"';
|
|
||||||
*buf = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_response_common_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data, const char *prefix)
|
|
||||||
{
|
{
|
||||||
struct cb_data *cbd = user_data;
|
struct cb_data *cbd = user_data;
|
||||||
GAtResultIter iter;
|
GAtResultIter iter;
|
||||||
@@ -116,7 +94,7 @@ static void get_response_common_cb(gboolean ok, GAtResult *result,
|
|||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
g_at_result_iter_init(&iter, result);
|
||||||
|
|
||||||
if (!g_at_result_iter_next(&iter, prefix))
|
if (!g_at_result_iter_next(&iter, "+CRSM:"))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
g_at_result_iter_next_number(&iter, &sw1);
|
g_at_result_iter_next_number(&iter, &sw1);
|
||||||
@@ -157,11 +135,6 @@ error:
|
|||||||
EF_STATUS_INVALIDATED, cbd->data);
|
EF_STATUS_INVALIDATED, cbd->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
|
||||||
{
|
|
||||||
get_response_common_cb(ok, result, user_data, "+CRSM:");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_sim_read_info(struct ofono_sim *sim, int fileid,
|
static void at_sim_read_info(struct ofono_sim *sim, int fileid,
|
||||||
const unsigned char *path,
|
const unsigned char *path,
|
||||||
unsigned int path_len,
|
unsigned int path_len,
|
||||||
@@ -203,7 +176,15 @@ static void at_sim_read_info(struct ofono_sim *sim, int fileid,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
append_file_path(buf + len, path, path_len);
|
if (path_len > 0) {
|
||||||
|
len += sprintf(buf + len, ",,\"");
|
||||||
|
|
||||||
|
for (; path_len; path_len--)
|
||||||
|
len += sprintf(buf + len, "%02hhX", *path++);
|
||||||
|
|
||||||
|
buf[len++] = '\"';
|
||||||
|
buf[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, buf, crsm_prefix,
|
if (g_at_chat_send(sd->chat, buf, crsm_prefix,
|
||||||
at_crsm_info_cb, cbd, g_free) > 0)
|
at_crsm_info_cb, cbd, g_free) > 0)
|
||||||
@@ -277,7 +258,17 @@ static void at_sim_read_binary(struct ofono_sim *sim, int fileid,
|
|||||||
len = snprintf(buf, sizeof(buf), "AT+CRSM=176,%i,%i,%i,%i", fileid,
|
len = snprintf(buf, sizeof(buf), "AT+CRSM=176,%i,%i,%i,%i", fileid,
|
||||||
start >> 8, start & 0xff, length);
|
start >> 8, start & 0xff, length);
|
||||||
|
|
||||||
append_file_path(buf + len, path, path_len);
|
if (path_len > 0) {
|
||||||
|
buf[len++] = ',';
|
||||||
|
buf[len++] = ',';
|
||||||
|
buf[len++] = '\"';
|
||||||
|
|
||||||
|
for (; path_len; path_len--)
|
||||||
|
len += sprintf(buf + len, "%02hhX", *path++);
|
||||||
|
|
||||||
|
buf[len++] = '\"';
|
||||||
|
buf[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, buf, crsm_prefix,
|
if (g_at_chat_send(sd->chat, buf, crsm_prefix,
|
||||||
at_crsm_read_cb, cbd, g_free) > 0)
|
at_crsm_read_cb, cbd, g_free) > 0)
|
||||||
@@ -297,13 +288,10 @@ static void at_sim_read_record(struct ofono_sim *sim, int fileid,
|
|||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
struct cb_data *cbd = cb_data_new(cb, data);
|
||||||
char buf[128];
|
char buf[128];
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
len = snprintf(buf, sizeof(buf), "AT+CRSM=178,%i,%i,4,%i", fileid,
|
snprintf(buf, sizeof(buf), "AT+CRSM=178,%i,%i,4,%i", fileid,
|
||||||
record, length);
|
record, length);
|
||||||
|
|
||||||
append_file_path(buf + len, path, path_len);
|
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, buf, crsm_prefix,
|
if (g_at_chat_send(sd->chat, buf, crsm_prefix,
|
||||||
at_crsm_read_cb, cbd, g_free) > 0)
|
at_crsm_read_cb, cbd, g_free) > 0)
|
||||||
return;
|
return;
|
||||||
@@ -849,7 +837,7 @@ static void at_cpinr_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
|||||||
cb(&error, retries, cbd->data);
|
cb(&error, retries, cbd->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void simcom_spic_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
static void at_spic_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct cb_data *cbd = user_data;
|
struct cb_data *cbd = user_data;
|
||||||
ofono_sim_pin_retries_cb_t cb = cbd->cb;
|
ofono_sim_pin_retries_cb_t cb = cbd->cb;
|
||||||
@@ -1066,46 +1054,6 @@ error:
|
|||||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cinterion_spic_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
struct ofono_sim *sim = cbd->user;
|
|
||||||
ofono_sim_pin_retries_cb_t cb = cbd->cb;
|
|
||||||
const char *final = g_at_result_final_response(result);
|
|
||||||
GAtResultIter iter;
|
|
||||||
struct ofono_error error;
|
|
||||||
int retries[OFONO_SIM_PASSWORD_INVALID];
|
|
||||||
size_t i;
|
|
||||||
int pin_type = ofono_sim_get_password_type(sim);
|
|
||||||
|
|
||||||
decode_at_error(&error, final);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
cb(&error, NULL, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
|
|
||||||
retries[i] = -1;
|
|
||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next(&iter, "^SPIC:"))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next_number(&iter, &retries[pin_type]))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
DBG("Retry : %d, type : %d", retries[pin_type], pin_type);
|
|
||||||
cb(&error, retries, cbd->data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_pin_retries_query(struct ofono_sim *sim,
|
static void at_pin_retries_query(struct ofono_sim *sim,
|
||||||
ofono_sim_pin_retries_cb_t cb,
|
ofono_sim_pin_retries_cb_t cb,
|
||||||
void *data)
|
void *data)
|
||||||
@@ -1153,8 +1101,8 @@ static void at_pin_retries_query(struct ofono_sim *sim,
|
|||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case OFONO_VENDOR_SIMCOM:
|
case OFONO_VENDOR_SIMCOM:
|
||||||
if (g_at_chat_send(sd->chat, "AT+SPIC", simcom_spic_prefix,
|
if (g_at_chat_send(sd->chat, "AT+SPIC", spic_prefix,
|
||||||
simcom_spic_cb, cbd, g_free) > 0)
|
at_spic_cb, cbd, g_free) > 0)
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case OFONO_VENDOR_TELIT:
|
case OFONO_VENDOR_TELIT:
|
||||||
@@ -1178,11 +1126,6 @@ static void at_pin_retries_query(struct ofono_sim *sim,
|
|||||||
upincnt_cb, cbd, g_free) > 0)
|
upincnt_cb, cbd, g_free) > 0)
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case OFONO_VENDOR_CINTERION:
|
|
||||||
if (g_at_chat_send(sd->chat, "AT^SPIC", cinterion_spic_prefix,
|
|
||||||
cinterion_spic_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
if (g_at_chat_send(sd->chat, "AT+CPINR", cpinr_prefixes,
|
if (g_at_chat_send(sd->chat, "AT+CPINR", cpinr_prefixes,
|
||||||
at_cpinr_cb, cbd, g_free) > 0)
|
at_cpinr_cb, cbd, g_free) > 0)
|
||||||
@@ -1273,24 +1216,100 @@ static void at_pin_query(struct ofono_sim *sim, ofono_sim_passwd_cb_t cb,
|
|||||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void at_xsim_notify(GAtResult *result, gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
struct sim_data *sd = cbd->user;
|
||||||
|
ofono_sim_lock_unlock_cb_t cb = cbd->cb;
|
||||||
|
struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
|
||||||
|
GAtResultIter iter;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
g_at_result_iter_init(&iter, result);
|
||||||
|
|
||||||
|
if (!g_at_result_iter_next(&iter, "+XSIM:"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!g_at_result_iter_next_number(&iter, &state))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case 3: /* PIN verified – Ready */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(&error, cbd->data);
|
||||||
|
|
||||||
|
g_at_chat_unregister(sd->chat, sd->ready_id);
|
||||||
|
sd->ready_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void at_epev_notify(GAtResult *result, gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
struct sim_data *sd = cbd->user;
|
||||||
|
ofono_sim_lock_unlock_cb_t cb = cbd->cb;
|
||||||
|
struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
|
||||||
|
|
||||||
|
cb(&error, cbd->data);
|
||||||
|
|
||||||
|
g_at_chat_unregister(sd->chat, sd->ready_id);
|
||||||
|
sd->ready_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void at_qss_notify(GAtResult *result, gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
struct sim_data *sd = cbd->user;
|
||||||
|
ofono_sim_lock_unlock_cb_t cb = cbd->cb;
|
||||||
|
struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
|
||||||
|
GAtResultIter iter;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
g_at_result_iter_init(&iter, result);
|
||||||
|
|
||||||
|
if (!g_at_result_iter_next(&iter, "#QSS:"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!g_at_result_iter_next_number(&iter, &state))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case 3: /* SIM inserted and READY. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(&error, cbd->data);
|
||||||
|
|
||||||
|
g_at_chat_unregister(sd->chat, sd->ready_id);
|
||||||
|
sd->ready_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void sim_state_cb(gboolean present, gpointer user_data)
|
static void sim_state_cb(gboolean present, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct ofono_sim *sim = user_data;
|
struct cb_data *cbd = user_data;
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
struct sim_data *sd = cbd->user;
|
||||||
|
ofono_sim_lock_unlock_cb_t cb = cbd->cb;
|
||||||
|
void *data = cbd->data;
|
||||||
|
|
||||||
at_util_sim_state_query_free(sd->sim_state_query);
|
at_util_sim_state_query_free(sd->sim_state_query);
|
||||||
sd->sim_state_query = NULL;
|
sd->sim_state_query = NULL;
|
||||||
|
|
||||||
if (present == 1)
|
if (present == 1)
|
||||||
ofono_sim_initialized_notify(sim);
|
CALLBACK_WITH_SUCCESS(cb, data);
|
||||||
|
else
|
||||||
|
CALLBACK_WITH_FAILURE(cb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void at_pin_send_cb(gboolean ok, GAtResult *result,
|
static void at_pin_send_cb(gboolean ok, GAtResult *result,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
struct cb_data *cbd = user_data;
|
struct cb_data *cbd = user_data;
|
||||||
struct ofono_sim *sim = cbd->user;
|
struct sim_data *sd = cbd->user;
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
ofono_sim_lock_unlock_cb_t cb = cbd->cb;
|
ofono_sim_lock_unlock_cb_t cb = cbd->cb;
|
||||||
struct ofono_error error;
|
struct ofono_error error;
|
||||||
|
|
||||||
@@ -1300,6 +1319,36 @@ static void at_pin_send_cb(gboolean ok, GAtResult *result,
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
switch (sd->vendor) {
|
switch (sd->vendor) {
|
||||||
|
case OFONO_VENDOR_IFX:
|
||||||
|
/*
|
||||||
|
* On the IFX modem, AT+CPIN? can return READY too
|
||||||
|
* early and so use +XSIM notification to detect
|
||||||
|
* the ready state of the SIM.
|
||||||
|
*/
|
||||||
|
sd->ready_id = g_at_chat_register(sd->chat, "+XSIM",
|
||||||
|
at_xsim_notify,
|
||||||
|
FALSE, cbd, g_free);
|
||||||
|
return;
|
||||||
|
case OFONO_VENDOR_MBM:
|
||||||
|
/*
|
||||||
|
* On the MBM modem, AT+CPIN? keeps returning SIM PIN
|
||||||
|
* for a moment after successful AT+CPIN="..", but then
|
||||||
|
* sends *EPEV when that changes.
|
||||||
|
*/
|
||||||
|
sd->ready_id = g_at_chat_register(sd->chat, "*EPEV",
|
||||||
|
at_epev_notify,
|
||||||
|
FALSE, cbd, g_free);
|
||||||
|
return;
|
||||||
|
case OFONO_VENDOR_TELIT:
|
||||||
|
/*
|
||||||
|
* On the Telit modem, AT+CPIN? can return READY too
|
||||||
|
* early and so use #QSS notification to detect
|
||||||
|
* the ready state of the SIM.
|
||||||
|
*/
|
||||||
|
sd->ready_id = g_at_chat_register(sd->chat, "#QSS",
|
||||||
|
at_qss_notify,
|
||||||
|
FALSE, cbd, g_free);
|
||||||
|
return;
|
||||||
case OFONO_VENDOR_ZTE:
|
case OFONO_VENDOR_ZTE:
|
||||||
case OFONO_VENDOR_ALCATEL:
|
case OFONO_VENDOR_ALCATEL:
|
||||||
case OFONO_VENDOR_HUAWEI:
|
case OFONO_VENDOR_HUAWEI:
|
||||||
@@ -1317,12 +1366,15 @@ static void at_pin_send_cb(gboolean ok, GAtResult *result,
|
|||||||
* state.
|
* state.
|
||||||
*/
|
*/
|
||||||
sd->sim_state_query = at_util_sim_state_query_new(sd->chat,
|
sd->sim_state_query = at_util_sim_state_query_new(sd->chat,
|
||||||
2, 20, sim_state_cb, sim,
|
2, 20, sim_state_cb, cbd,
|
||||||
NULL);
|
g_free);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
cb(&error, cbd->data);
|
cb(&error, cbd->data);
|
||||||
|
|
||||||
|
g_free(cbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void at_pin_send(struct ofono_sim *sim, const char *passwd,
|
static void at_pin_send(struct ofono_sim *sim, const char *passwd,
|
||||||
@@ -1333,12 +1385,12 @@ static void at_pin_send(struct ofono_sim *sim, const char *passwd,
|
|||||||
char buf[64];
|
char buf[64];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cbd->user = sim;
|
cbd->user = sd;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\"", passwd);
|
snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\"", passwd);
|
||||||
|
|
||||||
ret = g_at_chat_send(sd->chat, buf, none_prefix,
|
ret = g_at_chat_send(sd->chat, buf, none_prefix,
|
||||||
at_pin_send_cb, cbd, g_free);
|
at_pin_send_cb, cbd, NULL);
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
@@ -1551,327 +1603,6 @@ done:
|
|||||||
ofono_sim_register(sim);
|
ofono_sim_register(sim);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void at_discover_apps_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
GAtResultIter iter;
|
|
||||||
ofono_sim_list_apps_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_error error;
|
|
||||||
const unsigned char *buffer;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
cb(&error, NULL, 0, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next(&iter, "+CUAD:"))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next_hexstring(&iter, &buffer, &len))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cb(&error, buffer, len, cbd->data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_discover_apps(struct ofono_sim *sim,
|
|
||||||
ofono_sim_list_apps_cb_t cb,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, "AT+CUAD", cuad_prefix,
|
|
||||||
at_discover_apps_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_open_channel_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
GAtResultIter iter;
|
|
||||||
ofono_sim_open_channel_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_error error;
|
|
||||||
int session_id = -1;
|
|
||||||
|
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
|
||||||
|
|
||||||
if (!ok)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next(&iter, "+CCHO:"))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next_number(&iter, &session_id))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cb(&error, session_id, cbd->data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
cb(&error, -1, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_open_channel(struct ofono_sim *sim, const unsigned char *aid,
|
|
||||||
ofono_sim_open_channel_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
char cmd[43];
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
strcpy(cmd, "AT+CCHO=\"");
|
|
||||||
ret += 9;
|
|
||||||
|
|
||||||
encode_hex_own_buf(aid, 16, 0, cmd + ret);
|
|
||||||
ret += 32;
|
|
||||||
|
|
||||||
strcpy(cmd + ret, "\"");
|
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, cmd, ccho_prefix, at_open_channel_cb,
|
|
||||||
cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_close_channel_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
ofono_sim_close_channel_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_error error;
|
|
||||||
|
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
|
||||||
|
|
||||||
if (cb)
|
|
||||||
cb(&error, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_close_channel(struct ofono_sim *sim, int session_id,
|
|
||||||
ofono_sim_close_channel_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
char cmd[15];
|
|
||||||
|
|
||||||
sprintf(cmd, "AT+CCHC=%d", session_id);
|
|
||||||
|
|
||||||
g_at_chat_send(sd->chat, cmd, NULL, at_close_channel_cb, cbd, g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_crla_read_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
GAtResultIter iter;
|
|
||||||
ofono_sim_read_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_error error;
|
|
||||||
const guint8 *response;
|
|
||||||
gint sw1, sw2, len;
|
|
||||||
|
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
cb(&error, NULL, 0, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next(&iter, "+CRLA:")) {
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_at_result_iter_next_number(&iter, &sw1);
|
|
||||||
g_at_result_iter_next_number(&iter, &sw2);
|
|
||||||
|
|
||||||
if ((sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92 && sw1 != 0x9f) ||
|
|
||||||
(sw1 == 0x90 && sw2 != 0x00)) {
|
|
||||||
memset(&error, 0, sizeof(error));
|
|
||||||
|
|
||||||
error.type = OFONO_ERROR_TYPE_SIM;
|
|
||||||
error.error = (sw1 << 8) | sw2;
|
|
||||||
|
|
||||||
cb(&error, NULL, 0, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next_hexstring(&iter, &response, &len)) {
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG("crla_read_cb: %02x, %02x, %d", sw1, sw2, len);
|
|
||||||
|
|
||||||
cb(&error, response, len, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_session_read_binary(struct ofono_sim *sim, int session,
|
|
||||||
int fileid, int start, int length,
|
|
||||||
const unsigned char *path,
|
|
||||||
unsigned int path_len,
|
|
||||||
ofono_sim_read_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
char buf[64];
|
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
len = snprintf(buf, sizeof(buf), "AT+CRLA=%i,176,%i,%i,%i,%i,,",
|
|
||||||
session, fileid, start >> 8, start & 0xff, length);
|
|
||||||
|
|
||||||
append_file_path(buf + len, path, path_len);
|
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, buf, crla_prefix,
|
|
||||||
at_crla_read_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_session_read_record(struct ofono_sim *sim, int session_id,
|
|
||||||
int fileid, int record, int length,
|
|
||||||
const unsigned char *path,
|
|
||||||
unsigned int path_len,
|
|
||||||
ofono_sim_read_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
char buf[128];
|
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
len = snprintf(buf, sizeof(buf), "AT+CRLA=%i,178,%i,%i,4,%i",
|
|
||||||
session_id, fileid, record, length);
|
|
||||||
|
|
||||||
append_file_path(buf + len, path, path_len);
|
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, buf, crla_prefix,
|
|
||||||
at_crla_read_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_crla_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
|
||||||
{
|
|
||||||
get_response_common_cb(ok, result, user_data, "+CRLA:");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_session_read_info(struct ofono_sim *sim, int session_id,
|
|
||||||
int fileid, const unsigned char *path,
|
|
||||||
unsigned int path_len,
|
|
||||||
ofono_sim_file_info_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
char buf[128];
|
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
len = snprintf(buf, sizeof(buf), "AT+CRLA=%i,192,%i", session_id,
|
|
||||||
fileid);
|
|
||||||
|
|
||||||
append_file_path(buf + len, path, path_len);
|
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, buf, crla_prefix,
|
|
||||||
at_crla_info_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL,
|
|
||||||
EF_STATUS_INVALIDATED, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void logical_access_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
ofono_sim_logical_access_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_error error;
|
|
||||||
const char *str_data;
|
|
||||||
unsigned char *raw;
|
|
||||||
gint len = 0;
|
|
||||||
GAtResultIter iter;
|
|
||||||
|
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
|
||||||
|
|
||||||
if (!ok)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next(&iter, "+CGLA:"))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next_number(&iter, &len))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next_string(&iter, &str_data))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
raw = alloca(len / 2);
|
|
||||||
|
|
||||||
decode_hex_own_buf(str_data, len, NULL, 0, raw);
|
|
||||||
|
|
||||||
cb(&error, raw, len / 2, cbd->data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
cb(&error, NULL, 0, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_logical_access(struct ofono_sim *sim, int session_id,
|
|
||||||
const unsigned char *pdu, unsigned int len,
|
|
||||||
ofono_sim_logical_access_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
int ret = 0;
|
|
||||||
char cmd[(len * 2) + 19];
|
|
||||||
|
|
||||||
ret = sprintf(cmd, "AT+CGLA=%d,%d,\"", session_id, len * 2);
|
|
||||||
|
|
||||||
encode_hex_own_buf(pdu, len, 0, cmd + ret);
|
|
||||||
ret += len * 2;
|
|
||||||
|
|
||||||
strcpy(cmd + ret, "\"");
|
|
||||||
|
|
||||||
if (g_at_chat_send(sd->chat, cmd, cgla_prefix, logical_access_cb,
|
|
||||||
cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int at_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
static int at_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
@@ -1883,6 +1614,9 @@ static int at_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
|||||||
sd->chat = g_at_chat_clone(chat);
|
sd->chat = g_at_chat_clone(chat);
|
||||||
sd->vendor = vendor;
|
sd->vendor = vendor;
|
||||||
|
|
||||||
|
if (sd->vendor == OFONO_VENDOR_MBM)
|
||||||
|
g_at_chat_send(sd->chat, "AT*EPEE=1", NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
ofono_sim_set_data(sim, sd);
|
ofono_sim_set_data(sim, sd);
|
||||||
|
|
||||||
/* <fac>s supported by default */
|
/* <fac>s supported by default */
|
||||||
@@ -1928,13 +1662,6 @@ static struct ofono_sim_driver driver = {
|
|||||||
.lock = at_pin_enable,
|
.lock = at_pin_enable,
|
||||||
.change_passwd = at_change_passwd,
|
.change_passwd = at_change_passwd,
|
||||||
.query_facility_lock = at_query_clck,
|
.query_facility_lock = at_query_clck,
|
||||||
.list_apps = at_discover_apps,
|
|
||||||
.open_channel = at_open_channel,
|
|
||||||
.close_channel = at_close_channel,
|
|
||||||
.session_read_binary = at_session_read_binary,
|
|
||||||
.session_read_record = at_session_read_record,
|
|
||||||
.session_read_info = at_session_read_info,
|
|
||||||
.logical_access = at_logical_access
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofono_sim_driver driver_noef = {
|
static struct ofono_sim_driver driver_noef = {
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ static struct ofono_call *create_call(struct ofono_voicecall *vc, int type,
|
|||||||
if (clip != 2) {
|
if (clip != 2) {
|
||||||
strncpy(call->phone_number.number, num,
|
strncpy(call->phone_number.number, num,
|
||||||
OFONO_MAX_PHONE_NUMBER_LENGTH);
|
OFONO_MAX_PHONE_NUMBER_LENGTH);
|
||||||
call->phone_number.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
|
|
||||||
call->phone_number.type = num_type;
|
call->phone_number.type = num_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,45 +404,6 @@ static void hfp_dial(struct ofono_voicecall *vc,
|
|||||||
CALLBACK_WITH_FAILURE(cb, data);
|
CALLBACK_WITH_FAILURE(cb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hfp_dial_last(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
|
|
||||||
cbd->user = vc;
|
|
||||||
|
|
||||||
if (g_at_chat_send(vd->chat, "AT+BLDN", none_prefix,
|
|
||||||
atd_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hfp_dial_memory(struct ofono_voicecall *vc,
|
|
||||||
unsigned int memory_location,
|
|
||||||
ofono_voicecall_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
char buf[256];
|
|
||||||
|
|
||||||
cbd->user = vc;
|
|
||||||
DBG("Calling memory location %d\n", memory_location);
|
|
||||||
snprintf(buf, sizeof(buf), "ATD>%d;", memory_location);
|
|
||||||
|
|
||||||
if (g_at_chat_send(vd->chat, buf, none_prefix,
|
|
||||||
atd_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(cbd);
|
|
||||||
DBG("at_chat_failed");
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hfp_template(const char *cmd, struct ofono_voicecall *vc,
|
static void hfp_template(const char *cmd, struct ofono_voicecall *vc,
|
||||||
GAtResultFunc result_cb, unsigned int affected_types,
|
GAtResultFunc result_cb, unsigned int affected_types,
|
||||||
ofono_voicecall_cb_t cb, void *data)
|
ofono_voicecall_cb_t cb, void *data)
|
||||||
@@ -1308,8 +1268,6 @@ static struct ofono_voicecall_driver driver = {
|
|||||||
.probe = hfp_voicecall_probe,
|
.probe = hfp_voicecall_probe,
|
||||||
.remove = hfp_voicecall_remove,
|
.remove = hfp_voicecall_remove,
|
||||||
.dial = hfp_dial,
|
.dial = hfp_dial,
|
||||||
.dial_last = hfp_dial_last,
|
|
||||||
.dial_memory = hfp_dial_memory,
|
|
||||||
.answer = hfp_answer,
|
.answer = hfp_answer,
|
||||||
.hangup_active = hfp_hangup,
|
.hangup_active = hfp_hangup,
|
||||||
.hold_all_active = hfp_hold_all_active,
|
.hold_all_active = hfp_hold_all_active,
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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 <ofono/log.h>
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/devinfo.h>
|
|
||||||
|
|
||||||
#include "drivers/mbimmodem/mbimmodem.h"
|
|
||||||
|
|
||||||
struct devinfo_data {
|
|
||||||
struct l_idle *delayed_register;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mbim_query_revision(struct ofono_devinfo *info,
|
|
||||||
ofono_devinfo_query_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = ofono_devinfo_get_modem(info);
|
|
||||||
const char *revision = ofono_modem_get_string(modem, "FirmwareInfo");
|
|
||||||
|
|
||||||
if (revision)
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, revision, data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_query_serial(struct ofono_devinfo *info,
|
|
||||||
ofono_devinfo_query_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = ofono_devinfo_get_modem(info);
|
|
||||||
const char *serial = ofono_modem_get_string(modem, "DeviceId");
|
|
||||||
|
|
||||||
if (serial)
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, serial, data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void delayed_register(struct l_idle *idle, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_devinfo *info = user_data;
|
|
||||||
struct devinfo_data *dd = ofono_devinfo_get_data(info);
|
|
||||||
|
|
||||||
l_idle_remove(idle);
|
|
||||||
dd->delayed_register = NULL;
|
|
||||||
|
|
||||||
ofono_devinfo_register(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_devinfo_probe(struct ofono_devinfo *info, unsigned int vendor,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct devinfo_data *dd = l_new(struct devinfo_data, 1);
|
|
||||||
|
|
||||||
dd->delayed_register = l_idle_create(delayed_register, info, NULL);
|
|
||||||
ofono_devinfo_set_data(info, dd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_devinfo_remove(struct ofono_devinfo *info)
|
|
||||||
{
|
|
||||||
struct devinfo_data *dd = ofono_devinfo_get_data(info);
|
|
||||||
|
|
||||||
ofono_devinfo_set_data(info, NULL);
|
|
||||||
l_idle_remove(dd->delayed_register);
|
|
||||||
l_free(dd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_devinfo_driver driver = {
|
|
||||||
.name = "mbim",
|
|
||||||
.probe = mbim_devinfo_probe,
|
|
||||||
.remove = mbim_devinfo_remove,
|
|
||||||
.query_revision = mbim_query_revision,
|
|
||||||
.query_serial = mbim_query_serial,
|
|
||||||
};
|
|
||||||
|
|
||||||
void mbim_devinfo_init(void)
|
|
||||||
{
|
|
||||||
ofono_devinfo_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbim_devinfo_exit(void)
|
|
||||||
{
|
|
||||||
ofono_devinfo_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -1,464 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/gprs-context.h>
|
|
||||||
|
|
||||||
#include "drivers/mbimmodem/mbim.h"
|
|
||||||
#include "drivers/mbimmodem/mbim-message.h"
|
|
||||||
#include "drivers/mbimmodem/mbimmodem.h"
|
|
||||||
|
|
||||||
enum state {
|
|
||||||
STATE_IDLE,
|
|
||||||
STATE_ENABLING,
|
|
||||||
STATE_DISABLING,
|
|
||||||
STATE_ACTIVE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gprs_context_data {
|
|
||||||
struct mbim_device *device;
|
|
||||||
unsigned int active_context;
|
|
||||||
enum ofono_gprs_proto proto;
|
|
||||||
enum state state;
|
|
||||||
ofono_gprs_context_cb_t cb;
|
|
||||||
void *cb_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint32_t proto_to_context_ip_type(enum ofono_gprs_proto proto)
|
|
||||||
{
|
|
||||||
switch (proto) {
|
|
||||||
case OFONO_GPRS_PROTO_IP:
|
|
||||||
return 1; /* MBIMContextIPTypeIPv4 */
|
|
||||||
case OFONO_GPRS_PROTO_IPV6:
|
|
||||||
return 2; /* MBIMContextIPTypeIPv6 */
|
|
||||||
case OFONO_GPRS_PROTO_IPV4V6:
|
|
||||||
return 3; /* MBIMContextIPTypeIPv4v6 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t auth_method_to_auth_protocol(enum ofono_gprs_auth_method method)
|
|
||||||
{
|
|
||||||
switch (method) {
|
|
||||||
case OFONO_GPRS_AUTH_METHOD_CHAP:
|
|
||||||
return 2; /* MBIMAuthProtocolChap */
|
|
||||||
case OFONO_GPRS_AUTH_METHOD_PAP:
|
|
||||||
return 1; /* MBIMAuthProtocolPap */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_deactivate_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_gprs_context *gc = user;
|
|
||||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
gcd->active_context = 0;
|
|
||||||
gcd->state = STATE_IDLE;
|
|
||||||
|
|
||||||
if (!gcd->cb)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_gprs_deactivate_primary(struct ofono_gprs_context *gc,
|
|
||||||
unsigned int cid,
|
|
||||||
ofono_gprs_context_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("cid %u", cid);
|
|
||||||
|
|
||||||
gcd->state = STATE_DISABLING;
|
|
||||||
gcd->cb = cb;
|
|
||||||
gcd->cb_data = data;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_CONNECT,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "uusssuuu16y",
|
|
||||||
cid, 0, NULL, NULL, NULL, 0, 0, 0,
|
|
||||||
mbim_context_type_internet);
|
|
||||||
|
|
||||||
if (mbim_device_send(gcd->device, GPRS_CONTEXT_GROUP, message,
|
|
||||||
mbim_deactivate_cb, gc, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mbim_message_unref(message);
|
|
||||||
|
|
||||||
if (cb)
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_ip_configuration_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_gprs_context *gc = user;
|
|
||||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
|
||||||
struct ofono_modem *modem = ofono_gprs_context_get_modem(gc);
|
|
||||||
const char *interface;
|
|
||||||
uint32_t session_id;
|
|
||||||
uint32_t ipv4_config_available;
|
|
||||||
uint32_t ipv6_config_available;
|
|
||||||
uint32_t n_ipv4_addr;
|
|
||||||
uint32_t ipv4_addr_offset;
|
|
||||||
uint32_t n_ipv6_addr;
|
|
||||||
uint32_t ipv6_addr_offset;
|
|
||||||
uint32_t ipv4_gw_offset;
|
|
||||||
uint32_t ipv6_gw_offset;
|
|
||||||
uint32_t n_ipv4_dns;
|
|
||||||
uint32_t ipv4_dns_offset;
|
|
||||||
uint32_t n_ipv6_dns;
|
|
||||||
uint32_t ipv6_dns_offset;
|
|
||||||
uint32_t ipv4_mtu;
|
|
||||||
uint32_t ipv6_mtu;
|
|
||||||
|
|
||||||
struct in6_addr ipv6;
|
|
||||||
struct in_addr ipv4;
|
|
||||||
char buf[INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
DBG("%u", mbim_message_get_error(message));
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuuuuuuuuuuuuuu",
|
|
||||||
&session_id,
|
|
||||||
&ipv4_config_available, &ipv6_config_available,
|
|
||||||
&n_ipv4_addr, &ipv4_addr_offset,
|
|
||||||
&n_ipv6_addr, &ipv6_addr_offset,
|
|
||||||
&ipv4_gw_offset, &ipv6_gw_offset,
|
|
||||||
&n_ipv4_dns, &ipv4_dns_offset,
|
|
||||||
&n_ipv6_dns, &ipv6_dns_offset,
|
|
||||||
&ipv4_mtu, &ipv6_mtu))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (gcd->proto == OFONO_GPRS_PROTO_IPV6)
|
|
||||||
goto ipv6;
|
|
||||||
|
|
||||||
if (ipv4_config_available & 0x1) { /* Address Info present */
|
|
||||||
uint32_t prefix;
|
|
||||||
|
|
||||||
if (!mbim_message_get_ipv4_element(message, ipv4_addr_offset,
|
|
||||||
&prefix, &ipv4))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET, &ipv4, buf, sizeof(buf));
|
|
||||||
ofono_gprs_context_set_ipv4_address(gc, buf, TRUE);
|
|
||||||
ofono_gprs_context_set_ipv4_prefix_length(gc, prefix);
|
|
||||||
} else
|
|
||||||
ofono_gprs_context_set_ipv4_address(gc, NULL, FALSE);
|
|
||||||
|
|
||||||
if (ipv4_config_available & 0x2) { /* IPv4 Gateway info */
|
|
||||||
if (!mbim_message_get_ipv4_address(message,
|
|
||||||
ipv4_gw_offset, &ipv4))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET, &ipv4, buf, sizeof(buf));
|
|
||||||
|
|
||||||
ofono_gprs_context_set_ipv4_gateway(gc, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipv4_config_available & 0x3) { /* IPv4 DNS Info */
|
|
||||||
const char *dns[3];
|
|
||||||
char dns1[INET_ADDRSTRLEN];
|
|
||||||
char dns2[INET_ADDRSTRLEN];
|
|
||||||
|
|
||||||
memset(dns, 0, sizeof(dns));
|
|
||||||
|
|
||||||
if (n_ipv4_dns > 1) { /* Grab second DNS */
|
|
||||||
if (!mbim_message_get_ipv4_address(message,
|
|
||||||
ipv4_dns_offset + 4,
|
|
||||||
&ipv4))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET, &ipv4, dns2, sizeof(dns2));
|
|
||||||
dns[1] = dns2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_ipv4_dns > 0) { /* Grab first DNS */
|
|
||||||
if (!mbim_message_get_ipv4_address(message,
|
|
||||||
ipv4_dns_offset,
|
|
||||||
&ipv4))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET, &ipv4, dns1, sizeof(dns1));
|
|
||||||
dns[0] = dns1;
|
|
||||||
|
|
||||||
ofono_gprs_context_set_ipv4_dns_servers(gc, dns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gcd->proto == OFONO_GPRS_PROTO_IP)
|
|
||||||
goto done;
|
|
||||||
ipv6:
|
|
||||||
if (ipv6_config_available & 0x1) { /* Address Info present */
|
|
||||||
uint32_t prefix;
|
|
||||||
|
|
||||||
if (!mbim_message_get_ipv6_element(message, ipv6_addr_offset,
|
|
||||||
&prefix, &ipv6))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET6, &ipv6, buf, sizeof(buf));
|
|
||||||
ofono_gprs_context_set_ipv6_address(gc, buf);
|
|
||||||
ofono_gprs_context_set_ipv6_prefix_length(gc, prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipv6_config_available & 0x2) { /* IPv6 Gateway info */
|
|
||||||
if (!mbim_message_get_ipv6_address(message,
|
|
||||||
ipv6_gw_offset, &ipv6))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET6, &ipv6, buf, sizeof(buf));
|
|
||||||
|
|
||||||
ofono_gprs_context_set_ipv6_gateway(gc, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipv6_config_available & 0x3) { /* IPv6 DNS Info */
|
|
||||||
const char *dns[3];
|
|
||||||
char dns1[INET6_ADDRSTRLEN];
|
|
||||||
char dns2[INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
memset(dns, 0, sizeof(dns));
|
|
||||||
|
|
||||||
if (n_ipv6_dns > 1) { /* Grab second DNS */
|
|
||||||
if (!mbim_message_get_ipv6_address(message,
|
|
||||||
ipv6_dns_offset + 16,
|
|
||||||
&ipv6))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET6, &ipv6, dns2, sizeof(dns2));
|
|
||||||
dns[1] = dns2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_ipv6_dns > 0) { /* Grab first DNS */
|
|
||||||
if (!mbim_message_get_ipv6_address(message,
|
|
||||||
ipv6_dns_offset,
|
|
||||||
&ipv6))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
inet_ntop(AF_INET6, &ipv6, dns1, sizeof(dns1));
|
|
||||||
dns[0] = dns1;
|
|
||||||
|
|
||||||
ofono_gprs_context_set_ipv6_dns_servers(gc, dns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
|
|
||||||
gcd->state = STATE_ACTIVE;
|
|
||||||
interface = ofono_modem_get_string(modem, "NetworkInterface");
|
|
||||||
ofono_gprs_context_set_interface(gc, interface);
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
|
|
||||||
gcd->cb = NULL;
|
|
||||||
gcd->cb_data = NULL;
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
|
|
||||||
gcd->state = STATE_IDLE;
|
|
||||||
gcd->cb = NULL;
|
|
||||||
gcd->cb_data = NULL;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_CONNECT,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "uusssuuu16y",
|
|
||||||
gcd->active_context, 0,
|
|
||||||
NULL, NULL, NULL, 0, 0, 0,
|
|
||||||
mbim_context_type_internet);
|
|
||||||
|
|
||||||
if (!mbim_device_send(gcd->device, GPRS_CONTEXT_GROUP, message,
|
|
||||||
NULL, NULL, NULL))
|
|
||||||
mbim_message_unref(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_activate_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_gprs_context *gc = user;
|
|
||||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_IP_CONFIGURATION,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "uuuuuuuuuuuuuuu",
|
|
||||||
gcd->active_context,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
if (mbim_device_send(gcd->device, GPRS_CONTEXT_GROUP, message,
|
|
||||||
mbim_ip_configuration_cb, gc, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
|
|
||||||
gcd->state = STATE_IDLE;
|
|
||||||
gcd->cb = NULL;
|
|
||||||
gcd->cb_data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_gprs_activate_primary(struct ofono_gprs_context *gc,
|
|
||||||
const struct ofono_gprs_primary_context *ctx,
|
|
||||||
ofono_gprs_context_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("cid %u", ctx->cid);
|
|
||||||
|
|
||||||
gcd->state = STATE_ENABLING;
|
|
||||||
gcd->cb = cb;
|
|
||||||
gcd->cb_data = data;
|
|
||||||
gcd->active_context = ctx->cid;
|
|
||||||
gcd->proto = ctx->proto;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_CONNECT,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "uusssuuu16y",
|
|
||||||
ctx->cid,
|
|
||||||
1, /* MBIMActivationCommandActivate */
|
|
||||||
ctx->apn,
|
|
||||||
ctx->username[0] ? ctx->username : NULL,
|
|
||||||
ctx->password[0] ? ctx->password : NULL,
|
|
||||||
0, /*MBIMCompressionNone */
|
|
||||||
auth_method_to_auth_protocol(ctx->auth_method),
|
|
||||||
proto_to_context_ip_type(ctx->proto),
|
|
||||||
mbim_context_type_internet);
|
|
||||||
|
|
||||||
if (mbim_device_send(gcd->device, GPRS_CONTEXT_GROUP, message,
|
|
||||||
mbim_activate_cb, gc, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_gprs_detach_shutdown(struct ofono_gprs_context *gc,
|
|
||||||
unsigned int cid)
|
|
||||||
{
|
|
||||||
DBG("");
|
|
||||||
mbim_gprs_deactivate_primary(gc, cid, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_connect_notify(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
uint32_t session_id;
|
|
||||||
uint32_t activation_state;
|
|
||||||
uint32_t voice_call_state;
|
|
||||||
uint32_t ip_type;
|
|
||||||
uint8_t context_type[16];
|
|
||||||
uint32_t nw_error;
|
|
||||||
char uuidstr[37];
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuuu16yu",
|
|
||||||
&session_id, &activation_state,
|
|
||||||
&voice_call_state, &ip_type,
|
|
||||||
context_type, &nw_error))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("session_id: %u, activation_state: %u, ip_type: %u",
|
|
||||||
session_id, activation_state, ip_type);
|
|
||||||
l_uuid_to_string(context_type, uuidstr, sizeof(uuidstr));
|
|
||||||
DBG("context_type: %s, nw_error: %u", uuidstr, nw_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_gprs_context_probe(struct ofono_gprs_context *gc,
|
|
||||||
unsigned int vendor, void *data)
|
|
||||||
{
|
|
||||||
struct mbim_device *device = data;
|
|
||||||
struct gprs_context_data *gcd;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_device_register(device, GPRS_CONTEXT_GROUP,
|
|
||||||
mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_CONNECT,
|
|
||||||
mbim_connect_notify, gc, NULL))
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
gcd = l_new(struct gprs_context_data, 1);
|
|
||||||
gcd->device = mbim_device_ref(device);
|
|
||||||
|
|
||||||
ofono_gprs_context_set_data(gc, gcd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_gprs_context_remove(struct ofono_gprs_context *gc)
|
|
||||||
{
|
|
||||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
ofono_gprs_context_set_data(gc, NULL);
|
|
||||||
|
|
||||||
mbim_device_cancel_group(gcd->device, GPRS_CONTEXT_GROUP);
|
|
||||||
mbim_device_unregister_group(gcd->device, GPRS_CONTEXT_GROUP);
|
|
||||||
mbim_device_unref(gcd->device);
|
|
||||||
gcd->device = NULL;
|
|
||||||
l_free(gcd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_gprs_context_driver driver = {
|
|
||||||
.name = "mbim",
|
|
||||||
.probe = mbim_gprs_context_probe,
|
|
||||||
.remove = mbim_gprs_context_remove,
|
|
||||||
.activate_primary = mbim_gprs_activate_primary,
|
|
||||||
.deactivate_primary = mbim_gprs_deactivate_primary,
|
|
||||||
.detach_shutdown = mbim_gprs_detach_shutdown
|
|
||||||
};
|
|
||||||
|
|
||||||
void mbim_gprs_context_init(void)
|
|
||||||
{
|
|
||||||
ofono_gprs_context_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbim_gprs_context_exit(void)
|
|
||||||
{
|
|
||||||
ofono_gprs_context_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -1,299 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/gprs.h>
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "drivers/mbimmodem/mbim.h"
|
|
||||||
#include "drivers/mbimmodem/mbim-message.h"
|
|
||||||
#include "drivers/mbimmodem/mbimmodem.h"
|
|
||||||
|
|
||||||
struct gprs_data {
|
|
||||||
struct mbim_device *device;
|
|
||||||
struct l_idle *delayed_register;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mbim_packet_service_set_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_gprs_cb_t cb = cbd->cb;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_gprs_set_attached(struct ofono_gprs *gprs, int attached,
|
|
||||||
ofono_gprs_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_PACKET_SERVICE,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
/*
|
|
||||||
* MBIMPacketServiceActionAttach (0) or
|
|
||||||
* MBIMPacketServiceActionDetach (1)
|
|
||||||
*/
|
|
||||||
mbim_message_set_arguments(message, "u", attached ? 0 : 1);
|
|
||||||
|
|
||||||
if (mbim_device_send(gd->device, GPRS_GROUP, message,
|
|
||||||
mbim_packet_service_set_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_packet_service_query_cb(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_gprs_status_cb_t cb = cbd->cb;
|
|
||||||
uint32_t dummy;
|
|
||||||
uint32_t state;
|
|
||||||
|
|
||||||
DBG("%u", mbim_message_get_error(message));
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uu", &dummy, &state))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (state == 2)
|
|
||||||
CALLBACK_WITH_SUCCESS(cb,
|
|
||||||
NETWORK_REGISTRATION_STATUS_REGISTERED,
|
|
||||||
cbd->data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, NETWORK_REGISTRATION_STATUS_UNKNOWN,
|
|
||||||
cbd->data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_gprs_registration_status(struct ofono_gprs *gprs,
|
|
||||||
ofono_gprs_status_cb_t cb,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_PACKET_SERVICE,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (mbim_device_send(gd->device, GPRS_GROUP, message,
|
|
||||||
mbim_packet_service_query_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_packet_service_changed(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_gprs *gprs = user;
|
|
||||||
uint32_t nw_error;
|
|
||||||
uint32_t packet_service_state;
|
|
||||||
uint32_t highest_avail_data_class;
|
|
||||||
uint64_t uplink_speed;
|
|
||||||
uint64_t downlink_speed;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuutt",
|
|
||||||
&nw_error,
|
|
||||||
&packet_service_state,
|
|
||||||
&highest_avail_data_class,
|
|
||||||
&uplink_speed,
|
|
||||||
&downlink_speed))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("uplink: %"PRIu64", downlink: %"PRIu64,
|
|
||||||
uplink_speed, downlink_speed);
|
|
||||||
DBG("nw_error: %u", nw_error);
|
|
||||||
|
|
||||||
if (packet_service_state == 2) {
|
|
||||||
uint32_t bearer =
|
|
||||||
mbim_data_class_to_tech(highest_avail_data_class);
|
|
||||||
|
|
||||||
ofono_gprs_status_notify(gprs,
|
|
||||||
NETWORK_REGISTRATION_STATUS_REGISTERED);
|
|
||||||
ofono_gprs_bearer_notify(gprs, bearer);
|
|
||||||
} else
|
|
||||||
ofono_gprs_status_notify(gprs,
|
|
||||||
NETWORK_REGISTRATION_STATUS_UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void provisioned_contexts_query_cb(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct mbim_message_iter contexts;
|
|
||||||
uint32_t n_contexts;
|
|
||||||
uint32_t id;
|
|
||||||
uint8_t type[16];
|
|
||||||
char *apn;
|
|
||||||
char *username;
|
|
||||||
char *password;
|
|
||||||
uint32_t compression;
|
|
||||||
uint32_t auth_protocol;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "a(u16ysssuu)",
|
|
||||||
&n_contexts, &contexts))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("n_contexts: %u", n_contexts);
|
|
||||||
|
|
||||||
while (mbim_message_iter_next_entry(&contexts, &id, type, &apn,
|
|
||||||
&username, &password,
|
|
||||||
&compression, &auth_protocol)) {
|
|
||||||
char uuidstr[37];
|
|
||||||
|
|
||||||
l_uuid_to_string(type, uuidstr, sizeof(uuidstr));
|
|
||||||
DBG("id: %u, type: %s", id, uuidstr);
|
|
||||||
DBG("apn: %s, username: %s, password: %s",
|
|
||||||
apn, username, password);
|
|
||||||
DBG("compression: %u, auth_protocol: %u",
|
|
||||||
compression, auth_protocol);
|
|
||||||
|
|
||||||
l_free(apn);
|
|
||||||
l_free(username);
|
|
||||||
l_free(password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void delayed_register(struct l_idle *idle, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_gprs *gprs = user_data;
|
|
||||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
l_idle_remove(idle);
|
|
||||||
gd->delayed_register = NULL;
|
|
||||||
|
|
||||||
/* Query provisioned contexts for debugging purposes only */
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_PROVISIONED_CONTEXTS,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
mbim_device_send(gd->device, 0, message,
|
|
||||||
provisioned_contexts_query_cb, gprs, NULL);
|
|
||||||
|
|
||||||
if (!mbim_device_register(gd->device, GPRS_GROUP,
|
|
||||||
mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_PACKET_SERVICE,
|
|
||||||
mbim_packet_service_changed,
|
|
||||||
gprs, NULL))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ofono_gprs_register(gprs);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_gprs_remove(gprs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_gprs_probe(struct ofono_gprs *gprs, unsigned int vendor,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct mbim_device *device = data;
|
|
||||||
struct gprs_data *gd;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
gd = l_new(struct gprs_data, 1);
|
|
||||||
gd->device = mbim_device_ref(device);
|
|
||||||
gd->delayed_register = l_idle_create(delayed_register, gprs, NULL);
|
|
||||||
|
|
||||||
ofono_gprs_set_data(gprs, gd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_gprs_remove(struct ofono_gprs *gprs)
|
|
||||||
{
|
|
||||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
ofono_gprs_set_data(gprs, NULL);
|
|
||||||
|
|
||||||
l_idle_remove(gd->delayed_register);
|
|
||||||
mbim_device_cancel_group(gd->device, GPRS_GROUP);
|
|
||||||
mbim_device_unregister_group(gd->device, GPRS_GROUP);
|
|
||||||
mbim_device_unref(gd->device);
|
|
||||||
gd->device = NULL;
|
|
||||||
l_free(gd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_gprs_driver driver = {
|
|
||||||
.name = "mbim",
|
|
||||||
.probe = mbim_gprs_probe,
|
|
||||||
.remove = mbim_gprs_remove,
|
|
||||||
.set_attached = mbim_gprs_set_attached,
|
|
||||||
.attached_status = mbim_gprs_registration_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
void mbim_gprs_init(void)
|
|
||||||
{
|
|
||||||
ofono_gprs_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbim_gprs_exit(void)
|
|
||||||
{
|
|
||||||
ofono_gprs_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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 <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "mbim-desc.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Attempts to find MBIM specific descriptors.
|
|
||||||
*
|
|
||||||
* Returns true if the MBIM Function descriptor was found, false otherwise.
|
|
||||||
*/
|
|
||||||
bool mbim_find_descriptors(const uint8_t *data, size_t data_len,
|
|
||||||
const struct mbim_desc **out_desc,
|
|
||||||
const struct mbim_extended_desc **out_ext_desc)
|
|
||||||
{
|
|
||||||
bool r = false;
|
|
||||||
|
|
||||||
while (data_len > 3) {
|
|
||||||
uint8_t len = data[0];
|
|
||||||
|
|
||||||
if (data[1] != 0x24)
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
/* MBIM v1.0, Table 4-3 */
|
|
||||||
switch (data[2]) {
|
|
||||||
case 0x1b:
|
|
||||||
if (!out_desc)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (len != sizeof(struct mbim_desc) || data_len < len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*out_desc = (const struct mbim_desc *) data;
|
|
||||||
r = true;
|
|
||||||
break;
|
|
||||||
case 0x1c:
|
|
||||||
if (!out_ext_desc)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (len != sizeof(struct mbim_extended_desc) ||
|
|
||||||
data_len < len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*out_ext_desc =
|
|
||||||
(const struct mbim_extended_desc *) data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
|
||||||
data_len -= len;
|
|
||||||
data += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
/* MBIM v1.0, Section 6.4: MBIM Functional Descriptor */
|
|
||||||
struct mbim_desc {
|
|
||||||
uint8_t bFunctionLength;
|
|
||||||
uint8_t bDescriptorType;
|
|
||||||
uint8_t bDescriptorSubtype;
|
|
||||||
__le16 bcdMBIMVersion;
|
|
||||||
__le16 wMaxControlMessage;
|
|
||||||
uint8_t bNumberFilters;
|
|
||||||
uint8_t bMaxFilterSize;
|
|
||||||
__le16 wMaxSegmentSize;
|
|
||||||
uint8_t bmNetworkCapabilities;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
/* MBIM v1.0, Section 6.5: MBIM Extended Functional Descriptor */
|
|
||||||
struct mbim_extended_desc {
|
|
||||||
uint8_t bFunctionLength;
|
|
||||||
uint8_t bDescriptorType;
|
|
||||||
uint8_t bDescriptorSubtype;
|
|
||||||
__le16 bcdMBIMExtendedVersion;
|
|
||||||
uint8_t bMaxOutstandingCommandMessages;
|
|
||||||
__le16 wMTU;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
bool mbim_find_descriptors(const uint8_t *data, size_t data_len,
|
|
||||||
const struct mbim_desc **out_desc,
|
|
||||||
const struct mbim_extended_desc **out_ext_desc);
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
struct mbim_message;
|
|
||||||
struct mbim_message_iter;
|
|
||||||
|
|
||||||
enum mbim_command_type {
|
|
||||||
MBIM_COMMAND_TYPE_QUERY = 0,
|
|
||||||
MBIM_COMMAND_TYPE_SET = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mbim_message_iter {
|
|
||||||
const char *sig_start;
|
|
||||||
uint8_t sig_len;
|
|
||||||
uint8_t sig_pos;
|
|
||||||
const struct iovec *iov;
|
|
||||||
uint32_t n_iov;
|
|
||||||
uint32_t cur_iov;
|
|
||||||
size_t cur_iov_offset;
|
|
||||||
size_t len;
|
|
||||||
size_t pos;
|
|
||||||
size_t base_offset;
|
|
||||||
uint32_t n_elem;
|
|
||||||
char container_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mbim_message *mbim_message_new(const uint8_t *uuid, uint32_t cid,
|
|
||||||
enum mbim_command_type type);
|
|
||||||
struct mbim_message *mbim_message_ref(struct mbim_message *msg);
|
|
||||||
void mbim_message_unref(struct mbim_message *msg);
|
|
||||||
|
|
||||||
uint32_t mbim_message_get_error(struct mbim_message *message);
|
|
||||||
uint32_t mbim_message_get_cid(struct mbim_message *message);
|
|
||||||
const uint8_t *mbim_message_get_uuid(struct mbim_message *message);
|
|
||||||
bool mbim_message_get_arguments(struct mbim_message *message,
|
|
||||||
const char *signature, ...);
|
|
||||||
|
|
||||||
bool mbim_message_get_ipv4_address(struct mbim_message *message,
|
|
||||||
uint32_t offset,
|
|
||||||
struct in_addr *addr);
|
|
||||||
bool mbim_message_get_ipv4_element(struct mbim_message *message,
|
|
||||||
uint32_t offset,
|
|
||||||
uint32_t *prefix_len,
|
|
||||||
struct in_addr *addr);
|
|
||||||
bool mbim_message_get_ipv6_address(struct mbim_message *essage,
|
|
||||||
uint32_t offset,
|
|
||||||
struct in6_addr *addr);
|
|
||||||
bool mbim_message_get_ipv6_element(struct mbim_message *message,
|
|
||||||
uint32_t offset,
|
|
||||||
uint32_t *prefix_len,
|
|
||||||
struct in6_addr *addr);
|
|
||||||
|
|
||||||
bool mbim_message_iter_next_entry(struct mbim_message_iter *iter, ...);
|
|
||||||
|
|
||||||
struct mbim_message_builder *mbim_message_builder_new(struct mbim_message *msg);
|
|
||||||
void mbim_message_builder_free(struct mbim_message_builder *builder);
|
|
||||||
bool mbim_message_builder_append_basic(struct mbim_message_builder *builder,
|
|
||||||
char type, const void *value);
|
|
||||||
bool mbim_message_builder_append_bytes(struct mbim_message_builder *builder,
|
|
||||||
size_t len, const uint8_t *bytes);
|
|
||||||
bool mbim_message_builder_enter_struct(struct mbim_message_builder *builder,
|
|
||||||
const char *signature);
|
|
||||||
bool mbim_message_builder_leave_struct(struct mbim_message_builder *builder);
|
|
||||||
bool mbim_message_builder_enter_array(struct mbim_message_builder *builder,
|
|
||||||
const char *signature);
|
|
||||||
bool mbim_message_builder_leave_array(struct mbim_message_builder *builder);
|
|
||||||
bool mbim_message_builder_enter_databuf(struct mbim_message_builder *builder,
|
|
||||||
const char *signature);
|
|
||||||
bool mbim_message_builder_leave_databuf(struct mbim_message_builder *builder);
|
|
||||||
struct mbim_message *mbim_message_builder_finalize(
|
|
||||||
struct mbim_message_builder *builder);
|
|
||||||
|
|
||||||
bool mbim_message_set_arguments(struct mbim_message *message,
|
|
||||||
const char *signature, ...);
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define align_len(len, boundary) (((len)+(boundary)-1) & ~((boundary)-1))
|
|
||||||
|
|
||||||
enum mbim_control_message {
|
|
||||||
MBIM_OPEN_MSG = 0x1,
|
|
||||||
MBIM_CLOSE_MSG = 0x2,
|
|
||||||
MBIM_COMMAND_MSG = 0x3,
|
|
||||||
MBIM_HOST_ERROR_MSG = 0x4,
|
|
||||||
MBIM_OPEN_DONE = 0x80000001,
|
|
||||||
MBIM_CLOSE_DONE = 0x80000002,
|
|
||||||
MBIM_COMMAND_DONE = 0x80000003,
|
|
||||||
MBIM_FUNCTION_ERROR_MSG = 0x80000004,
|
|
||||||
MBIM_INDICATE_STATUS_MSG = 0x80000007,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* MBIM v1.0, Section 9.1 */
|
|
||||||
struct mbim_message_header {
|
|
||||||
__le32 type;
|
|
||||||
__le32 len;
|
|
||||||
__le32 tid;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
/* MBIM v1.0, Section 9.1 */
|
|
||||||
struct mbim_fragment_header {
|
|
||||||
__le32 num_frags;
|
|
||||||
__le32 cur_frag;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct mbim_message *_mbim_message_build(const void *header,
|
|
||||||
struct iovec *frags,
|
|
||||||
uint32_t n_frags);
|
|
||||||
struct mbim_message *_mbim_message_new_command_done(const uint8_t *uuid,
|
|
||||||
uint32_t cid, uint32_t status);
|
|
||||||
uint32_t _mbim_information_buffer_offset(uint32_t type);
|
|
||||||
void _mbim_message_set_tid(struct mbim_message *message, uint32_t tid);
|
|
||||||
void *_mbim_message_to_bytearray(struct mbim_message *message, size_t *out_len);
|
|
||||||
void *_mbim_message_get_header(struct mbim_message *message, size_t *out_len);
|
|
||||||
struct iovec *_mbim_message_get_body(struct mbim_message *message,
|
|
||||||
size_t *out_n_iov, size_t *out_len);
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct mbim_device;
|
|
||||||
struct mbim_message;
|
|
||||||
|
|
||||||
#define MBIM_CID_DEVICE_CAPS 1
|
|
||||||
#define MBIM_CID_SUBSCRIBER_READY_STATUS 2
|
|
||||||
#define MBIM_CID_RADIO_STATE 3
|
|
||||||
#define MBIM_CID_PIN 4
|
|
||||||
#define MBIM_CID_PIN_LIST 5
|
|
||||||
#define MBIM_CID_HOME_PROVIDER 6
|
|
||||||
#define MBIM_CID_PREFERRED_PROVIDERS 7
|
|
||||||
#define MBIM_CID_VISIBLE_PROVIDERS 8
|
|
||||||
#define MBIM_CID_REGISTER_STATE 9
|
|
||||||
#define MBIM_CID_PACKET_SERVICE 10
|
|
||||||
#define MBIM_CID_SIGNAL_STATE 11
|
|
||||||
#define MBIM_CID_CONNECT 12
|
|
||||||
#define MBIM_CID_PROVISIONED_CONTEXTS 13
|
|
||||||
#define MBIM_CID_SERVICE_ACTIVATION 14
|
|
||||||
#define MBIM_CID_IP_CONFIGURATION 15
|
|
||||||
#define MBIM_CID_DEVICE_SERVICES 16
|
|
||||||
#define MBIM_CID_DEVICE_SERVICE_SUBSCRIBE_LIST 19
|
|
||||||
#define MBIM_CID_PACKET_STATISTICS 20
|
|
||||||
#define MBIM_CID_NETWORK_IDLE_HINT 21
|
|
||||||
#define MBIM_CID_EMERGENCY_MODE 22
|
|
||||||
#define MBIM_CID_IP_PACKET_FILTERS 23
|
|
||||||
#define MBIM_CID_MULTICARRIER_PROVIDERS 24
|
|
||||||
|
|
||||||
#define MBIM_CID_SMS_CONFIGURATION 1
|
|
||||||
#define MBIM_CID_SMS_READ 2
|
|
||||||
#define MBIM_CID_SMS_SEND 3
|
|
||||||
#define MBIM_CID_SMS_DELETE 4
|
|
||||||
#define MBIM_CID_SMS_MESSAGE_STORE_STATUS 5
|
|
||||||
|
|
||||||
#define MBIM_CID_USSD 1
|
|
||||||
|
|
||||||
#define MBIM_CID_PHONEBOOK_CONFIGURATION 1
|
|
||||||
#define MBIM_CID_PHONEBOOK_READ 2
|
|
||||||
#define MBIM_CID_PHONEBOOK_DELETE 3
|
|
||||||
#define MBIM_CID_PHONEBOOK_WRITE 4
|
|
||||||
|
|
||||||
#define MBIM_CID_STK_PAC 1
|
|
||||||
#define MBIM_CID_STK_TERMINAL_RESPONSE 2
|
|
||||||
#define MBIM_CID_STK_ENVELOPE 3
|
|
||||||
|
|
||||||
#define MBIM_CID_AKA_AUTH 1
|
|
||||||
#define MBIM_CID_AKAP_AUTH 2
|
|
||||||
#define MBIM_CID_SIM_AUTH 3
|
|
||||||
|
|
||||||
#define MBIM_CID_DSS_CONNECT 1
|
|
||||||
|
|
||||||
/* Table 10-11 */
|
|
||||||
enum mbim_data_class {
|
|
||||||
MBIM_DATA_CLASS_NONE = 0x00,
|
|
||||||
MBIM_DATA_CLASS_GPRS = 0x01,
|
|
||||||
MBIM_DATA_CLASS_EDGE = 0x02,
|
|
||||||
MBIM_DATA_CLASS_UMTS = 0x04,
|
|
||||||
MBIM_DATA_CLASS_HSDPA = 0x08,
|
|
||||||
MBIM_DATA_CLASS_HSUPA = 0x10,
|
|
||||||
MBIM_DATA_CLASS_LTE = 0x20,
|
|
||||||
MBIM_DATA_CLASS_1XRTT = 0x10000,
|
|
||||||
MBIM_DATA_CLASS_EVDO = 0x20000,
|
|
||||||
MBIM_DATA_CLASS_EVDO_REVA = 0x40000,
|
|
||||||
MBIM_DATA_CLASS_1XEVDV = 0x80000,
|
|
||||||
MBIM_DATA_CLASS_3XRTT = 0x100000,
|
|
||||||
MBIM_DATA_CLASS_1XEVDO_REVB = 0x200000,
|
|
||||||
MBIM_DATA_CLASS_UMB = 0x400000,
|
|
||||||
MBIM_DATA_CLASS_CUSTOM = 0x80000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*mbim_device_debug_func_t) (const char *str, void *user_data);
|
|
||||||
typedef void (*mbim_device_disconnect_func_t) (void *user_data);
|
|
||||||
typedef void (*mbim_device_destroy_func_t) (void *user_data);
|
|
||||||
typedef void (*mbim_device_ready_func_t) (void *user_data);
|
|
||||||
typedef void (*mbim_device_reply_func_t) (struct mbim_message *message,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
extern const uint8_t mbim_uuid_basic_connect[];
|
|
||||||
extern const uint8_t mbim_uuid_sms[];
|
|
||||||
extern const uint8_t mbim_uuid_ussd[];
|
|
||||||
extern const uint8_t mbim_uuid_phonebook[];
|
|
||||||
extern const uint8_t mbim_uuid_stk[];
|
|
||||||
extern const uint8_t mbim_uuid_auth[];
|
|
||||||
extern const uint8_t mbim_uuid_dss[];
|
|
||||||
|
|
||||||
extern const uint8_t mbim_context_type_none[];
|
|
||||||
extern const uint8_t mbim_context_type_internet[];
|
|
||||||
extern const uint8_t mbim_context_type_vpn[];
|
|
||||||
extern const uint8_t mbim_context_type_voice[];
|
|
||||||
extern const uint8_t mbim_context_type_video_share[];
|
|
||||||
extern const uint8_t mbim_context_type_purchase[];
|
|
||||||
extern const uint8_t mbim_context_type_ims[];
|
|
||||||
extern const uint8_t mbim_context_type_mms[];
|
|
||||||
extern const uint8_t mbim_context_type_local[];
|
|
||||||
|
|
||||||
struct mbim_device *mbim_device_new(int fd, uint32_t max_segment_size);
|
|
||||||
bool mbim_device_set_close_on_unref(struct mbim_device *device, bool do_close);
|
|
||||||
struct mbim_device *mbim_device_ref(struct mbim_device *device);
|
|
||||||
void mbim_device_unref(struct mbim_device *device);
|
|
||||||
bool mbim_device_shutdown(struct mbim_device *device);
|
|
||||||
|
|
||||||
bool mbim_device_set_max_outstanding(struct mbim_device *device, uint32_t max);
|
|
||||||
|
|
||||||
bool mbim_device_set_debug(struct mbim_device *device,
|
|
||||||
mbim_device_debug_func_t func, void *user_data,
|
|
||||||
mbim_device_destroy_func_t destroy);
|
|
||||||
bool mbim_device_set_disconnect_handler(struct mbim_device *device,
|
|
||||||
mbim_device_disconnect_func_t function,
|
|
||||||
void *user_data,
|
|
||||||
mbim_device_destroy_func_t destroy);
|
|
||||||
bool mbim_device_set_ready_handler(struct mbim_device *device,
|
|
||||||
mbim_device_ready_func_t function,
|
|
||||||
void *user_data,
|
|
||||||
mbim_device_destroy_func_t destroy);
|
|
||||||
|
|
||||||
uint32_t mbim_device_send(struct mbim_device *device, uint32_t gid,
|
|
||||||
struct mbim_message *message,
|
|
||||||
mbim_device_reply_func_t function,
|
|
||||||
void *user_data,
|
|
||||||
mbim_device_destroy_func_t destroy);
|
|
||||||
bool mbim_device_cancel(struct mbim_device *device, uint32_t tid);
|
|
||||||
bool mbim_device_cancel_group(struct mbim_device *device, uint32_t gid);
|
|
||||||
|
|
||||||
uint32_t mbim_device_register(struct mbim_device *device, uint32_t gid,
|
|
||||||
const uint8_t *uuid, uint32_t cid,
|
|
||||||
mbim_device_reply_func_t notify,
|
|
||||||
void *user_data,
|
|
||||||
mbim_device_destroy_func_t destroy);
|
|
||||||
bool mbim_device_unregister(struct mbim_device *device, uint32_t id);
|
|
||||||
bool mbim_device_unregister_group(struct mbim_device *device, uint32_t gid);
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
|
|
||||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
|
||||||
#include <ofono/plugin.h>
|
|
||||||
|
|
||||||
#include "mbimmodem.h"
|
|
||||||
|
|
||||||
static int mbimmodem_init(void)
|
|
||||||
{
|
|
||||||
mbim_devinfo_init();
|
|
||||||
mbim_sim_init();
|
|
||||||
mbim_netreg_init();
|
|
||||||
mbim_sms_exit();
|
|
||||||
mbim_gprs_init();
|
|
||||||
mbim_gprs_context_init();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbimmodem_exit(void)
|
|
||||||
{
|
|
||||||
mbim_gprs_context_exit();
|
|
||||||
mbim_gprs_exit();
|
|
||||||
mbim_sms_exit();
|
|
||||||
mbim_netreg_exit();
|
|
||||||
mbim_sim_exit();
|
|
||||||
mbim_devinfo_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
OFONO_PLUGIN_DEFINE(mbimmodem, "MBIM modem driver", VERSION,
|
|
||||||
OFONO_PLUGIN_PRIORITY_DEFAULT, mbimmodem_init, mbimmodem_exit)
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
enum MBIM_GROUP {
|
|
||||||
SIM_GROUP = 1,
|
|
||||||
NETREG_GROUP = 2,
|
|
||||||
SMS_GROUP = 3,
|
|
||||||
GPRS_GROUP = 4,
|
|
||||||
GPRS_CONTEXT_GROUP = 101,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void mbim_devinfo_init(void);
|
|
||||||
extern void mbim_devinfo_exit(void);
|
|
||||||
|
|
||||||
extern void mbim_sim_init(void);
|
|
||||||
extern void mbim_sim_exit(void);
|
|
||||||
|
|
||||||
extern void mbim_netreg_init(void);
|
|
||||||
extern void mbim_netreg_exit(void);
|
|
||||||
|
|
||||||
extern void mbim_sms_init(void);
|
|
||||||
extern void mbim_sms_exit(void);
|
|
||||||
|
|
||||||
extern void mbim_gprs_init(void);
|
|
||||||
extern void mbim_gprs_exit(void);
|
|
||||||
|
|
||||||
extern void mbim_gprs_context_init(void);
|
|
||||||
extern void mbim_gprs_context_exit(void);
|
|
||||||
@@ -1,416 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/netreg.h>
|
|
||||||
|
|
||||||
#include "src/common.h"
|
|
||||||
|
|
||||||
#include "drivers/mbimmodem/mbim.h"
|
|
||||||
#include "drivers/mbimmodem/mbim-message.h"
|
|
||||||
#include "drivers/mbimmodem/mbimmodem.h"
|
|
||||||
|
|
||||||
struct netreg_data {
|
|
||||||
struct mbim_device *device;
|
|
||||||
struct l_idle *delayed_register;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int register_state_to_status(uint32_t register_state)
|
|
||||||
{
|
|
||||||
switch (register_state) {
|
|
||||||
case 0: /* MBIMRegisterStateUnknown */
|
|
||||||
return NETWORK_REGISTRATION_STATUS_UNKNOWN;
|
|
||||||
case 1: /* MBIMRegisterStateDeregistered */
|
|
||||||
return NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
|
|
||||||
case 2: /* MBIMRegisterStateSearching */
|
|
||||||
return NETWORK_REGISTRATION_STATUS_SEARCHING;
|
|
||||||
case 3: /* MBIMRegisterStateHome */
|
|
||||||
return NETWORK_REGISTRATION_STATUS_REGISTERED;
|
|
||||||
case 4: /* MBIMRegisterStateRoaming */
|
|
||||||
case 5: /* MBIMRegisterStatePartner */
|
|
||||||
return NETWORK_REGISTRATION_STATUS_ROAMING;
|
|
||||||
case 6: /* MBIMRegisterStateDenied */
|
|
||||||
return NETWORK_REGISTRATION_STATUS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NETWORK_REGISTRATION_STATUS_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_register_state_changed(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_netreg *netreg = user;
|
|
||||||
uint32_t nw_error;
|
|
||||||
uint32_t register_state;
|
|
||||||
uint32_t register_mode;
|
|
||||||
uint32_t available_data_classes;
|
|
||||||
int status;
|
|
||||||
int tech;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuuu",
|
|
||||||
&nw_error, ®ister_state,
|
|
||||||
®ister_mode,
|
|
||||||
&available_data_classes))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("NwError: %u, RegisterMode: %u", nw_error, register_mode);
|
|
||||||
|
|
||||||
status = register_state_to_status(register_state);
|
|
||||||
tech = mbim_data_class_to_tech(available_data_classes);
|
|
||||||
|
|
||||||
ofono_netreg_status_notify(netreg, status, -1, -1, tech);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_registration_status_cb(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_netreg_status_cb_t cb = cbd->cb;
|
|
||||||
uint32_t dummy;
|
|
||||||
uint32_t register_state;
|
|
||||||
uint32_t available_data_classes;
|
|
||||||
int status;
|
|
||||||
int tech;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuuu",
|
|
||||||
&dummy, ®ister_state,
|
|
||||||
&dummy,
|
|
||||||
&available_data_classes))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
status = register_state_to_status(register_state);
|
|
||||||
tech = mbim_data_class_to_tech(available_data_classes);
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, status, -1, -1, tech, cbd->data);
|
|
||||||
return;
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_registration_status(struct ofono_netreg *netreg,
|
|
||||||
ofono_netreg_status_cb_t cb,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_REGISTER_STATE,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (mbim_device_send(nd->device, NETREG_GROUP, message,
|
|
||||||
mbim_registration_status_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_current_operator_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_netreg_operator_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_network_operator op;
|
|
||||||
uint32_t dummy;
|
|
||||||
uint32_t register_state;
|
|
||||||
uint32_t available_data_classes;
|
|
||||||
L_AUTO_FREE_VAR(char *, provider_id) = NULL;
|
|
||||||
L_AUTO_FREE_VAR(char *, provider_name) = NULL;
|
|
||||||
L_AUTO_FREE_VAR(char *, roaming_text) = NULL;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuuuusss",
|
|
||||||
&dummy, ®ister_state, &dummy,
|
|
||||||
&available_data_classes, &dummy,
|
|
||||||
&provider_id, &provider_name,
|
|
||||||
&roaming_text))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (register_state < 3 || register_state > 5)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
DBG("provider: %s(%s)", provider_name, provider_id);
|
|
||||||
|
|
||||||
/* If MBIMRegisterStateRoaming or MBIMRegisterStatePartner */
|
|
||||||
if (register_state == 4 || register_state == 5)
|
|
||||||
DBG("roaming text: %s", roaming_text);
|
|
||||||
|
|
||||||
strncpy(op.name, provider_name, OFONO_MAX_OPERATOR_NAME_LENGTH);
|
|
||||||
op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
|
|
||||||
|
|
||||||
strncpy(op.mcc, provider_id, OFONO_MAX_MCC_LENGTH);
|
|
||||||
op.mcc[OFONO_MAX_MCC_LENGTH] = '\0';
|
|
||||||
|
|
||||||
strncpy(op.mnc, provider_id + OFONO_MAX_MCC_LENGTH,
|
|
||||||
OFONO_MAX_MNC_LENGTH);
|
|
||||||
op.mnc[OFONO_MAX_MNC_LENGTH] = '\0';
|
|
||||||
|
|
||||||
/* Set to current */
|
|
||||||
op.status = 2;
|
|
||||||
op.tech = mbim_data_class_to_tech(available_data_classes);
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, &op, cbd->data);
|
|
||||||
return;
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_current_operator(struct ofono_netreg *netreg,
|
|
||||||
ofono_netreg_operator_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_REGISTER_STATE,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (mbim_device_send(nd->device, NETREG_GROUP, message,
|
|
||||||
mbim_current_operator_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_register_state_set_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_netreg_register_cb_t cb = cbd->cb;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_register_auto(struct ofono_netreg *netreg,
|
|
||||||
ofono_netreg_register_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
static const uint32_t data_class = MBIM_DATA_CLASS_GPRS |
|
|
||||||
MBIM_DATA_CLASS_EDGE |
|
|
||||||
MBIM_DATA_CLASS_UMTS |
|
|
||||||
MBIM_DATA_CLASS_HSDPA |
|
|
||||||
MBIM_DATA_CLASS_HSUPA |
|
|
||||||
MBIM_DATA_CLASS_LTE;
|
|
||||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_REGISTER_STATE,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "suu", NULL, 0, data_class);
|
|
||||||
|
|
||||||
if (mbim_device_send(nd->device, NETREG_GROUP, message,
|
|
||||||
mbim_register_state_set_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int convert_signal_strength(uint32_t strength)
|
|
||||||
{
|
|
||||||
if (strength == 99)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return strength * 100 / 31;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_signal_state_query_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_netreg_strength_cb_t cb = cbd->cb;
|
|
||||||
uint32_t strength;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "u", &strength))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, convert_signal_strength(strength), cbd->data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_signal_strength(struct ofono_netreg *netreg,
|
|
||||||
ofono_netreg_strength_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_SIGNAL_STATE,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (mbim_device_send(nd->device, NETREG_GROUP, message,
|
|
||||||
mbim_signal_state_query_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_signal_state_changed(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_netreg *netreg = user;
|
|
||||||
uint32_t strength;
|
|
||||||
uint32_t error_rate;
|
|
||||||
uint32_t signal_strength_interval;
|
|
||||||
uint32_t rssi_threshold;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuuu",
|
|
||||||
&strength, &error_rate,
|
|
||||||
&signal_strength_interval,
|
|
||||||
&rssi_threshold))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("strength: %u, error_rate: %u", strength, error_rate);
|
|
||||||
DBG("strength interval: %u, rssi_threshold: %u",
|
|
||||||
signal_strength_interval, rssi_threshold);
|
|
||||||
|
|
||||||
ofono_netreg_strength_notify(netreg, convert_signal_strength(strength));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void delayed_register(struct l_idle *idle, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_netreg *netreg = user_data;
|
|
||||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
l_idle_remove(idle);
|
|
||||||
nd->delayed_register = NULL;
|
|
||||||
|
|
||||||
if (!mbim_device_register(nd->device, NETREG_GROUP,
|
|
||||||
mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_SIGNAL_STATE,
|
|
||||||
mbim_signal_state_changed,
|
|
||||||
netreg, NULL))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_device_register(nd->device, NETREG_GROUP,
|
|
||||||
mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_REGISTER_STATE,
|
|
||||||
mbim_register_state_changed,
|
|
||||||
netreg, NULL))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ofono_netreg_register(netreg);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_netreg_remove(netreg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct mbim_device *device = data;
|
|
||||||
struct netreg_data *nd = l_new(struct netreg_data, 1);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
nd->device = mbim_device_ref(device);
|
|
||||||
nd->delayed_register = l_idle_create(delayed_register, netreg, NULL);
|
|
||||||
|
|
||||||
ofono_netreg_set_data(netreg, nd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_netreg_remove(struct ofono_netreg *netreg)
|
|
||||||
{
|
|
||||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
ofono_netreg_set_data(netreg, NULL);
|
|
||||||
|
|
||||||
l_idle_remove(nd->delayed_register);
|
|
||||||
mbim_device_cancel_group(nd->device, NETREG_GROUP);
|
|
||||||
mbim_device_unregister_group(nd->device, NETREG_GROUP);
|
|
||||||
mbim_device_unref(nd->device);
|
|
||||||
nd->device = NULL;
|
|
||||||
l_free(nd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_netreg_driver driver = {
|
|
||||||
.name = "mbim",
|
|
||||||
.probe = mbim_netreg_probe,
|
|
||||||
.remove = mbim_netreg_remove,
|
|
||||||
.registration_status = mbim_registration_status,
|
|
||||||
.current_operator = mbim_current_operator,
|
|
||||||
.register_auto = mbim_register_auto,
|
|
||||||
.strength = mbim_signal_strength,
|
|
||||||
};
|
|
||||||
|
|
||||||
void mbim_netreg_init(void)
|
|
||||||
{
|
|
||||||
ofono_netreg_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbim_netreg_exit(void)
|
|
||||||
{
|
|
||||||
ofono_netreg_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -1,533 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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 <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/sim.h>
|
|
||||||
|
|
||||||
#include "drivers/mbimmodem/mbim.h"
|
|
||||||
#include "drivers/mbimmodem/mbim-message.h"
|
|
||||||
#include "drivers/mbimmodem/mbimmodem.h"
|
|
||||||
|
|
||||||
struct sim_data {
|
|
||||||
struct mbim_device *device;
|
|
||||||
char *iccid;
|
|
||||||
char *imsi;
|
|
||||||
uint32_t last_pin_type;
|
|
||||||
bool present : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mbim_sim_state_changed(struct ofono_sim *sim, uint32_t ready_state)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
|
|
||||||
DBG("ready_state: %u", ready_state);
|
|
||||||
|
|
||||||
switch (ready_state) {
|
|
||||||
case 0: /* Not Initialized */
|
|
||||||
break;
|
|
||||||
case 1: /* Initialized */
|
|
||||||
if (!sd->present)
|
|
||||||
ofono_sim_inserted_notify(sim, true);
|
|
||||||
|
|
||||||
sd->present = true;
|
|
||||||
ofono_sim_initialized_notify(sim);
|
|
||||||
break;
|
|
||||||
case 6: /* Device Locked */
|
|
||||||
if (!sd->present)
|
|
||||||
ofono_sim_inserted_notify(sim, true);
|
|
||||||
|
|
||||||
sd->present = true;
|
|
||||||
break;
|
|
||||||
case 2: /* Not inserted */
|
|
||||||
case 3: /* Bad SIM */
|
|
||||||
case 4: /* Failure */
|
|
||||||
case 5: /* Not activated */
|
|
||||||
if (sd->present)
|
|
||||||
ofono_sim_inserted_notify(sim, false);
|
|
||||||
|
|
||||||
sd->present = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_read_imsi(struct ofono_sim *sim,
|
|
||||||
ofono_sim_imsi_cb_t cb, void *user_data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, sd->imsi, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ofono_sim_password_type mbim_pin_type_to_sim_password(
|
|
||||||
uint32_t pin_type)
|
|
||||||
{
|
|
||||||
switch (pin_type) {
|
|
||||||
case 0: /* No Pin */
|
|
||||||
return OFONO_SIM_PASSWORD_NONE;
|
|
||||||
case 2: /* PIN1 key */
|
|
||||||
return OFONO_SIM_PASSWORD_SIM_PIN;
|
|
||||||
case 3: /* PIN2 key */
|
|
||||||
return OFONO_SIM_PASSWORD_SIM_PIN2;
|
|
||||||
case 4: /* device to SIM key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHSIM_PIN;
|
|
||||||
case 5: /* device to very first SIM key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHFSIM_PIN;
|
|
||||||
case 6: /* network personalization key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHNET_PIN;
|
|
||||||
case 7: /* network subset personalization key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHNETSUB_PIN;
|
|
||||||
case 8: /* service provider (SP) personalization key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHSP_PIN;
|
|
||||||
case 9: /* corporate personalization key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHCORP_PIN;
|
|
||||||
case 11: /* PUK1 */
|
|
||||||
return OFONO_SIM_PASSWORD_SIM_PUK;
|
|
||||||
case 12: /* PUK2 */
|
|
||||||
return OFONO_SIM_PASSWORD_SIM_PUK2;
|
|
||||||
case 13: /* device to very first SIM PIN unlock key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHFSIM_PUK;
|
|
||||||
case 14: /* network personalization unlock key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHNET_PUK;
|
|
||||||
case 15: /* network subset personaliation unlock key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHNETSUB_PUK;
|
|
||||||
case 16: /* service provider (SP) personalization unlock key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHSP_PUK;
|
|
||||||
case 17: /* corporate personalization unlock key */
|
|
||||||
return OFONO_SIM_PASSWORD_PHCORP_PUK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return OFONO_SIM_PASSWORD_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t mbim_pin_type_from_sim_password(
|
|
||||||
enum ofono_sim_password_type type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case OFONO_SIM_PASSWORD_SIM_PIN:
|
|
||||||
return 2; /* PIN1 key */
|
|
||||||
case OFONO_SIM_PASSWORD_SIM_PIN2:
|
|
||||||
return 3; /* PIN2 key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHSIM_PIN:
|
|
||||||
return 4; /* device to SIM key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHFSIM_PIN:
|
|
||||||
return 5; /* device to very first SIM key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHNET_PIN:
|
|
||||||
return 6; /* network personalization key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
|
|
||||||
return 7; /* network subset personalization key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHSP_PIN:
|
|
||||||
return 8; /* service provider (SP) personalization key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHCORP_PIN:
|
|
||||||
return 9; /* corporate personalization key */
|
|
||||||
case OFONO_SIM_PASSWORD_SIM_PUK:
|
|
||||||
return 11; /* PUK1 */
|
|
||||||
case OFONO_SIM_PASSWORD_SIM_PUK2:
|
|
||||||
return 12; /* PUK2 */
|
|
||||||
case OFONO_SIM_PASSWORD_PHFSIM_PUK:
|
|
||||||
return 13; /* device to very first SIM PIN unlock key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHNET_PUK:
|
|
||||||
return 14; /* network personalization unlock key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHNETSUB_PUK:
|
|
||||||
return 15; /* network subset personaliation unlock key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHSP_PUK:
|
|
||||||
return 16; /* service provider (SP) personalization unlock key */
|
|
||||||
case OFONO_SIM_PASSWORD_PHCORP_PUK:
|
|
||||||
return 17; /* corporate personalization unlock key */
|
|
||||||
case OFONO_SIM_PASSWORD_NONE:
|
|
||||||
case OFONO_SIM_PASSWORD_INVALID:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_query_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
struct sim_data *sd = cbd->user;
|
|
||||||
ofono_sim_passwd_cb_t cb = cbd->cb;
|
|
||||||
uint32_t pin_type;
|
|
||||||
uint32_t pin_state;
|
|
||||||
enum ofono_sim_password_type sim_password;
|
|
||||||
bool r;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
r = mbim_message_get_arguments(message, "uu",
|
|
||||||
&pin_type, &pin_state);
|
|
||||||
if (!r)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
sim_password = mbim_pin_type_to_sim_password(pin_type);
|
|
||||||
if (sim_password == OFONO_SIM_PASSWORD_INVALID)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (pin_state == 0)
|
|
||||||
sim_password = OFONO_SIM_PASSWORD_NONE;
|
|
||||||
|
|
||||||
sd->last_pin_type = pin_type;
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, sim_password, cbd->data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_query(struct ofono_sim *sim,
|
|
||||||
ofono_sim_passwd_cb_t cb, void *user_data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
cbd->user = sd;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_PIN,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (mbim_device_send(sd->device, SIM_GROUP, message,
|
|
||||||
mbim_pin_query_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_retries_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_sim_pin_retries_cb_t cb = cbd->cb;
|
|
||||||
int retries[OFONO_SIM_PASSWORD_INVALID];
|
|
||||||
size_t i;
|
|
||||||
uint32_t pin_type;
|
|
||||||
uint32_t pin_state;
|
|
||||||
uint32_t remaining;
|
|
||||||
enum ofono_sim_password_type sim_password;
|
|
||||||
bool r;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
r = mbim_message_get_arguments(message, "uuu",
|
|
||||||
&pin_type, &pin_state, &remaining);
|
|
||||||
if (!r)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
sim_password = mbim_pin_type_to_sim_password(pin_type);
|
|
||||||
if (sim_password == OFONO_SIM_PASSWORD_INVALID)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
|
|
||||||
retries[i] = -1;
|
|
||||||
|
|
||||||
if (pin_state == 0 || sim_password == OFONO_SIM_PASSWORD_NONE) {
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, retries, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remaining == 0xffffffff)
|
|
||||||
retries[sim_password] = -1;
|
|
||||||
else
|
|
||||||
retries[sim_password] = remaining;
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, retries, cbd->data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_retries_query(struct ofono_sim *sim,
|
|
||||||
ofono_sim_pin_retries_cb_t cb, void *user_data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_PIN,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (mbim_device_send(sd->device, SIM_GROUP, message,
|
|
||||||
mbim_pin_retries_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_set_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_sim_lock_unlock_cb_t cb = cbd->cb;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_set(struct ofono_sim *sim, uint32_t pin_type,
|
|
||||||
uint32_t pin_operation,
|
|
||||||
const char *old_passwd,
|
|
||||||
const char *new_passwd,
|
|
||||||
ofono_sim_lock_unlock_cb_t cb,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("%u %u %s %s", pin_type, pin_operation, old_passwd, new_passwd);
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_PIN,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "uuss", pin_type, pin_operation,
|
|
||||||
old_passwd, new_passwd);
|
|
||||||
|
|
||||||
if (mbim_device_send(sd->device, SIM_GROUP, message,
|
|
||||||
mbim_pin_set_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_enter(struct ofono_sim *sim, const char *passwd,
|
|
||||||
ofono_sim_lock_unlock_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
|
|
||||||
/* Use MBIMPinOperationEnter (0) and NULL second PIN */
|
|
||||||
mbim_pin_set(sim, sd->last_pin_type, 0, passwd, NULL, cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_puk_enter(struct ofono_sim *sim, const char *puk,
|
|
||||||
const char *passwd,
|
|
||||||
ofono_sim_lock_unlock_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
|
|
||||||
/* Use MBIMPinOperationEnter (0) and second PIN */
|
|
||||||
mbim_pin_set(sim, sd->last_pin_type, 0, puk, passwd, cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_enable(struct ofono_sim *sim,
|
|
||||||
enum ofono_sim_password_type passwd_type,
|
|
||||||
int enable, const char *passwd,
|
|
||||||
ofono_sim_lock_unlock_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
uint32_t pin_type = mbim_pin_type_from_sim_password(passwd_type);
|
|
||||||
|
|
||||||
if (pin_type == 0) {
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use MBIMPinOperationEnable (1) or MBIMPinOperationDisable (2) */
|
|
||||||
mbim_pin_set(sim, pin_type, enable ? 1 : 2, passwd, NULL, cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pin_change(struct ofono_sim *sim,
|
|
||||||
enum ofono_sim_password_type passwd_type,
|
|
||||||
const char *old_passwd, const char *new_passwd,
|
|
||||||
ofono_sim_lock_unlock_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
uint32_t pin_type = mbim_pin_type_from_sim_password(passwd_type);
|
|
||||||
|
|
||||||
if (pin_type == 0) {
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use MBIMPinOperationChange (3) */
|
|
||||||
mbim_pin_set(sim, pin_type, 3, old_passwd, new_passwd, cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_subscriber_ready_status_changed(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sim *sim = user;
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
uint32_t ready_state;
|
|
||||||
char *imsi;
|
|
||||||
char *iccid;
|
|
||||||
uint32_t ready_info;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "ussu",
|
|
||||||
&ready_state, &imsi,
|
|
||||||
&iccid, &ready_info))
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(sd->iccid);
|
|
||||||
sd->iccid = iccid;
|
|
||||||
|
|
||||||
l_free(sd->imsi);
|
|
||||||
sd->imsi = imsi;
|
|
||||||
|
|
||||||
DBG("%s %s", iccid, imsi);
|
|
||||||
|
|
||||||
mbim_sim_state_changed(sim, ready_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_subscriber_ready_status_cb(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sim *sim = user;
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
uint32_t ready_state;
|
|
||||||
char *imsi;
|
|
||||||
char *iccid;
|
|
||||||
uint32_t ready_info;
|
|
||||||
bool r;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* We don't bother parsing MSISDN/MDN array */
|
|
||||||
r = mbim_message_get_arguments(message, "ussu",
|
|
||||||
&ready_state, &imsi,
|
|
||||||
&iccid, &ready_info);
|
|
||||||
if (!r)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
sd->iccid = iccid;
|
|
||||||
sd->imsi = imsi;
|
|
||||||
|
|
||||||
if (!mbim_device_register(sd->device, SIM_GROUP,
|
|
||||||
mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_SUBSCRIBER_READY_STATUS,
|
|
||||||
mbim_subscriber_ready_status_changed,
|
|
||||||
sim, NULL))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ofono_sim_register(sim);
|
|
||||||
DBG("%s %s", iccid, imsi);
|
|
||||||
mbim_sim_state_changed(sim, ready_state);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_sim_remove(sim);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct mbim_device *device = data;
|
|
||||||
struct mbim_message *message;
|
|
||||||
struct sim_data *sd;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_SUBSCRIBER_READY_STATUS,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
if (!message)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (!mbim_device_send(device, SIM_GROUP, message,
|
|
||||||
mbim_subscriber_ready_status_cb, sim, NULL)) {
|
|
||||||
mbim_message_unref(message);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
sd = l_new(struct sim_data, 1);
|
|
||||||
sd->device = mbim_device_ref(device);
|
|
||||||
ofono_sim_set_data(sim, sd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sim_remove(struct ofono_sim *sim)
|
|
||||||
{
|
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
|
||||||
|
|
||||||
ofono_sim_set_data(sim, NULL);
|
|
||||||
|
|
||||||
mbim_device_cancel_group(sd->device, SIM_GROUP);
|
|
||||||
mbim_device_unregister_group(sd->device, SIM_GROUP);
|
|
||||||
mbim_device_unref(sd->device);
|
|
||||||
sd->device = NULL;
|
|
||||||
|
|
||||||
l_free(sd->iccid);
|
|
||||||
l_free(sd->imsi);
|
|
||||||
l_free(sd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_sim_driver driver = {
|
|
||||||
.name = "mbim",
|
|
||||||
.probe = mbim_sim_probe,
|
|
||||||
.remove = mbim_sim_remove,
|
|
||||||
.read_imsi = mbim_read_imsi,
|
|
||||||
.query_passwd_state = mbim_pin_query,
|
|
||||||
.query_pin_retries = mbim_pin_retries_query,
|
|
||||||
.send_passwd = mbim_pin_enter,
|
|
||||||
.reset_passwd = mbim_puk_enter,
|
|
||||||
.change_passwd = mbim_pin_change,
|
|
||||||
.lock = mbim_pin_enable,
|
|
||||||
};
|
|
||||||
|
|
||||||
void mbim_sim_init(void)
|
|
||||||
{
|
|
||||||
ofono_sim_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbim_sim_exit(void)
|
|
||||||
{
|
|
||||||
ofono_sim_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -1,516 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/sms.h>
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "drivers/mbimmodem/mbim.h"
|
|
||||||
#include "drivers/mbimmodem/mbim-message.h"
|
|
||||||
#include "drivers/mbimmodem/mbimmodem.h"
|
|
||||||
|
|
||||||
struct sms_data {
|
|
||||||
struct mbim_device *device;
|
|
||||||
uint32_t configuration_notify_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mbim_sca_set_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_sms_sca_set_cb_t cb = cbd->cb;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sca_set(struct ofono_sms *sms,
|
|
||||||
const struct ofono_phone_number *sca,
|
|
||||||
ofono_sms_sca_set_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
const char *numberstr = phone_number_to_string(sca);
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_CONFIGURATION,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "us", 0, numberstr);
|
|
||||||
|
|
||||||
if (mbim_device_send(sd->device, SMS_GROUP, message,
|
|
||||||
mbim_sca_set_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sca_query_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_sms_sca_query_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_phone_number sca;
|
|
||||||
uint32_t dummy;
|
|
||||||
L_AUTO_FREE_VAR(char *, number) = NULL;
|
|
||||||
const char *p;
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uuuus",
|
|
||||||
&dummy, &dummy, &dummy, &dummy,
|
|
||||||
&number))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (number[0] == '+') {
|
|
||||||
p = number + 1;
|
|
||||||
sca.type = 145;
|
|
||||||
} else {
|
|
||||||
p = number;
|
|
||||||
sca.type = 129;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(sca.number, p, OFONO_MAX_PHONE_NUMBER_LENGTH);
|
|
||||||
sca.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, &sca, cbd->data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sca_query(struct ofono_sms *sms, ofono_sms_sca_query_cb_t cb,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_CONFIGURATION,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (mbim_device_send(sd->device, SMS_GROUP, message,
|
|
||||||
mbim_sca_query_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, NULL, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_delete_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
DBG("%u", mbim_message_get_error(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_send_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
struct sms_data *sd = cbd->user;
|
|
||||||
ofono_sms_submit_cb_t cb = cbd->cb;
|
|
||||||
uint32_t mr;
|
|
||||||
struct mbim_message *delete;
|
|
||||||
|
|
||||||
DBG("%u", mbim_message_get_error(message));
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "u", &mr))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Just in case, send an SMS DELETE command for Sent messages */
|
|
||||||
delete = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_DELETE,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(delete, "uu", 4, 0);
|
|
||||||
|
|
||||||
if (!mbim_device_send(sd->device, SMS_GROUP, delete,
|
|
||||||
mbim_delete_cb, NULL, NULL))
|
|
||||||
mbim_message_unref(delete);
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, mr, cbd->data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_submit(struct ofono_sms *sms, const unsigned char *pdu,
|
|
||||||
int pdu_len, int tpdu_len, int mms,
|
|
||||||
ofono_sms_submit_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("pdu_len: %d tpdu_len: %d mms: %d", pdu_len, tpdu_len, mms);
|
|
||||||
|
|
||||||
cbd->user = sd;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_SEND,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "ud", 0, "ay", pdu_len, pdu);
|
|
||||||
|
|
||||||
if (mbim_device_send(sd->device, SMS_GROUP, message,
|
|
||||||
mbim_sms_send_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
mbim_message_unref(message);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_send_delete(struct sms_data *sd, uint32_t index)
|
|
||||||
{
|
|
||||||
struct mbim_message *delete;
|
|
||||||
|
|
||||||
DBG("%u", index);
|
|
||||||
|
|
||||||
delete = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_DELETE,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(delete, "uu", 1, index);
|
|
||||||
|
|
||||||
if (!mbim_device_send(sd->device, SMS_GROUP, delete,
|
|
||||||
mbim_delete_cb, NULL, NULL))
|
|
||||||
mbim_message_unref(delete);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_parse_sms_read_info(struct mbim_message *message,
|
|
||||||
struct ofono_sms *sms)
|
|
||||||
{
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
uint32_t format;
|
|
||||||
uint32_t n_sms;
|
|
||||||
struct mbim_message_iter array;
|
|
||||||
struct mbim_message_iter bytes;
|
|
||||||
uint32_t index;
|
|
||||||
uint32_t status;
|
|
||||||
uint32_t pdu_len;
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "ua(uuay)",
|
|
||||||
&format, &n_sms, &array))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (format != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (mbim_message_iter_next_entry(&array, &index, &status,
|
|
||||||
&pdu_len, &bytes)) {
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
/* Ignore Draft (2) and Sent (3) messages */
|
|
||||||
if (status == 0 || status == 1) {
|
|
||||||
uint8_t pdu[176];
|
|
||||||
uint32_t tpdu_len;
|
|
||||||
|
|
||||||
while (mbim_message_iter_next_entry(&bytes, pdu + i))
|
|
||||||
i++;
|
|
||||||
|
|
||||||
tpdu_len = pdu_len - pdu[0] - 1;
|
|
||||||
ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
mbim_sms_send_delete(sd, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_read_notify(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sms *sms = user;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
mbim_parse_sms_read_info(message, sms);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_read_new_query_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sms *sms = user;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
mbim_parse_sms_read_info(message, sms);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_message_store_status_changed(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sms *sms = user;
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
uint32_t flag;
|
|
||||||
uint32_t index;
|
|
||||||
struct mbim_message *read_query;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "uu", &flag, &index))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("%u %u", flag, index);
|
|
||||||
|
|
||||||
/* MBIM_SMS_FLAG_NEW_MESSAGE not set */
|
|
||||||
if ((flag & 2) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
read_query = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_READ,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
if (!read_query)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Query using MBIMSmsFormatPdu(0) and MBIMSmsFlagNew (2) */
|
|
||||||
mbim_message_set_arguments(read_query, "uuu", 0, 2, 0);
|
|
||||||
|
|
||||||
if (!mbim_device_send(sd->device, SMS_GROUP, read_query,
|
|
||||||
mbim_sms_read_new_query_cb, sms, NULL))
|
|
||||||
mbim_message_unref(read_query);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_read_all_query_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sms *sms = user;
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
mbim_parse_sms_read_info(message, sms);
|
|
||||||
|
|
||||||
mbim_device_register(sd->device, SMS_GROUP, mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_MESSAGE_STORE_STATUS,
|
|
||||||
mbim_sms_message_store_status_changed,
|
|
||||||
sms, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool mbim_sms_finish_init(struct ofono_sms *sms)
|
|
||||||
{
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Class 0 SMS comes via SMS_READ notification, so register for these
|
|
||||||
* here. After that we send an SMS_READ request to retrieve any new
|
|
||||||
* SMS messages. In the callback we will register to
|
|
||||||
* MESSAGE_STORE_STATUS to receive notification that new SMS messages
|
|
||||||
* have arrived
|
|
||||||
*/
|
|
||||||
if (!mbim_device_register(sd->device, SMS_GROUP,
|
|
||||||
mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_READ,
|
|
||||||
mbim_sms_read_notify, sms, NULL))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_READ,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
if (!message)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Query using MBIMSmsFormatPdu(0) and MBIMSmsFlagAll (0) */
|
|
||||||
mbim_message_set_arguments(message, "uuu", 0, 0, 0);
|
|
||||||
|
|
||||||
if (!mbim_device_send(sd->device, SMS_GROUP, message,
|
|
||||||
mbim_sms_read_all_query_cb, sms, NULL)) {
|
|
||||||
mbim_message_unref(message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_configuration_changed(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sms *sms = user;
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
uint32_t storage_state;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!mbim_message_get_arguments(message, "u", &storage_state))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (storage_state != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mbim_device_unregister(sd->device, sd->configuration_notify_id);
|
|
||||||
sd->configuration_notify_id = 0;
|
|
||||||
|
|
||||||
if (!mbim_sms_finish_init(sms))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ofono_sms_register(sms);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_sms_remove(sms);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_configuration_query_cb(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_sms *sms = user;
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
uint32_t error;
|
|
||||||
uint32_t storage_state;
|
|
||||||
uint32_t format;
|
|
||||||
uint32_t max_messages;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
error = mbim_message_get_error(message);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SUBSCRIBER_READY_STATUS tells us that a SIM is in ReadyState,
|
|
||||||
* unfortunately that seems to be not enough to know that the SMS
|
|
||||||
* state is initialized. Handle this here, if we get an error 14
|
|
||||||
* 'MBIM_STATUS_NOT_INITIALIZED', then listen for the
|
|
||||||
* SMS_CONFIGURATION notification. Why some devices return an error
|
|
||||||
* here instead of responding with a 0 storage state is a mystery
|
|
||||||
*/
|
|
||||||
switch (error) {
|
|
||||||
case 14: /* Seems SIM ReadyState is sometimes not enough */
|
|
||||||
goto setup_notification;
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't bother parsing CdmaShortMessageSize or ScAddress array */
|
|
||||||
if (!mbim_message_get_arguments(message, "uuu",
|
|
||||||
&storage_state, &format, &max_messages))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
DBG("storage_state: %u, format: %u, max_messages: %u",
|
|
||||||
storage_state, format, max_messages);
|
|
||||||
|
|
||||||
if (format != 0) {
|
|
||||||
DBG("Unsupported SMS Format, expect 0 (PDU)");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (storage_state == 1) {
|
|
||||||
if (!mbim_sms_finish_init(sms))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ofono_sms_register(sms);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_notification:
|
|
||||||
/* Wait for storage_state to go to Initialized before registering */
|
|
||||||
sd->configuration_notify_id = mbim_device_register(sd->device,
|
|
||||||
SMS_GROUP,
|
|
||||||
mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_CONFIGURATION,
|
|
||||||
mbim_sms_configuration_changed,
|
|
||||||
sms, NULL);
|
|
||||||
if (sd->configuration_notify_id > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_sms_remove(sms);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_sms_probe(struct ofono_sms *sms, unsigned int vendor,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct mbim_device *device = data;
|
|
||||||
struct sms_data *sd;
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_sms,
|
|
||||||
MBIM_CID_SMS_CONFIGURATION,
|
|
||||||
MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
if (!message)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
|
|
||||||
if (!mbim_device_send(device, SMS_GROUP, message,
|
|
||||||
mbim_sms_configuration_query_cb, sms, NULL)) {
|
|
||||||
mbim_message_unref(message);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
sd = l_new(struct sms_data, 1);
|
|
||||||
sd->device = mbim_device_ref(device);
|
|
||||||
ofono_sms_set_data(sms, sd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_sms_remove(struct ofono_sms *sms)
|
|
||||||
{
|
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
ofono_sms_set_data(sms, NULL);
|
|
||||||
|
|
||||||
mbim_device_cancel_group(sd->device, SMS_GROUP);
|
|
||||||
mbim_device_unregister_group(sd->device, SMS_GROUP);
|
|
||||||
mbim_device_unref(sd->device);
|
|
||||||
sd->device = NULL;
|
|
||||||
l_free(sd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_sms_driver driver = {
|
|
||||||
.name = "mbim",
|
|
||||||
.probe = mbim_sms_probe,
|
|
||||||
.remove = mbim_sms_remove,
|
|
||||||
.sca_query = mbim_sca_query,
|
|
||||||
.sca_set = mbim_sca_set,
|
|
||||||
.submit = mbim_submit,
|
|
||||||
};
|
|
||||||
|
|
||||||
void mbim_sms_init(void)
|
|
||||||
{
|
|
||||||
ofono_sms_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbim_sms_exit(void)
|
|
||||||
{
|
|
||||||
ofono_sms_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "src/common.h"
|
|
||||||
#include "mbim.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
int mbim_data_class_to_tech(uint32_t n)
|
|
||||||
{
|
|
||||||
if (n & MBIM_DATA_CLASS_LTE)
|
|
||||||
return ACCESS_TECHNOLOGY_EUTRAN;
|
|
||||||
|
|
||||||
if (n & (MBIM_DATA_CLASS_HSUPA | MBIM_DATA_CLASS_HSDPA))
|
|
||||||
return ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA;
|
|
||||||
|
|
||||||
if (n & MBIM_DATA_CLASS_HSUPA)
|
|
||||||
return ACCESS_TECHNOLOGY_UTRAN_HSUPA;
|
|
||||||
|
|
||||||
if (n & MBIM_DATA_CLASS_HSDPA)
|
|
||||||
return ACCESS_TECHNOLOGY_UTRAN_HSDPA;
|
|
||||||
|
|
||||||
if (n & MBIM_DATA_CLASS_UMTS)
|
|
||||||
return ACCESS_TECHNOLOGY_UTRAN;
|
|
||||||
|
|
||||||
if (n & MBIM_DATA_CLASS_EDGE)
|
|
||||||
return ACCESS_TECHNOLOGY_GSM_EGPRS;
|
|
||||||
|
|
||||||
if (n & MBIM_DATA_CLASS_GPRS)
|
|
||||||
return ACCESS_TECHNOLOGY_GSM;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ell/ell.h>
|
|
||||||
|
|
||||||
struct cb_data {
|
|
||||||
void *cb;
|
|
||||||
void *data;
|
|
||||||
void *user;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct cb_data *cb_data_new(void *cb, void *data)
|
|
||||||
{
|
|
||||||
struct cb_data *ret;
|
|
||||||
|
|
||||||
ret = l_new(struct cb_data, 1);
|
|
||||||
ret->cb = cb;
|
|
||||||
ret->data = data;
|
|
||||||
ret->user = NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CALLBACK_WITH_FAILURE(cb, args...) \
|
|
||||||
do { \
|
|
||||||
struct ofono_error cb_e; \
|
|
||||||
cb_e.type = OFONO_ERROR_TYPE_FAILURE; \
|
|
||||||
cb_e.error = 0; \
|
|
||||||
\
|
|
||||||
cb(&cb_e, ##args); \
|
|
||||||
} while (0) \
|
|
||||||
|
|
||||||
#define CALLBACK_WITH_SUCCESS(f, args...) \
|
|
||||||
do { \
|
|
||||||
struct ofono_error e; \
|
|
||||||
e.type = OFONO_ERROR_TYPE_NO_ERROR; \
|
|
||||||
e.error = 0; \
|
|
||||||
f(&e, ##args); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
int mbim_data_class_to_tech(uint32_t n);
|
|
||||||
@@ -29,16 +29,12 @@
|
|||||||
|
|
||||||
#include "qmi.h"
|
#include "qmi.h"
|
||||||
#include "nas.h"
|
#include "nas.h"
|
||||||
#include "wds.h"
|
|
||||||
|
|
||||||
#include "src/common.h"
|
#include "src/common.h"
|
||||||
#include "qmimodem.h"
|
#include "qmimodem.h"
|
||||||
|
|
||||||
struct gprs_data {
|
struct gprs_data {
|
||||||
struct qmi_device *dev;
|
|
||||||
struct qmi_service *nas;
|
struct qmi_service *nas;
|
||||||
struct qmi_service *wds;
|
|
||||||
unsigned int last_auto_context_id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
|
static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
|
||||||
@@ -68,124 +64,8 @@ static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_gprs *gprs = user_data;
|
|
||||||
struct gprs_data *data = ofono_gprs_get_data(gprs);
|
|
||||||
char *apn = NULL;
|
|
||||||
uint16_t error;
|
|
||||||
uint8_t iptype;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (qmi_result_set_error(result, &error)) {
|
|
||||||
ofono_error("Failed to query LTE attach params: %hd", error);
|
|
||||||
goto noapn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* APN */
|
|
||||||
apn = qmi_result_get_string(result, 0x10);
|
|
||||||
if (!apn) {
|
|
||||||
DBG("Default profile has no APN setting");
|
|
||||||
goto noapn;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qmi_result_get_uint8(result, 0x11, &iptype))
|
|
||||||
ofono_info("LTE attach IP type: %hhd", iptype);
|
|
||||||
|
|
||||||
ofono_gprs_cid_activated(gprs, data->last_auto_context_id, apn);
|
|
||||||
g_free(apn);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
noapn:
|
|
||||||
data->last_auto_context_id = 0;
|
|
||||||
ofono_error("LTE bearer established but APN not set");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_default_profile_cb(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_gprs* gprs = user_data;
|
|
||||||
struct gprs_data *data = ofono_gprs_get_data(gprs);
|
|
||||||
uint16_t error;
|
|
||||||
uint8_t index;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (qmi_result_set_error(result, &error)) {
|
|
||||||
ofono_error("Get default profile error: %hd", error);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Profile index */
|
|
||||||
if (!qmi_result_get_uint8(result, 0x01, &index)) {
|
|
||||||
ofono_error("Failed query default profile");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG("Default profile index: %hhd", index);
|
|
||||||
|
|
||||||
data->last_auto_context_id = index;
|
|
||||||
|
|
||||||
/* Get LTE Attach Parameters */
|
|
||||||
if (qmi_service_send(data->wds, 0x85, NULL,
|
|
||||||
get_lte_attach_param_cb, gprs, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
data->last_auto_context_id = 0;
|
|
||||||
ofono_error("LTE bearer established but APN not set");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Query the settings in effect on the default bearer. These may be
|
|
||||||
* implicit or may even be something other than requested as the gateway
|
|
||||||
* is allowed to override whatever was requested by the user.
|
|
||||||
*/
|
|
||||||
static void get_lte_attach_params(struct ofono_gprs* gprs)
|
|
||||||
{
|
|
||||||
struct gprs_data *data = ofono_gprs_get_data(gprs);
|
|
||||||
struct {
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t family;
|
|
||||||
} __attribute((packed)) p = {
|
|
||||||
.type = 0, /* 3GPP */
|
|
||||||
.family = 0, /* embedded */
|
|
||||||
};
|
|
||||||
struct qmi_param *param;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (data->last_auto_context_id != 0)
|
|
||||||
return; /* Established or in progress */
|
|
||||||
|
|
||||||
/* Set query in progress */
|
|
||||||
data->last_auto_context_id = -1;
|
|
||||||
|
|
||||||
/* First we query the default profile in order to find out which
|
|
||||||
* context the modem has activated.
|
|
||||||
*/
|
|
||||||
param = qmi_param_new();
|
|
||||||
if (!param)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Profile type */
|
|
||||||
qmi_param_append(param, 0x1, sizeof(p), &p);
|
|
||||||
|
|
||||||
/* Get default profile */
|
|
||||||
if (qmi_service_send(data->wds, 0x49, param,
|
|
||||||
get_default_profile_cb, gprs, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qmi_param_free(param);
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_warn("Unable to query LTE APN... will not activate context");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
|
static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
|
||||||
{
|
{
|
||||||
struct gprs_data *data = ofono_gprs_get_data(gprs);
|
|
||||||
int status;
|
int status;
|
||||||
int tech;
|
int tech;
|
||||||
|
|
||||||
@@ -194,20 +74,17 @@ static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
|
|||||||
if (!extract_ss_info(result, &status, &tech))
|
if (!extract_ss_info(result, &status, &tech))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
|
if (status == NETWORK_REGISTRATION_STATUS_REGISTERED)
|
||||||
if (tech == ACCESS_TECHNOLOGY_EUTRAN) {
|
if (tech == ACCESS_TECHNOLOGY_EUTRAN) {
|
||||||
/* On LTE we are effectively always attached; and
|
/* On LTE we are effectively always attached; and
|
||||||
* the default bearer is established as soon as the
|
* the default bearer is established as soon as the
|
||||||
* network is joined. We just need to query the
|
* network is joined.
|
||||||
* parameters in effect on the default bearer and
|
|
||||||
* let the ofono core know about the activated
|
|
||||||
* context.
|
|
||||||
*/
|
*/
|
||||||
get_lte_attach_params(gprs);
|
/* FIXME: query default profile number and APN
|
||||||
|
* instead of assuming profile 1 and ""
|
||||||
|
*/
|
||||||
|
ofono_gprs_cid_activated(gprs, 1 , "automatic");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
data->last_auto_context_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -321,7 +198,7 @@ static void qmi_attached_status(struct ofono_gprs *gprs,
|
|||||||
g_free(cbd);
|
g_free(cbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_wds_cb(struct qmi_service *service, void *user_data)
|
static void create_nas_cb(struct qmi_service *service, void *user_data)
|
||||||
{
|
{
|
||||||
struct ofono_gprs *gprs = user_data;
|
struct ofono_gprs *gprs = user_data;
|
||||||
struct gprs_data *data = ofono_gprs_get_data(gprs);
|
struct gprs_data *data = ofono_gprs_get_data(gprs);
|
||||||
@@ -329,12 +206,12 @@ static void create_wds_cb(struct qmi_service *service, void *user_data)
|
|||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
if (!service) {
|
if (!service) {
|
||||||
ofono_error("Failed to request WDS service");
|
ofono_error("Failed to request NAS service");
|
||||||
ofono_gprs_remove(gprs);
|
ofono_gprs_remove(gprs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->wds = qmi_service_ref(service);
|
data->nas = qmi_service_ref(service);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First get the SS info - the modem may already be connected,
|
* First get the SS info - the modem may already be connected,
|
||||||
@@ -351,25 +228,6 @@ static void create_wds_cb(struct qmi_service *service, void *user_data)
|
|||||||
ofono_gprs_register(gprs);
|
ofono_gprs_register(gprs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_nas_cb(struct qmi_service *service, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_gprs *gprs = user_data;
|
|
||||||
struct gprs_data *data = ofono_gprs_get_data(gprs);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!service) {
|
|
||||||
ofono_error("Failed to request NAS service");
|
|
||||||
ofono_gprs_remove(gprs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->nas = qmi_service_ref(service);
|
|
||||||
|
|
||||||
qmi_service_create_shared(data->dev, QMI_SERVICE_WDS,
|
|
||||||
create_wds_cb, gprs, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qmi_gprs_probe(struct ofono_gprs *gprs,
|
static int qmi_gprs_probe(struct ofono_gprs *gprs,
|
||||||
unsigned int vendor, void *user_data)
|
unsigned int vendor, void *user_data)
|
||||||
{
|
{
|
||||||
@@ -382,8 +240,6 @@ static int qmi_gprs_probe(struct ofono_gprs *gprs,
|
|||||||
|
|
||||||
ofono_gprs_set_data(gprs, data);
|
ofono_gprs_set_data(gprs, data);
|
||||||
|
|
||||||
data->dev = device;
|
|
||||||
|
|
||||||
qmi_service_create_shared(device, QMI_SERVICE_NAS,
|
qmi_service_create_shared(device, QMI_SERVICE_NAS,
|
||||||
create_nas_cb, gprs, NULL);
|
create_nas_cb, gprs, NULL);
|
||||||
|
|
||||||
@@ -398,9 +254,6 @@ static void qmi_gprs_remove(struct ofono_gprs *gprs)
|
|||||||
|
|
||||||
ofono_gprs_set_data(gprs, NULL);
|
ofono_gprs_set_data(gprs, NULL);
|
||||||
|
|
||||||
qmi_service_unregister_all(data->wds);
|
|
||||||
qmi_service_unref(data->wds);
|
|
||||||
|
|
||||||
qmi_service_unregister_all(data->nas);
|
qmi_service_unregister_all(data->nas);
|
||||||
|
|
||||||
qmi_service_unref(data->nas);
|
qmi_service_unref(data->nas);
|
||||||
|
|||||||
@@ -1,264 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2018 Jonas Bonn. All rights reserved.
|
|
||||||
* Copyright (C) 2018 Norrbonn AB. All rights reserved.
|
|
||||||
* Copyright (C) 2018 Data Respons ASA. All rights reserved.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/gprs-context.h>
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/lte.h>
|
|
||||||
|
|
||||||
#include "qmi.h"
|
|
||||||
#include "wds.h"
|
|
||||||
|
|
||||||
#include "qmimodem.h"
|
|
||||||
|
|
||||||
struct lte_data {
|
|
||||||
struct qmi_service *wds;
|
|
||||||
uint8_t default_profile;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void modify_profile_cb(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
ofono_lte_cb_t cb = cbd->cb;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (qmi_result_set_error(result, &error)) {
|
|
||||||
DBG("Failed to modify profile: %d", error);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qmimodem_lte_set_default_attach_info(const struct ofono_lte *lte,
|
|
||||||
const struct ofono_lte_default_attach_info *info,
|
|
||||||
ofono_lte_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct lte_data *ldd = ofono_lte_get_data(lte);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct qmi_param* param;
|
|
||||||
struct {
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t index;
|
|
||||||
} __attribute__((packed)) p = {
|
|
||||||
.type = 0, /* 3GPP */
|
|
||||||
};
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
p.index = ldd->default_profile;
|
|
||||||
|
|
||||||
param = qmi_param_new();
|
|
||||||
if (!param)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Profile selector */
|
|
||||||
qmi_param_append(param, 0x01, sizeof(p), &p);
|
|
||||||
|
|
||||||
/* WDS APN Name */
|
|
||||||
qmi_param_append(param, QMI_WDS_PARAM_APN,
|
|
||||||
strlen(info->apn), info->apn);
|
|
||||||
|
|
||||||
/* Modify profile */
|
|
||||||
if (qmi_service_send(ldd->wds, 0x28, param,
|
|
||||||
modify_profile_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qmi_param_free(param);
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reset_profile_cb(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_lte *lte = user_data;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (qmi_result_set_error(result, &error))
|
|
||||||
ofono_error("Reset profile error: %hd", error);
|
|
||||||
|
|
||||||
ofono_lte_register(lte);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_default_profile_cb(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_lte *lte = user_data;
|
|
||||||
struct lte_data *ldd = ofono_lte_get_data(lte);
|
|
||||||
uint16_t error;
|
|
||||||
uint8_t index;
|
|
||||||
struct qmi_param *param;
|
|
||||||
struct {
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t index;
|
|
||||||
} __attribute__((packed)) p = {
|
|
||||||
.type = 0, /* 3GPP */
|
|
||||||
};
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (qmi_result_set_error(result, &error)) {
|
|
||||||
ofono_error("Get default profile error: %hd", error);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Profile index */
|
|
||||||
if (!qmi_result_get_uint8(result, 0x01, &index)) {
|
|
||||||
ofono_error("Failed query default profile");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG("Default profile index: %hhd", index);
|
|
||||||
|
|
||||||
ldd->default_profile = index;
|
|
||||||
|
|
||||||
p.index = index;
|
|
||||||
|
|
||||||
param = qmi_param_new();
|
|
||||||
if (!param)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Profile selector */
|
|
||||||
qmi_param_append(param, 0x01, sizeof(p), &p);
|
|
||||||
|
|
||||||
/* Reset profile */
|
|
||||||
if (qmi_service_send(ldd->wds, 0x4b, param,
|
|
||||||
reset_profile_cb, lte, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qmi_param_free(param);
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_error("Failed to reset profile %hhd", index);
|
|
||||||
ofono_lte_remove(lte);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void create_wds_cb(struct qmi_service *service, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_lte *lte = user_data;
|
|
||||||
struct lte_data *ldd = ofono_lte_get_data(lte);
|
|
||||||
struct qmi_param *param;
|
|
||||||
struct {
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t family;
|
|
||||||
} __attribute((packed)) p = {
|
|
||||||
.type = 0, /* 3GPP */
|
|
||||||
.family = 0, /* embedded */
|
|
||||||
};
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (!service) {
|
|
||||||
ofono_error("Failed to request WDS service");
|
|
||||||
ofono_lte_remove(lte);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ldd->wds = qmi_service_ref(service);
|
|
||||||
|
|
||||||
/* Query the default profile */
|
|
||||||
param = qmi_param_new();
|
|
||||||
if (!param)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Profile type */
|
|
||||||
qmi_param_append(param, 0x1, sizeof(p), &p);
|
|
||||||
|
|
||||||
/* Get default profile */
|
|
||||||
if (qmi_service_send(ldd->wds, 0x49, param,
|
|
||||||
get_default_profile_cb, lte, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qmi_param_free(param);
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_error("Failed to query default profile");
|
|
||||||
ofono_lte_register(lte);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qmimodem_lte_probe(struct ofono_lte *lte, void *data)
|
|
||||||
{
|
|
||||||
struct qmi_device *device = data;
|
|
||||||
struct lte_data *ldd;
|
|
||||||
|
|
||||||
DBG("qmimodem lte probe");
|
|
||||||
|
|
||||||
ldd = g_try_new0(struct lte_data, 1);
|
|
||||||
if (!ldd)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ofono_lte_set_data(lte, ldd);
|
|
||||||
|
|
||||||
qmi_service_create_shared(device, QMI_SERVICE_WDS,
|
|
||||||
create_wds_cb, lte, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qmimodem_lte_remove(struct ofono_lte *lte)
|
|
||||||
{
|
|
||||||
struct lte_data *ldd = ofono_lte_get_data(lte);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
ofono_lte_set_data(lte, NULL);
|
|
||||||
|
|
||||||
qmi_service_unregister_all(ldd->wds);
|
|
||||||
|
|
||||||
qmi_service_unref(ldd->wds);
|
|
||||||
|
|
||||||
g_free(ldd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_lte_driver driver = {
|
|
||||||
.name = "qmimodem",
|
|
||||||
.probe = qmimodem_lte_probe,
|
|
||||||
.remove = qmimodem_lte_remove,
|
|
||||||
.set_default_attach_info = qmimodem_lte_set_default_attach_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
void qmi_lte_init(void)
|
|
||||||
{
|
|
||||||
ofono_lte_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void qmi_lte_exit(void)
|
|
||||||
{
|
|
||||||
ofono_lte_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -332,7 +332,6 @@ static void register_net_cb(struct qmi_result *result, void *user_data)
|
|||||||
struct cb_data *cbd = user_data;
|
struct cb_data *cbd = user_data;
|
||||||
ofono_netreg_register_cb_t cb = cbd->cb;
|
ofono_netreg_register_cb_t cb = cbd->cb;
|
||||||
uint16_t error;
|
uint16_t error;
|
||||||
int cme_error;
|
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
@@ -342,8 +341,7 @@ static void register_net_cb(struct qmi_result *result, void *user_data)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
cme_error = qmi_error_to_ofono_cme(error);
|
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||||
CALLBACK_WITH_CME_ERROR(cb, cme_error, cbd->data);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -476,17 +476,6 @@ static const char *__error_to_string(uint16_t error)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qmi_error_to_ofono_cme(int qmi_error) {
|
|
||||||
switch (qmi_error) {
|
|
||||||
case 0x0019:
|
|
||||||
return 4; /* Not Supported */
|
|
||||||
case 0x0052:
|
|
||||||
return 32; /* Access Denied */
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __debug_msg(const char dir, const void *buf, size_t len,
|
static void __debug_msg(const char dir, const void *buf, size_t len,
|
||||||
qmi_debug_func_t function, void *user_data)
|
qmi_debug_func_t function, void *user_data)
|
||||||
{
|
{
|
||||||
@@ -1084,7 +1073,6 @@ struct discover_data {
|
|||||||
qmi_discover_func_t func;
|
qmi_discover_func_t func;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
qmi_destroy_func_t destroy;
|
qmi_destroy_func_t destroy;
|
||||||
uint8_t tid;
|
|
||||||
guint timeout;
|
guint timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1145,13 +1133,6 @@ static void discover_callback(uint16_t message, uint16_t length,
|
|||||||
uint8_t type = service_list->services[i].type;
|
uint8_t type = service_list->services[i].type;
|
||||||
const char *name = __service_type_to_string(type);
|
const char *name = __service_type_to_string(type);
|
||||||
|
|
||||||
if (name)
|
|
||||||
__debug_device(device, "found service [%s %d.%d]",
|
|
||||||
name, major, minor);
|
|
||||||
else
|
|
||||||
__debug_device(device, "found service [%d %d.%d]",
|
|
||||||
type, major, minor);
|
|
||||||
|
|
||||||
if (type == QMI_SERVICE_CONTROL) {
|
if (type == QMI_SERVICE_CONTROL) {
|
||||||
device->control_major = major;
|
device->control_major = major;
|
||||||
device->control_minor = minor;
|
device->control_minor = minor;
|
||||||
@@ -1164,6 +1145,13 @@ static void discover_callback(uint16_t message, uint16_t length,
|
|||||||
list[count].name = name;
|
list[count].name = name;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
__debug_device(device, "found service [%s %d.%d]",
|
||||||
|
name, major, minor);
|
||||||
|
else
|
||||||
|
__debug_device(device, "found service [%d %d.%d]",
|
||||||
|
type, major, minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = tlv_get(buffer, length, 0x10, &len);
|
ptr = tlv_get(buffer, length, 0x10, &len);
|
||||||
@@ -1172,6 +1160,13 @@ static void discover_callback(uint16_t message, uint16_t length,
|
|||||||
|
|
||||||
device->version_str = strndup(ptr + 1, *((uint8_t *) ptr));
|
device->version_str = strndup(ptr + 1, *((uint8_t *) ptr));
|
||||||
|
|
||||||
|
service_list = ptr + *((uint8_t *) ptr) + 1;
|
||||||
|
|
||||||
|
for (i = 0; i < service_list->count; i++) {
|
||||||
|
if (service_list->services[i].type == QMI_SERVICE_CONTROL)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
device->version_list = list;
|
device->version_list = list;
|
||||||
device->version_count = count;
|
device->version_count = count;
|
||||||
@@ -1186,38 +1181,14 @@ static gboolean discover_reply(gpointer user_data)
|
|||||||
{
|
{
|
||||||
struct discover_data *data = user_data;
|
struct discover_data *data = user_data;
|
||||||
struct qmi_device *device = data->device;
|
struct qmi_device *device = data->device;
|
||||||
unsigned int tid = data->tid;
|
|
||||||
GList *list;
|
|
||||||
struct qmi_request *req = NULL;
|
|
||||||
|
|
||||||
data->timeout = 0;
|
data->timeout = 0;
|
||||||
|
|
||||||
/* remove request from queues */
|
|
||||||
if (tid != 0) {
|
|
||||||
list = g_queue_find_custom(device->req_queue,
|
|
||||||
GUINT_TO_POINTER(tid), __request_compare);
|
|
||||||
|
|
||||||
if (list) {
|
|
||||||
req = list->data;
|
|
||||||
g_queue_delete_link(device->req_queue, list);
|
|
||||||
} else {
|
|
||||||
list = g_queue_find_custom(device->control_queue,
|
|
||||||
GUINT_TO_POINTER(tid), __request_compare);
|
|
||||||
|
|
||||||
if (list) {
|
|
||||||
req = list->data;
|
|
||||||
g_queue_delete_link(device->control_queue,
|
|
||||||
list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->func)
|
if (data->func)
|
||||||
data->func(device->version_count,
|
data->func(device->version_count,
|
||||||
device->version_list, data->user_data);
|
device->version_list, data->user_data);
|
||||||
|
|
||||||
__qmi_device_discovery_complete(data->device, &data->super);
|
__qmi_device_discovery_complete(data->device, &data->super);
|
||||||
__request_free(req, NULL);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1263,7 +1234,6 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
|
|||||||
|
|
||||||
hdr->type = 0x00;
|
hdr->type = 0x00;
|
||||||
hdr->transaction = device->next_control_tid++;
|
hdr->transaction = device->next_control_tid++;
|
||||||
data->tid = hdr->transaction;
|
|
||||||
|
|
||||||
__request_submit(device, req, hdr->transaction);
|
__request_submit(device, req, hdr->transaction);
|
||||||
|
|
||||||
@@ -1353,65 +1323,6 @@ bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sync_data {
|
|
||||||
qmi_sync_func_t func;
|
|
||||||
void *user_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void qmi_device_sync_callback(uint16_t message, uint16_t length,
|
|
||||||
const void *buffer, void *user_data)
|
|
||||||
{
|
|
||||||
struct sync_data *data = user_data;
|
|
||||||
|
|
||||||
if (data->func)
|
|
||||||
data->func(data->user_data);
|
|
||||||
|
|
||||||
g_free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sync will release all previous clients */
|
|
||||||
bool qmi_device_sync(struct qmi_device *device,
|
|
||||||
qmi_sync_func_t func, void *user_data)
|
|
||||||
{
|
|
||||||
struct qmi_request *req;
|
|
||||||
struct qmi_control_hdr *hdr;
|
|
||||||
struct sync_data *func_data;
|
|
||||||
|
|
||||||
if (!device)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
__debug_device(device, "Sending sync to reset QMI");
|
|
||||||
|
|
||||||
func_data = g_new0(struct sync_data, 1);
|
|
||||||
func_data->func = func;
|
|
||||||
func_data->user_data = user_data;
|
|
||||||
|
|
||||||
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
|
|
||||||
QMI_CTL_SYNC, QMI_CONTROL_HDR_SIZE,
|
|
||||||
NULL, 0,
|
|
||||||
qmi_device_sync_callback, func_data, (void **) &hdr);
|
|
||||||
|
|
||||||
if (device->next_control_tid < 1)
|
|
||||||
device->next_control_tid = 1;
|
|
||||||
|
|
||||||
hdr->type = 0x00;
|
|
||||||
hdr->transaction = device->next_control_tid++;
|
|
||||||
|
|
||||||
__request_submit(device, req, hdr->transaction);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if the device support the QMI call SYNC over the CTL interface */
|
|
||||||
bool qmi_device_is_sync_supported(struct qmi_device *device)
|
|
||||||
{
|
|
||||||
if (device == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (device->control_major > 1 ||
|
|
||||||
(device->control_major == 1 && device->control_minor >= 5));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool get_device_file_name(struct qmi_device *device,
|
static bool get_device_file_name(struct qmi_device *device,
|
||||||
char *file_name, int size)
|
char *file_name, int size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ typedef void (*qmi_destroy_func_t)(void *user_data);
|
|||||||
struct qmi_device;
|
struct qmi_device;
|
||||||
|
|
||||||
typedef void (*qmi_debug_func_t)(const char *str, void *user_data);
|
typedef void (*qmi_debug_func_t)(const char *str, void *user_data);
|
||||||
typedef void (*qmi_sync_func_t)(void *user_data);
|
|
||||||
typedef void (*qmi_shutdown_func_t)(void *user_data);
|
typedef void (*qmi_shutdown_func_t)(void *user_data);
|
||||||
typedef void (*qmi_discover_func_t)(uint8_t count,
|
typedef void (*qmi_discover_func_t)(uint8_t count,
|
||||||
const struct qmi_version *list, void *user_data);
|
const struct qmi_version *list, void *user_data);
|
||||||
@@ -96,10 +96,6 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
|
|||||||
bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
|
bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
|
||||||
void *user_data, qmi_destroy_func_t destroy);
|
void *user_data, qmi_destroy_func_t destroy);
|
||||||
|
|
||||||
bool qmi_device_sync(struct qmi_device *device,
|
|
||||||
qmi_sync_func_t func, void *user_data);
|
|
||||||
bool qmi_device_is_sync_supported(struct qmi_device *device);
|
|
||||||
|
|
||||||
enum qmi_device_expected_data_format qmi_device_get_expected_data_format(
|
enum qmi_device_expected_data_format qmi_device_get_expected_data_format(
|
||||||
struct qmi_device *device);
|
struct qmi_device *device);
|
||||||
bool qmi_device_set_expected_data_format(struct qmi_device *device,
|
bool qmi_device_set_expected_data_format(struct qmi_device *device,
|
||||||
@@ -144,8 +140,6 @@ bool qmi_result_get_uint64(struct qmi_result *result, uint8_t type,
|
|||||||
uint64_t *value);
|
uint64_t *value);
|
||||||
void qmi_result_print_tlvs(struct qmi_result *result);
|
void qmi_result_print_tlvs(struct qmi_result *result);
|
||||||
|
|
||||||
int qmi_error_to_ofono_cme(int qmi_error);
|
|
||||||
|
|
||||||
struct qmi_service;
|
struct qmi_service;
|
||||||
|
|
||||||
typedef void (*qmi_result_func_t)(struct qmi_result *result, void *user_data);
|
typedef void (*qmi_result_func_t)(struct qmi_result *result, void *user_data);
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ static int qmimodem_init(void)
|
|||||||
qmi_ussd_init();
|
qmi_ussd_init();
|
||||||
qmi_gprs_init();
|
qmi_gprs_init();
|
||||||
qmi_gprs_context_init();
|
qmi_gprs_context_init();
|
||||||
qmi_lte_init();
|
|
||||||
qmi_radio_settings_init();
|
qmi_radio_settings_init();
|
||||||
qmi_location_reporting_init();
|
qmi_location_reporting_init();
|
||||||
qmi_netmon_init();
|
qmi_netmon_init();
|
||||||
@@ -52,7 +51,6 @@ static void qmimodem_exit(void)
|
|||||||
qmi_netmon_exit();
|
qmi_netmon_exit();
|
||||||
qmi_location_reporting_exit();
|
qmi_location_reporting_exit();
|
||||||
qmi_radio_settings_exit();
|
qmi_radio_settings_exit();
|
||||||
qmi_lte_exit();
|
|
||||||
qmi_gprs_context_exit();
|
qmi_gprs_context_exit();
|
||||||
qmi_gprs_exit();
|
qmi_gprs_exit();
|
||||||
qmi_ussd_exit();
|
qmi_ussd_exit();
|
||||||
|
|||||||
@@ -48,9 +48,6 @@ extern void qmi_gprs_exit(void);
|
|||||||
extern void qmi_gprs_context_init(void);
|
extern void qmi_gprs_context_init(void);
|
||||||
extern void qmi_gprs_context_exit(void);
|
extern void qmi_gprs_context_exit(void);
|
||||||
|
|
||||||
extern void qmi_lte_init(void);
|
|
||||||
extern void qmi_lte_exit(void);
|
|
||||||
|
|
||||||
extern void qmi_radio_settings_init(void);
|
extern void qmi_radio_settings_init(void);
|
||||||
extern void qmi_radio_settings_exit(void);
|
extern void qmi_radio_settings_exit(void);
|
||||||
|
|
||||||
|
|||||||
@@ -277,9 +277,6 @@ static void qmi_radio_settings_remove(struct ofono_radio_settings *rs)
|
|||||||
|
|
||||||
ofono_radio_settings_set_data(rs, NULL);
|
ofono_radio_settings_set_data(rs, NULL);
|
||||||
|
|
||||||
qmi_service_unregister_all(data->dms);
|
|
||||||
qmi_service_unref(data->dms);
|
|
||||||
|
|
||||||
qmi_service_unregister_all(data->nas);
|
qmi_service_unregister_all(data->nas);
|
||||||
|
|
||||||
qmi_service_unref(data->nas);
|
qmi_service_unref(data->nas);
|
||||||
|
|||||||
@@ -334,38 +334,9 @@ error:
|
|||||||
g_free(cbd);
|
g_free(cbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raw_read_cb(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_sms *sms = user_data;
|
|
||||||
const struct qmi_wms_raw_message* msg;
|
|
||||||
uint16_t len;
|
|
||||||
uint16_t error;
|
|
||||||
|
|
||||||
if (qmi_result_set_error(result, &error)) {
|
|
||||||
DBG("Raw read error: %d (%s)", error,
|
|
||||||
qmi_result_get_error(result));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Raw message data */
|
|
||||||
msg = qmi_result_get(result, 0x01, &len);
|
|
||||||
if (msg) {
|
|
||||||
uint16_t plen;
|
|
||||||
uint16_t tpdu_len;
|
|
||||||
|
|
||||||
plen = GUINT16_FROM_LE(msg->msg_length);
|
|
||||||
tpdu_len = plen - msg->msg_data[0] - 1;
|
|
||||||
|
|
||||||
ofono_sms_deliver_notify(sms, msg->msg_data, plen, tpdu_len);
|
|
||||||
} else {
|
|
||||||
DBG("No message data available at requested position");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void event_notify(struct qmi_result *result, void *user_data)
|
static void event_notify(struct qmi_result *result, void *user_data)
|
||||||
{
|
{
|
||||||
struct ofono_sms *sms = user_data;
|
struct ofono_sms *sms = user_data;
|
||||||
struct sms_data *data = ofono_sms_get_data(sms);
|
|
||||||
const struct qmi_wms_result_new_msg_notify *notify;
|
const struct qmi_wms_result_new_msg_notify *notify;
|
||||||
const struct qmi_wms_result_message *message;
|
const struct qmi_wms_result_message *message;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
@@ -389,34 +360,6 @@ static void event_notify(struct qmi_result *result, void *user_data)
|
|||||||
DBG("msg format %d PDU length %d", message->msg_format, plen);
|
DBG("msg format %d PDU length %d", message->msg_format, plen);
|
||||||
|
|
||||||
ofono_sms_deliver_notify(sms, message->msg_data, plen, plen);
|
ofono_sms_deliver_notify(sms, message->msg_data, plen, plen);
|
||||||
} else {
|
|
||||||
/* The Quectel EC21, at least, does not provide the
|
|
||||||
* message data in the event notification, so a 'raw read'
|
|
||||||
* needs to be issued in order to query the message itself
|
|
||||||
*/
|
|
||||||
struct qmi_param *param;
|
|
||||||
|
|
||||||
param = qmi_param_new();
|
|
||||||
if (!param)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Message memory storage ID */
|
|
||||||
qmi_param_append(param, 0x01, sizeof(*notify), notify);
|
|
||||||
/* The 'message mode' parameter is documented as optional,
|
|
||||||
* but the Quectel EC21 errors out with error 17 (missing
|
|
||||||
* argument) if it is not provided... we default to 3GPP
|
|
||||||
* here because that's what works for me and it's not clear
|
|
||||||
* how to actually query what this should be otherwise...
|
|
||||||
*/
|
|
||||||
/* Message mode */
|
|
||||||
qmi_param_append_uint8(param, 0x10,
|
|
||||||
QMI_WMS_MESSAGE_MODE_GSMWCDMA);
|
|
||||||
|
|
||||||
if (qmi_service_send(data->wms, QMI_WMS_RAW_READ, param,
|
|
||||||
raw_read_cb, sms, NULL) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qmi_param_free(param);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2012 Intel Corporation. All rights reserved.
|
* Copyright (C) 2011-2012 Intel Corporation. All rights reserved.
|
||||||
* Copyright (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -24,103 +23,20 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#include <ofono/log.h>
|
#include <ofono/log.h>
|
||||||
#include <ofono/modem.h>
|
#include <ofono/modem.h>
|
||||||
#include <ofono/ussd.h>
|
#include <ofono/ussd.h>
|
||||||
#include <smsutil.h>
|
|
||||||
#include "qmi.h"
|
#include "qmi.h"
|
||||||
|
|
||||||
#include "qmimodem.h"
|
#include "qmimodem.h"
|
||||||
|
|
||||||
#include "voice.h"
|
|
||||||
|
|
||||||
struct ussd_data {
|
struct ussd_data {
|
||||||
struct qmi_service *voice;
|
struct qmi_service *voice;
|
||||||
uint16_t major;
|
uint16_t major;
|
||||||
uint16_t minor;
|
uint16_t minor;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int validate_ussd_data(const struct qmi_ussd_data *data, uint16_t size)
|
|
||||||
{
|
|
||||||
if (data == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (size < sizeof(*data))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (size < sizeof(*data) + data->length)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (data->dcs < QMI_USSD_DCS_ASCII || data->dcs > QMI_USSD_DCS_UCS2)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int convert_qmi_dcs_gsm_dcs(int qmi_dcs, int *gsm_dcs)
|
|
||||||
{
|
|
||||||
switch (qmi_dcs) {
|
|
||||||
case QMI_USSD_DCS_ASCII:
|
|
||||||
*gsm_dcs = USSD_DCS_8BIT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void async_orig_ind(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_ussd *ussd = user_data;
|
|
||||||
const struct qmi_ussd_data *qmi_ussd;
|
|
||||||
uint16_t error = 0;
|
|
||||||
uint16_t len;
|
|
||||||
int gsm_dcs;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
qmi_result_get_uint16(result, QMI_VOICE_PARAM_ASYNC_USSD_ERROR, &error);
|
|
||||||
|
|
||||||
switch (error) {
|
|
||||||
case 0:
|
|
||||||
/* no error */
|
|
||||||
break;
|
|
||||||
case 92:
|
|
||||||
qmi_result_get_uint16(result,
|
|
||||||
QMI_VOICE_PARAM_ASYNC_USSD_FAILURE_CASE,
|
|
||||||
&error);
|
|
||||||
DBG("Failure Cause: 0x%04x", error);
|
|
||||||
goto error;
|
|
||||||
default:
|
|
||||||
DBG("USSD Error 0x%04x", error);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
qmi_ussd = qmi_result_get(result, QMI_VOICE_PARAM_ASYNC_USSD_DATA,
|
|
||||||
&len);
|
|
||||||
if (qmi_ussd == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (validate_ussd_data(qmi_ussd, len))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (convert_qmi_dcs_gsm_dcs(qmi_ussd->dcs, &gsm_dcs))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
ofono_ussd_notify(ussd, OFONO_USSD_STATUS_NOTIFY, gsm_dcs,
|
|
||||||
qmi_ussd->data, qmi_ussd->length);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
ofono_ussd_notify(ussd, OFONO_USSD_STATUS_TERMINATED, 0, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void create_voice_cb(struct qmi_service *service, void *user_data)
|
static void create_voice_cb(struct qmi_service *service, void *user_data)
|
||||||
{
|
{
|
||||||
struct ofono_ussd *ussd = user_data;
|
struct ofono_ussd *ussd = user_data;
|
||||||
@@ -128,7 +44,7 @@ static void create_voice_cb(struct qmi_service *service, void *user_data)
|
|||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
if (service == NULL) {
|
if (!service) {
|
||||||
ofono_error("Failed to request Voice service");
|
ofono_error("Failed to request Voice service");
|
||||||
ofono_ussd_remove(ussd);
|
ofono_ussd_remove(ussd);
|
||||||
return;
|
return;
|
||||||
@@ -142,9 +58,6 @@ static void create_voice_cb(struct qmi_service *service, void *user_data)
|
|||||||
|
|
||||||
data->voice = qmi_service_ref(service);
|
data->voice = qmi_service_ref(service);
|
||||||
|
|
||||||
qmi_service_register(data->voice, QMI_VOICE_ASYNC_ORIG_USSD,
|
|
||||||
async_orig_ind, ussd, NULL);
|
|
||||||
|
|
||||||
ofono_ussd_register(ussd);
|
ofono_ussd_register(ussd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +77,7 @@ static int qmi_ussd_probe(struct ofono_ussd *ussd,
|
|||||||
create_voice_cb, ussd, NULL);
|
create_voice_cb, ussd, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qmi_ussd_remove(struct ofono_ussd *ussd)
|
static void qmi_ussd_remove(struct ofono_ussd *ussd)
|
||||||
@@ -179,103 +93,10 @@ static void qmi_ussd_remove(struct ofono_ussd *ussd)
|
|||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qmi_ussd_cancel(struct ofono_ussd *ussd,
|
|
||||||
ofono_ussd_cb_t cb, void *user_data)
|
|
||||||
{
|
|
||||||
struct ussd_data *ud = ofono_ussd_get_data(ussd);
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
if (qmi_service_send(ud->voice, QMI_VOICE_CANCEL_USSD, NULL,
|
|
||||||
NULL, NULL, NULL) > 0)
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, user_data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_FAILURE(cb, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The cb is called when the request (on modem layer) reports success or
|
|
||||||
* failure. It doesn't contain a network result. We get the network answer
|
|
||||||
* via VOICE_IND.
|
|
||||||
*/
|
|
||||||
static void qmi_ussd_request_cb(struct qmi_result *result, void *user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
ofono_ussd_cb_t cb = cbd->cb;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
qmi_result_print_tlvs(result);
|
|
||||||
|
|
||||||
if (qmi_result_set_error(result, NULL)) {
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qmi_ussd_request(struct ofono_ussd *ussd, int dcs,
|
|
||||||
const unsigned char *pdu, int len,
|
|
||||||
ofono_ussd_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct ussd_data *ud = ofono_ussd_get_data(ussd);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
struct qmi_ussd_data *qmi_ussd;
|
|
||||||
struct qmi_param *param;
|
|
||||||
char *utf8 = NULL;
|
|
||||||
long utf8_len = 0;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
switch (dcs) {
|
|
||||||
case 0xf: /* 7bit GSM unspecific */
|
|
||||||
utf8 = ussd_decode(dcs, len, pdu);
|
|
||||||
if (!utf8)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
utf8_len = strlen(utf8);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG("Unsupported USSD Data Coding Scheme 0x%x", dcs);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* So far only DCS_ASCII works.
|
|
||||||
* DCS_8BIT and DCS_UCS2 is broken, because the modem firmware
|
|
||||||
* (least on a EC20) encodes those in-correctly onto the air interface,
|
|
||||||
* resulting in wrong decoded USSD data.
|
|
||||||
*/
|
|
||||||
qmi_ussd = alloca(sizeof(struct qmi_ussd_data) + utf8_len);
|
|
||||||
qmi_ussd->dcs = QMI_USSD_DCS_ASCII;
|
|
||||||
qmi_ussd->length = len;
|
|
||||||
memcpy(qmi_ussd->data, utf8, utf8_len);
|
|
||||||
|
|
||||||
param = qmi_param_new();
|
|
||||||
if (param == NULL)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
qmi_param_append(param, QMI_VOICE_PARAM_USS_DATA,
|
|
||||||
sizeof(struct qmi_ussd_data) + utf8_len, qmi_ussd);
|
|
||||||
|
|
||||||
if (qmi_service_send(ud->voice, QMI_VOICE_ASYNC_ORIG_USSD, param,
|
|
||||||
qmi_ussd_request_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qmi_param_free(param);
|
|
||||||
error:
|
|
||||||
g_free(utf8);
|
|
||||||
g_free(cbd);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_ussd_driver driver = {
|
static struct ofono_ussd_driver driver = {
|
||||||
.name = "qmimodem",
|
.name = "qmimodem",
|
||||||
.probe = qmi_ussd_probe,
|
.probe = qmi_ussd_probe,
|
||||||
.remove = qmi_ussd_remove,
|
.remove = qmi_ussd_remove,
|
||||||
.request = qmi_ussd_request,
|
|
||||||
.cancel = qmi_ussd_cancel
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void qmi_ussd_init(void)
|
void qmi_ussd_init(void)
|
||||||
|
|||||||
@@ -39,15 +39,6 @@ static inline struct cb_data *cb_data_new(void *cb, void *data)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CALLBACK_WITH_CME_ERROR(cb, err, args...) \
|
|
||||||
do { \
|
|
||||||
struct ofono_error cb_e; \
|
|
||||||
cb_e.type = OFONO_ERROR_TYPE_CME; \
|
|
||||||
cb_e.error = err; \
|
|
||||||
\
|
|
||||||
cb(&cb_e, ##args); \
|
|
||||||
} while (0) \
|
|
||||||
|
|
||||||
#define CALLBACK_WITH_FAILURE(cb, args...) \
|
#define CALLBACK_WITH_FAILURE(cb, args...) \
|
||||||
do { \
|
do { \
|
||||||
struct ofono_error cb_e; \
|
struct ofono_error cb_e; \
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define QMI_VOICE_PARAM_USS_DATA 0x01
|
|
||||||
|
|
||||||
#define QMI_VOICE_PARAM_ASYNC_USSD_ERROR 0x10
|
|
||||||
#define QMI_VOICE_PARAM_ASYNC_USSD_FAILURE_CASE 0x11
|
|
||||||
#define QMI_VOICE_PARAM_ASYNC_USSD_DATA 0x12
|
|
||||||
|
|
||||||
#define QMI_VOICE_PARAM_USSD_IND_USER_ACTION 0x01
|
|
||||||
#define QMI_VOICE_PARAM_USSD_IND_DATA 0x10
|
|
||||||
#define QMI_VOICE_PARAM_USSD_IND_UCS2 0x11
|
|
||||||
|
|
||||||
/* according to GSM TS 23.038 section 5
|
|
||||||
* coding group 1111, No message class, 8 bit data
|
|
||||||
*/
|
|
||||||
#define USSD_DCS_8BIT 0xf4
|
|
||||||
/* coding group 01xx, Class 0, UCS2 (16 bit) */
|
|
||||||
#define USSD_DCS_UCS2 0x48
|
|
||||||
/* default alphabet Language unspecific */
|
|
||||||
#define USSD_DCS_UNSPECIFIC 0x0f
|
|
||||||
|
|
||||||
/* based on qmi ussd definition */
|
|
||||||
enum qmi_ussd_dcs {
|
|
||||||
QMI_USSD_DCS_ASCII = 0x1,
|
|
||||||
QMI_USSD_DCS_8BIT,
|
|
||||||
QMI_USSD_DCS_UCS2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum qmi_ussd_user_required {
|
|
||||||
QMI_USSD_NO_USER_ACTION_REQUIRED = 0x1,
|
|
||||||
QMI_USSD_USER_ACTION_REQUIRED,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* QMI service voice. Using an enum to prevent doublicated entries */
|
|
||||||
enum voice_commands {
|
|
||||||
QMI_VOICE_CANCEL_USSD = 0x3c,
|
|
||||||
QMI_VOICE_USSD_RELEASE_IND = 0x3d,
|
|
||||||
QMI_VOICE_USSD_IND = 0x3e,
|
|
||||||
QMI_VOICE_SUPS_IND = 0x42,
|
|
||||||
QMI_VOICE_ASYNC_ORIG_USSD = 0x43,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct qmi_ussd_data {
|
|
||||||
uint8_t dcs;
|
|
||||||
uint8_t length;
|
|
||||||
uint8_t data[0];
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
@@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
#define QMI_WMS_RAW_SEND 32 /* Send a raw message */
|
#define QMI_WMS_RAW_SEND 32 /* Send a raw message */
|
||||||
|
|
||||||
#define QMI_WMS_RAW_READ 34 /* Read raw message from storage*/
|
|
||||||
|
|
||||||
#define QMI_WMS_GET_MSG_LIST 49 /* Get list of messages from the device */
|
#define QMI_WMS_GET_MSG_LIST 49 /* Get list of messages from the device */
|
||||||
#define QMI_WMS_SET_ROUTES 50 /* Set routes for message memory storage */
|
#define QMI_WMS_SET_ROUTES 50 /* Set routes for message memory storage */
|
||||||
#define QMI_WMS_GET_ROUTES 51 /* Get routes for message memory storage */
|
#define QMI_WMS_GET_ROUTES 51 /* Get routes for message memory storage */
|
||||||
@@ -68,13 +66,6 @@ struct qmi_wms_param_message {
|
|||||||
|
|
||||||
#define QMI_WMS_MESSAGE_MODE_GSMWCDMA 1
|
#define QMI_WMS_MESSAGE_MODE_GSMWCDMA 1
|
||||||
|
|
||||||
struct qmi_wms_raw_message {
|
|
||||||
uint8_t msg_tag;
|
|
||||||
uint8_t msg_format;
|
|
||||||
uint16_t msg_length;
|
|
||||||
uint8_t msg_data[0];
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
/* Get routes for message memory storage */
|
/* Get routes for message memory storage */
|
||||||
#define QMI_WMS_RESULT_ROUTE_LIST 0x01
|
#define QMI_WMS_RESULT_ROUTE_LIST 0x01
|
||||||
#define QMI_WMS_PARAM_ROUTE_LIST 0x01
|
#define QMI_WMS_PARAM_ROUTE_LIST 0x01
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2019 Jolla Ltd.
|
* Copyright (C) 2016-2018 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
#include <gutil_idlepool.h>
|
#include <gutil_idlepool.h>
|
||||||
#include <gutil_misc.h>
|
#include <gutil_misc.h>
|
||||||
|
|
||||||
#define DEFAULT_UPDATE_RATE_MS (10000) /* 10 sec */
|
#define DISPLAY_ON_UPDATE_RATE (1000) /* 1 sec */
|
||||||
|
#define DISPLAY_OFF_UPDATE_RATE (60000) /* 1 min */
|
||||||
#define MAX_RETRIES (5)
|
#define MAX_RETRIES (5)
|
||||||
|
|
||||||
typedef GObjectClass RilCellInfoClass;
|
typedef GObjectClass RilCellInfoClass;
|
||||||
@@ -36,12 +37,13 @@ struct ril_cell_info {
|
|||||||
GObject object;
|
GObject object;
|
||||||
struct sailfish_cell_info info;
|
struct sailfish_cell_info info;
|
||||||
GRilIoChannel *io;
|
GRilIoChannel *io;
|
||||||
|
MceDisplay *display;
|
||||||
struct ril_radio *radio;
|
struct ril_radio *radio;
|
||||||
struct ril_sim_card *sim_card;
|
struct ril_sim_card *sim_card;
|
||||||
|
gulong display_state_event_id;
|
||||||
gulong radio_state_event_id;
|
gulong radio_state_event_id;
|
||||||
gulong sim_status_event_id;
|
gulong sim_status_event_id;
|
||||||
gboolean sim_card_ready;
|
gboolean sim_card_ready;
|
||||||
int update_rate_ms;
|
|
||||||
char *log_prefix;
|
char *log_prefix;
|
||||||
gulong event_id;
|
gulong event_id;
|
||||||
guint query_id;
|
guint query_id;
|
||||||
@@ -356,11 +358,12 @@ static void ril_cell_info_query(struct ril_cell_info *self)
|
|||||||
grilio_request_unref(req);
|
grilio_request_unref(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_cell_info_set_rate(struct ril_cell_info *self)
|
static void ril_cell_info_set_rate(struct ril_cell_info *self, int ms)
|
||||||
{
|
{
|
||||||
GRilIoRequest *req = grilio_request_array_int32_new(1,
|
GRilIoRequest *req = grilio_request_sized_new(8);
|
||||||
(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_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
|
||||||
grilio_channel_cancel_request(self->io, self->set_rate_id, FALSE);
|
grilio_channel_cancel_request(self->io, self->set_rate_id, FALSE);
|
||||||
self->set_rate_id = grilio_channel_send_request_full(self->io, req,
|
self->set_rate_id = grilio_channel_send_request_full(self->io, req,
|
||||||
@@ -369,6 +372,20 @@ static void ril_cell_info_set_rate(struct ril_cell_info *self)
|
|||||||
grilio_request_unref(req);
|
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)
|
static void ril_cell_info_refresh(struct ril_cell_info *self)
|
||||||
{
|
{
|
||||||
/* RIL_REQUEST_GET_CELL_INFO_LIST fails without SIM card */
|
/* RIL_REQUEST_GET_CELL_INFO_LIST fails without SIM card */
|
||||||
@@ -394,15 +411,12 @@ static void ril_cell_info_sim_status_cb(struct ril_sim_card *sim, void *arg)
|
|||||||
self->sim_card_ready = ril_sim_card_ready(sim);
|
self->sim_card_ready = ril_sim_card_ready(sim);
|
||||||
DBG_(self, "%sready", self->sim_card_ready ? "" : "not ");
|
DBG_(self, "%sready", self->sim_card_ready ? "" : "not ");
|
||||||
ril_cell_info_refresh(self);
|
ril_cell_info_refresh(self);
|
||||||
if (self->sim_card_ready) {
|
ril_cell_info_update_rate(self);
|
||||||
ril_cell_info_set_rate(self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sailfish_cell_info interface callbacks */
|
/* sailfish_cell_info interface callbacks */
|
||||||
|
|
||||||
struct ril_cell_info_closure {
|
struct ril_cell_info_signal_data {
|
||||||
GCClosure cclosure;
|
|
||||||
sailfish_cell_info_cb_t cb;
|
sailfish_cell_info_cb_t cb;
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
@@ -424,9 +438,17 @@ 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,
|
static void ril_cell_info_cells_changed_cb(struct ril_cell_info *self,
|
||||||
struct ril_cell_info_closure *closure)
|
void *user_data)
|
||||||
{
|
{
|
||||||
closure->cb(&self->info, closure->arg);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gulong ril_cell_info_add_cells_changed_handler_proc
|
static gulong ril_cell_info_add_cells_changed_handler_proc
|
||||||
@@ -434,18 +456,16 @@ static gulong ril_cell_info_add_cells_changed_handler_proc
|
|||||||
sailfish_cell_info_cb_t cb, void *arg)
|
sailfish_cell_info_cb_t cb, void *arg)
|
||||||
{
|
{
|
||||||
if (cb) {
|
if (cb) {
|
||||||
struct ril_cell_info_closure *closure =
|
struct ril_cell_info_signal_data *data =
|
||||||
(struct ril_cell_info_closure *) g_closure_new_simple
|
g_slice_new(struct ril_cell_info_signal_data);
|
||||||
(sizeof(struct ril_cell_info_closure), NULL);
|
|
||||||
GCClosure* cc = &closure->cclosure;
|
|
||||||
|
|
||||||
cc->closure.data = closure;
|
data->cb = cb;
|
||||||
cc->callback = G_CALLBACK(ril_cell_info_cells_changed_cb);
|
data->arg = arg;
|
||||||
closure->cb = cb;
|
return g_signal_connect_data(ril_cell_info_cast(info),
|
||||||
closure->arg = arg;
|
SIGNAL_CELLS_CHANGED_NAME,
|
||||||
return g_signal_connect_closure_by_id(ril_cell_info_cast(info),
|
G_CALLBACK(ril_cell_info_cells_changed_cb),
|
||||||
ril_cell_info_signals[SIGNAL_CELLS_CHANGED], 0,
|
data, ril_cell_info_cells_disconnect_notify,
|
||||||
&cc->closure, FALSE);
|
G_CONNECT_AFTER);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -459,36 +479,22 @@ 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,
|
struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
||||||
const char *log_prefix, struct ril_radio *radio,
|
const char *log_prefix, MceDisplay *display,
|
||||||
struct ril_sim_card *sim_card)
|
struct ril_radio *radio, struct ril_sim_card *sim_card)
|
||||||
{
|
{
|
||||||
static const struct sailfish_cell_info_proc ril_cell_info_proc = {
|
static const struct sailfish_cell_info_proc ril_cell_info_proc = {
|
||||||
ril_cell_info_ref_proc,
|
ril_cell_info_ref_proc,
|
||||||
ril_cell_info_unref_proc,
|
ril_cell_info_unref_proc,
|
||||||
ril_cell_info_add_cells_changed_handler_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);
|
struct ril_cell_info *self = g_object_new(RIL_CELL_INFO_TYPE, 0);
|
||||||
|
|
||||||
self->info.proc = &ril_cell_info_proc;
|
self->info.proc = &ril_cell_info_proc;
|
||||||
self->io = grilio_channel_ref(io);
|
self->io = grilio_channel_ref(io);
|
||||||
|
self->display = mce_display_ref(display);
|
||||||
self->radio = ril_radio_ref(radio);
|
self->radio = ril_radio_ref(radio);
|
||||||
self->sim_card = ril_sim_card_ref(sim_card);
|
self->sim_card = ril_sim_card_ref(sim_card);
|
||||||
self->log_prefix = (log_prefix && log_prefix[0]) ?
|
self->log_prefix = (log_prefix && log_prefix[0]) ?
|
||||||
@@ -496,6 +502,9 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
|||||||
DBG_(self, "");
|
DBG_(self, "");
|
||||||
self->event_id = grilio_channel_add_unsol_event_handler(self->io,
|
self->event_id = grilio_channel_add_unsol_event_handler(self->io,
|
||||||
ril_cell_info_list_changed_cb, RIL_UNSOL_CELL_INFO_LIST, self);
|
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 =
|
self->radio_state_event_id =
|
||||||
ril_radio_add_state_changed_handler(radio,
|
ril_radio_add_state_changed_handler(radio,
|
||||||
ril_cell_info_radio_state_cb, self);
|
ril_cell_info_radio_state_cb, self);
|
||||||
@@ -504,15 +513,12 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
|||||||
ril_cell_info_sim_status_cb, self);
|
ril_cell_info_sim_status_cb, self);
|
||||||
self->sim_card_ready = ril_sim_card_ready(sim_card);
|
self->sim_card_ready = ril_sim_card_ready(sim_card);
|
||||||
ril_cell_info_refresh(self);
|
ril_cell_info_refresh(self);
|
||||||
if (self->sim_card_ready) {
|
ril_cell_info_update_rate(self);
|
||||||
ril_cell_info_set_rate(self);
|
|
||||||
}
|
|
||||||
return &self->info;
|
return &self->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_cell_info_init(struct ril_cell_info *self)
|
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)
|
static void ril_cell_info_dispose(GObject *object)
|
||||||
@@ -529,6 +535,8 @@ static void ril_cell_info_dispose(GObject *object)
|
|||||||
FALSE);
|
FALSE);
|
||||||
self->set_rate_id = 0;
|
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_radio_remove_handlers(self->radio, &self->radio_state_event_id, 1);
|
||||||
ril_sim_card_remove_handlers(self->sim_card,
|
ril_sim_card_remove_handlers(self->sim_card,
|
||||||
&self->sim_status_event_id, 1);
|
&self->sim_status_event_id, 1);
|
||||||
@@ -542,6 +550,7 @@ static void ril_cell_info_finalize(GObject *object)
|
|||||||
DBG_(self, "");
|
DBG_(self, "");
|
||||||
g_free(self->log_prefix);
|
g_free(self->log_prefix);
|
||||||
grilio_channel_unref(self->io);
|
grilio_channel_unref(self->io);
|
||||||
|
mce_display_unref(self->display);
|
||||||
ril_radio_unref(self->radio);
|
ril_radio_unref(self->radio);
|
||||||
ril_sim_card_unref(self->sim_card);
|
ril_sim_card_unref(self->sim_card);
|
||||||
g_slist_free_full(self->info.cells, ril_cell_free1);
|
g_slist_free_full(self->info.cells, ril_cell_free1);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2019 Jolla Ltd.
|
* Copyright (C) 2016-2017 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -17,12 +17,12 @@
|
|||||||
#define RIL_CELL_INFO_H
|
#define RIL_CELL_INFO_H
|
||||||
|
|
||||||
#include "ril_types.h"
|
#include "ril_types.h"
|
||||||
|
#include <mce_display.h>
|
||||||
#include <sailfish_cell_info.h>
|
#include <sailfish_cell_info.h>
|
||||||
|
|
||||||
struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
||||||
const char *log_prefix, struct ril_radio *radio,
|
const char *log_prefix, MceDisplay *display,
|
||||||
struct ril_sim_card *sim_card);
|
struct ril_radio *radio, struct ril_sim_card *sim_card);
|
||||||
|
|
||||||
#endif /* RIL_CELL_INFO_H */
|
#endif /* RIL_CELL_INFO_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 Jolla Ltd.
|
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -238,6 +237,337 @@ char *ril_config_ints_to_string(GUtilInts *ints, char separator)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ril_config_merge_files() function does the following:
|
||||||
|
*
|
||||||
|
* 1. Loads the specified key file (say, "/etc/foo.conf")
|
||||||
|
* 2. Scans the subdirectory named after the file (e.g. "/etc/foo.d/")
|
||||||
|
* for the files with the same suffix as the main file (e.g. "*.conf")
|
||||||
|
* 3. Sorts the files from the subdirectory (alphabetically)
|
||||||
|
* 4. Merges the contents of the additional files with the main file
|
||||||
|
* according to their sort order.
|
||||||
|
*
|
||||||
|
* When the entries are merged, keys and groups overwrite the exising
|
||||||
|
* ones by default. Keys can be suffixed with special characters to
|
||||||
|
* remove or modify the existing entries instead:
|
||||||
|
*
|
||||||
|
* ':' Sets the (default) value if the key is missing
|
||||||
|
* '+' Appends values to the string list
|
||||||
|
* '?' Appends only new (non-existent) values to the string list
|
||||||
|
* '-' Removes the values from the string list
|
||||||
|
*
|
||||||
|
* Both keys and groups can be prefixed with '!' to remove the entire key
|
||||||
|
* or group.
|
||||||
|
*
|
||||||
|
* For example if we merge these two files:
|
||||||
|
*
|
||||||
|
* /etc/foo.conf:
|
||||||
|
*
|
||||||
|
* [foo]
|
||||||
|
* a=1
|
||||||
|
* b=2,3
|
||||||
|
* c=4
|
||||||
|
* d=5
|
||||||
|
* [bar]
|
||||||
|
* e=5
|
||||||
|
*
|
||||||
|
* /etc/foo.d/bar.conf:
|
||||||
|
*
|
||||||
|
* [foo]
|
||||||
|
* a+=2
|
||||||
|
* b-=2
|
||||||
|
* c=5
|
||||||
|
* !d
|
||||||
|
* [!bar]
|
||||||
|
*
|
||||||
|
* we end up with this:
|
||||||
|
*
|
||||||
|
* [foo]
|
||||||
|
* a=1
|
||||||
|
* b=2,3
|
||||||
|
* c=5
|
||||||
|
*
|
||||||
|
* Not that the list separator is assumed to be ',' (rather than default ';').
|
||||||
|
* The keyfile passed to ril_config_merge_files() should use the same list
|
||||||
|
* separator, because the default values are copied from the config files
|
||||||
|
* as is.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static gint ril_config_sort_files(gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
/* The comparison function for g_ptr_array_sort() doesn't take
|
||||||
|
* the pointers from the array as arguments, it takes pointers
|
||||||
|
* to the pointers in the array. */
|
||||||
|
return strcmp(*(char**)a, *(char**)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char **ril_config_collect_files(const char *path, const char *suffix)
|
||||||
|
{
|
||||||
|
/* Returns sorted list of regular files in the directory,
|
||||||
|
* optionally having the specified suffix (e.g. ".conf").
|
||||||
|
* Returns NULL if nothing appropriate has been found. */
|
||||||
|
char **files = NULL;
|
||||||
|
DIR *d = opendir(path);
|
||||||
|
|
||||||
|
if (d) {
|
||||||
|
GPtrArray *list = g_ptr_array_new();
|
||||||
|
const struct dirent *p;
|
||||||
|
|
||||||
|
while ((p = readdir(d)) != NULL) {
|
||||||
|
/* No need to even stat . and .. */
|
||||||
|
if (strcmp(p->d_name, ".") &&
|
||||||
|
strcmp(p->d_name, "..") && (!suffix ||
|
||||||
|
g_str_has_suffix(p->d_name, suffix))) {
|
||||||
|
struct stat st;
|
||||||
|
char *buf = g_strconcat(path, "/", p->d_name,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!stat(buf, &st) && S_ISREG(st.st_mode)) {
|
||||||
|
g_ptr_array_add(list, buf);
|
||||||
|
} else {
|
||||||
|
g_free(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list->len > 0) {
|
||||||
|
g_ptr_array_sort(list, ril_config_sort_files);
|
||||||
|
g_ptr_array_add(list, NULL);
|
||||||
|
files = (char**)g_ptr_array_free(list, FALSE);
|
||||||
|
} else {
|
||||||
|
g_ptr_array_free(list, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ril_config_list_find(char **list, gsize len, const char *value)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!strcmp(list[i], value)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_config_list_append(GKeyFile *conf, GKeyFile *k,
|
||||||
|
const char *group, const char *key,
|
||||||
|
char **values, gsize n, gboolean unique)
|
||||||
|
{
|
||||||
|
/* Note: will steal strings from values */
|
||||||
|
if (n > 0) {
|
||||||
|
int i;
|
||||||
|
gsize len = 0;
|
||||||
|
gchar **list = g_key_file_get_string_list(conf, group, key,
|
||||||
|
&len, NULL);
|
||||||
|
GPtrArray *newlist = g_ptr_array_new_full(0, g_free);
|
||||||
|
|
||||||
|
for (i = 0; i < (int)len; i++) {
|
||||||
|
g_ptr_array_add(newlist, list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (int)n; i++) {
|
||||||
|
char *val = values[i];
|
||||||
|
|
||||||
|
if (!unique || ril_config_list_find((char**)
|
||||||
|
newlist->pdata, newlist->len, val) < 0) {
|
||||||
|
/* Move the string to the new list */
|
||||||
|
g_ptr_array_add(newlist, val);
|
||||||
|
memmove(values + i, values + i + 1,
|
||||||
|
sizeof(char*) * (n - i));
|
||||||
|
i--;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newlist->len > len) {
|
||||||
|
g_key_file_set_string_list(conf, group, key,
|
||||||
|
(const gchar * const *) newlist->pdata,
|
||||||
|
newlist->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strings are deallocated by GPtrArray */
|
||||||
|
g_ptr_array_free(newlist, TRUE);
|
||||||
|
g_free(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_config_list_remove(GKeyFile *conf, GKeyFile *k,
|
||||||
|
const char *group, const char *key, char **values, gsize n)
|
||||||
|
{
|
||||||
|
if (n > 0) {
|
||||||
|
gsize len = 0;
|
||||||
|
gchar **list = g_key_file_get_string_list(conf, group, key,
|
||||||
|
&len, NULL);
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
gsize i;
|
||||||
|
const gsize oldlen = len;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
/* Remove all matching values */
|
||||||
|
while ((pos = ril_config_list_find(list, len,
|
||||||
|
values[i])) >= 0) {
|
||||||
|
g_free(list[pos]);
|
||||||
|
memmove(list + pos, list + pos + 1,
|
||||||
|
sizeof(char*) * (len - pos));
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < oldlen) {
|
||||||
|
g_key_file_set_string_list(conf, group, key,
|
||||||
|
(const gchar * const *) list, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_config_merge_group(GKeyFile *conf, GKeyFile *k,
|
||||||
|
const char *group)
|
||||||
|
{
|
||||||
|
gsize i, n = 0;
|
||||||
|
char **keys = g_key_file_get_keys(k, group, &n, NULL);
|
||||||
|
|
||||||
|
for (i=0; i<n; i++) {
|
||||||
|
char *key = keys[i];
|
||||||
|
|
||||||
|
if (key[0] == '!') {
|
||||||
|
if (key[1]) {
|
||||||
|
g_key_file_remove_key(conf, group, key+1, NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const gsize len = strlen(key);
|
||||||
|
const char last = (len > 0) ? key[len-1] : 0;
|
||||||
|
|
||||||
|
if (last == '+' || last == '?') {
|
||||||
|
gsize count = 0;
|
||||||
|
gchar **values = g_key_file_get_string_list(k,
|
||||||
|
group, key, &count, NULL);
|
||||||
|
|
||||||
|
key[len-1] = 0;
|
||||||
|
ril_config_list_append(conf, k, group, key,
|
||||||
|
values, count, last == '?');
|
||||||
|
g_strfreev(values);
|
||||||
|
} else if (last == '-') {
|
||||||
|
gsize count = 0;
|
||||||
|
gchar **values = g_key_file_get_string_list(k,
|
||||||
|
group, key, &count, NULL);
|
||||||
|
|
||||||
|
key[len-1] = 0;
|
||||||
|
ril_config_list_remove(conf, k, group, key,
|
||||||
|
values, count);
|
||||||
|
g_strfreev(values);
|
||||||
|
} else {
|
||||||
|
/* Overwrite the value (it must exist in k) */
|
||||||
|
gchar *value = g_key_file_get_value(k, group,
|
||||||
|
key, NULL);
|
||||||
|
|
||||||
|
if (last == ':') {
|
||||||
|
/* Default value */
|
||||||
|
key[len-1] = 0;
|
||||||
|
if (!g_key_file_has_key(conf,
|
||||||
|
group, key, NULL)) {
|
||||||
|
g_key_file_set_value(conf,
|
||||||
|
group, key, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_key_file_set_value(conf, group, key,
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
g_free(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_config_merge_keyfile(GKeyFile *conf, GKeyFile *k)
|
||||||
|
{
|
||||||
|
gsize i, n = 0;
|
||||||
|
char **groups = g_key_file_get_groups(k, &n);
|
||||||
|
|
||||||
|
for (i=0; i<n; i++) {
|
||||||
|
const char *group = groups[i];
|
||||||
|
|
||||||
|
if (group[0] == '!') {
|
||||||
|
g_key_file_remove_group(conf, group + 1, NULL);
|
||||||
|
} else {
|
||||||
|
ril_config_merge_group(conf, k, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev(groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_config_merge_file(GKeyFile *conf, const char *file)
|
||||||
|
{
|
||||||
|
GKeyFile *k = g_key_file_new();
|
||||||
|
|
||||||
|
g_key_file_set_list_separator(k, ',');
|
||||||
|
|
||||||
|
if (g_key_file_load_from_file(k, file, 0, NULL)) {
|
||||||
|
ril_config_merge_keyfile(conf, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_key_file_unref(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ril_config_merge_files(GKeyFile *conf, const char *file)
|
||||||
|
{
|
||||||
|
if (conf && file && file[0]) {
|
||||||
|
char *dot = strrchr(file, '.');
|
||||||
|
const char *suffix;
|
||||||
|
char *dir;
|
||||||
|
char **files;
|
||||||
|
|
||||||
|
if (!dot) {
|
||||||
|
dir = g_strconcat(file, ".d", NULL);
|
||||||
|
suffix = NULL;
|
||||||
|
} else if (!dot[1]) {
|
||||||
|
dir = g_strconcat(file, "d", NULL);
|
||||||
|
suffix = NULL;
|
||||||
|
} else {
|
||||||
|
/* 2 bytes for ".d" and 1 for NULL terminator */
|
||||||
|
dir = g_malloc(dot - file + 3);
|
||||||
|
strncpy(dir, file, dot - file);
|
||||||
|
strcpy(dir + (dot - file), ".d");
|
||||||
|
suffix = dot + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
files = ril_config_collect_files(dir, suffix);
|
||||||
|
g_free(dir);
|
||||||
|
|
||||||
|
/* Load the main config */
|
||||||
|
if (g_file_test(file, G_FILE_TEST_EXISTS)) {
|
||||||
|
DBG("Loading %s", file);
|
||||||
|
ril_config_merge_file(conf, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files) {
|
||||||
|
char **ptr;
|
||||||
|
|
||||||
|
for (ptr = files; *ptr; ptr++) {
|
||||||
|
DBG("Merging %s", *ptr);
|
||||||
|
ril_config_merge_file(conf, *ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev(files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* mode: C
|
* mode: C
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 Jolla Ltd.
|
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -23,6 +22,8 @@
|
|||||||
|
|
||||||
#define RILCONF_SETTINGS_GROUP "Settings"
|
#define RILCONF_SETTINGS_GROUP "Settings"
|
||||||
|
|
||||||
|
void ril_config_merge_files(GKeyFile *conf, const char *file);
|
||||||
|
|
||||||
char *ril_config_get_string(GKeyFile *file, const char *group,
|
char *ril_config_get_string(GKeyFile *file, const char *group,
|
||||||
const char *key);
|
const char *key);
|
||||||
char **ril_config_get_strings(GKeyFile *file, const char *group,
|
char **ril_config_get_strings(GKeyFile *file, const char *group,
|
||||||
|
|||||||
@@ -1,622 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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:
|
|
||||||
*/
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 Canonical Ltd.
|
||||||
* Copyright (C) 2013-2020 Jolla Ltd.
|
* Copyright (C) 2013-2019 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -205,44 +205,10 @@ enum ril_data_call_fail_cause {
|
|||||||
PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
|
PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
|
||||||
PDP_FAIL_NSAPI_IN_USE = 0x23,
|
PDP_FAIL_NSAPI_IN_USE = 0x23,
|
||||||
PDP_FAIL_REGULAR_DEACTIVATION = 0x24,
|
PDP_FAIL_REGULAR_DEACTIVATION = 0x24,
|
||||||
PDP_FAIL_QOS_NOT_ACCEPTED = 0x25,
|
|
||||||
PDP_FAIL_NETWORK_FAILURE = 0x26,
|
|
||||||
PDP_FAIL_UMTS_REACTIVATION_REQ = 0x27,
|
|
||||||
PDP_FAIL_FEATURE_NOT_SUPP = 0x28,
|
|
||||||
PDP_FAIL_TFT_SEMANTIC_ERROR = 0x29,
|
|
||||||
PDP_FAIL_TFT_SYTAX_ERROR = 0x2A,
|
|
||||||
PDP_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B,
|
|
||||||
PDP_FAIL_FILTER_SEMANTIC_ERROR = 0x2C,
|
|
||||||
PDP_FAIL_FILTER_SYTAX_ERROR = 0x2D,
|
|
||||||
PDP_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E,
|
|
||||||
PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32,
|
PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32,
|
||||||
PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33,
|
PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33,
|
||||||
PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
|
PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
|
||||||
PDP_FAIL_ESM_INFO_NOT_RECEIVED = 0x35,
|
|
||||||
PDP_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36,
|
|
||||||
PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
|
|
||||||
PDP_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
|
|
||||||
PDP_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
|
|
||||||
PDP_FAIL_INVALID_TRANSACTION_ID = 0x51,
|
|
||||||
PDP_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F,
|
|
||||||
PDP_FAIL_INVALID_MANDATORY_INFO = 0x60,
|
|
||||||
PDP_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61,
|
|
||||||
PDP_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
|
|
||||||
PDP_FAIL_UNKNOWN_INFO_ELEMENT = 0x63,
|
|
||||||
PDP_FAIL_CONDITIONAL_IE_ERROR = 0x64,
|
|
||||||
PDP_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
|
|
||||||
PDP_FAIL_PROTOCOL_ERRORS = 0x6F,
|
PDP_FAIL_PROTOCOL_ERRORS = 0x6F,
|
||||||
PDP_FAIL_APN_TYPE_CONFLICT = 0x70,
|
|
||||||
PDP_FAIL_INVALID_PCSCF_ADDR = 0x71,
|
|
||||||
PDP_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
|
|
||||||
PDP_FAIL_EMM_ACCESS_BARRED = 0x73,
|
|
||||||
PDP_FAIL_EMERGENCY_IFACE_ONLY = 0x74,
|
|
||||||
PDP_FAIL_IFACE_MISMATCH = 0x75,
|
|
||||||
PDP_FAIL_COMPANION_IFACE_IN_USE = 0x76,
|
|
||||||
PDP_FAIL_IP_ADDRESS_MISMATCH = 0x77,
|
|
||||||
PDP_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
|
|
||||||
PDP_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
|
|
||||||
PDP_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
|
|
||||||
PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
|
PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
|
||||||
PDP_FAIL_DATA_REGISTRATION_FAIL = -2,
|
PDP_FAIL_DATA_REGISTRATION_FAIL = -2,
|
||||||
PDP_FAIL_SIGNAL_LOST = -3,
|
PDP_FAIL_SIGNAL_LOST = -3,
|
||||||
@@ -267,12 +233,6 @@ enum ril_data_profile {
|
|||||||
RIL_DATA_PROFILE_INVALID = 0xFFFFFFFF
|
RIL_DATA_PROFILE_INVALID = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ril_profile_type {
|
|
||||||
RIL_PROFILE_COMMON = 0,
|
|
||||||
RIL_PROFILE_3GPP = 1,
|
|
||||||
RIL_PROFILE_3GPP2 = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ril_auth {
|
enum ril_auth {
|
||||||
RIL_AUTH_NONE = 0,
|
RIL_AUTH_NONE = 0,
|
||||||
RIL_AUTH_PAP = 1,
|
RIL_AUTH_PAP = 1,
|
||||||
@@ -368,6 +328,8 @@ enum ril_restricted_state {
|
|||||||
RIL_RESTRICTED_STATE_PS_ALL = 0x10
|
RIL_RESTRICTED_STATE_PS_ALL = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DATA_PROFILE_DEFAULT_STR "0"
|
||||||
|
|
||||||
/* Suplementary services Service class*/
|
/* Suplementary services Service class*/
|
||||||
#define SERVICE_CLASS_NONE 0
|
#define SERVICE_CLASS_NONE 0
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2020 Jolla Ltd.
|
* Copyright (C) 2016-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -14,8 +13,6 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
|
|
||||||
#include "ril_data.h"
|
#include "ril_data.h"
|
||||||
#include "ril_radio.h"
|
#include "ril_radio.h"
|
||||||
#include "ril_network.h"
|
#include "ril_network.h"
|
||||||
@@ -31,8 +28,6 @@
|
|||||||
#include <grilio_parser.h>
|
#include <grilio_parser.h>
|
||||||
#include <grilio_request.h>
|
#include <grilio_request.h>
|
||||||
|
|
||||||
#include "common.h" /* ACCESS_TECHNOLOGY_EUTRAN */
|
|
||||||
|
|
||||||
/* Yes, it does sometimes take minutes in roaming */
|
/* Yes, it does sometimes take minutes in roaming */
|
||||||
#define SETUP_DATA_CALL_TIMEOUT (300*1000) /* ms */
|
#define SETUP_DATA_CALL_TIMEOUT (300*1000) /* ms */
|
||||||
|
|
||||||
@@ -111,15 +106,12 @@ struct ril_data_priv {
|
|||||||
struct ril_data_request *pending_req;
|
struct ril_data_request *pending_req;
|
||||||
|
|
||||||
struct ril_data_options options;
|
struct ril_data_options options;
|
||||||
gboolean use_data_profiles;
|
|
||||||
guint mms_data_profile_id;
|
|
||||||
guint slot;
|
guint slot;
|
||||||
char *log_prefix;
|
char *log_prefix;
|
||||||
guint query_id;
|
guint query_id;
|
||||||
gulong io_event_id[IO_EVENT_COUNT];
|
gulong io_event_id[IO_EVENT_COUNT];
|
||||||
gulong settings_event_id[SETTINGS_EVENT_COUNT];
|
gulong settings_event_id[SETTINGS_EVENT_COUNT];
|
||||||
GHashTable* grab;
|
GHashTable* grab;
|
||||||
gboolean downgraded_tech; /* Status 55 workaround */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ril_data_signal {
|
enum ril_data_signal {
|
||||||
@@ -170,7 +162,6 @@ struct ril_data_request {
|
|||||||
|
|
||||||
struct ril_data_request_setup {
|
struct ril_data_request_setup {
|
||||||
struct ril_data_request req;
|
struct ril_data_request req;
|
||||||
guint profile_id;
|
|
||||||
char *apn;
|
char *apn;
|
||||||
char *username;
|
char *username;
|
||||||
char *password;
|
char *password;
|
||||||
@@ -190,6 +181,7 @@ struct ril_data_request_allow_data {
|
|||||||
gboolean allow;
|
gboolean allow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void ril_data_manager_check_data(struct ril_data_manager *dm);
|
||||||
static void ril_data_manager_check_network_mode(struct ril_data_manager *dm);
|
static void ril_data_manager_check_network_mode(struct ril_data_manager *dm);
|
||||||
static void ril_data_call_deact_cid(struct ril_data *data, int cid);
|
static void ril_data_call_deact_cid(struct ril_data *data, int cid);
|
||||||
static void ril_data_power_update(struct ril_data *self);
|
static void ril_data_power_update(struct ril_data *self);
|
||||||
@@ -439,7 +431,7 @@ static gboolean ril_data_call_list_equal(const struct ril_data_call_list *l1,
|
|||||||
if (!l1 && !l2) {
|
if (!l1 && !l2) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else if (l1 && l2) {
|
} else if (l1 && l2) {
|
||||||
if (l1->version == l2->version && l1->num == l2->num) {
|
if (l1->version == l1->version && l1->num == l2->num) {
|
||||||
GSList *p1 = l1->calls;
|
GSList *p1 = l1->calls;
|
||||||
GSList *p2 = l2->calls;
|
GSList *p2 = l2->calls;
|
||||||
|
|
||||||
@@ -820,31 +812,6 @@ static gboolean ril_data_call_setup_retry(void *user_data)
|
|||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean ril_data_call_retry(struct ril_data_request_setup *setup)
|
|
||||||
{
|
|
||||||
struct ril_data_request *req = &setup->req;
|
|
||||||
const struct ril_data_options *options = &req->data->priv->options;
|
|
||||||
|
|
||||||
if (setup->retry_count < options->data_call_retry_limit) {
|
|
||||||
req->pending_id = 0;
|
|
||||||
GASSERT(!setup->retry_delay_id);
|
|
||||||
if (!setup->retry_count) {
|
|
||||||
/* No delay first time */
|
|
||||||
setup->retry_count++;
|
|
||||||
DBG("silent retry %u out of %u", setup->retry_count,
|
|
||||||
options->data_call_retry_limit);
|
|
||||||
req->submit(req);
|
|
||||||
} else {
|
|
||||||
const guint ms = options->data_call_retry_delay_ms;
|
|
||||||
DBG("silent retry scheduled in %u ms", ms);
|
|
||||||
setup->retry_delay_id = g_timeout_add(ms,
|
|
||||||
ril_data_call_setup_retry, setup);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
|
static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
|
||||||
const void *data, guint len, void *user_data)
|
const void *data, guint len, void *user_data)
|
||||||
{
|
{
|
||||||
@@ -869,49 +836,33 @@ static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call) {
|
if (call && call->status == PDP_FAIL_ERROR_UNSPECIFIED &&
|
||||||
switch (call->status) {
|
setup->retry_count < priv->options.data_call_retry_limit) {
|
||||||
/*
|
/*
|
||||||
* According to the comment from ril.h we should silently
|
* According to the comment from ril.h we should silently
|
||||||
* retry. First time we retry immediately and if that doesn't
|
* retry. First time we retry immediately and if that doedsn't
|
||||||
* work, then after certain delay.
|
* work, then after certain delay.
|
||||||
*/
|
*/
|
||||||
case PDP_FAIL_ERROR_UNSPECIFIED:
|
req->pending_id = 0;
|
||||||
if (ril_data_call_retry(setup)) {
|
GASSERT(!setup->retry_delay_id);
|
||||||
ril_data_call_list_free(list);
|
if (!setup->retry_count) {
|
||||||
return;
|
setup->retry_count++;
|
||||||
}
|
DBG("silent retry %u out of %u", setup->retry_count,
|
||||||
break;
|
priv->options.data_call_retry_limit);
|
||||||
/*
|
req->submit(req);
|
||||||
* With some networks we sometimes start getting error 55
|
} else {
|
||||||
* (Multiple PDN connections for a given APN not allowed)
|
guint ms = priv->options.data_call_retry_delay_ms;
|
||||||
* when trying to setup an LTE data call and this error
|
DBG("silent retry scheduled in %u ms", ms);
|
||||||
* doesn't go away until we successfully establish a data
|
setup->retry_delay_id = g_timeout_add(ms,
|
||||||
* call over 3G. Then we can switch back to LTE.
|
ril_data_call_setup_retry, setup);
|
||||||
*/
|
|
||||||
case PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED:
|
|
||||||
if (priv->network->data.access_tech ==
|
|
||||||
ACCESS_TECHNOLOGY_EUTRAN &&
|
|
||||||
!priv->downgraded_tech) {
|
|
||||||
DBG("downgrading preferred technology");
|
|
||||||
priv->downgraded_tech = TRUE;
|
|
||||||
ril_data_manager_check_network_mode(priv->dm);
|
|
||||||
/* And let this call fail */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
ril_data_call_list_free(list);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ril_data_request_completed(req);
|
ril_data_request_completed(req);
|
||||||
|
|
||||||
if (call && call->status == PDP_FAIL_NONE) {
|
if (call && call->status == PDP_FAIL_NONE) {
|
||||||
if (priv->downgraded_tech) {
|
|
||||||
DBG("done with status 55 workaround");
|
|
||||||
priv->downgraded_tech = FALSE;
|
|
||||||
ril_data_manager_check_network_mode(priv->dm);
|
|
||||||
}
|
|
||||||
if (ril_data_call_list_move_calls(self->data_calls, list) > 0) {
|
if (ril_data_call_list_move_calls(self->data_calls, list) > 0) {
|
||||||
DBG("data call(s) added");
|
DBG("data call(s) added");
|
||||||
ril_data_signal_emit(self, SIGNAL_CALLS_CHANGED);
|
ril_data_signal_emit(self, SIGNAL_CALLS_CHANGED);
|
||||||
@@ -966,7 +917,7 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
|
|||||||
|
|
||||||
/* Give vendor code a chance to build a vendor specific packet */
|
/* Give vendor code a chance to build a vendor specific packet */
|
||||||
ioreq = ril_vendor_data_call_req(priv->vendor, tech,
|
ioreq = ril_vendor_data_call_req(priv->vendor, tech,
|
||||||
setup->profile_id, setup->apn, setup->username,
|
DATA_PROFILE_DEFAULT_STR, setup->apn, setup->username,
|
||||||
setup->password, auth, proto_str);
|
setup->password, auth, proto_str);
|
||||||
|
|
||||||
if (!ioreq) {
|
if (!ioreq) {
|
||||||
@@ -974,7 +925,7 @@ static gboolean ril_data_call_setup_submit(struct ril_data_request *req)
|
|||||||
ioreq = grilio_request_new();
|
ioreq = grilio_request_new();
|
||||||
grilio_request_append_int32(ioreq, 7 /* Parameter count */);
|
grilio_request_append_int32(ioreq, 7 /* Parameter count */);
|
||||||
grilio_request_append_format(ioreq, "%d", tech);
|
grilio_request_append_format(ioreq, "%d", tech);
|
||||||
grilio_request_append_format(ioreq, "%d", setup->profile_id);
|
grilio_request_append_utf8(ioreq, DATA_PROFILE_DEFAULT_STR);
|
||||||
grilio_request_append_utf8(ioreq, setup->apn);
|
grilio_request_append_utf8(ioreq, setup->apn);
|
||||||
grilio_request_append_utf8(ioreq, setup->username);
|
grilio_request_append_utf8(ioreq, setup->username);
|
||||||
grilio_request_append_utf8(ioreq, setup->password);
|
grilio_request_append_utf8(ioreq, setup->password);
|
||||||
@@ -1004,18 +955,12 @@ 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,
|
static struct ril_data_request *ril_data_call_setup_new(struct ril_data *data,
|
||||||
const struct ofono_gprs_primary_context *ctx,
|
const struct ofono_gprs_primary_context *ctx,
|
||||||
enum ofono_gprs_context_type context_type,
|
|
||||||
ril_data_call_setup_cb_t cb, void *arg)
|
ril_data_call_setup_cb_t cb, void *arg)
|
||||||
{
|
{
|
||||||
struct ril_data_priv *priv = data->priv;
|
|
||||||
struct ril_data_request_setup *setup =
|
struct ril_data_request_setup *setup =
|
||||||
g_new0(struct ril_data_request_setup, 1);
|
g_new0(struct ril_data_request_setup, 1);
|
||||||
struct ril_data_request *req = &setup->req;
|
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->apn = g_strdup(ctx->apn);
|
||||||
setup->username = g_strdup(ctx->username);
|
setup->username = g_strdup(ctx->username);
|
||||||
setup->password = g_strdup(ctx->password);
|
setup->password = g_strdup(ctx->password);
|
||||||
@@ -1197,11 +1142,6 @@ static struct ril_data_request *ril_data_allow_new(struct ril_data *data,
|
|||||||
/*==========================================================================*
|
/*==========================================================================*
|
||||||
* ril_data
|
* ril_data
|
||||||
*==========================================================================*/
|
*==========================================================================*/
|
||||||
static enum ofono_radio_access_mode ril_data_max_mode(struct ril_data *self)
|
|
||||||
{
|
|
||||||
return self->priv->downgraded_tech ? OFONO_RADIO_ACCESS_MODE_UMTS :
|
|
||||||
OFONO_RADIO_ACCESS_MODE_ANY;
|
|
||||||
}
|
|
||||||
|
|
||||||
gulong ril_data_add_allow_changed_handler(struct ril_data *self,
|
gulong ril_data_add_allow_changed_handler(struct ril_data *self,
|
||||||
ril_data_cb_t cb, void *arg)
|
ril_data_cb_t cb, void *arg)
|
||||||
@@ -1271,8 +1211,6 @@ struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
|
|||||||
priv->log_prefix = (name && name[0]) ?
|
priv->log_prefix = (name && name[0]) ?
|
||||||
g_strconcat(name, " ", NULL) : g_strdup("");
|
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->slot = config->slot;
|
||||||
priv->q = grilio_queue_new(io);
|
priv->q = grilio_queue_new(io);
|
||||||
priv->io = grilio_channel_ref(io);
|
priv->io = grilio_channel_ref(io);
|
||||||
@@ -1526,11 +1464,10 @@ 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,
|
struct ril_data_request *ril_data_call_setup(struct ril_data *self,
|
||||||
const struct ofono_gprs_primary_context *ctx,
|
const struct ofono_gprs_primary_context *ctx,
|
||||||
enum ofono_gprs_context_type context_type,
|
|
||||||
ril_data_call_setup_cb_t cb, void *arg)
|
ril_data_call_setup_cb_t cb, void *arg)
|
||||||
{
|
{
|
||||||
struct ril_data_request *req =
|
struct ril_data_request *req =
|
||||||
ril_data_call_setup_new(self, ctx, context_type, cb, arg);
|
ril_data_call_setup_new(self, ctx, cb, arg);
|
||||||
|
|
||||||
ril_data_request_queue(req);
|
ril_data_request_queue(req);
|
||||||
return req;
|
return req;
|
||||||
@@ -1697,8 +1634,7 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)
|
|||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
|
|
||||||
if ((self->flags & RIL_DATA_MANAGER_FORCE_GSM_ON_OTHER_SLOTS) &&
|
if (ril_data_manager_handover(self)) {
|
||||||
ril_data_manager_handover(self)) {
|
|
||||||
struct ril_network *lte_network = NULL;
|
struct ril_network *lte_network = NULL;
|
||||||
int non_gsm_count = 0;
|
int non_gsm_count = 0;
|
||||||
|
|
||||||
@@ -1735,7 +1671,7 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)
|
|||||||
|
|
||||||
ril_network_set_max_pref_mode(network,
|
ril_network_set_max_pref_mode(network,
|
||||||
(network == lte_network) ?
|
(network == lte_network) ?
|
||||||
ril_data_max_mode(data) :
|
OFONO_RADIO_ACCESS_MODE_ANY :
|
||||||
OFONO_RADIO_ACCESS_MODE_GSM,
|
OFONO_RADIO_ACCESS_MODE_GSM,
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
@@ -1745,7 +1681,7 @@ static void ril_data_manager_check_network_mode(struct ril_data_manager *self)
|
|||||||
for (l= self->data_list; l; l = l->next) {
|
for (l= self->data_list; l; l = l->next) {
|
||||||
struct ril_data *data = l->data;
|
struct ril_data *data = l->data;
|
||||||
ril_network_set_max_pref_mode(data->priv->network,
|
ril_network_set_max_pref_mode(data->priv->network,
|
||||||
ril_data_max_mode(data), FALSE);
|
OFONO_RADIO_ACCESS_MODE_ANY, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1774,7 +1710,7 @@ static void ril_data_manager_switch_data_on(struct ril_data_manager *self,
|
|||||||
|
|
||||||
if (ril_data_manager_handover(self)) {
|
if (ril_data_manager_handover(self)) {
|
||||||
ril_network_set_max_pref_mode(priv->network,
|
ril_network_set_max_pref_mode(priv->network,
|
||||||
ril_data_max_mode(data), TRUE);
|
OFONO_RADIO_ACCESS_MODE_ANY, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->options.allow_data == RIL_ALLOW_DATA_ENABLED) {
|
if (priv->options.allow_data == RIL_ALLOW_DATA_ENABLED) {
|
||||||
@@ -1787,7 +1723,7 @@ static void ril_data_manager_switch_data_on(struct ril_data_manager *self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ril_data_manager_check_data(struct ril_data_manager *self)
|
static void ril_data_manager_check_data(struct ril_data_manager *self)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Don't do anything if there any requests pending.
|
* Don't do anything if there any requests pending.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2019 Jolla Ltd.
|
* Copyright (C) 2016-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -55,8 +54,7 @@ struct ril_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum ril_data_manager_flags {
|
enum ril_data_manager_flags {
|
||||||
RIL_DATA_MANAGER_3GLTE_HANDOVER = 0x01,
|
RIL_DATA_MANAGER_3GLTE_HANDOVER = 0x01
|
||||||
RIL_DATA_MANAGER_FORCE_GSM_ON_OTHER_SLOTS = 0x02
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ril_data_allow_data_opt {
|
enum ril_data_allow_data_opt {
|
||||||
@@ -89,7 +87,6 @@ struct ril_data_manager;
|
|||||||
struct ril_data_manager *ril_data_manager_new(enum ril_data_manager_flags flg);
|
struct ril_data_manager *ril_data_manager_new(enum ril_data_manager_flags flg);
|
||||||
struct ril_data_manager *ril_data_manager_ref(struct ril_data_manager *dm);
|
struct ril_data_manager *ril_data_manager_ref(struct ril_data_manager *dm);
|
||||||
void ril_data_manager_unref(struct ril_data_manager *dm);
|
void ril_data_manager_unref(struct ril_data_manager *dm);
|
||||||
void ril_data_manager_check_data(struct ril_data_manager *dm);
|
|
||||||
void ril_data_manager_assert_data_on(struct ril_data_manager *dm);
|
void ril_data_manager_assert_data_on(struct ril_data_manager *dm);
|
||||||
|
|
||||||
typedef void (*ril_data_cb_t)(struct ril_data *data, void *arg);
|
typedef void (*ril_data_cb_t)(struct ril_data *data, void *arg);
|
||||||
@@ -120,7 +117,6 @@ void ril_data_allow(struct ril_data *data, enum ril_data_role role);
|
|||||||
struct ril_data_request;
|
struct ril_data_request;
|
||||||
struct ril_data_request *ril_data_call_setup(struct ril_data *data,
|
struct ril_data_request *ril_data_call_setup(struct ril_data *data,
|
||||||
const struct ofono_gprs_primary_context *ctx,
|
const struct ofono_gprs_primary_context *ctx,
|
||||||
enum ofono_gprs_context_type context_type,
|
|
||||||
ril_data_call_setup_cb_t cb, void *arg);
|
ril_data_call_setup_cb_t cb, void *arg);
|
||||||
struct ril_data_request *ril_data_call_deactivate(struct ril_data *data,
|
struct ril_data_request *ril_data_call_deactivate(struct ril_data *data,
|
||||||
int cid, ril_data_call_deactivate_cb_t cb, void *arg);
|
int cid, ril_data_call_deactivate_cb_t cb, void *arg);
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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:
|
|
||||||
*/
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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:
|
|
||||||
*/
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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:
|
|
||||||
*/
|
|
||||||
@@ -1,342 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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:
|
|
||||||
*/
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2020 Jolla Ltd.
|
* Copyright (C) 2016 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -14,8 +13,6 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
|
|
||||||
#include "ril_ecclist.h"
|
#include "ril_ecclist.h"
|
||||||
#include "ril_log.h"
|
#include "ril_log.h"
|
||||||
|
|
||||||
@@ -50,53 +47,6 @@ G_DEFINE_TYPE(RilEccList, ril_ecclist, G_TYPE_OBJECT)
|
|||||||
#define RIL_ECCLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
#define RIL_ECCLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||||
RIL_ECCLIST_TYPE, RilEccList))
|
RIL_ECCLIST_TYPE, RilEccList))
|
||||||
|
|
||||||
static char **ril_ecclist_parse(const char *content)
|
|
||||||
{
|
|
||||||
char **ptr;
|
|
||||||
char **list = NULL;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some MediaTek devices use ECC,CAT;ECC,CAT kind of syntax
|
|
||||||
*/
|
|
||||||
if (strchr(content, ';')) {
|
|
||||||
list = g_strsplit(content, ";", 0);
|
|
||||||
for (ptr = list; *ptr; ptr++) {
|
|
||||||
char* comma;
|
|
||||||
|
|
||||||
*ptr = g_strstrip(*ptr);
|
|
||||||
|
|
||||||
/* Strip service category */
|
|
||||||
comma = strchr(*ptr, ',');
|
|
||||||
if (comma) {
|
|
||||||
*comma = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* The right ECC,ECC syntax is handled here */
|
|
||||||
list = g_strsplit(content, ",", 0);
|
|
||||||
for (ptr = list; *ptr; ptr++) {
|
|
||||||
*ptr = g_strstrip(*ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the list */
|
|
||||||
gutil_strv_sort(list, TRUE);
|
|
||||||
|
|
||||||
/* Remove empty strings (those are at the beginning after sorting) */
|
|
||||||
while (list[0] && !list[0][0]) {
|
|
||||||
list = gutil_strv_remove_at(list, 0, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove duplicates */
|
|
||||||
for (i = 0; list[i] && list[i+1]; i++) {
|
|
||||||
while (list[i+1] && !strcmp(list[i], list[i+1])) {
|
|
||||||
list = gutil_strv_remove_at(list, i+1, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char **ril_ecclist_read(struct ril_ecclist *self)
|
static char **ril_ecclist_read(struct ril_ecclist *self)
|
||||||
{
|
{
|
||||||
struct ril_ecclist_priv *priv = self->priv;
|
struct ril_ecclist_priv *priv = self->priv;
|
||||||
@@ -108,9 +58,16 @@ static char **ril_ecclist_read(struct ril_ecclist *self)
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (g_file_get_contents(priv->path, &content, &len, &error)) {
|
if (g_file_get_contents(priv->path, &content, &len, &error)) {
|
||||||
|
char **ptr;
|
||||||
|
|
||||||
DBG("%s = %s", priv->name, content);
|
DBG("%s = %s", priv->name, content);
|
||||||
list = ril_ecclist_parse(content);
|
list = g_strsplit(content, ",", 0);
|
||||||
} else {
|
for (ptr = list; *ptr; ptr++) {
|
||||||
|
*ptr = g_strstrip(*ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
gutil_strv_sort(list, TRUE);
|
||||||
|
} else if (error) {
|
||||||
DBG("%s: %s", priv->path, GERRMSG(error));
|
DBG("%s: %s", priv->path, GERRMSG(error));
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
}
|
}
|
||||||
@@ -132,8 +89,7 @@ static void ril_ecclist_update(struct ril_ecclist *self)
|
|||||||
DBG("%s changed", priv->name);
|
DBG("%s changed", priv->name);
|
||||||
g_strfreev(self->list);
|
g_strfreev(self->list);
|
||||||
self->list = list;
|
self->list = list;
|
||||||
g_signal_emit(self, ril_ecclist_signals
|
g_signal_emit(self, ril_ecclist_signals[SIGNAL_LIST_CHANGED], 0);
|
||||||
[SIGNAL_LIST_CHANGED], 0);
|
|
||||||
} else {
|
} else {
|
||||||
g_strfreev(list);
|
g_strfreev(list);
|
||||||
}
|
}
|
||||||
@@ -165,9 +121,10 @@ static void ril_ecclist_dir_changed(GUtilInotifyWatch *watch, guint mask,
|
|||||||
priv->file_watch = gutil_inotify_watch_callback_new(priv->path,
|
priv->file_watch = gutil_inotify_watch_callback_new(priv->path,
|
||||||
IN_MODIFY | IN_CLOSE_WRITE,
|
IN_MODIFY | IN_CLOSE_WRITE,
|
||||||
ril_ecclist_changed, self);
|
ril_ecclist_changed, self);
|
||||||
DBG("%swatching %s", priv->file_watch ? "" : "not ",
|
if (priv->file_watch) {
|
||||||
priv->path);
|
DBG("watching %s", priv->path);
|
||||||
ril_ecclist_update(self);
|
ril_ecclist_update(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & IN_IGNORED) {
|
if (mask & IN_IGNORED) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 Jolla Ltd.
|
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -468,7 +468,6 @@ static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
|
|||||||
gcd->activate.cb = cb;
|
gcd->activate.cb = cb;
|
||||||
gcd->activate.data = data;
|
gcd->activate.data = data;
|
||||||
gcd->activate.req = ril_data_call_setup(gcd->data, ctx,
|
gcd->activate.req = ril_data_call_setup(gcd->data, ctx,
|
||||||
__ofono_gprs_context_get_assigned_type(gc),
|
|
||||||
ril_gprs_context_activate_primary_cb, gcd);
|
ril_gprs_context_activate_primary_cb, gcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 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
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -20,7 +19,6 @@
|
|||||||
#include "ril_sim_card.h"
|
#include "ril_sim_card.h"
|
||||||
#include "ril_sim_settings.h"
|
#include "ril_sim_settings.h"
|
||||||
#include "ril_cell_info.h"
|
#include "ril_cell_info.h"
|
||||||
#include "ril_vendor.h"
|
|
||||||
#include "ril_data.h"
|
#include "ril_data.h"
|
||||||
#include "ril_util.h"
|
#include "ril_util.h"
|
||||||
#include "ril_log.h"
|
#include "ril_log.h"
|
||||||
@@ -45,15 +43,7 @@ enum ril_modem_online_state {
|
|||||||
GOING_OFFLINE
|
GOING_OFFLINE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ril_modem_watch_event {
|
|
||||||
WATCH_IMSI,
|
|
||||||
WATCH_ICCID,
|
|
||||||
WATCH_SIM_STATE,
|
|
||||||
WATCH_EVENT_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ril_modem_online_request {
|
struct ril_modem_online_request {
|
||||||
const char *name;
|
|
||||||
ofono_modem_online_cb_t cb;
|
ofono_modem_online_cb_t cb;
|
||||||
struct ril_modem_data *md;
|
struct ril_modem_data *md;
|
||||||
void *data;
|
void *data;
|
||||||
@@ -68,10 +58,7 @@ struct ril_modem_data {
|
|||||||
char *imeisv;
|
char *imeisv;
|
||||||
char *imei;
|
char *imei;
|
||||||
char *ecclist_file;
|
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;
|
guint online_check_id;
|
||||||
enum ril_modem_power_state power_state;
|
enum ril_modem_power_state power_state;
|
||||||
@@ -135,20 +122,6 @@ void ril_modem_delete(struct ril_modem *md)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_modem_online_request_done(struct ril_modem_online_request *req)
|
|
||||||
{
|
|
||||||
if (req->cb) {
|
|
||||||
struct ofono_error error;
|
|
||||||
ofono_modem_online_cb_t cb = req->cb;
|
|
||||||
void *data = req->data;
|
|
||||||
|
|
||||||
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)
|
static void ril_modem_online_request_ok(struct ril_modem_online_request *req)
|
||||||
{
|
{
|
||||||
if (req->timeout_id) {
|
if (req->timeout_id) {
|
||||||
@@ -156,20 +129,28 @@ static void ril_modem_online_request_ok(struct ril_modem_online_request *req)
|
|||||||
req->timeout_id = 0;
|
req->timeout_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ril_modem_online_request_done(req);
|
if (req->cb) {
|
||||||
|
struct ofono_error error;
|
||||||
|
ofono_modem_online_cb_t cb = req->cb;
|
||||||
|
void *data = req->data;
|
||||||
|
|
||||||
|
req->cb = NULL;
|
||||||
|
req->data = NULL;
|
||||||
|
cb(ril_error_ok(&error), data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_modem_update_online_state(struct ril_modem_data *md)
|
static void ril_modem_update_online_state(struct ril_modem_data *md)
|
||||||
{
|
{
|
||||||
switch (md->modem.radio->state) {
|
switch (md->modem.radio->state) {
|
||||||
case RADIO_STATE_ON:
|
case RADIO_STATE_ON:
|
||||||
DBG_(md, "online");
|
DBG("online");
|
||||||
ril_modem_online_request_ok(&md->set_online);
|
ril_modem_online_request_ok(&md->set_online);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RADIO_STATE_OFF:
|
case RADIO_STATE_OFF:
|
||||||
case RADIO_STATE_UNAVAILABLE:
|
case RADIO_STATE_UNAVAILABLE:
|
||||||
DBG_(md, "offline");
|
DBG("offline");
|
||||||
ril_modem_online_request_ok(&md->set_offline);
|
ril_modem_online_request_ok(&md->set_offline);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -189,11 +170,17 @@ static void ril_modem_update_online_state(struct ril_modem_data *md)
|
|||||||
static gboolean ril_modem_online_request_timeout(gpointer data)
|
static gboolean ril_modem_online_request_timeout(gpointer data)
|
||||||
{
|
{
|
||||||
struct ril_modem_online_request *req = 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(req->timeout_id);
|
||||||
|
GASSERT(cb);
|
||||||
|
|
||||||
req->timeout_id = 0;
|
req->timeout_id = 0;
|
||||||
DBG_(req->md, "%s", req->name);
|
req->cb = NULL;
|
||||||
ril_modem_online_request_done(req);
|
req->data = NULL;
|
||||||
|
cb(ril_error_failure(&error), cb_data);
|
||||||
ril_modem_update_online_state(req->md);
|
ril_modem_update_online_state(req->md);
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
@@ -255,32 +242,6 @@ static void ril_modem_imsi_cb(struct ofono_watch *watch, void *data)
|
|||||||
ril_modem_update_radio_settings(md);
|
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)
|
static void ril_modem_pre_sim(struct ofono_modem *modem)
|
||||||
{
|
{
|
||||||
struct ril_modem_data *md = ril_modem_data_from_ofono(modem);
|
struct ril_modem_data *md = ril_modem_data_from_ofono(modem);
|
||||||
@@ -325,13 +286,7 @@ static void ril_modem_post_sim(struct ofono_modem *modem)
|
|||||||
ofono_call_barring_create(modem, 0, RILMODEM_DRIVER, md);
|
ofono_call_barring_create(modem, 0, RILMODEM_DRIVER, md);
|
||||||
ofono_message_waiting_register(ofono_message_waiting_create(modem));
|
ofono_message_waiting_register(ofono_message_waiting_create(modem));
|
||||||
if (md->modem.config.enable_stk) {
|
if (md->modem.config.enable_stk) {
|
||||||
if (!md->reset_iccid ||
|
ofono_stk_create(modem, 0, RILMODEM_DRIVER, md);
|
||||||
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) {
|
if (md->modem.config.enable_cbs) {
|
||||||
ofono_cbs_create(modem, 0, RILMODEM_DRIVER, md);
|
ofono_cbs_create(modem, 0, RILMODEM_DRIVER, md);
|
||||||
@@ -421,7 +376,7 @@ static void ril_modem_remove(struct ofono_modem *ofono)
|
|||||||
ril_radio_unref(modem->radio);
|
ril_radio_unref(modem->radio);
|
||||||
ril_sim_settings_unref(modem->sim_settings);
|
ril_sim_settings_unref(modem->sim_settings);
|
||||||
|
|
||||||
ofono_watch_remove_all_handlers(md->watch, md->watch_event_id);
|
ofono_watch_remove_handler(md->watch, md->imsi_event_id);
|
||||||
ofono_watch_unref(md->watch);
|
ofono_watch_unref(md->watch);
|
||||||
|
|
||||||
if (md->online_check_id) {
|
if (md->online_check_id) {
|
||||||
@@ -436,7 +391,6 @@ static void ril_modem_remove(struct ofono_modem *ofono)
|
|||||||
g_source_remove(md->set_offline.timeout_id);
|
g_source_remove(md->set_offline.timeout_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ril_vendor_unref(modem->vendor);
|
|
||||||
ril_network_unref(modem->network);
|
ril_network_unref(modem->network);
|
||||||
ril_sim_card_unref(modem->sim_card);
|
ril_sim_card_unref(modem->sim_card);
|
||||||
ril_data_unref(modem->data);
|
ril_data_unref(modem->data);
|
||||||
@@ -444,8 +398,6 @@ static void ril_modem_remove(struct ofono_modem *ofono)
|
|||||||
grilio_channel_unref(modem->io);
|
grilio_channel_unref(modem->io);
|
||||||
grilio_queue_cancel_all(md->q, FALSE);
|
grilio_queue_cancel_all(md->q, FALSE);
|
||||||
grilio_queue_unref(md->q);
|
grilio_queue_unref(md->q);
|
||||||
g_free(md->last_known_iccid);
|
|
||||||
g_free(md->reset_iccid);
|
|
||||||
g_free(md->ecclist_file);
|
g_free(md->ecclist_file);
|
||||||
g_free(md->log_prefix);
|
g_free(md->log_prefix);
|
||||||
g_free(md->imeisv);
|
g_free(md->imeisv);
|
||||||
@@ -458,7 +410,7 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
|
|||||||
const char *ecclist_file, const struct ril_slot_config *config,
|
const char *ecclist_file, const struct ril_slot_config *config,
|
||||||
struct ril_radio *radio, struct ril_network *network,
|
struct ril_radio *radio, struct ril_network *network,
|
||||||
struct ril_sim_card *card, struct ril_data *data,
|
struct ril_sim_card *card, struct ril_data *data,
|
||||||
struct ril_sim_settings *settings, struct ril_vendor *vendor,
|
struct ril_sim_settings *settings,
|
||||||
struct sailfish_cell_info *cell_info)
|
struct sailfish_cell_info *cell_info)
|
||||||
{
|
{
|
||||||
/* Skip the slash from the path, it looks like "/ril_0" */
|
/* Skip the slash from the path, it looks like "/ril_0" */
|
||||||
@@ -485,7 +437,6 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
|
|||||||
g_strconcat(log_prefix, " ", NULL) : g_strdup("");
|
g_strconcat(log_prefix, " ", NULL) : g_strdup("");
|
||||||
|
|
||||||
modem->ofono = ofono;
|
modem->ofono = ofono;
|
||||||
modem->vendor = ril_vendor_ref(vendor);
|
|
||||||
modem->radio = ril_radio_ref(radio);
|
modem->radio = ril_radio_ref(radio);
|
||||||
modem->network = ril_network_ref(network);
|
modem->network = ril_network_ref(network);
|
||||||
modem->sim_card = ril_sim_card_ref(card);
|
modem->sim_card = ril_sim_card_ref(card);
|
||||||
@@ -495,21 +446,12 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
|
|||||||
modem->io = grilio_channel_ref(io);
|
modem->io = grilio_channel_ref(io);
|
||||||
md->q = grilio_queue_new(io);
|
md->q = grilio_queue_new(io);
|
||||||
md->watch = ofono_watch_new(path);
|
md->watch = ofono_watch_new(path);
|
||||||
md->last_known_iccid = g_strdup(md->watch->iccid);
|
|
||||||
|
|
||||||
md->watch_event_id[WATCH_IMSI] =
|
md->imsi_event_id =
|
||||||
ofono_watch_add_imsi_changed_handler(md->watch,
|
ofono_watch_add_imsi_changed_handler(md->watch,
|
||||||
ril_modem_imsi_cb, md);
|
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_online.md = md;
|
||||||
md->set_offline.name = "offline";
|
|
||||||
md->set_offline.md = md;
|
md->set_offline.md = md;
|
||||||
ofono_modem_set_data(ofono, md);
|
ofono_modem_set_data(ofono, md);
|
||||||
err = ofono_modem_register(ofono);
|
err = ofono_modem_register(ofono);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2020 Jolla Ltd.
|
* Copyright (C) 2015-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -17,7 +16,6 @@
|
|||||||
#include "ril_plugin.h"
|
#include "ril_plugin.h"
|
||||||
#include "ril_network.h"
|
#include "ril_network.h"
|
||||||
#include "ril_util.h"
|
#include "ril_util.h"
|
||||||
#include "ril_vendor.h"
|
|
||||||
#include "ril_log.h"
|
#include "ril_log.h"
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -42,11 +40,8 @@ struct ril_netreg {
|
|||||||
GRilIoChannel *io;
|
GRilIoChannel *io;
|
||||||
GRilIoQueue *q;
|
GRilIoQueue *q;
|
||||||
gboolean network_selection_manual_0;
|
gboolean network_selection_manual_0;
|
||||||
int signal_strength_dbm_weak;
|
|
||||||
int signal_strength_dbm_strong;
|
|
||||||
struct ofono_netreg *netreg;
|
struct ofono_netreg *netreg;
|
||||||
struct ril_network *network;
|
struct ril_network *network;
|
||||||
struct ril_vendor *vendor;
|
|
||||||
char *log_prefix;
|
char *log_prefix;
|
||||||
guint timer_id;
|
guint timer_id;
|
||||||
guint notify_id;
|
guint notify_id;
|
||||||
@@ -336,92 +331,100 @@ static void ril_netreg_register_manual(struct ofono_netreg *netreg,
|
|||||||
grilio_request_unref(req);
|
grilio_request_unref(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ril_netreg_qdbm_to_percentage(struct ril_netreg *nd, int qdbm)
|
static int ril_netreg_dbm_to_percentage(int dbm)
|
||||||
{
|
{
|
||||||
const int min_qdbm = 4 * nd->signal_strength_dbm_weak; /* 4*dBm */
|
const int min_dbm = -100; /* very weak signal, 0.0000000001 mW */
|
||||||
const int max_qdbm = 4 * nd->signal_strength_dbm_strong; /* 4*dBm */
|
const int max_dbm = -60; /* strong signal, 0.000001 mW */
|
||||||
|
|
||||||
return (qdbm <= min_qdbm) ? 1 :
|
return (dbm <= min_dbm) ? 1 :
|
||||||
(qdbm >= max_qdbm) ? 100 :
|
(dbm >= max_dbm) ? 100 :
|
||||||
(100 * (qdbm - min_qdbm) / (max_qdbm - min_qdbm));
|
(100 * (dbm - min_dbm) / (max_dbm - min_dbm));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ril_netreg_get_signal_strength(struct ril_netreg *nd,
|
static int ril_netreg_get_signal_strength(const void *data, guint len)
|
||||||
const void *data, guint len)
|
|
||||||
{
|
{
|
||||||
GRilIoParser rilp;
|
GRilIoParser rilp;
|
||||||
struct ril_vendor_signal_strength signal;
|
int gw_signal = 0, cdma_dbm = 0, evdo_dbm = 0, lte_signal = 0;
|
||||||
|
int rsrp = 0, tdscdma_dbm = 0;
|
||||||
|
|
||||||
grilio_parser_init(&rilp, data, len);
|
grilio_parser_init(&rilp, data, len);
|
||||||
signal.gsm = INT_MAX;
|
|
||||||
signal.lte = INT_MAX;
|
|
||||||
signal.qdbm = 0;
|
|
||||||
|
|
||||||
if (!ril_vendor_signal_strength_parse(nd->vendor, &signal, &rilp)) {
|
/* GW_SignalStrength */
|
||||||
gint32 rsrp = 0, tdscdma_dbm = 0;
|
grilio_parser_get_int32(&rilp, &gw_signal);
|
||||||
|
grilio_parser_get_int32(&rilp, NULL); /* bitErrorRate */
|
||||||
|
|
||||||
/* Apply default parsing algorithm */
|
/* CDMA_SignalStrength */
|
||||||
grilio_parser_init(&rilp, data, len);
|
grilio_parser_get_int32(&rilp, &cdma_dbm);
|
||||||
signal.gsm = INT_MAX;
|
grilio_parser_get_int32(&rilp, NULL); /* ecio */
|
||||||
signal.lte = INT_MAX;
|
|
||||||
signal.qdbm = 0;
|
|
||||||
|
|
||||||
/* GW_SignalStrength */
|
/* EVDO_SignalStrength */
|
||||||
grilio_parser_get_int32(&rilp, &signal.gsm);
|
grilio_parser_get_int32(&rilp, &evdo_dbm);
|
||||||
grilio_parser_get_int32(&rilp, NULL); /* bitErrorRate */
|
grilio_parser_get_int32(&rilp, NULL); /* ecio */
|
||||||
|
grilio_parser_get_int32(&rilp, NULL); /* signalNoiseRatio */
|
||||||
|
|
||||||
/* CDMA_SignalStrength */
|
/* LTE_SignalStrength */
|
||||||
grilio_parser_get_int32(&rilp, NULL); /* dbm */
|
grilio_parser_get_int32(&rilp, <e_signal);
|
||||||
grilio_parser_get_int32(&rilp, NULL); /* ecio */
|
grilio_parser_get_int32(&rilp, &rsrp);
|
||||||
|
|
||||||
/* EVDO_SignalStrength */
|
/* Skip the rest of LTE_SignalStrength_v8 */
|
||||||
grilio_parser_get_int32(&rilp, NULL); /* dbm */
|
if (grilio_parser_get_int32(&rilp, NULL) && /* rsrq */
|
||||||
grilio_parser_get_int32(&rilp, NULL); /* ecio */
|
grilio_parser_get_int32(&rilp, NULL) && /* rssnr */
|
||||||
grilio_parser_get_int32(&rilp, NULL); /* signalNoiseRatio */
|
grilio_parser_get_int32(&rilp, NULL) && /* cqi */
|
||||||
|
grilio_parser_get_int32(&rilp, NULL)) { /* timingAdvance */
|
||||||
|
|
||||||
/* LTE_SignalStrength */
|
/* TD_SCDMA_SignalStrength */
|
||||||
grilio_parser_get_int32(&rilp, &signal.lte);
|
grilio_parser_get_int32(&rilp, &tdscdma_dbm); /* rscp */
|
||||||
grilio_parser_get_int32(&rilp, &rsrp);
|
|
||||||
|
|
||||||
/* The rest is considered optional */
|
|
||||||
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) && /* timingAdv */
|
|
||||||
/* TD_SCDMA_SignalStrength */
|
|
||||||
grilio_parser_get_int32(&rilp, &tdscdma_dbm) &&
|
|
||||||
/* RSCP range: 25 to 120 dBm per 3GPP TS 25.123 */
|
|
||||||
tdscdma_dbm >= 25 && tdscdma_dbm <= 120) {
|
|
||||||
signal.qdbm = -4 * tdscdma_dbm;
|
|
||||||
} else if (signal.lte == 99 && rsrp >= 44 && rsrp <= 140) {
|
|
||||||
/* RSRP range: 44 to 140 dBm per 3GPP TS 36.133 */
|
|
||||||
signal.qdbm = -rsrp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("gw: %d, lte: %d, qdbm: %d", signal.gsm, signal.lte, signal.qdbm);
|
if (rsrp == INT_MAX) {
|
||||||
|
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, tdscdma: %d",
|
||||||
|
gw_signal, cdma_dbm, evdo_dbm,
|
||||||
|
lte_signal, rsrp, tdscdma_dbm);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the first valid one */
|
/* Return the first valid one */
|
||||||
|
|
||||||
/* Some RILs (namely, from MediaTek) report 0 here AND a valid LTE
|
/* Some RILs (namely, from MediaTek) report 0 here AND a valid LTE
|
||||||
* RSRP value. If we've got zero, don't report it just yet. */
|
* RSRP value. If we've got zero, don't report it just yet. */
|
||||||
if (signal.gsm >= 1 && signal.gsm <= 31) {
|
if (gw_signal >= 1 && gw_signal <= 31) {
|
||||||
/* Valid values are (0-31, 99) as defined in TS 27.007 */
|
/* Valid values are (0-31, 99) as defined in TS 27.007 */
|
||||||
return (signal.gsm * 100) / 31;
|
return (gw_signal * 100) / 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Valid values are (0-31, 99) as defined in TS 27.007 */
|
/* Valid values are (0-31, 99) as defined in TS 27.007 */
|
||||||
if (signal.lte >= 0 && signal.lte <= 31) {
|
if (lte_signal >= 0 && lte_signal <= 31) {
|
||||||
return (signal.lte * 100) / 31;
|
return (lte_signal * 100) / 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signal.qdbm < 0) {
|
/* RSCP range: 25 to 120 dBm as defined in 3GPP TS 25.123 */
|
||||||
return ril_netreg_qdbm_to_percentage(nd, signal.qdbm);
|
if (tdscdma_dbm >= 25 && tdscdma_dbm <= 120) {
|
||||||
} else if (signal.gsm == 0) {
|
return ril_netreg_dbm_to_percentage(-tdscdma_dbm);
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RSRP range: 44 to 140 dBm as defined in 3GPP TS 36.133 */
|
||||||
|
if (lte_signal == 99 && rsrp >= 44 && rsrp <= 140) {
|
||||||
|
return ril_netreg_dbm_to_percentage(-rsrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we've got zero strength and no valid RSRP, then so be it */
|
||||||
|
if (gw_signal == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In case of dbm, return the value directly */
|
||||||
|
if (cdma_dbm != -1) {
|
||||||
|
return MIN(cdma_dbm, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evdo_dbm != -1) {
|
||||||
|
return MIN(evdo_dbm, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_netreg_strength_notify(GRilIoChannel *io, guint ril_event,
|
static void ril_netreg_strength_notify(GRilIoChannel *io, guint ril_event,
|
||||||
@@ -431,11 +434,9 @@ static void ril_netreg_strength_notify(GRilIoChannel *io, guint ril_event,
|
|||||||
int strength;
|
int strength;
|
||||||
|
|
||||||
GASSERT(ril_event == RIL_UNSOL_SIGNAL_STRENGTH);
|
GASSERT(ril_event == RIL_UNSOL_SIGNAL_STRENGTH);
|
||||||
strength = ril_netreg_get_signal_strength(nd, data, len);
|
strength = ril_netreg_get_signal_strength(data, len);
|
||||||
DBG_(nd, "%d", strength);
|
DBG_(nd, "%d", strength);
|
||||||
if (strength >= 0) {
|
ofono_netreg_strength_notify(nd->netreg, strength);
|
||||||
ofono_netreg_strength_notify(nd->netreg, strength);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_netreg_strength_cb(GRilIoChannel *io, int status,
|
static void ril_netreg_strength_cb(GRilIoChannel *io, int status,
|
||||||
@@ -446,8 +447,8 @@ static void ril_netreg_strength_cb(GRilIoChannel *io, int status,
|
|||||||
struct ofono_error error;
|
struct ofono_error error;
|
||||||
|
|
||||||
if (status == RIL_E_SUCCESS) {
|
if (status == RIL_E_SUCCESS) {
|
||||||
cb(ril_error_ok(&error), ril_netreg_get_signal_strength
|
int strength = ril_netreg_get_signal_strength(data, len);
|
||||||
(cbd->nd, data, len), cbd->data);
|
cb(ril_error_ok(&error), strength, cbd->data);
|
||||||
} else {
|
} else {
|
||||||
ofono_error("Failed to retrive the signal strength: %s",
|
ofono_error("Failed to retrive the signal strength: %s",
|
||||||
ril_error_to_string(status));
|
ril_error_to_string(status));
|
||||||
@@ -557,12 +558,9 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
|
|||||||
DBG_(nd, "%p", netreg);
|
DBG_(nd, "%p", netreg);
|
||||||
nd->io = grilio_channel_ref(ril_modem_io(modem));
|
nd->io = grilio_channel_ref(ril_modem_io(modem));
|
||||||
nd->q = grilio_queue_new(nd->io);
|
nd->q = grilio_queue_new(nd->io);
|
||||||
nd->vendor = ril_vendor_ref(modem->vendor);
|
|
||||||
nd->network = ril_network_ref(modem->network);
|
nd->network = ril_network_ref(modem->network);
|
||||||
nd->netreg = netreg;
|
nd->netreg = netreg;
|
||||||
nd->network_selection_manual_0 = config->network_selection_manual_0;
|
nd->network_selection_manual_0 = config->network_selection_manual_0;
|
||||||
nd->signal_strength_dbm_weak = config->signal_strength_dbm_weak;
|
|
||||||
nd->signal_strength_dbm_strong = config->signal_strength_dbm_strong;
|
|
||||||
|
|
||||||
ofono_netreg_set_data(netreg, nd);
|
ofono_netreg_set_data(netreg, nd);
|
||||||
nd->timer_id = g_idle_add(ril_netreg_register, nd);
|
nd->timer_id = g_idle_add(ril_netreg_register, nd);
|
||||||
@@ -591,7 +589,6 @@ static void ril_netreg_remove(struct ofono_netreg *netreg)
|
|||||||
|
|
||||||
ril_network_remove_all_handlers(nd->network, nd->network_event_id);
|
ril_network_remove_all_handlers(nd->network, nd->network_event_id);
|
||||||
ril_network_unref(nd->network);
|
ril_network_unref(nd->network);
|
||||||
ril_vendor_unref(nd->vendor);
|
|
||||||
|
|
||||||
grilio_channel_remove_all_handlers(nd->io, nd->ril_event_id);
|
grilio_channel_remove_all_handlers(nd->io, nd->ril_event_id);
|
||||||
grilio_channel_unref(nd->io);
|
grilio_channel_unref(nd->io);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2020 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
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -14,8 +13,6 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
|
|
||||||
#include "ril_network.h"
|
#include "ril_network.h"
|
||||||
#include "ril_radio.h"
|
#include "ril_radio.h"
|
||||||
#include "ril_sim_card.h"
|
#include "ril_sim_card.h"
|
||||||
@@ -29,7 +26,6 @@
|
|||||||
#include <grilio_parser.h>
|
#include <grilio_parser.h>
|
||||||
|
|
||||||
#include <gutil_misc.h>
|
#include <gutil_misc.h>
|
||||||
#include <gutil_macros.h>
|
|
||||||
|
|
||||||
#include <ofono/netreg.h>
|
#include <ofono/netreg.h>
|
||||||
#include <ofono/watch.h>
|
#include <ofono/watch.h>
|
||||||
@@ -72,20 +68,6 @@ enum ril_network_watch_event {
|
|||||||
WATCH_EVENT_COUNT
|
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 {
|
struct ril_network_priv {
|
||||||
GRilIoChannel *io;
|
GRilIoChannel *io;
|
||||||
GRilIoQueue *q;
|
GRilIoQueue *q;
|
||||||
@@ -113,11 +95,6 @@ struct ril_network_priv {
|
|||||||
gboolean set_initial_attach_apn;
|
gboolean set_initial_attach_apn;
|
||||||
struct ofono_network_operator operator;
|
struct ofono_network_operator operator;
|
||||||
gboolean assert_rat;
|
gboolean assert_rat;
|
||||||
gboolean force_gsm_when_radio_off;
|
|
||||||
gboolean use_data_profiles;
|
|
||||||
int mms_data_profile_id;
|
|
||||||
GSList *data_profiles;
|
|
||||||
guint set_data_profiles_id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ril_network_signal {
|
enum ril_network_signal {
|
||||||
@@ -519,12 +496,13 @@ static enum ofono_radio_access_mode ril_network_actual_pref_mode
|
|||||||
struct ril_network_priv *priv = self->priv;
|
struct ril_network_priv *priv = self->priv;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On most dual-SIM phones only one slot at a time is allowed
|
* On dual-SIM phones such as Jolla C only one slot at a time
|
||||||
* to use LTE. On some phones (such as Jolla C), even if the
|
* is allowed to use LTE. Even if the slot which has been using
|
||||||
* slot which has been using LTE gets powered off, we still
|
* LTE gets powered off, we still need to explicitely set its
|
||||||
* need to explicitly set its preferred mode to GSM, to make
|
* preferred mode to GSM, to make LTE machinery available to
|
||||||
* LTE machinery available to the other slot. This behavior is
|
* the other slot. This sort of behaviour might not be necessary
|
||||||
* configurable.
|
* on some hardware and can (should) be made configurable when
|
||||||
|
* it becomes necessary.
|
||||||
*/
|
*/
|
||||||
const enum ofono_radio_access_mode max_pref_mode =
|
const enum ofono_radio_access_mode max_pref_mode =
|
||||||
(priv->radio->state == RADIO_STATE_ON) ? self->max_pref_mode :
|
(priv->radio->state == RADIO_STATE_ON) ? self->max_pref_mode :
|
||||||
@@ -579,7 +557,8 @@ static void ril_network_set_initial_attach_apn(struct ril_network *self,
|
|||||||
password = "";
|
password = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
req = ril_vendor_set_attach_apn_req(priv->vendor,ctx->apn,
|
req = ril_vendor_set_attach_apn_req(priv->vendor,
|
||||||
|
DATA_PROFILE_DEFAULT_STR, ctx->apn,
|
||||||
username, password, auth, proto);
|
username, password, auth, proto);
|
||||||
|
|
||||||
if (!req) {
|
if (!req) {
|
||||||
@@ -631,191 +610,6 @@ static void ril_network_check_initial_attach_apn(struct ril_network *self)
|
|||||||
ril_network_try_set_initial_attach_apn(self);
|
ril_network_try_set_initial_attach_apn(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ril_network_data_profile *ril_network_data_profile_new
|
|
||||||
(const struct ofono_gprs_primary_context* context,
|
|
||||||
enum ril_data_profile profile_id)
|
|
||||||
{
|
|
||||||
/* Allocate the whole thing as a single memory block */
|
|
||||||
struct ril_network_data_profile *profile;
|
|
||||||
const enum ofono_gprs_auth_method auth_method =
|
|
||||||
(context->username[0] || context->password[0]) ?
|
|
||||||
context->auth_method : OFONO_GPRS_AUTH_METHOD_NONE;
|
|
||||||
const gsize apn_size = strlen(context->apn) + 1;
|
|
||||||
gsize username_size = 0;
|
|
||||||
gsize password_size = 0;
|
|
||||||
gsize size = G_ALIGN8(sizeof(*profile)) + G_ALIGN8(apn_size);
|
|
||||||
char* ptr;
|
|
||||||
|
|
||||||
if (auth_method != OFONO_GPRS_AUTH_METHOD_NONE) {
|
|
||||||
username_size = strlen(context->username) + 1;
|
|
||||||
password_size = strlen(context->password) + 1;
|
|
||||||
size += G_ALIGN8(username_size) + G_ALIGN8(password_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = g_malloc0(size);
|
|
||||||
|
|
||||||
profile = (struct ril_network_data_profile*)ptr;
|
|
||||||
ptr += G_ALIGN8(sizeof(*profile));
|
|
||||||
|
|
||||||
profile->profile_id = profile_id;
|
|
||||||
profile->type = RIL_PROFILE_3GPP;
|
|
||||||
profile->auth_method = auth_method;
|
|
||||||
profile->proto = context->proto;
|
|
||||||
profile->enabled = TRUE;
|
|
||||||
|
|
||||||
/* Copy strings */
|
|
||||||
profile->apn = ptr;
|
|
||||||
memcpy(ptr, context->apn, apn_size - 1);
|
|
||||||
ptr += G_ALIGN8(apn_size);
|
|
||||||
|
|
||||||
if (auth_method == OFONO_GPRS_AUTH_METHOD_NONE) {
|
|
||||||
profile->user = "";
|
|
||||||
profile->password = "";
|
|
||||||
} else {
|
|
||||||
profile->user = ptr;
|
|
||||||
memcpy(ptr, context->username, username_size - 1);
|
|
||||||
ptr += G_ALIGN8(username_size);
|
|
||||||
|
|
||||||
profile->password = ptr;
|
|
||||||
memcpy(ptr, context->password, password_size - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean ril_network_data_profile_equal
|
|
||||||
(const struct ril_network_data_profile *profile1,
|
|
||||||
const struct ril_network_data_profile *profile2)
|
|
||||||
{
|
|
||||||
if (profile1 == profile2) {
|
|
||||||
return TRUE;
|
|
||||||
} else if (!profile1 || !profile2) {
|
|
||||||
return FALSE;
|
|
||||||
} else {
|
|
||||||
return profile1->profile_id == profile2->profile_id &&
|
|
||||||
profile1->type == profile2->type &&
|
|
||||||
profile1->auth_method == profile2->auth_method &&
|
|
||||||
profile1->proto == profile2->proto &&
|
|
||||||
profile1->enabled == profile2->enabled &&
|
|
||||||
!g_strcmp0(profile1->apn, profile2->apn) &&
|
|
||||||
!g_strcmp0(profile1->user, profile2->user) &&
|
|
||||||
!g_strcmp0(profile1->password, profile2->password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean ril_network_data_profiles_equal(GSList *list1, GSList *list2)
|
|
||||||
{
|
|
||||||
if (g_slist_length(list1) != g_slist_length(list2)) {
|
|
||||||
return FALSE;
|
|
||||||
} else {
|
|
||||||
GSList *l1 = list1;
|
|
||||||
GSList *l2 = list2;
|
|
||||||
|
|
||||||
while (l1 && l2) {
|
|
||||||
const struct ril_network_data_profile *p1 = l1->data;
|
|
||||||
const struct ril_network_data_profile *p2 = l2->data;
|
|
||||||
|
|
||||||
if (!ril_network_data_profile_equal(p1, p2)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
l1 = l1->next;
|
|
||||||
l2 = l2->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ril_network_data_profiles_free(GSList *list)
|
|
||||||
{
|
|
||||||
/* Profiles are allocated as single memory blocks */
|
|
||||||
g_slist_free_full(list, g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_network_set_data_profiles_done(GRilIoChannel *channel,
|
|
||||||
int status, const void *data, guint len, void *user_data)
|
|
||||||
{
|
|
||||||
struct ril_network *self = RIL_NETWORK(user_data);
|
|
||||||
struct ril_network_priv *priv = self->priv;
|
|
||||||
|
|
||||||
GASSERT(priv->set_data_profiles_id);
|
|
||||||
priv->set_data_profiles_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_network_set_data_profiles(struct ril_network *self)
|
|
||||||
{
|
|
||||||
struct ril_network_priv *priv = self->priv;
|
|
||||||
GRilIoRequest *req = grilio_request_new();
|
|
||||||
GSList *l = priv->data_profiles;
|
|
||||||
|
|
||||||
grilio_request_append_int32(req, g_slist_length(l));
|
|
||||||
while (l) {
|
|
||||||
const struct ril_network_data_profile *p = l->data;
|
|
||||||
|
|
||||||
grilio_request_append_int32(req, p->profile_id);
|
|
||||||
grilio_request_append_utf8(req, p->apn);
|
|
||||||
grilio_request_append_utf8(req, ril_protocol_from_ofono
|
|
||||||
(p->proto));
|
|
||||||
grilio_request_append_int32(req, ril_auth_method_from_ofono
|
|
||||||
(p->auth_method));
|
|
||||||
grilio_request_append_utf8(req, p->user);
|
|
||||||
grilio_request_append_utf8(req, p->password);
|
|
||||||
grilio_request_append_int32(req, p->type);
|
|
||||||
grilio_request_append_int32(req, p->max_conns_time);
|
|
||||||
grilio_request_append_int32(req, p->max_conns);
|
|
||||||
grilio_request_append_int32(req, p->wait_time);
|
|
||||||
grilio_request_append_int32(req, p->enabled);
|
|
||||||
l = l->next;
|
|
||||||
}
|
|
||||||
grilio_queue_cancel_request(priv->q, priv->set_data_profiles_id, FALSE);
|
|
||||||
priv->set_data_profiles_id = grilio_queue_send_request_full(priv->q,
|
|
||||||
req, RIL_REQUEST_SET_DATA_PROFILE,
|
|
||||||
ril_network_set_data_profiles_done,
|
|
||||||
NULL, self);
|
|
||||||
grilio_request_unref(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_network_check_data_profiles(struct ril_network *self)
|
|
||||||
{
|
|
||||||
struct ril_network_priv *priv = self->priv;
|
|
||||||
struct ofono_gprs *gprs = priv->watch->gprs;
|
|
||||||
|
|
||||||
if (gprs) {
|
|
||||||
const struct ofono_gprs_primary_context* internet =
|
|
||||||
ofono_gprs_context_settings_by_type(gprs,
|
|
||||||
OFONO_GPRS_CONTEXT_TYPE_INTERNET);
|
|
||||||
const struct ofono_gprs_primary_context* mms =
|
|
||||||
ofono_gprs_context_settings_by_type(gprs,
|
|
||||||
OFONO_GPRS_CONTEXT_TYPE_MMS);
|
|
||||||
GSList *l = NULL;
|
|
||||||
|
|
||||||
if (internet) {
|
|
||||||
DBG_(self, "internet apn \"%s\"", internet->apn);
|
|
||||||
l = g_slist_append(l,
|
|
||||||
ril_network_data_profile_new(internet,
|
|
||||||
RIL_DATA_PROFILE_DEFAULT));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mms) {
|
|
||||||
DBG_(self, "mms apn \"%s\"", mms->apn);
|
|
||||||
l = g_slist_append(l,
|
|
||||||
ril_network_data_profile_new(mms,
|
|
||||||
priv->mms_data_profile_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ril_network_data_profiles_equal(priv->data_profiles, l)) {
|
|
||||||
ril_network_data_profiles_free(l);
|
|
||||||
} else {
|
|
||||||
ril_network_data_profiles_free(priv->data_profiles);
|
|
||||||
priv->data_profiles = l;
|
|
||||||
ril_network_set_data_profiles(self);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ril_network_data_profiles_free(priv->data_profiles);
|
|
||||||
priv->data_profiles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean ril_network_can_set_pref_mode(struct ril_network *self)
|
static gboolean ril_network_can_set_pref_mode(struct ril_network *self)
|
||||||
{
|
{
|
||||||
struct ril_network_priv *priv = self->priv;
|
struct ril_network_priv *priv = self->priv;
|
||||||
@@ -905,52 +699,33 @@ static void ril_network_check_pref_mode(struct ril_network *self,
|
|||||||
gboolean immediate)
|
gboolean immediate)
|
||||||
{
|
{
|
||||||
struct ril_network_priv *priv = self->priv;
|
struct ril_network_priv *priv = self->priv;
|
||||||
struct ril_radio *radio = priv->radio;
|
const int rat = ril_network_mode_to_rat
|
||||||
|
(self, ril_network_actual_pref_mode(self));
|
||||||
|
|
||||||
/*
|
if (priv->timer[TIMER_FORCE_CHECK_PREF_MODE]) {
|
||||||
* On most dual-SIM phones only one slot at a time is allowed
|
ril_network_stop_timer(self, TIMER_FORCE_CHECK_PREF_MODE);
|
||||||
* to use LTE. On some phones (such as Jolla C), even if the
|
/*
|
||||||
* slot which has been using LTE gets powered off, we still
|
* TIMER_FORCE_CHECK_PREF_MODE is scheduled by
|
||||||
* need to explicitly set its preferred mode to GSM, to make
|
* ril_network_pref_mode_changed_cb and is meant
|
||||||
* LTE machinery available to the other slot. This behavior is
|
* to force radio tech check right now.
|
||||||
* configurable.
|
*/
|
||||||
*/
|
immediate = TRUE;
|
||||||
if (radio->state == RADIO_STATE_ON || priv->force_gsm_when_radio_off) {
|
}
|
||||||
const enum ofono_radio_access_mode expected =
|
|
||||||
ril_network_actual_pref_mode(self);
|
|
||||||
const enum ofono_radio_access_mode actual =
|
|
||||||
ril_network_rat_to_mode(priv->rat);
|
|
||||||
|
|
||||||
if (priv->timer[TIMER_FORCE_CHECK_PREF_MODE]) {
|
if (priv->rat != rat) {
|
||||||
ril_network_stop_timer(self,
|
DBG_(self, "rat mode %d, expected %d", priv->rat, rat);
|
||||||
TIMER_FORCE_CHECK_PREF_MODE);
|
}
|
||||||
/*
|
|
||||||
* TIMER_FORCE_CHECK_PREF_MODE is scheduled by
|
|
||||||
* ril_network_pref_mode_changed_cb and is meant
|
|
||||||
* to force radio tech check right now.
|
|
||||||
*/
|
|
||||||
immediate = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->rat >= 0 && actual != expected) {
|
if (immediate) {
|
||||||
DBG_(self, "rat %d (%s), expected %s", priv->rat,
|
ril_network_stop_timer(self, TIMER_SET_RAT_HOLDOFF);
|
||||||
ofono_radio_access_mode_to_string(actual),
|
}
|
||||||
ofono_radio_access_mode_to_string(expected));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (immediate) {
|
if (priv->rat != rat || priv->assert_rat) {
|
||||||
ril_network_stop_timer(self, TIMER_SET_RAT_HOLDOFF);
|
if (!priv->timer[TIMER_SET_RAT_HOLDOFF]) {
|
||||||
}
|
ril_network_set_pref_mode(self, rat);
|
||||||
|
} else {
|
||||||
if (actual != expected || priv->assert_rat) {
|
/* OK, later */
|
||||||
const int rat = ril_network_mode_to_rat(self, expected);
|
DBG_(self, "need to set rat mode %d", rat);
|
||||||
|
|
||||||
if (!priv->timer[TIMER_SET_RAT_HOLDOFF]) {
|
|
||||||
ril_network_set_pref_mode(self, rat);
|
|
||||||
} else {
|
|
||||||
/* OK, later */
|
|
||||||
DBG_(self, "need to set rat mode %d", rat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1193,9 +968,6 @@ static void ril_network_watch_gprs_cb(struct ofono_watch *watch,
|
|||||||
|
|
||||||
DBG_(self, "gprs %s", watch->gprs ? "appeared" : "is gone");
|
DBG_(self, "gprs %s", watch->gprs ? "appeared" : "is gone");
|
||||||
priv->set_initial_attach_apn = TRUE;
|
priv->set_initial_attach_apn = TRUE;
|
||||||
if (priv->use_data_profiles) {
|
|
||||||
ril_network_check_data_profiles(self);
|
|
||||||
}
|
|
||||||
ril_network_check_initial_attach_apn(self);
|
ril_network_check_initial_attach_apn(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1204,14 +976,8 @@ static void ril_network_watch_gprs_settings_cb(struct ofono_watch *watch,
|
|||||||
const struct ofono_gprs_primary_context *settings,
|
const struct ofono_gprs_primary_context *settings,
|
||||||
void *user_data)
|
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) {
|
if (type == OFONO_GPRS_CONTEXT_TYPE_INTERNET) {
|
||||||
|
struct ril_network *self = RIL_NETWORK(user_data);
|
||||||
struct ril_network_priv *priv = self->priv;
|
struct ril_network_priv *priv = self->priv;
|
||||||
|
|
||||||
priv->set_initial_attach_apn = TRUE;
|
priv->set_initial_attach_apn = TRUE;
|
||||||
@@ -1219,6 +985,7 @@ static void ril_network_watch_gprs_settings_cb(struct ofono_watch *watch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
||||||
const char *log_prefix, struct ril_radio *radio,
|
const char *log_prefix, struct ril_radio *radio,
|
||||||
struct ril_sim_card *simcard,
|
struct ril_sim_card *simcard,
|
||||||
@@ -1244,9 +1011,6 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
|||||||
priv->lte_network_mode = config->lte_network_mode;
|
priv->lte_network_mode = config->lte_network_mode;
|
||||||
priv->umts_network_mode = config->umts_network_mode;
|
priv->umts_network_mode = config->umts_network_mode;
|
||||||
priv->network_mode_timeout = config->network_mode_timeout;
|
priv->network_mode_timeout = config->network_mode_timeout;
|
||||||
priv->force_gsm_when_radio_off = config->force_gsm_when_radio_off;
|
|
||||||
priv->use_data_profiles = config->use_data_profiles;
|
|
||||||
priv->mms_data_profile_id = config->mms_data_profile_id;
|
|
||||||
|
|
||||||
/* Register listeners */
|
/* Register listeners */
|
||||||
priv->unsol_event_id[UNSOL_EVENT_NETWORK_STATE] =
|
priv->unsol_event_id[UNSOL_EVENT_NETWORK_STATE] =
|
||||||
@@ -1298,9 +1062,6 @@ struct ril_network *ril_network_new(const char *path, GRilIoChannel *io,
|
|||||||
ril_network_need_initial_attach_apn(self);
|
ril_network_need_initial_attach_apn(self);
|
||||||
|
|
||||||
ril_vendor_set_network(vendor, 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);
|
ril_network_try_set_initial_attach_apn(self);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -1359,7 +1120,6 @@ static void ril_network_finalize(GObject *object)
|
|||||||
priv->settings_event_id);
|
priv->settings_event_id);
|
||||||
ril_sim_settings_unref(self->settings);
|
ril_sim_settings_unref(self->settings);
|
||||||
ril_vendor_unref(priv->vendor);
|
ril_vendor_unref(priv->vendor);
|
||||||
g_slist_free_full(priv->data_profiles, g_free);
|
|
||||||
g_free(priv->log_prefix);
|
g_free(priv->log_prefix);
|
||||||
G_OBJECT_CLASS(ril_network_parent_class)->finalize(object);
|
G_OBJECT_CLASS(ril_network_parent_class)->finalize(object);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2020 Jolla Ltd.
|
* Copyright (C) 2015-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -25,13 +24,9 @@
|
|||||||
#include "ril_data.h"
|
#include "ril_data.h"
|
||||||
#include "ril_util.h"
|
#include "ril_util.h"
|
||||||
#include "ril_vendor.h"
|
#include "ril_vendor.h"
|
||||||
#include "ril_devmon.h"
|
|
||||||
#include "ril_log.h"
|
#include "ril_log.h"
|
||||||
|
|
||||||
#include "ofono.h"
|
#include <ofono/sailfish_manager.h>
|
||||||
#include "sailfish_manager.h"
|
|
||||||
|
|
||||||
#include <ofono/storage.h>
|
|
||||||
#include <ofono/watch.h>
|
#include <ofono/watch.h>
|
||||||
|
|
||||||
#include <grilio_transport.h>
|
#include <grilio_transport.h>
|
||||||
@@ -40,6 +35,7 @@
|
|||||||
#include <gutil_macros.h>
|
#include <gutil_macros.h>
|
||||||
#include <gutil_misc.h>
|
#include <gutil_misc.h>
|
||||||
|
|
||||||
|
#include <mce_display.h>
|
||||||
#include <mce_log.h>
|
#include <mce_log.h>
|
||||||
|
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
@@ -64,7 +60,7 @@
|
|||||||
|
|
||||||
#define RIL_SUB_SIZE 4
|
#define RIL_SUB_SIZE 4
|
||||||
|
|
||||||
#define RILMODEM_CONF_FILE "ril_subscription.conf"
|
#define RILMODEM_CONF_FILE CONFIGDIR "/ril_subscription.conf"
|
||||||
#define RILMODEM_DEFAULT_IDENTITY "radio:radio"
|
#define RILMODEM_DEFAULT_IDENTITY "radio:radio"
|
||||||
#define RILMODEM_DEFAULT_SOCK "/dev/socket/rild"
|
#define RILMODEM_DEFAULT_SOCK "/dev/socket/rild"
|
||||||
#define RILMODEM_DEFAULT_SOCK2 "/dev/socket/rild2"
|
#define RILMODEM_DEFAULT_SOCK2 "/dev/socket/rild2"
|
||||||
@@ -73,8 +69,6 @@
|
|||||||
#define RILMODEM_DEFAULT_LTE_MODE PREF_NET_TYPE_LTE_GSM_WCDMA
|
#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_UMTS_MODE PREF_NET_TYPE_GSM_WCDMA_AUTO
|
||||||
#define RILMODEM_DEFAULT_NETWORK_MODE_TIMEOUT (20*1000) /* ms */
|
#define RILMODEM_DEFAULT_NETWORK_MODE_TIMEOUT (20*1000) /* ms */
|
||||||
#define RILMODEM_DEFAULT_DBM_WEAK (-100) /* very weak, 0.0000000001 mW */
|
|
||||||
#define RILMODEM_DEFAULT_DBM_STRONG (-60) /* strong signal, 0.000001 mW */
|
|
||||||
#define RILMODEM_DEFAULT_ENABLE_VOICECALL TRUE
|
#define RILMODEM_DEFAULT_ENABLE_VOICECALL TRUE
|
||||||
#define RILMODEM_DEFAULT_ENABLE_CBS TRUE
|
#define RILMODEM_DEFAULT_ENABLE_CBS TRUE
|
||||||
#define RILMODEM_DEFAULT_ENABLE_STK TRUE
|
#define RILMODEM_DEFAULT_ENABLE_STK TRUE
|
||||||
@@ -82,8 +76,7 @@
|
|||||||
#define RILMODEM_DEFAULT_TIMEOUT 0 /* No timeout */
|
#define RILMODEM_DEFAULT_TIMEOUT 0 /* No timeout */
|
||||||
#define RILMODEM_DEFAULT_SIM_FLAGS RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND
|
#define RILMODEM_DEFAULT_SIM_FLAGS RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND
|
||||||
#define RILMODEM_DEFAULT_DATA_OPT RIL_ALLOW_DATA_AUTO
|
#define RILMODEM_DEFAULT_DATA_OPT RIL_ALLOW_DATA_AUTO
|
||||||
#define RILMODEM_DEFAULT_DM_FLAGS (RIL_DATA_MANAGER_3GLTE_HANDOVER | \
|
#define RILMODEM_DEFAULT_DM_FLAGS RIL_DATA_MANAGER_3GLTE_HANDOVER
|
||||||
RIL_DATA_MANAGER_FORCE_GSM_ON_OTHER_SLOTS)
|
|
||||||
#define RILMODEM_DEFAULT_START_TIMEOUT 20000 /* ms */
|
#define RILMODEM_DEFAULT_START_TIMEOUT 20000 /* ms */
|
||||||
#define RILMODEM_DEFAULT_DATA_CALL_FORMAT RIL_DATA_CALL_FORMAT_AUTO
|
#define RILMODEM_DEFAULT_DATA_CALL_FORMAT RIL_DATA_CALL_FORMAT_AUTO
|
||||||
#define RILMODEM_DEFAULT_DATA_CALL_RETRY_LIMIT 4
|
#define RILMODEM_DEFAULT_DATA_CALL_RETRY_LIMIT 4
|
||||||
@@ -94,9 +87,6 @@
|
|||||||
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
|
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
|
||||||
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
|
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
|
||||||
#define RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0 TRUE
|
#define RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0 TRUE
|
||||||
#define RILMODEM_DEFAULT_FORCE_GSM_WHEN_RADIO_OFF 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
|
#define RILMODEM_DEFAULT_SLOT_FLAGS SAILFISH_SLOT_NO_FLAGS
|
||||||
|
|
||||||
/* RIL socket transport name and parameters */
|
/* RIL socket transport name and parameters */
|
||||||
@@ -114,7 +104,6 @@
|
|||||||
#define RILCONF_SETTINGS_EMPTY "EmptyConfig"
|
#define RILCONF_SETTINGS_EMPTY "EmptyConfig"
|
||||||
#define RILCONF_SETTINGS_IDENTITY "Identity"
|
#define RILCONF_SETTINGS_IDENTITY "Identity"
|
||||||
#define RILCONF_SETTINGS_3GHANDOVER "3GLTEHandover"
|
#define RILCONF_SETTINGS_3GHANDOVER "3GLTEHandover"
|
||||||
#define RILCONF_SETTINGS_GSM_NON_DATA_SLOTS "ForceGsmForNonDataSlots"
|
|
||||||
#define RILCONF_SETTINGS_SET_RADIO_CAP "SetRadioCapability"
|
#define RILCONF_SETTINGS_SET_RADIO_CAP "SetRadioCapability"
|
||||||
|
|
||||||
#define RILCONF_MODEM_PREFIX "ril_"
|
#define RILCONF_MODEM_PREFIX "ril_"
|
||||||
@@ -134,7 +123,6 @@
|
|||||||
#define RILCONF_LTE_MODE "lteNetworkMode"
|
#define RILCONF_LTE_MODE "lteNetworkMode"
|
||||||
#define RILCONF_UMTS_MODE "umtsNetworkMode"
|
#define RILCONF_UMTS_MODE "umtsNetworkMode"
|
||||||
#define RILCONF_NETWORK_MODE_TIMEOUT "networkModeTimeout"
|
#define RILCONF_NETWORK_MODE_TIMEOUT "networkModeTimeout"
|
||||||
#define RILCONF_SIGNAL_STRENGTH_RANGE "signalStrengthRange"
|
|
||||||
#define RILCONF_UICC_WORKAROUND "uiccWorkaround"
|
#define RILCONF_UICC_WORKAROUND "uiccWorkaround"
|
||||||
#define RILCONF_ECCLIST_FILE "ecclistFile"
|
#define RILCONF_ECCLIST_FILE "ecclistFile"
|
||||||
#define RILCONF_ALLOW_DATA_REQ "allowDataReq"
|
#define RILCONF_ALLOW_DATA_REQ "allowDataReq"
|
||||||
@@ -150,10 +138,6 @@
|
|||||||
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
|
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
|
||||||
#define RILCONF_SINGLE_DATA_CONTEXT "singleDataContext"
|
#define RILCONF_SINGLE_DATA_CONTEXT "singleDataContext"
|
||||||
#define RILCONF_NETWORK_SELECTION_MANUAL_0 "networkSelectionManual0"
|
#define RILCONF_NETWORK_SELECTION_MANUAL_0 "networkSelectionManual0"
|
||||||
#define RILCONF_FORCE_GSM_WHEN_RADIO_OFF "forceGsmWhenRadioOff"
|
|
||||||
#define RILCONF_USE_DATA_PROFILES "useDataProfiles"
|
|
||||||
#define RILCONF_MMS_DATA_PROFILE_ID "mmsDataProfileId"
|
|
||||||
#define RILCONF_DEVMON "deviceStateTracking"
|
|
||||||
|
|
||||||
/* Modem error ids */
|
/* Modem error ids */
|
||||||
#define RIL_ERROR_ID_RILD_RESTART "rild-restart"
|
#define RIL_ERROR_ID_RILD_RESTART "rild-restart"
|
||||||
@@ -167,6 +151,12 @@ enum ril_plugin_io_events {
|
|||||||
IO_EVENT_COUNT
|
IO_EVENT_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ril_plugin_display_events {
|
||||||
|
DISPLAY_EVENT_VALID,
|
||||||
|
DISPLAY_EVENT_STATE,
|
||||||
|
DISPLAY_EVENT_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
enum ril_plugin_watch_events {
|
enum ril_plugin_watch_events {
|
||||||
WATCH_EVENT_MODEM,
|
WATCH_EVENT_MODEM,
|
||||||
WATCH_EVENT_COUNT
|
WATCH_EVENT_COUNT
|
||||||
@@ -178,13 +168,6 @@ enum ril_set_radio_cap_opt {
|
|||||||
RIL_SET_RADIO_CAP_DISABLED
|
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 {
|
struct ril_plugin_identity {
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
@@ -203,6 +186,7 @@ typedef struct sailfish_slot_manager_impl {
|
|||||||
struct ril_plugin_settings settings;
|
struct ril_plugin_settings settings;
|
||||||
gulong caps_manager_event_id;
|
gulong caps_manager_event_id;
|
||||||
guint start_timeout_id;
|
guint start_timeout_id;
|
||||||
|
MceDisplay *display;
|
||||||
GSList *slots;
|
GSList *slots;
|
||||||
} ril_plugin;
|
} ril_plugin;
|
||||||
|
|
||||||
@@ -238,8 +222,9 @@ typedef struct sailfish_slot_impl {
|
|||||||
enum sailfish_slot_flags slot_flags;
|
enum sailfish_slot_flags slot_flags;
|
||||||
guint start_timeout;
|
guint start_timeout;
|
||||||
guint start_timeout_id;
|
guint start_timeout_id;
|
||||||
struct ril_devmon *devmon;
|
MceDisplay *display;
|
||||||
struct ril_devmon_io *devmon_io;
|
gboolean display_on;
|
||||||
|
gulong display_event_id[DISPLAY_EVENT_COUNT];
|
||||||
GRilIoChannel *io;
|
GRilIoChannel *io;
|
||||||
gulong io_event_id[IO_EVENT_COUNT];
|
gulong io_event_id[IO_EVENT_COUNT];
|
||||||
gulong sim_card_state_event_id;
|
gulong sim_card_state_event_id;
|
||||||
@@ -269,10 +254,10 @@ GLOG_MODULE_DEFINE("rilmodem");
|
|||||||
static const char ril_debug_trace_name[] = "ril_trace";
|
static const char ril_debug_trace_name[] = "ril_trace";
|
||||||
|
|
||||||
static GLogModule ril_debug_trace_module = {
|
static GLogModule ril_debug_trace_module = {
|
||||||
.name = ril_debug_trace_name,
|
.name = ril_debug_trace_name,
|
||||||
.max_level = GLOG_LEVEL_VERBOSE,
|
.max_level = GLOG_LEVEL_VERBOSE,
|
||||||
.level = GLOG_LEVEL_VERBOSE,
|
.level = GLOG_LEVEL_VERBOSE,
|
||||||
.flags = GLOG_FLAG_HIDE_NAME
|
.flags = GLOG_FLAG_HIDE_NAME
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofono_debug_desc ril_debug_trace OFONO_DEBUG_ATTR = {
|
static struct ofono_debug_desc ril_debug_trace OFONO_DEBUG_ATTR = {
|
||||||
@@ -351,6 +336,41 @@ static void ril_plugin_foreach_slot_manager(struct sailfish_slot_driver_reg *r,
|
|||||||
ril_plugin_foreach_slot_manager_proc, fn);
|
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)
|
static void ril_plugin_remove_slot_handler(ril_slot *slot, int id)
|
||||||
{
|
{
|
||||||
GASSERT(id >= 0 && id<IO_EVENT_COUNT);
|
GASSERT(id >= 0 && id<IO_EVENT_COUNT);
|
||||||
@@ -376,11 +396,6 @@ static void ril_plugin_shutdown_slot(ril_slot *slot, gboolean kill_io)
|
|||||||
slot->retry_id = 0;
|
slot->retry_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot->devmon_io) {
|
|
||||||
ril_devmon_io_free(slot->devmon_io);
|
|
||||||
slot->devmon_io = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot->cell_info) {
|
if (slot->cell_info) {
|
||||||
sailfish_cell_info_unref(slot->cell_info);
|
sailfish_cell_info_unref(slot->cell_info);
|
||||||
slot->cell_info = NULL;
|
slot->cell_info = NULL;
|
||||||
@@ -844,7 +859,7 @@ static void ril_plugin_create_modem(ril_slot *slot)
|
|||||||
modem = ril_modem_create(slot->io, log_prefix, slot->path, slot->imei,
|
modem = ril_modem_create(slot->io, log_prefix, slot->path, slot->imei,
|
||||||
slot->imeisv, slot->ecclist_file, &slot->config, slot->radio,
|
slot->imeisv, slot->ecclist_file, &slot->config, slot->radio,
|
||||||
slot->network, slot->sim_card, slot->data, slot->sim_settings,
|
slot->network, slot->sim_card, slot->data, slot->sim_settings,
|
||||||
slot->vendor, slot->cell_info);
|
slot->cell_info);
|
||||||
|
|
||||||
if (modem) {
|
if (modem) {
|
||||||
slot->modem = modem;
|
slot->modem = modem;
|
||||||
@@ -918,8 +933,14 @@ static void ril_plugin_radio_caps_cb(const struct ril_radio_capability *cap,
|
|||||||
static void ril_plugin_manager_started(ril_plugin *plugin)
|
static void ril_plugin_manager_started(ril_plugin *plugin)
|
||||||
{
|
{
|
||||||
ril_plugin_drop_orphan_slots(plugin);
|
ril_plugin_drop_orphan_slots(plugin);
|
||||||
ril_data_manager_check_data(plugin->data_manager);
|
|
||||||
sailfish_slot_manager_started(plugin->handle);
|
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)
|
static void ril_plugin_all_slots_started_cb(ril_slot *slot, void *param)
|
||||||
@@ -1006,7 +1027,7 @@ static void ril_plugin_slot_connected(ril_slot *slot)
|
|||||||
GASSERT(!slot->cell_info);
|
GASSERT(!slot->cell_info);
|
||||||
if (slot->io->ril_version >= 9) {
|
if (slot->io->ril_version >= 9) {
|
||||||
slot->cell_info = ril_cell_info_new(slot->io, log_prefix,
|
slot->cell_info = ril_cell_info_new(slot->io, log_prefix,
|
||||||
slot->radio, slot->sim_card);
|
slot->display, slot->radio, slot->sim_card);
|
||||||
}
|
}
|
||||||
|
|
||||||
GASSERT(!slot->caps);
|
GASSERT(!slot->caps);
|
||||||
@@ -1020,12 +1041,6 @@ static void ril_plugin_slot_connected(ril_slot *slot)
|
|||||||
ril_plugin_radio_caps_cb, 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) {
|
if (!slot->handle) {
|
||||||
GASSERT(plugin->start_timeout_id);
|
GASSERT(plugin->start_timeout_id);
|
||||||
GASSERT(slot->start_timeout_id);
|
GASSERT(slot->start_timeout_id);
|
||||||
@@ -1040,12 +1055,12 @@ static void ril_plugin_slot_connected(ril_slot *slot)
|
|||||||
slot->imeisv, ril_plugin_sim_state(slot),
|
slot->imeisv, ril_plugin_sim_state(slot),
|
||||||
slot->slot_flags);
|
slot->slot_flags);
|
||||||
sailfish_manager_set_cell_info(slot->handle, slot->cell_info);
|
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 */
|
/* Check if this was the last slot we were waiting for */
|
||||||
ril_plugin_check_if_started(plugin);
|
ril_plugin_check_if_started(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ril_plugin_send_screen_state(slot);
|
||||||
ril_plugin_check_modem(slot);
|
ril_plugin_check_modem(slot);
|
||||||
ril_plugin_check_ready(slot);
|
ril_plugin_check_ready(slot);
|
||||||
}
|
}
|
||||||
@@ -1149,9 +1164,10 @@ static void ril_slot_free(ril_slot *slot)
|
|||||||
DBG("%s", slot->path);
|
DBG("%s", slot->path);
|
||||||
ril_plugin_shutdown_slot(slot, TRUE);
|
ril_plugin_shutdown_slot(slot, TRUE);
|
||||||
plugin->slots = g_slist_remove(plugin->slots, slot);
|
plugin->slots = g_slist_remove(plugin->slots, slot);
|
||||||
|
mce_display_remove_all_handlers(slot->display, slot->display_event_id);
|
||||||
|
mce_display_unref(slot->display);
|
||||||
ofono_watch_remove_all_handlers(slot->watch, slot->watch_event_id);
|
ofono_watch_remove_all_handlers(slot->watch, slot->watch_event_id);
|
||||||
ofono_watch_unref(slot->watch);
|
ofono_watch_unref(slot->watch);
|
||||||
ril_devmon_free(slot->devmon);
|
|
||||||
ril_sim_settings_unref(slot->sim_settings);
|
ril_sim_settings_unref(slot->sim_settings);
|
||||||
gutil_ints_unref(slot->config.local_hangup_reasons);
|
gutil_ints_unref(slot->config.local_hangup_reasons);
|
||||||
gutil_ints_unref(slot->config.remote_hangup_reasons);
|
gutil_ints_unref(slot->config.remote_hangup_reasons);
|
||||||
@@ -1193,9 +1209,6 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
|
|||||||
config->techs = RILMODEM_DEFAULT_TECHS;
|
config->techs = RILMODEM_DEFAULT_TECHS;
|
||||||
config->lte_network_mode = RILMODEM_DEFAULT_LTE_MODE;
|
config->lte_network_mode = RILMODEM_DEFAULT_LTE_MODE;
|
||||||
config->umts_network_mode = RILMODEM_DEFAULT_UMTS_MODE;
|
config->umts_network_mode = RILMODEM_DEFAULT_UMTS_MODE;
|
||||||
config->network_mode_timeout = RILMODEM_DEFAULT_NETWORK_MODE_TIMEOUT;
|
|
||||||
config->signal_strength_dbm_weak = RILMODEM_DEFAULT_DBM_WEAK;
|
|
||||||
config->signal_strength_dbm_strong = RILMODEM_DEFAULT_DBM_STRONG;
|
|
||||||
config->empty_pin_query = RILMODEM_DEFAULT_EMPTY_PIN_QUERY;
|
config->empty_pin_query = RILMODEM_DEFAULT_EMPTY_PIN_QUERY;
|
||||||
config->radio_power_cycle = RILMODEM_DEFAULT_RADIO_POWER_CYCLE;
|
config->radio_power_cycle = RILMODEM_DEFAULT_RADIO_POWER_CYCLE;
|
||||||
config->confirm_radio_power_on =
|
config->confirm_radio_power_on =
|
||||||
@@ -1207,10 +1220,6 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
|
|||||||
RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE;
|
RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE;
|
||||||
config->network_selection_manual_0 =
|
config->network_selection_manual_0 =
|
||||||
RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0;
|
RILMODEM_DEFAULT_NETWORK_SELECTION_MANUAL_0;
|
||||||
config->force_gsm_when_radio_off =
|
|
||||||
RILMODEM_DEFAULT_FORCE_GSM_WHEN_RADIO_OFF;
|
|
||||||
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->timeout = RILMODEM_DEFAULT_TIMEOUT;
|
||||||
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
|
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
|
||||||
slot->slot_flags = RILMODEM_DEFAULT_SLOT_FLAGS;
|
slot->slot_flags = RILMODEM_DEFAULT_SLOT_FLAGS;
|
||||||
@@ -1223,7 +1232,15 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
|
|||||||
slot->data_opt.data_call_retry_delay_ms =
|
slot->data_opt.data_call_retry_delay_ms =
|
||||||
RILMODEM_DEFAULT_DATA_CALL_RETRY_DELAY;
|
RILMODEM_DEFAULT_DATA_CALL_RETRY_DELAY;
|
||||||
|
|
||||||
slot->devmon = ril_devmon_auto_new();
|
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 = ofono_watch_new(dbus_path);
|
slot->watch = ofono_watch_new(dbus_path);
|
||||||
slot->watch_event_id[WATCH_EVENT_MODEM] =
|
slot->watch_event_id[WATCH_EVENT_MODEM] =
|
||||||
ofono_watch_add_modem_changed_handler(slot->watch,
|
ofono_watch_add_modem_changed_handler(slot->watch,
|
||||||
@@ -1243,10 +1260,6 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
|
|||||||
defaults.enable_cbs = config->enable_cbs;
|
defaults.enable_cbs = config->enable_cbs;
|
||||||
defaults.enable_stk = config->enable_stk;
|
defaults.enable_stk = config->enable_stk;
|
||||||
defaults.empty_pin_query = config->empty_pin_query;
|
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.force_gsm_when_radio_off =
|
|
||||||
config->force_gsm_when_radio_off;
|
|
||||||
defaults.query_available_band_mode =
|
defaults.query_available_band_mode =
|
||||||
config->query_available_band_mode;
|
config->query_available_band_mode;
|
||||||
|
|
||||||
@@ -1255,10 +1268,6 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
|
|||||||
config->enable_cbs = defaults.enable_cbs;
|
config->enable_cbs = defaults.enable_cbs;
|
||||||
config->enable_stk = defaults.enable_stk;
|
config->enable_stk = defaults.enable_stk;
|
||||||
config->empty_pin_query = defaults.empty_pin_query;
|
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->force_gsm_when_radio_off =
|
|
||||||
defaults.force_gsm_when_radio_off;
|
|
||||||
config->query_available_band_mode =
|
config->query_available_band_mode =
|
||||||
defaults.query_available_band_mode;
|
defaults.query_available_band_mode;
|
||||||
}
|
}
|
||||||
@@ -1368,7 +1377,6 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
|||||||
char *sval;
|
char *sval;
|
||||||
char **strv;
|
char **strv;
|
||||||
char *modem;
|
char *modem;
|
||||||
GUtilInts *ints;
|
|
||||||
GHashTable *transport_params = g_hash_table_new_full(g_str_hash,
|
GHashTable *transport_params = g_hash_table_new_full(g_str_hash,
|
||||||
g_str_equal, g_free, g_free);
|
g_str_equal, g_free, g_free);
|
||||||
char *transport = NULL;
|
char *transport = NULL;
|
||||||
@@ -1488,29 +1496,6 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
|||||||
config->network_selection_manual_0 ? "yes" : "no");
|
config->network_selection_manual_0 ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* forceGsmWhenRadioOff */
|
|
||||||
if (ril_config_get_boolean(file, group,
|
|
||||||
RILCONF_FORCE_GSM_WHEN_RADIO_OFF,
|
|
||||||
&config->force_gsm_when_radio_off)) {
|
|
||||||
DBG("%s: " RILCONF_FORCE_GSM_WHEN_RADIO_OFF " %s", group,
|
|
||||||
config->force_gsm_when_radio_off ? "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 */
|
/* technologies */
|
||||||
strv = ril_config_get_strings(file, group, RILCONF_TECHNOLOGIES, ',');
|
strv = ril_config_get_strings(file, group, RILCONF_TECHNOLOGIES, ',');
|
||||||
if (strv) {
|
if (strv) {
|
||||||
@@ -1566,21 +1551,6 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
|||||||
config->network_mode_timeout);
|
config->network_mode_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* signalStrengthRange */
|
|
||||||
ints = ril_config_get_ints(file, group, RILCONF_SIGNAL_STRENGTH_RANGE);
|
|
||||||
if (gutil_ints_get_count(ints) == 2) {
|
|
||||||
const int* dbms = gutil_ints_get_data(ints, NULL);
|
|
||||||
|
|
||||||
/* MIN,MAX */
|
|
||||||
if (dbms[0] < dbms[1]) {
|
|
||||||
DBG("%s: " RILCONF_SIGNAL_STRENGTH_RANGE " [%d,%d]",
|
|
||||||
group, dbms[0], dbms[1]);
|
|
||||||
config->signal_strength_dbm_weak = dbms[0];
|
|
||||||
config->signal_strength_dbm_strong = dbms[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gutil_ints_unref(ints);
|
|
||||||
|
|
||||||
/* enable4G (deprecated but still supported) */
|
/* enable4G (deprecated but still supported) */
|
||||||
ival = config->techs;
|
ival = config->techs;
|
||||||
if (ril_config_get_flag(file, group, RILCONF_4G,
|
if (ril_config_get_flag(file, group, RILCONF_4G,
|
||||||
@@ -1705,27 +1675,6 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
|||||||
slot->legacy_imei_query ? "on" : "off");
|
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;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1862,12 +1811,6 @@ static GSList *ril_plugin_parse_config_file(GKeyFile *file,
|
|||||||
RIL_DATA_MANAGER_3GLTE_HANDOVER,
|
RIL_DATA_MANAGER_3GLTE_HANDOVER,
|
||||||
&ps->dm_flags);
|
&ps->dm_flags);
|
||||||
|
|
||||||
/* ForceGsmForNonDataSlots */
|
|
||||||
ril_config_get_flag(file, group,
|
|
||||||
RILCONF_SETTINGS_GSM_NON_DATA_SLOTS,
|
|
||||||
RIL_DATA_MANAGER_FORCE_GSM_ON_OTHER_SLOTS,
|
|
||||||
&ps->dm_flags);
|
|
||||||
|
|
||||||
/* SetRadioCapability */
|
/* SetRadioCapability */
|
||||||
if (ril_config_get_enum(file, group,
|
if (ril_config_get_enum(file, group,
|
||||||
RILCONF_SETTINGS_SET_RADIO_CAP, &ival,
|
RILCONF_SETTINGS_SET_RADIO_CAP, &ival,
|
||||||
@@ -1907,7 +1850,7 @@ static GSList *ril_plugin_load_config(const char *path,
|
|||||||
GKeyFile *file = g_key_file_new();
|
GKeyFile *file = g_key_file_new();
|
||||||
gboolean empty = FALSE;
|
gboolean empty = FALSE;
|
||||||
|
|
||||||
config_merge_files(file, path);
|
ril_config_merge_files(file, path);
|
||||||
if (ril_config_get_boolean(file, RILCONF_SETTINGS_GROUP,
|
if (ril_config_get_boolean(file, RILCONF_SETTINGS_GROUP,
|
||||||
RILCONF_SETTINGS_EMPTY, &empty) && empty) {
|
RILCONF_SETTINGS_EMPTY, &empty) && empty) {
|
||||||
DBG("Empty config");
|
DBG("Empty config");
|
||||||
@@ -2073,6 +2016,13 @@ static ril_plugin *ril_plugin_manager_create(struct sailfish_slot_manager *m)
|
|||||||
struct ril_plugin_settings *ps = &plugin->settings;
|
struct ril_plugin_settings *ps = &plugin->settings;
|
||||||
|
|
||||||
DBG("");
|
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;
|
plugin->handle = m;
|
||||||
ril_plugin_parse_identity(&ps->identity, RILMODEM_DEFAULT_IDENTITY);
|
ril_plugin_parse_identity(&ps->identity, RILMODEM_DEFAULT_IDENTITY);
|
||||||
ps->dm_flags = RILMODEM_DEFAULT_DM_FLAGS;
|
ps->dm_flags = RILMODEM_DEFAULT_DM_FLAGS;
|
||||||
@@ -2093,15 +2043,12 @@ static guint ril_plugin_manager_start(ril_plugin *plugin)
|
|||||||
{
|
{
|
||||||
struct ril_plugin_settings *ps = &plugin->settings;
|
struct ril_plugin_settings *ps = &plugin->settings;
|
||||||
guint start_timeout = 0;
|
guint start_timeout = 0;
|
||||||
char* config_file = g_build_filename(ofono_config_dir(),
|
|
||||||
RILMODEM_CONF_FILE, NULL);
|
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
GASSERT(!plugin->start_timeout_id);
|
GASSERT(!plugin->start_timeout_id);
|
||||||
plugin->slots = ril_plugin_load_config(config_file, ps);
|
plugin->slots = ril_plugin_load_config(RILMODEM_CONF_FILE, ps);
|
||||||
plugin->data_manager = ril_data_manager_new(ps->dm_flags);
|
plugin->data_manager = ril_data_manager_new(ps->dm_flags);
|
||||||
ril_plugin_init_slots(plugin);
|
ril_plugin_init_slots(plugin);
|
||||||
g_free(config_file);
|
|
||||||
|
|
||||||
ofono_modem_driver_register(&ril_modem_driver);
|
ofono_modem_driver_register(&ril_modem_driver);
|
||||||
ofono_sim_driver_register(&ril_sim_driver);
|
ofono_sim_driver_register(&ril_sim_driver);
|
||||||
@@ -2143,6 +2090,7 @@ static void ril_plugin_manager_free(ril_plugin *plugin)
|
|||||||
{
|
{
|
||||||
if (plugin) {
|
if (plugin) {
|
||||||
GASSERT(!plugin->slots);
|
GASSERT(!plugin->slots);
|
||||||
|
mce_display_unref(plugin->display);
|
||||||
ril_data_manager_unref(plugin->data_manager);
|
ril_data_manager_unref(plugin->data_manager);
|
||||||
ril_radio_caps_manager_remove_handler(plugin->caps_manager,
|
ril_radio_caps_manager_remove_handler(plugin->caps_manager,
|
||||||
plugin->caps_manager_event_id);
|
plugin->caps_manager_event_id);
|
||||||
@@ -2163,9 +2111,7 @@ static void ril_slot_enabled_changed(struct sailfish_slot_impl *s)
|
|||||||
{
|
{
|
||||||
if (s->handle->enabled) {
|
if (s->handle->enabled) {
|
||||||
ril_plugin_check_modem(s);
|
ril_plugin_check_modem(s);
|
||||||
grilio_channel_set_enabled(s->io, TRUE);
|
|
||||||
} else {
|
} else {
|
||||||
grilio_channel_set_enabled(s->io, FALSE);
|
|
||||||
ril_plugin_shutdown_slot(s, FALSE);
|
ril_plugin_shutdown_slot(s, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 Jolla Ltd.
|
* Copyright (C) 2015-2017 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -53,7 +52,6 @@ struct ril_modem {
|
|||||||
const char *ecclist_file;
|
const char *ecclist_file;
|
||||||
struct ofono_modem *ofono;
|
struct ofono_modem *ofono;
|
||||||
struct sailfish_cell_info *cell_info;
|
struct sailfish_cell_info *cell_info;
|
||||||
struct ril_vendor *vendor;
|
|
||||||
struct ril_radio *radio;
|
struct ril_radio *radio;
|
||||||
struct ril_data *data;
|
struct ril_data *data;
|
||||||
struct ril_network *network;
|
struct ril_network *network;
|
||||||
@@ -72,7 +70,7 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
|
|||||||
const char *ecclist_file, const struct ril_slot_config *config,
|
const char *ecclist_file, const struct ril_slot_config *config,
|
||||||
struct ril_radio *radio, struct ril_network *network,
|
struct ril_radio *radio, struct ril_network *network,
|
||||||
struct ril_sim_card *card, struct ril_data *data,
|
struct ril_sim_card *card, struct ril_data *data,
|
||||||
struct ril_sim_settings *settings, struct ril_vendor *vendor,
|
struct ril_sim_settings *settings,
|
||||||
struct sailfish_cell_info *cell_info);
|
struct sailfish_cell_info *cell_info);
|
||||||
void ril_modem_delete(struct ril_modem *modem);
|
void ril_modem_delete(struct ril_modem *modem);
|
||||||
struct ofono_sim *ril_modem_ofono_sim(struct ril_modem *modem);
|
struct ofono_sim *ril_modem_ofono_sim(struct ril_modem *modem);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2020 Jolla Ltd.
|
* Copyright (C) 2015-2019 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -13,8 +13,6 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
|
|
||||||
#include "ril_radio.h"
|
#include "ril_radio.h"
|
||||||
#include "ril_util.h"
|
#include "ril_util.h"
|
||||||
#include "ril_log.h"
|
#include "ril_log.h"
|
||||||
|
|||||||
@@ -1133,7 +1133,6 @@ static void ril_sim_pin_change_state_status_cb(struct ril_sim_card *sc,
|
|||||||
cbd->cb(ril_error_ok(&error), cbd->data);
|
cbd->cb(ril_error_ok(&error), cbd->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ofono_sim_initialized_notify(sd->sim);
|
|
||||||
sd->pin_cbd_list = g_list_remove(sd->pin_cbd_list, cbd);
|
sd->pin_cbd_list = g_list_remove(sd->pin_cbd_list, cbd);
|
||||||
ril_sim_pin_cbd_free(cbd);
|
ril_sim_pin_cbd_free(cbd);
|
||||||
} else {
|
} else {
|
||||||
@@ -1172,10 +1171,7 @@ static void ril_sim_pin_change_state_cb(GRilIoChannel *io, int ril_status,
|
|||||||
|
|
||||||
ril_sim_check_perm_lock(sd);
|
ril_sim_check_perm_lock(sd);
|
||||||
cbd->ril_status = ril_status;
|
cbd->ril_status = ril_status;
|
||||||
|
if (cbd->card_status_id && (!cbd->state_event_count ||
|
||||||
/* RIL_E_PASSWORD_INCORRECT is the final result, no need to wait */
|
|
||||||
if (ril_status != RIL_E_PASSWORD_INCORRECT &&
|
|
||||||
cbd->card_status_id && (!cbd->state_event_count ||
|
|
||||||
ril_sim_app_in_transient_state(sd))) {
|
ril_sim_app_in_transient_state(sd))) {
|
||||||
|
|
||||||
GASSERT(!g_list_find(sd->pin_cbd_list, cbd));
|
GASSERT(!g_list_find(sd->pin_cbd_list, cbd));
|
||||||
@@ -1210,9 +1206,6 @@ static void ril_sim_pin_change_state_cb(GRilIoChannel *io, int ril_status,
|
|||||||
cbd->card_status_id);
|
cbd->card_status_id);
|
||||||
cbd->card_status_id = 0;
|
cbd->card_status_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the core that we are ready to accept more requests */
|
|
||||||
ofono_sim_initialized_notify(sd->sim);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2020 Jolla Ltd.
|
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -13,8 +13,6 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
|
|
||||||
#include "ril_sim_card.h"
|
#include "ril_sim_card.h"
|
||||||
#include "ril_radio.h"
|
#include "ril_radio.h"
|
||||||
#include "ril_util.h"
|
#include "ril_util.h"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2020 Jolla Ltd.
|
* Copyright (C) 2016-2019 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -13,8 +13,6 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
|
|
||||||
#include "ril_sim_settings.h"
|
#include "ril_sim_settings.h"
|
||||||
#include "ril_log.h"
|
#include "ril_log.h"
|
||||||
|
|
||||||
|
|||||||
@@ -42,13 +42,6 @@
|
|||||||
#
|
#
|
||||||
#3GLTEHandover=true
|
#3GLTEHandover=true
|
||||||
|
|
||||||
# If this option is on, preferred technology is set to GSM for non-data
|
|
||||||
# slots.
|
|
||||||
#
|
|
||||||
# Default true (for historical reasons)
|
|
||||||
#
|
|
||||||
#ForceGsmForNonDataSlots=true
|
|
||||||
|
|
||||||
# RIL_REQUEST_SET_RADIO_CAPABILITY may or may not be supported by your RIL.
|
# RIL_REQUEST_SET_RADIO_CAPABILITY may or may not be supported by your RIL.
|
||||||
# This option allows you to forcibly enable or disable use of this request.
|
# This option allows you to forcibly enable or disable use of this request.
|
||||||
# It's involved in 3G/LTE handover between the modems, meaning that it only
|
# It's involved in 3G/LTE handover between the modems, meaning that it only
|
||||||
@@ -237,17 +230,6 @@ socket=/dev/socket/rild
|
|||||||
#
|
#
|
||||||
#networkModeTimeout=20000
|
#networkModeTimeout=20000
|
||||||
|
|
||||||
# Comma-separated signal strength range, in dBm.
|
|
||||||
#
|
|
||||||
# These values are used for translating dBm values returned by the modem in
|
|
||||||
# LTE mode into signal strength percentage. If you are getting significantly
|
|
||||||
# different signal strength readings in GSM and LTE modes, you may need to
|
|
||||||
# tweak those.
|
|
||||||
#
|
|
||||||
# Default -100,-60
|
|
||||||
#
|
|
||||||
#signalStrengthRange=-100,-60
|
|
||||||
|
|
||||||
# Cycle radio power at startup.
|
# Cycle radio power at startup.
|
||||||
#
|
#
|
||||||
# Default true (cycle the power)
|
# Default true (cycle the power)
|
||||||
@@ -282,37 +264,3 @@ socket=/dev/socket/rild
|
|||||||
# Default true
|
# Default true
|
||||||
#
|
#
|
||||||
#networkSelectionManual0=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
|
|
||||||
|
|
||||||
# On some phones (such as Jolla C), even if the slot which has been
|
|
||||||
# using LTE gets powered off, we still need to explicitely set its
|
|
||||||
# preferred mode to GSM, to make LTE machinery available to the other slot.
|
|
||||||
#
|
|
||||||
# Default true (false for MTK RILs)
|
|
||||||
#
|
|
||||||
#forceGsmWhenRadioOff=true
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2020 Jolla Ltd.
|
* Copyright (C) 2015-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -55,8 +54,6 @@ struct ril_slot_config {
|
|||||||
enum ril_pref_net_type lte_network_mode;
|
enum ril_pref_net_type lte_network_mode;
|
||||||
enum ril_pref_net_type umts_network_mode;
|
enum ril_pref_net_type umts_network_mode;
|
||||||
int network_mode_timeout;
|
int network_mode_timeout;
|
||||||
int signal_strength_dbm_weak;
|
|
||||||
int signal_strength_dbm_strong;
|
|
||||||
gboolean query_available_band_mode;
|
gboolean query_available_band_mode;
|
||||||
gboolean empty_pin_query;
|
gboolean empty_pin_query;
|
||||||
gboolean radio_power_cycle;
|
gboolean radio_power_cycle;
|
||||||
@@ -65,9 +62,6 @@ struct ril_slot_config {
|
|||||||
gboolean enable_cbs;
|
gboolean enable_cbs;
|
||||||
gboolean enable_stk;
|
gboolean enable_stk;
|
||||||
gboolean network_selection_manual_0;
|
gboolean network_selection_manual_0;
|
||||||
gboolean force_gsm_when_radio_off;
|
|
||||||
gboolean use_data_profiles;
|
|
||||||
guint mms_data_profile_id;
|
|
||||||
GUtilInts *local_hangup_reasons;
|
GUtilInts *local_hangup_reasons;
|
||||||
GUtilInts *remote_hangup_reasons;
|
GUtilInts *remote_hangup_reasons;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 Jolla Ltd.
|
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -21,77 +20,48 @@
|
|||||||
#include "smsutil.h"
|
#include "smsutil.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define USSD_REQUEST_TIMEOUT_SEC (30)
|
|
||||||
#define USSD_CANCEL_TIMEOUT_SEC (20)
|
#define USSD_CANCEL_TIMEOUT_SEC (20)
|
||||||
|
|
||||||
struct ril_ussd {
|
struct ril_ussd {
|
||||||
struct ofono_ussd *ussd;
|
struct ofono_ussd *ussd;
|
||||||
GRilIoChannel *io;
|
GRilIoChannel *io;
|
||||||
GRilIoQueue *q;
|
GRilIoQueue *q;
|
||||||
guint request_id;
|
|
||||||
guint cancel_id;
|
|
||||||
guint timer_id;
|
guint timer_id;
|
||||||
gulong event_id;
|
gulong event_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ril_ussd_cbd {
|
struct ril_ussd_cbd {
|
||||||
struct ril_ussd *ud;
|
|
||||||
ofono_ussd_cb_t cb;
|
ofono_ussd_cb_t cb;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ril_ussd_cbd_free g_free
|
||||||
|
|
||||||
static inline struct ril_ussd *ril_ussd_get_data(struct ofono_ussd *ussd)
|
static inline struct ril_ussd *ril_ussd_get_data(struct ofono_ussd *ussd)
|
||||||
{
|
{
|
||||||
return ofono_ussd_get_data(ussd);
|
return ofono_ussd_get_data(ussd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ril_ussd_cbd *ril_ussd_cbd_new(struct ril_ussd *ud,
|
static struct ril_ussd_cbd *ril_ussd_cbd_new(ofono_ussd_cb_t cb, void *data)
|
||||||
ofono_ussd_cb_t cb, void *data)
|
|
||||||
{
|
{
|
||||||
struct ril_ussd_cbd *cbd = g_slice_new(struct ril_ussd_cbd);
|
struct ril_ussd_cbd *cbd = g_new0(struct ril_ussd_cbd, 1);
|
||||||
|
|
||||||
cbd->ud = ud;
|
|
||||||
cbd->cb = cb;
|
cbd->cb = cb;
|
||||||
cbd->data = data;
|
cbd->data = data;
|
||||||
return cbd;
|
return cbd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_ussd_cbd_free(void *cbd)
|
|
||||||
{
|
|
||||||
g_slice_free(struct ril_ussd_cbd, cbd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_ussd_cancel_cb(GRilIoChannel *io, int status,
|
static void ril_ussd_cancel_cb(GRilIoChannel *io, int status,
|
||||||
const void *data, guint len, void *user_data)
|
const void *data, guint len, void *user_data)
|
||||||
{
|
{
|
||||||
struct ofono_error error;
|
struct ofono_error error;
|
||||||
struct ril_ussd_cbd *cbd = user_data;
|
struct ril_ussd_cbd *cbd = user_data;
|
||||||
struct ril_ussd *ud = cbd->ud;
|
|
||||||
|
|
||||||
/* Always report sucessful completion, otherwise ofono may get
|
/* Always report sucessful completion, otherwise ofono may get
|
||||||
* stuck in the USSD_STATE_ACTIVE state */
|
* stuck in the USSD_STATE_ACTIVE state */
|
||||||
GASSERT(ud->cancel_id);
|
|
||||||
ud->cancel_id = 0;
|
|
||||||
cbd->cb(ril_error_ok(&error), cbd->data);
|
cbd->cb(ril_error_ok(&error), cbd->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_ussd_response(GRilIoChannel* channel, int status,
|
|
||||||
const void* data, guint len, void* user_data)
|
|
||||||
{
|
|
||||||
struct ofono_error error;
|
|
||||||
struct ril_ussd_cbd *cbd = user_data;
|
|
||||||
struct ril_ussd *ud = cbd->ud;
|
|
||||||
|
|
||||||
GASSERT(ud->request_id);
|
|
||||||
ud->request_id = 0;
|
|
||||||
if (status == RIL_E_SUCCESS) {
|
|
||||||
ril_error_init_ok(&error);
|
|
||||||
} else {
|
|
||||||
ril_error_init_failure(&error);
|
|
||||||
}
|
|
||||||
cbd->cb(&error, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
|
static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
|
||||||
const unsigned char *pdu, int len, ofono_ussd_cb_t cb, void *data)
|
const unsigned char *pdu, int len, ofono_ussd_cb_t cb, void *data)
|
||||||
{
|
{
|
||||||
@@ -100,12 +70,6 @@ static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
|
|||||||
struct ril_ussd *ud = ril_ussd_get_data(ussd);
|
struct ril_ussd *ud = ril_ussd_get_data(ussd);
|
||||||
|
|
||||||
ofono_info("send ussd, len:%d", len);
|
ofono_info("send ussd, len:%d", len);
|
||||||
GASSERT(!ud->request_id);
|
|
||||||
if (ud->request_id) {
|
|
||||||
grilio_queue_cancel_request(ud->q, ud->request_id, FALSE);
|
|
||||||
ud->request_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cbs_dcs_decode(dcs, NULL, NULL, &charset, NULL, NULL, NULL)) {
|
if (cbs_dcs_decode(dcs, NULL, NULL, &charset, NULL, NULL, NULL)) {
|
||||||
if (charset == SMS_CHARSET_7BIT) {
|
if (charset == SMS_CHARSET_7BIT) {
|
||||||
unsigned char unpacked_buf[182];
|
unsigned char unpacked_buf[182];
|
||||||
@@ -136,15 +100,10 @@ static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
|
|||||||
}
|
}
|
||||||
grilio_request_append_utf8_chars(req, (char*)
|
grilio_request_append_utf8_chars(req, (char*)
|
||||||
unpacked_buf, length);
|
unpacked_buf, length);
|
||||||
grilio_request_set_timeout(req,
|
grilio_queue_send_request(ud->q, req,
|
||||||
USSD_REQUEST_TIMEOUT_SEC * 1000);
|
RIL_REQUEST_SEND_USSD);
|
||||||
ud->request_id =
|
|
||||||
grilio_queue_send_request_full(ud->q,
|
|
||||||
req, RIL_REQUEST_SEND_USSD,
|
|
||||||
ril_ussd_response,
|
|
||||||
ril_ussd_cbd_free,
|
|
||||||
ril_ussd_cbd_new(ud, cb, data));
|
|
||||||
grilio_request_unref(req);
|
grilio_request_unref(req);
|
||||||
|
cb(ril_error_ok(&error), data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,12 +119,10 @@ static void ril_ussd_cancel(struct ofono_ussd *ussd,
|
|||||||
GRilIoRequest *req = grilio_request_new();
|
GRilIoRequest *req = grilio_request_new();
|
||||||
|
|
||||||
ofono_info("send ussd cancel");
|
ofono_info("send ussd cancel");
|
||||||
GASSERT(!ud->cancel_id);
|
|
||||||
grilio_queue_cancel_request(ud->q, ud->cancel_id, FALSE);
|
|
||||||
grilio_request_set_timeout(req, USSD_CANCEL_TIMEOUT_SEC * 1000);
|
grilio_request_set_timeout(req, USSD_CANCEL_TIMEOUT_SEC * 1000);
|
||||||
ud->cancel_id = grilio_queue_send_request_full(ud->q, req,
|
grilio_queue_send_request_full(ud->q, req, RIL_REQUEST_CANCEL_USSD,
|
||||||
RIL_REQUEST_CANCEL_USSD, ril_ussd_cancel_cb,
|
ril_ussd_cancel_cb, ril_ussd_cbd_free,
|
||||||
ril_ussd_cbd_free, ril_ussd_cbd_new(ud, cb, data));
|
ril_ussd_cbd_new(cb, data));
|
||||||
grilio_request_unref(req);
|
grilio_request_unref(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -239,18 +239,6 @@ const char *ril_request_to_string(guint request)
|
|||||||
RIL_REQUEST_(SHUTDOWN);
|
RIL_REQUEST_(SHUTDOWN);
|
||||||
RIL_REQUEST_(GET_RADIO_CAPABILITY);
|
RIL_REQUEST_(GET_RADIO_CAPABILITY);
|
||||||
RIL_REQUEST_(SET_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:
|
case RIL_RESPONSE_ACKNOWLEDGEMENT:
|
||||||
return "RESPONSE_ACK";
|
return "RESPONSE_ACK";
|
||||||
default:
|
default:
|
||||||
@@ -409,7 +397,6 @@ int ril_parse_tech(const char *stech, int *ril_tech)
|
|||||||
access_tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA;
|
access_tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA;
|
||||||
break;
|
break;
|
||||||
case RADIO_TECH_LTE:
|
case RADIO_TECH_LTE:
|
||||||
case RADIO_TECH_LTE_CA:
|
|
||||||
access_tech = ACCESS_TECHNOLOGY_EUTRAN;
|
access_tech = ACCESS_TECHNOLOGY_EUTRAN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 Jolla Ltd.
|
* Copyright (C) 2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -91,17 +90,18 @@ void ril_vendor_set_network(RilVendor *self, struct ril_network *nw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GRilIoRequest *ril_vendor_set_attach_apn_req(RilVendor *self, const char *apn,
|
GRilIoRequest *ril_vendor_set_attach_apn_req(RilVendor *self,
|
||||||
const char *user, const char *password,
|
const char *profile, const char *apn,
|
||||||
|
const char *username, const char *password,
|
||||||
enum ril_auth auth, const char *proto)
|
enum ril_auth auth, const char *proto)
|
||||||
{
|
{
|
||||||
return G_LIKELY(self) ? RIL_VENDOR_GET_CLASS(self)->
|
return G_LIKELY(self) ? RIL_VENDOR_GET_CLASS(self)->
|
||||||
set_attach_apn_req(self, apn, user, password, auth, proto) :
|
set_attach_apn_req(self, profile, apn, username, password,
|
||||||
NULL;
|
auth, proto) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GRilIoRequest *ril_vendor_data_call_req(RilVendor *self, int tech,
|
GRilIoRequest *ril_vendor_data_call_req(RilVendor *self,
|
||||||
enum ril_data_profile profile, const char *apn,
|
int tech, const char *profile, const char *apn,
|
||||||
const char *username, const char *password,
|
const char *username, const char *password,
|
||||||
enum ril_auth auth, const char *proto)
|
enum ril_auth auth, const char *proto)
|
||||||
{
|
{
|
||||||
@@ -117,14 +117,6 @@ gboolean ril_vendor_data_call_parse(RilVendor *self,
|
|||||||
data_call_parse(self, call, ver, rilp);
|
data_call_parse(self, call, ver, rilp);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean ril_vendor_signal_strength_parse(RilVendor *self,
|
|
||||||
struct ril_vendor_signal_strength *signal_strength,
|
|
||||||
GRilIoParser *rilp)
|
|
||||||
{
|
|
||||||
return G_LIKELY(self) && RIL_VENDOR_GET_CLASS(self)->
|
|
||||||
signal_strength_parse(self, signal_strength, rilp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_vendor_default_set_network(RilVendor *self,
|
static void ril_vendor_default_set_network(RilVendor *self,
|
||||||
struct ril_network *network)
|
struct ril_network *network)
|
||||||
{
|
{
|
||||||
@@ -147,16 +139,16 @@ static const char *ril_vendor_default_id_to_string(RilVendor *self, guint id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GRilIoRequest *ril_vendor_default_set_attach_apn_req(RilVendor *self,
|
static GRilIoRequest *ril_vendor_default_set_attach_apn_req(RilVendor *self,
|
||||||
const char *apn, const char *username,
|
const char *profile, const char *apn,
|
||||||
const char *password, enum ril_auth auth,
|
const char *username, const char *password,
|
||||||
const char *proto)
|
enum ril_auth auth, const char *proto)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GRilIoRequest *ril_vendor_default_data_call_req(RilVendor *self,
|
static GRilIoRequest *ril_vendor_default_data_call_req(RilVendor *self,
|
||||||
int tech, enum ril_data_profile profile,
|
int tech, const char *profile, const char *apn,
|
||||||
const char *apn, const char *user, const char *passwd,
|
const char *username, const char *password,
|
||||||
enum ril_auth auth, const char *proto)
|
enum ril_auth auth, const char *proto)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -169,13 +161,6 @@ static gboolean ril_vendor_default_data_call_parse(RilVendor *self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean ril_vendor_default_signal_strength_parse(RilVendor *self,
|
|
||||||
struct ril_vendor_signal_strength *signal_strength,
|
|
||||||
GRilIoParser *rilp)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ril_vendor_init_base(RilVendor *self, GRilIoChannel *io)
|
void ril_vendor_init_base(RilVendor *self, GRilIoChannel *io)
|
||||||
{
|
{
|
||||||
self->io = grilio_channel_ref(io);
|
self->io = grilio_channel_ref(io);
|
||||||
@@ -206,7 +191,6 @@ static void ril_vendor_class_init(RilVendorClass* klass)
|
|||||||
klass->set_attach_apn_req = ril_vendor_default_set_attach_apn_req;
|
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_req = ril_vendor_default_data_call_req;
|
||||||
klass->data_call_parse = ril_vendor_default_data_call_parse;
|
klass->data_call_parse = ril_vendor_default_data_call_parse;
|
||||||
klass->signal_strength_parse = ril_vendor_default_signal_strength_parse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2019 Jolla Ltd.
|
* Copyright (C) 2016-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -25,9 +24,6 @@ struct ril_vendor_defaults {
|
|||||||
gboolean enable_cbs;
|
gboolean enable_cbs;
|
||||||
gboolean enable_stk;
|
gboolean enable_stk;
|
||||||
gboolean query_available_band_mode;
|
gboolean query_available_band_mode;
|
||||||
gboolean use_data_profiles;
|
|
||||||
gboolean force_gsm_when_radio_off;
|
|
||||||
guint mms_data_profile_id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ril_vendor_driver {
|
struct ril_vendor_driver {
|
||||||
@@ -39,12 +35,6 @@ struct ril_vendor_driver {
|
|||||||
const struct ril_slot_config *cfg);
|
const struct ril_slot_config *cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ril_vendor_signal_strength {
|
|
||||||
gint32 gsm; /* (0-31, 99) per TS 27.007 8.5 */
|
|
||||||
gint32 lte; /* (0-31, 99) per TS 27.007 8.5 */
|
|
||||||
gint32 qdbm; /* 4*dBm, 0 if none */
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct ril_vendor_driver *ril_vendor_find_driver(const char *name);
|
const struct ril_vendor_driver *ril_vendor_find_driver(const char *name);
|
||||||
struct ril_vendor *ril_vendor_create
|
struct ril_vendor *ril_vendor_create
|
||||||
(const struct ril_vendor_driver *vendor, GRilIoChannel *io,
|
(const struct ril_vendor_driver *vendor, GRilIoChannel *io,
|
||||||
@@ -61,19 +51,16 @@ const char *ril_vendor_event_to_string(struct ril_vendor *vendor,
|
|||||||
guint event);
|
guint event);
|
||||||
void ril_vendor_set_network(struct ril_vendor *vendor, struct ril_network *nw);
|
void ril_vendor_set_network(struct ril_vendor *vendor, struct ril_network *nw);
|
||||||
GRilIoRequest *ril_vendor_set_attach_apn_req(struct ril_vendor *vendor,
|
GRilIoRequest *ril_vendor_set_attach_apn_req(struct ril_vendor *vendor,
|
||||||
const char *apn, const char *username,
|
const char *profile, const char *apn,
|
||||||
const char *password, enum ril_auth auth,
|
const char *username, const char *password,
|
||||||
const char *proto);
|
enum ril_auth auth, const char *proto);
|
||||||
GRilIoRequest *ril_vendor_data_call_req(struct ril_vendor *vendor, int tech,
|
GRilIoRequest *ril_vendor_data_call_req(struct ril_vendor *vendor,
|
||||||
enum ril_data_profile profile, const char *apn,
|
int tech, const char *profile, const char *apn,
|
||||||
const char *username, const char *password,
|
const char *username, const char *password,
|
||||||
enum ril_auth auth, const char *proto);
|
enum ril_auth auth, const char *proto);
|
||||||
gboolean ril_vendor_data_call_parse(struct ril_vendor *vendor,
|
gboolean ril_vendor_data_call_parse(struct ril_vendor *vendor,
|
||||||
struct ril_data_call *call, int version,
|
struct ril_data_call *call, int version,
|
||||||
GRilIoParser *rilp);
|
GRilIoParser *rilp);
|
||||||
gboolean ril_vendor_signal_strength_parse(struct ril_vendor *vendor,
|
|
||||||
struct ril_vendor_signal_strength *signal_strength,
|
|
||||||
GRilIoParser *rilp);
|
|
||||||
|
|
||||||
/* Put vendor driver descriptors to the "__vendor" section */
|
/* 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 \
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 Jolla Ltd.
|
* Copyright (C) 2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -33,19 +32,16 @@ typedef struct ril_vendor_class {
|
|||||||
const char *(*request_to_string)(RilVendor *vendor, guint request);
|
const char *(*request_to_string)(RilVendor *vendor, guint request);
|
||||||
const char *(*event_to_string)(RilVendor *vendor, guint event);
|
const char *(*event_to_string)(RilVendor *vendor, guint event);
|
||||||
GRilIoRequest *(*set_attach_apn_req)(RilVendor *vendor,
|
GRilIoRequest *(*set_attach_apn_req)(RilVendor *vendor,
|
||||||
const char *apn, const char *username,
|
const char *profile, const char *apn,
|
||||||
const char *password, enum ril_auth auth,
|
const char *username, const char *password,
|
||||||
const char *proto);
|
enum ril_auth auth, const char *proto);
|
||||||
GRilIoRequest *(*data_call_req)(RilVendor *vendor, int tech,
|
GRilIoRequest *(*data_call_req)(RilVendor *vendor,
|
||||||
enum ril_data_profile profile, const char *apn,
|
int tech, const char *profile, const char *apn,
|
||||||
const char *username, const char *password,
|
const char *username, const char *password,
|
||||||
enum ril_auth auth, const char *proto);
|
enum ril_auth auth, const char *proto);
|
||||||
gboolean (*data_call_parse)(RilVendor *vendor,
|
gboolean (*data_call_parse)(RilVendor *vendor,
|
||||||
struct ril_data_call *call, int version,
|
struct ril_data_call *call, int version,
|
||||||
GRilIoParser *rilp);
|
GRilIoParser *rilp);
|
||||||
gboolean (*signal_strength_parse)(RilVendor *vendor,
|
|
||||||
struct ril_vendor_signal_strength *signal_strength,
|
|
||||||
GRilIoParser *rilp);
|
|
||||||
} RilVendorClass;
|
} RilVendorClass;
|
||||||
|
|
||||||
GType ril_vendor_get_type(void);
|
GType ril_vendor_get_type(void);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2019 Jolla Ltd.
|
* Copyright (C) 2016-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -80,8 +79,6 @@ struct ril_mtk_flavor {
|
|||||||
enum ril_auth auth, const char *proto);
|
enum ril_auth auth, const char *proto);
|
||||||
gboolean (*data_call_parse_fn)(struct ril_data_call *call,
|
gboolean (*data_call_parse_fn)(struct ril_data_call *call,
|
||||||
int version, GRilIoParser *rilp);
|
int version, GRilIoParser *rilp);
|
||||||
gboolean (*signal_strength_fn)(struct ril_vendor_signal_strength *sig,
|
|
||||||
GRilIoParser *rilp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* MTK specific RIL messages (actual codes differ from model to model!) */
|
/* MTK specific RIL messages (actual codes differ from model to model!) */
|
||||||
@@ -326,8 +323,8 @@ static void ril_vendor_mtk_incoming_call_indication(GRilIoChannel *io, guint id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor, int tech,
|
static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor,
|
||||||
enum ril_data_profile profile, const char *apn,
|
int tech, const char *profile, const char *apn,
|
||||||
const char *username, const char *password,
|
const char *username, const char *password,
|
||||||
enum ril_auth auth, const char *proto)
|
enum ril_auth auth, const char *proto)
|
||||||
{
|
{
|
||||||
@@ -336,7 +333,7 @@ static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor, int tech,
|
|||||||
|
|
||||||
grilio_request_append_int32(req, 8); /* Number of parameters */
|
grilio_request_append_int32(req, 8); /* Number of parameters */
|
||||||
grilio_request_append_format(req, "%d", tech);
|
grilio_request_append_format(req, "%d", tech);
|
||||||
grilio_request_append_format(req, "%d", profile);
|
grilio_request_append_utf8(req, profile);
|
||||||
grilio_request_append_utf8(req, apn);
|
grilio_request_append_utf8(req, apn);
|
||||||
grilio_request_append_utf8(req, username);
|
grilio_request_append_utf8(req, username);
|
||||||
grilio_request_append_utf8(req, password);
|
grilio_request_append_utf8(req, password);
|
||||||
@@ -347,7 +344,8 @@ static GRilIoRequest *ril_vendor_mtk_data_call_req(RilVendor *vendor, int tech,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GRilIoRequest *ril_vendor_mtk_set_attach_apn_req(RilVendor *vendor,
|
static GRilIoRequest *ril_vendor_mtk_set_attach_apn_req(RilVendor *vendor,
|
||||||
const char *apn, const char *user, const char *pass,
|
const char *profile, const char *apn,
|
||||||
|
const char *user, const char *pass,
|
||||||
enum ril_auth auth, const char *prot)
|
enum ril_auth auth, const char *prot)
|
||||||
{
|
{
|
||||||
RilVendorMtk *self = RIL_VENDOR_MTK(vendor);
|
RilVendorMtk *self = RIL_VENDOR_MTK(vendor);
|
||||||
@@ -404,96 +402,6 @@ static gboolean ril_vendor_mtk_data_call_parse(RilVendor *vendor,
|
|||||||
data_call_parse(vendor, call, version, rilp);
|
data_call_parse(vendor, call, version, rilp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean ril_vendor_mtk_signal_strength_1
|
|
||||||
(struct ril_vendor_signal_strength *signal, GRilIoParser *rilp)
|
|
||||||
{
|
|
||||||
if (grilio_parser_bytes_remaining(rilp) == 64) {
|
|
||||||
gint32 rsrp = 0, rssi = 0;
|
|
||||||
|
|
||||||
/* GW_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, &signal->gsm);
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* bitErrorRate */
|
|
||||||
|
|
||||||
/* CDMA_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* dbm */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* ecio */
|
|
||||||
|
|
||||||
/* EVDO_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* dbm */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* ecio */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* signalNoiseRatio */
|
|
||||||
|
|
||||||
/* LTE_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, &signal->lte);
|
|
||||||
grilio_parser_get_int32(rilp, &rsrp); /* rsrp */
|
|
||||||
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);
|
|
||||||
grilio_parser_get_int32(rilp, &rssi);
|
|
||||||
grilio_parser_get_int32(rilp, NULL);
|
|
||||||
grilio_parser_get_int32(rilp, NULL);
|
|
||||||
|
|
||||||
signal->qdbm = (rssi > 0 && rssi != INT_MAX) ? (-4 * rssi) :
|
|
||||||
(rsrp >= 44 && rsrp <= 140) ? (-4 * rsrp) : 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean ril_vendor_mtk_signal_strength_2
|
|
||||||
(struct ril_vendor_signal_strength *signal, GRilIoParser *rilp)
|
|
||||||
{
|
|
||||||
if (grilio_parser_bytes_remaining(rilp) == 64) {
|
|
||||||
gint32 rsrp = 0, is_gsm = 0, rssi_qdbm = 0;
|
|
||||||
|
|
||||||
/* GW_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, &signal->gsm);
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* bitErrorRate */
|
|
||||||
|
|
||||||
/* CDMA_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* dbm */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* ecio */
|
|
||||||
|
|
||||||
/* EVDO_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* dbm */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* ecio */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* signalNoiseRatio */
|
|
||||||
|
|
||||||
/* LTE_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, &signal->lte);
|
|
||||||
grilio_parser_get_int32(rilp, &rsrp); /* rsrp */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* rsrq */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* rssnr */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* cqi */
|
|
||||||
|
|
||||||
/* WCDMA_SignalStrength */
|
|
||||||
grilio_parser_get_int32(rilp, &is_gsm); /* isGsm */
|
|
||||||
grilio_parser_get_int32(rilp, &rssi_qdbm); /* rssiQdbm */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* rscpQdbm */
|
|
||||||
grilio_parser_get_int32(rilp, NULL); /* Ecn0Qdbm*/
|
|
||||||
|
|
||||||
signal->qdbm = (is_gsm == 1 && rssi_qdbm < 0) ? rssi_qdbm :
|
|
||||||
(rsrp >= 44 && rsrp <= 140) ? (-4 * rsrp) : 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean ril_vendor_mtk_signal_strength_parse(RilVendor *vendor,
|
|
||||||
struct ril_vendor_signal_strength *signal,
|
|
||||||
GRilIoParser *rilp)
|
|
||||||
{
|
|
||||||
const struct ril_mtk_flavor *flavor = RIL_VENDOR_MTK(vendor)->flavor;
|
|
||||||
|
|
||||||
return flavor->signal_strength_fn ?
|
|
||||||
flavor->signal_strength_fn(signal, rilp) :
|
|
||||||
RIL_VENDOR_CLASS(ril_vendor_mtk_parent_class)->
|
|
||||||
signal_strength_parse(vendor, signal, rilp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_vendor_mtk_get_defaults(struct ril_vendor_defaults *defaults)
|
static void ril_vendor_mtk_get_defaults(struct ril_vendor_defaults *defaults)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -508,7 +416,6 @@ static void ril_vendor_mtk_get_defaults(struct ril_vendor_defaults *defaults)
|
|||||||
defaults->query_available_band_mode = FALSE;
|
defaults->query_available_band_mode = FALSE;
|
||||||
defaults->empty_pin_query = FALSE;
|
defaults->empty_pin_query = FALSE;
|
||||||
defaults->legacy_imei_query = TRUE;
|
defaults->legacy_imei_query = TRUE;
|
||||||
defaults->force_gsm_when_radio_off = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_vendor_mtk_base_init(RilVendorMtk *self, GRilIoChannel *io,
|
static void ril_vendor_mtk_base_init(RilVendorMtk *self, GRilIoChannel *io,
|
||||||
@@ -590,23 +497,20 @@ static void ril_vendor_mtk_class_init(RilVendorMtkClass* klass)
|
|||||||
klass->set_attach_apn_req = ril_vendor_mtk_set_attach_apn_req;
|
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_req = ril_vendor_mtk_data_call_req;
|
||||||
klass->data_call_parse = ril_vendor_mtk_data_call_parse;
|
klass->data_call_parse = ril_vendor_mtk_data_call_parse;
|
||||||
klass->signal_strength_parse = ril_vendor_mtk_signal_strength_parse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ril_mtk_flavor ril_mtk_flavor1 = {
|
static const struct ril_mtk_flavor ril_mtk_flavor1 = {
|
||||||
.name = "mtk1",
|
.name = "mtk1",
|
||||||
.msg = &msg_mtk1,
|
.msg = &msg_mtk1,
|
||||||
.build_attach_apn_req_fn = &ril_vendor_mtk_build_attach_apn_req_1,
|
.build_attach_apn_req_fn = &ril_vendor_mtk_build_attach_apn_req_1,
|
||||||
.data_call_parse_fn = NULL,
|
.data_call_parse_fn = NULL
|
||||||
.signal_strength_fn = &ril_vendor_mtk_signal_strength_1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ril_mtk_flavor ril_mtk_flavor2 = {
|
static const struct ril_mtk_flavor ril_mtk_flavor2 = {
|
||||||
.name = "mtk2",
|
.name = "mtk2",
|
||||||
.msg = &msg_mtk2,
|
.msg = &msg_mtk2,
|
||||||
.build_attach_apn_req_fn = &ril_vendor_mtk_build_attach_apn_req_2,
|
.build_attach_apn_req_fn = &ril_vendor_mtk_build_attach_apn_req_2,
|
||||||
.data_call_parse_fn = &ril_vendor_mtk_data_call_parse_v6,
|
.data_call_parse_fn = &ril_vendor_mtk_data_call_parse_v6
|
||||||
.signal_strength_fn = &ril_vendor_mtk_signal_strength_2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_MTK_TYPE (&ril_mtk_flavor1)
|
#define DEFAULT_MTK_TYPE (&ril_mtk_flavor1)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 Jolla Ltd.
|
* Copyright (C) 2015-2018 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -704,18 +704,13 @@ static void ril_voicecall_supp_svc_notification_event(GRilIoChannel *io,
|
|||||||
phone.number[0] = 0;
|
phone.number[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("RIL data: MT/MO: %d, code: %d, index: %d", type, code, index);
|
DBG("RIL data: MT/MO: %i, code: %i, index: %i", type, code, index);
|
||||||
|
|
||||||
switch (type) {
|
/* 0 stands for MO intermediate (support TBD), 1 for MT unsolicited */
|
||||||
case 0: /* MO intermediate result code */
|
if (type == 1) {
|
||||||
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);
|
ofono_voicecall_ssn_mt_notify(vd->vc, 0, code, index, &phone);
|
||||||
break;
|
} else {
|
||||||
default:
|
|
||||||
ofono_error("Unknown SS notification");
|
ofono_error("Unknown SS notification");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,255 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/ims.h>
|
|
||||||
|
|
||||||
#include "gatchat.h"
|
|
||||||
#include "gatresult.h"
|
|
||||||
|
|
||||||
#include "xmm7modem.h"
|
|
||||||
|
|
||||||
static const char *none_prefix[] = { NULL };
|
|
||||||
static const char *cireg_prefix[] = { "+CIREG:", NULL };
|
|
||||||
|
|
||||||
struct ims_driver_data {
|
|
||||||
GAtChat *chat;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void xmm_cireg_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
ofono_ims_status_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_error error;
|
|
||||||
GAtResultIter iter;
|
|
||||||
int reg_info, ext_info;
|
|
||||||
|
|
||||||
DBG("ok %d", ok);
|
|
||||||
|
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
cb(&error, -1, -1, cbd->data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
|
||||||
|
|
||||||
if (g_at_result_iter_next(&iter, "+CIREG:") == FALSE)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* skip value of n */
|
|
||||||
g_at_result_iter_skip_next(&iter);
|
|
||||||
|
|
||||||
if (g_at_result_iter_next_number(&iter, ®_info) == FALSE)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (reg_info == 0)
|
|
||||||
ext_info = -1;
|
|
||||||
else
|
|
||||||
if (g_at_result_iter_next_number(&iter, &ext_info) == FALSE)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cb(&error, reg_info, ext_info, cbd->data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, -1, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xmm_ims_registration_status(struct ofono_ims *ims,
|
|
||||||
ofono_ims_status_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct ims_driver_data *idd = ofono_ims_get_data(ims);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
|
|
||||||
if (g_at_chat_send(idd->chat, "AT+CIREG?", cireg_prefix,
|
|
||||||
xmm_cireg_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, -1, data);
|
|
||||||
g_free(cbd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xmm_ims_register_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user_data;
|
|
||||||
ofono_ims_register_cb_t cb = cbd->cb;
|
|
||||||
struct ofono_error error;
|
|
||||||
|
|
||||||
DBG("ok %d", ok);
|
|
||||||
|
|
||||||
decode_at_error(&error, g_at_result_final_response(result));
|
|
||||||
cb(&error, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xmm_ims_register(struct ofono_ims *ims,
|
|
||||||
ofono_ims_register_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct ims_driver_data *idd = ofono_ims_get_data(ims);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
|
|
||||||
if (g_at_chat_send(idd->chat, "AT+XIREG=1", none_prefix,
|
|
||||||
xmm_ims_register_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
g_free(cbd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xmm_ims_unregister(struct ofono_ims *ims,
|
|
||||||
ofono_ims_register_cb_t cb, void *data)
|
|
||||||
{
|
|
||||||
struct ims_driver_data *idd = ofono_ims_get_data(ims);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
|
||||||
|
|
||||||
if (g_at_chat_send(idd->chat, "AT+XIREG=0", none_prefix,
|
|
||||||
xmm_ims_register_cb, cbd, g_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
|
||||||
g_free(cbd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ciregu_notify(GAtResult *result, gpointer user_data)
|
|
||||||
{
|
|
||||||
struct ofono_ims *ims = user_data;
|
|
||||||
int reg_info, ext_info;
|
|
||||||
GAtResultIter iter;
|
|
||||||
|
|
||||||
g_at_result_iter_init(&iter, result);
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next(&iter, "+CIREGU:"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!g_at_result_iter_next_number(&iter, ®_info))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (reg_info == 0)
|
|
||||||
ext_info = -1;
|
|
||||||
else
|
|
||||||
if (!g_at_result_iter_next_number(&iter, &ext_info))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG("reg_info:%d, ext_info:%d", reg_info, ext_info);
|
|
||||||
|
|
||||||
ofono_ims_status_notify(ims, reg_info, ext_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xmm_cireg_set_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct ofono_ims *ims = user_data;
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
ofono_ims_remove(ims);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ofono_ims_register(ims);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cireg_support_cb(gboolean ok, GAtResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
struct ofono_ims *ims = user_data;
|
|
||||||
struct ims_driver_data *idd = ofono_ims_get_data(ims);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
ofono_ims_remove(ims);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_at_chat_register(idd->chat, "+CIREGU:", ciregu_notify,
|
|
||||||
FALSE, ims, NULL);
|
|
||||||
|
|
||||||
g_at_chat_send(idd->chat, "AT+CIREG=2", none_prefix,
|
|
||||||
xmm_cireg_set_cb, ims, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xmm_ims_probe(struct ofono_ims *ims, void *data)
|
|
||||||
{
|
|
||||||
GAtChat *chat = data;
|
|
||||||
struct ims_driver_data *idd;
|
|
||||||
|
|
||||||
DBG("at ims probe");
|
|
||||||
|
|
||||||
idd = g_try_new0(struct ims_driver_data, 1);
|
|
||||||
if (!idd)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
idd->chat = g_at_chat_clone(chat);
|
|
||||||
|
|
||||||
ofono_ims_set_data(ims, idd);
|
|
||||||
|
|
||||||
g_at_chat_send(idd->chat, "AT+CIREG=?", cireg_prefix,
|
|
||||||
cireg_support_cb, ims, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xmm_ims_remove(struct ofono_ims *ims)
|
|
||||||
{
|
|
||||||
struct ims_driver_data *idd = ofono_ims_get_data(ims);
|
|
||||||
|
|
||||||
DBG("at ims remove");
|
|
||||||
|
|
||||||
g_at_chat_unref(idd->chat);
|
|
||||||
|
|
||||||
ofono_ims_set_data(ims, NULL);
|
|
||||||
|
|
||||||
g_free(idd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_ims_driver driver = {
|
|
||||||
.name = "xmm7modem",
|
|
||||||
.probe = xmm_ims_probe,
|
|
||||||
.remove = xmm_ims_remove,
|
|
||||||
.ims_register = xmm_ims_register,
|
|
||||||
.ims_unregister = xmm_ims_unregister,
|
|
||||||
.registration_status = xmm_ims_registration_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
void xmm_ims_init(void)
|
|
||||||
{
|
|
||||||
ofono_ims_driver_register(&driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void xmm_ims_exit(void)
|
|
||||||
{
|
|
||||||
ofono_ims_driver_unregister(&driver);
|
|
||||||
}
|
|
||||||
@@ -36,7 +36,6 @@
|
|||||||
static int xmm7modem_init(void)
|
static int xmm7modem_init(void)
|
||||||
{
|
{
|
||||||
xmm_radio_settings_init();
|
xmm_radio_settings_init();
|
||||||
xmm_ims_init();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -44,7 +43,6 @@ static int xmm7modem_init(void)
|
|||||||
static void xmm7modem_exit(void)
|
static void xmm7modem_exit(void)
|
||||||
{
|
{
|
||||||
xmm_radio_settings_exit();
|
xmm_radio_settings_exit();
|
||||||
xmm_ims_exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OFONO_PLUGIN_DEFINE(xmm7modem, "Intel xmm7xxx series modem driver",
|
OFONO_PLUGIN_DEFINE(xmm7modem, "Intel xmm7xxx series modem driver",
|
||||||
|
|||||||
@@ -25,6 +25,3 @@
|
|||||||
|
|
||||||
extern void xmm_radio_settings_init(void);
|
extern void xmm_radio_settings_init(void);
|
||||||
extern void xmm_radio_settings_exit(void);
|
extern void xmm_radio_settings_exit(void);
|
||||||
|
|
||||||
extern void xmm_ims_init(void);
|
|
||||||
extern void xmm_ims_exit(void);
|
|
||||||
|
|||||||
@@ -59,16 +59,12 @@ extern "C" {
|
|||||||
#define OFONO_LOCATION_REPORTING_INTERFACE OFONO_SERVICE ".LocationReporting"
|
#define OFONO_LOCATION_REPORTING_INTERFACE OFONO_SERVICE ".LocationReporting"
|
||||||
#define OFONO_GNSS_INTERFACE "org.ofono.AssistedSatelliteNavigation"
|
#define OFONO_GNSS_INTERFACE "org.ofono.AssistedSatelliteNavigation"
|
||||||
#define OFONO_GNSS_POSR_AGENT_INTERFACE "org.ofono.PositioningRequestAgent"
|
#define OFONO_GNSS_POSR_AGENT_INTERFACE "org.ofono.PositioningRequestAgent"
|
||||||
#define OFONO_USIM_APPLICATION_INTERFACE "org.ofono.USimApplication"
|
|
||||||
#define OFONO_ISIM_APPLICATION_INTERFACE "org.ofono.ISimApplication"
|
|
||||||
#define OFONO_SIM_AUTHENTICATION_INTERFACE "org.ofono.SimAuthentication"
|
|
||||||
#define OFONO_HANDSFREE_INTERFACE OFONO_SERVICE ".Handsfree"
|
#define OFONO_HANDSFREE_INTERFACE OFONO_SERVICE ".Handsfree"
|
||||||
#define OFONO_NETWORK_TIME_INTERFACE OFONO_SERVICE ".NetworkTime"
|
#define OFONO_NETWORK_TIME_INTERFACE OFONO_SERVICE ".NetworkTime"
|
||||||
#define OFONO_SIRI_INTERFACE OFONO_SERVICE ".Siri"
|
#define OFONO_SIRI_INTERFACE OFONO_SERVICE ".Siri"
|
||||||
#define OFONO_NETMON_INTERFACE OFONO_SERVICE ".NetworkMonitor"
|
#define OFONO_NETMON_INTERFACE OFONO_SERVICE ".NetworkMonitor"
|
||||||
#define OFONO_NETMON_AGENT_INTERFACE OFONO_SERVICE ".NetworkMonitorAgent"
|
#define OFONO_NETMON_AGENT_INTERFACE OFONO_SERVICE ".NetworkMonitorAgent"
|
||||||
#define OFONO_LTE_INTERFACE OFONO_SERVICE ".LongTermEvolution"
|
#define OFONO_LTE_INTERFACE OFONO_SERVICE ".LongTermEvolution"
|
||||||
#define OFONO_IMS_INTERFACE OFONO_SERVICE ".IpMultimediaSystem"
|
|
||||||
|
|
||||||
/* CDMA Interfaces */
|
/* CDMA Interfaces */
|
||||||
#define OFONO_CDMA_VOICECALL_MANAGER_INTERFACE "org.ofono.cdma.VoiceCallManager"
|
#define OFONO_CDMA_VOICECALL_MANAGER_INTERFACE "org.ofono.cdma.VoiceCallManager"
|
||||||
|
|||||||
@@ -63,8 +63,6 @@ void ofono_devinfo_remove(struct ofono_devinfo *info);
|
|||||||
void ofono_devinfo_set_data(struct ofono_devinfo *info, void *data);
|
void ofono_devinfo_set_data(struct ofono_devinfo *info, void *data);
|
||||||
void *ofono_devinfo_get_data(struct ofono_devinfo *info);
|
void *ofono_devinfo_get_data(struct ofono_devinfo *info);
|
||||||
|
|
||||||
struct ofono_modem *ofono_devinfo_get_modem(struct ofono_devinfo *info);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -122,8 +122,6 @@ void ofono_gprs_context_set_ipv4_address(struct ofono_gprs_context *gc,
|
|||||||
ofono_bool_t static_ip);
|
ofono_bool_t static_ip);
|
||||||
void ofono_gprs_context_set_ipv4_netmask(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_set_ipv4_netmask(struct ofono_gprs_context *gc,
|
||||||
const char *netmask);
|
const char *netmask);
|
||||||
void ofono_gprs_context_set_ipv4_prefix_length(struct ofono_gprs_context *gc,
|
|
||||||
unsigned int prefix);
|
|
||||||
void ofono_gprs_context_set_ipv4_gateway(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_set_ipv4_gateway(struct ofono_gprs_context *gc,
|
||||||
const char *gateway);
|
const char *gateway);
|
||||||
void ofono_gprs_context_set_ipv4_dns_servers(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_set_ipv4_dns_servers(struct ofono_gprs_context *gc,
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __OFONO_IMS_H
|
|
||||||
#define __OFONO_IMS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ofono/types.h>
|
|
||||||
|
|
||||||
struct ofono_ims;
|
|
||||||
|
|
||||||
typedef void (*ofono_ims_register_cb_t)(const struct ofono_error *error,
|
|
||||||
void *data);
|
|
||||||
typedef void (*ofono_ims_status_cb_t)(const struct ofono_error *error,
|
|
||||||
int reg_info, int ext_info,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
struct ofono_ims_driver {
|
|
||||||
const char *name;
|
|
||||||
int (*probe)(struct ofono_ims *ims, void *data);
|
|
||||||
void (*remove)(struct ofono_ims *ims);
|
|
||||||
void (*ims_register)(struct ofono_ims *ims,
|
|
||||||
ofono_ims_register_cb_t cb, void *data);
|
|
||||||
void (*ims_unregister)(struct ofono_ims *ims,
|
|
||||||
ofono_ims_register_cb_t cb, void *data);
|
|
||||||
void (*registration_status)(struct ofono_ims *ims,
|
|
||||||
ofono_ims_status_cb_t cb, void *data);
|
|
||||||
};
|
|
||||||
|
|
||||||
void ofono_ims_status_notify(struct ofono_ims *ims, int reg_info,
|
|
||||||
int ext_info);
|
|
||||||
|
|
||||||
int ofono_ims_driver_register(const struct ofono_ims_driver *d);
|
|
||||||
void ofono_ims_driver_unregister(const struct ofono_ims_driver *d);
|
|
||||||
|
|
||||||
struct ofono_ims *ofono_ims_create(struct ofono_modem *modem,
|
|
||||||
const char *driver, void *data);
|
|
||||||
|
|
||||||
void ofono_ims_register(struct ofono_ims *ims);
|
|
||||||
void ofono_ims_remove(struct ofono_ims *ims);
|
|
||||||
|
|
||||||
void ofono_ims_set_data(struct ofono_ims *ims, void *data);
|
|
||||||
void *ofono_ims_get_data(const struct ofono_ims *ims);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -84,205 +84,190 @@ enum ril_status {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* RIL Request Messages, ofono -> rild */
|
/* RIL Request Messages, ofono -> rild */
|
||||||
enum ril_request {
|
#define RIL_REQUEST_GET_SIM_STATUS 1
|
||||||
RIL_REQUEST_GET_SIM_STATUS = 1,
|
#define RIL_REQUEST_ENTER_SIM_PIN 2
|
||||||
RIL_REQUEST_ENTER_SIM_PIN = 2,
|
#define RIL_REQUEST_ENTER_SIM_PUK 3
|
||||||
RIL_REQUEST_ENTER_SIM_PUK = 3,
|
#define RIL_REQUEST_ENTER_SIM_PIN2 4
|
||||||
RIL_REQUEST_ENTER_SIM_PIN2 = 4,
|
#define RIL_REQUEST_ENTER_SIM_PUK2 5
|
||||||
RIL_REQUEST_ENTER_SIM_PUK2 = 5,
|
#define RIL_REQUEST_CHANGE_SIM_PIN 6
|
||||||
RIL_REQUEST_CHANGE_SIM_PIN = 6,
|
#define RIL_REQUEST_CHANGE_SIM_PIN2 7
|
||||||
RIL_REQUEST_CHANGE_SIM_PIN2 = 7,
|
#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8
|
||||||
RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION = 8,
|
#define RIL_REQUEST_GET_CURRENT_CALLS 9
|
||||||
RIL_REQUEST_GET_CURRENT_CALLS = 9,
|
#define RIL_REQUEST_DIAL 10
|
||||||
RIL_REQUEST_DIAL = 10,
|
#define RIL_REQUEST_GET_IMSI 11
|
||||||
RIL_REQUEST_GET_IMSI = 11,
|
#define RIL_REQUEST_HANGUP 12
|
||||||
RIL_REQUEST_HANGUP = 12,
|
#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13
|
||||||
RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND = 13,
|
#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14
|
||||||
RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND = 14,
|
#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15
|
||||||
RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE = 15,
|
#define RIL_REQUEST_CONFERENCE 16
|
||||||
RIL_REQUEST_CONFERENCE = 16,
|
#define RIL_REQUEST_UDUB 17
|
||||||
RIL_REQUEST_UDUB = 17,
|
#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18
|
||||||
RIL_REQUEST_LAST_CALL_FAIL_CAUSE = 18,
|
#define RIL_REQUEST_SIGNAL_STRENGTH 19
|
||||||
RIL_REQUEST_SIGNAL_STRENGTH = 19,
|
#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20
|
||||||
RIL_REQUEST_VOICE_REGISTRATION_STATE = 20,
|
#define RIL_REQUEST_DATA_REGISTRATION_STATE 21
|
||||||
RIL_REQUEST_DATA_REGISTRATION_STATE = 21,
|
#define RIL_REQUEST_OPERATOR 22
|
||||||
RIL_REQUEST_OPERATOR = 22,
|
#define RIL_REQUEST_RADIO_POWER 23
|
||||||
RIL_REQUEST_RADIO_POWER = 23,
|
#define RIL_REQUEST_DTMF 24
|
||||||
RIL_REQUEST_DTMF = 24,
|
#define RIL_REQUEST_SEND_SMS 25
|
||||||
RIL_REQUEST_SEND_SMS = 25,
|
#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26
|
||||||
RIL_REQUEST_SEND_SMS_EXPECT_MORE = 26,
|
#define RIL_REQUEST_SETUP_DATA_CALL 27
|
||||||
RIL_REQUEST_SETUP_DATA_CALL = 27,
|
#define RIL_REQUEST_SIM_IO 28
|
||||||
RIL_REQUEST_SIM_IO = 28,
|
#define RIL_REQUEST_SEND_USSD 29
|
||||||
RIL_REQUEST_SEND_USSD = 29,
|
#define RIL_REQUEST_CANCEL_USSD 30
|
||||||
RIL_REQUEST_CANCEL_USSD = 30,
|
#define RIL_REQUEST_GET_CLIR 31
|
||||||
RIL_REQUEST_GET_CLIR = 31,
|
#define RIL_REQUEST_SET_CLIR 32
|
||||||
RIL_REQUEST_SET_CLIR = 32,
|
#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33
|
||||||
RIL_REQUEST_QUERY_CALL_FORWARD_STATUS = 33,
|
#define RIL_REQUEST_SET_CALL_FORWARD 34
|
||||||
RIL_REQUEST_SET_CALL_FORWARD = 34,
|
#define RIL_REQUEST_QUERY_CALL_WAITING 35
|
||||||
RIL_REQUEST_QUERY_CALL_WAITING = 35,
|
#define RIL_REQUEST_SET_CALL_WAITING 36
|
||||||
RIL_REQUEST_SET_CALL_WAITING = 36,
|
#define RIL_REQUEST_SMS_ACKNOWLEDGE 37
|
||||||
RIL_REQUEST_SMS_ACKNOWLEDGE = 37,
|
#define RIL_REQUEST_GET_IMEI 38
|
||||||
RIL_REQUEST_GET_IMEI = 38,
|
#define RIL_REQUEST_GET_IMEISV 39
|
||||||
RIL_REQUEST_GET_IMEISV = 39,
|
#define RIL_REQUEST_ANSWER 40
|
||||||
RIL_REQUEST_ANSWER = 40,
|
#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41
|
||||||
RIL_REQUEST_DEACTIVATE_DATA_CALL = 41,
|
#define RIL_REQUEST_QUERY_FACILITY_LOCK 42
|
||||||
RIL_REQUEST_QUERY_FACILITY_LOCK = 42,
|
#define RIL_REQUEST_SET_FACILITY_LOCK 43
|
||||||
RIL_REQUEST_SET_FACILITY_LOCK = 43,
|
#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44
|
||||||
RIL_REQUEST_CHANGE_BARRING_PASSWORD = 44,
|
#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45
|
||||||
RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE = 45,
|
#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46
|
||||||
RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC = 46,
|
#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47
|
||||||
RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL = 47,
|
#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48
|
||||||
RIL_REQUEST_QUERY_AVAILABLE_NETWORKS = 48,
|
#define RIL_REQUEST_DTMF_START 49
|
||||||
RIL_REQUEST_DTMF_START = 49,
|
#define RIL_REQUEST_DTMF_STOP 50
|
||||||
RIL_REQUEST_DTMF_STOP = 50,
|
#define RIL_REQUEST_BASEBAND_VERSION 51
|
||||||
RIL_REQUEST_BASEBAND_VERSION = 51,
|
#define RIL_REQUEST_SEPARATE_CONNECTION 52
|
||||||
RIL_REQUEST_SEPARATE_CONNECTION = 52,
|
#define RIL_REQUEST_SET_MUTE 53
|
||||||
RIL_REQUEST_SET_MUTE = 53,
|
#define RIL_REQUEST_GET_MUTE 54
|
||||||
RIL_REQUEST_GET_MUTE = 54,
|
#define RIL_REQUEST_QUERY_CLIP 55
|
||||||
RIL_REQUEST_QUERY_CLIP = 55,
|
#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56
|
||||||
RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE = 56,
|
#define RIL_REQUEST_DATA_CALL_LIST 57
|
||||||
RIL_REQUEST_DATA_CALL_LIST = 57,
|
#define RIL_REQUEST_RESET_RADIO 58
|
||||||
RIL_REQUEST_RESET_RADIO = 58,
|
#define RIL_REQUEST_OEM_HOOK_RAW 59
|
||||||
RIL_REQUEST_OEM_HOOK_RAW = 59,
|
#define RIL_REQUEST_OEM_HOOK_STRINGS 60
|
||||||
RIL_REQUEST_OEM_HOOK_STRINGS = 60,
|
#define RIL_REQUEST_SCREEN_STATE 61
|
||||||
RIL_REQUEST_SCREEN_STATE = 61,
|
#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62
|
||||||
RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION = 62,
|
#define RIL_REQUEST_WRITE_SMS_TO_SIM 63
|
||||||
RIL_REQUEST_WRITE_SMS_TO_SIM = 63,
|
#define RIL_REQUEST_DELETE_SMS_ON_SIM 64
|
||||||
RIL_REQUEST_DELETE_SMS_ON_SIM = 64,
|
#define RIL_REQUEST_SET_BAND_MODE 65
|
||||||
RIL_REQUEST_SET_BAND_MODE = 65,
|
#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66
|
||||||
RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE = 66,
|
#define RIL_REQUEST_STK_GET_PROFILE 67
|
||||||
RIL_REQUEST_STK_GET_PROFILE = 67,
|
#define RIL_REQUEST_STK_SET_PROFILE 68
|
||||||
RIL_REQUEST_STK_SET_PROFILE = 68,
|
#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69
|
||||||
RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND = 69,
|
#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70
|
||||||
RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE = 70,
|
#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71
|
||||||
RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM = 71,
|
#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72
|
||||||
RIL_REQUEST_EXPLICIT_CALL_TRANSFER = 72,
|
#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73
|
||||||
RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE = 73,
|
#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74
|
||||||
RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE = 74,
|
#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75
|
||||||
RIL_REQUEST_GET_NEIGHBORING_CELL_IDS = 75,
|
#define RIL_REQUEST_SET_LOCATION_UPDATES 76
|
||||||
RIL_REQUEST_SET_LOCATION_UPDATES = 76,
|
#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77
|
||||||
RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE = 77,
|
#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78
|
||||||
RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE = 78,
|
#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79
|
||||||
RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE = 79,
|
#define RIL_REQUEST_SET_TTY_MODE 80
|
||||||
RIL_REQUEST_SET_TTY_MODE = 80,
|
#define RIL_REQUEST_QUERY_TTY_MODE 81
|
||||||
RIL_REQUEST_QUERY_TTY_MODE = 81,
|
#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82
|
||||||
RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE = 82,
|
#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83
|
||||||
RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE = 83,
|
#define RIL_REQUEST_CDMA_FLASH 84
|
||||||
RIL_REQUEST_CDMA_FLASH = 84,
|
#define RIL_REQUEST_CDMA_BURST_DTMF 85
|
||||||
RIL_REQUEST_CDMA_BURST_DTMF = 85,
|
#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86
|
||||||
RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY = 86,
|
#define RIL_REQUEST_CDMA_SEND_SMS 87
|
||||||
RIL_REQUEST_CDMA_SEND_SMS = 87,
|
#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88
|
||||||
RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE = 88,
|
#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89
|
||||||
RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG = 89,
|
#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90
|
||||||
RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG = 90,
|
#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91
|
||||||
RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION = 91,
|
#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92
|
||||||
RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG = 92,
|
#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93
|
||||||
RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG = 93,
|
#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94
|
||||||
RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION = 94,
|
#define RIL_REQUEST_CDMA_SUBSCRIPTION 95
|
||||||
RIL_REQUEST_CDMA_SUBSCRIPTION = 95,
|
#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96
|
||||||
RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM = 96,
|
#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97
|
||||||
RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM = 97,
|
#define RIL_REQUEST_DEVICE_IDENTITY 98
|
||||||
RIL_REQUEST_DEVICE_IDENTITY = 98,
|
#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99
|
||||||
RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE = 99,
|
#define RIL_REQUEST_GET_SMSC_ADDRESS 100
|
||||||
RIL_REQUEST_GET_SMSC_ADDRESS = 100,
|
#define RIL_REQUEST_SET_SMSC_ADDRESS 101
|
||||||
RIL_REQUEST_SET_SMSC_ADDRESS = 101,
|
#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102
|
||||||
RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102,
|
#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103
|
||||||
RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103,
|
#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104
|
||||||
RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104,
|
#define RIL_REQUEST_ISIM_AUTHENTICATION 105
|
||||||
RIL_REQUEST_ISIM_AUTHENTICATION = 105,
|
#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106
|
||||||
RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106,
|
#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107
|
||||||
RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107,
|
#define RIL_REQUEST_VOICE_RADIO_TECH 108
|
||||||
RIL_REQUEST_VOICE_RADIO_TECH = 108,
|
#define RIL_REQUEST_GET_CELL_INFO_LIST 109
|
||||||
RIL_REQUEST_GET_CELL_INFO_LIST = 109,
|
#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110
|
||||||
RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE = 110,
|
#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111
|
||||||
RIL_REQUEST_SET_INITIAL_ATTACH_APN = 111,
|
#define RIL_REQUEST_IMS_REGISTRATION_STATE 112
|
||||||
RIL_REQUEST_IMS_REGISTRATION_STATE = 112,
|
#define RIL_REQUEST_IMS_SEND_SMS 113
|
||||||
RIL_REQUEST_IMS_SEND_SMS = 113,
|
#define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114
|
||||||
RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC = 114,
|
#define RIL_REQUEST_SIM_OPEN_CHANNEL 115
|
||||||
RIL_REQUEST_SIM_OPEN_CHANNEL = 115,
|
#define RIL_REQUEST_SIM_CLOSE_CHANNEL 116
|
||||||
RIL_REQUEST_SIM_CLOSE_CHANNEL = 116,
|
#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117
|
||||||
RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL = 117,
|
#define RIL_REQUEST_NV_READ_ITEM 118
|
||||||
RIL_REQUEST_NV_READ_ITEM = 118,
|
#define RIL_REQUEST_NV_WRITE_ITEM 119
|
||||||
RIL_REQUEST_NV_WRITE_ITEM = 119,
|
#define RIL_REQUEST_NV_WRITE_CDMA_PRL 120
|
||||||
RIL_REQUEST_NV_WRITE_CDMA_PRL = 120,
|
#define RIL_REQUEST_NV_RESET_CONFIG 121
|
||||||
RIL_REQUEST_NV_RESET_CONFIG = 121,
|
/* SET_UICC_SUBSCRIPTION was 115 in v9 and 122 in v10 and later */
|
||||||
/* SET_UICC_SUBSCRIPTION was 115 in v9 and 122 in v10 and later */
|
#define RIL_REQUEST_V9_SET_UICC_SUBSCRIPTION 115
|
||||||
RIL_REQUEST_V9_SET_UICC_SUBSCRIPTION = 115,
|
#define RIL_REQUEST_SET_UICC_SUBSCRIPTION 122
|
||||||
RIL_REQUEST_SET_UICC_SUBSCRIPTION = 122,
|
#define RIL_REQUEST_ALLOW_DATA 123
|
||||||
RIL_REQUEST_ALLOW_DATA = 123,
|
#define RIL_REQUEST_GET_HARDWARE_CONFIG 124
|
||||||
RIL_REQUEST_GET_HARDWARE_CONFIG = 124,
|
#define RIL_REQUEST_SIM_AUTHENTICATION 125
|
||||||
RIL_REQUEST_SIM_AUTHENTICATION = 125,
|
#define RIL_REQUEST_GET_DC_RT_INFO 126
|
||||||
RIL_REQUEST_GET_DC_RT_INFO = 126,
|
#define RIL_REQUEST_SET_DC_RT_INFO_RATE 127
|
||||||
RIL_REQUEST_SET_DC_RT_INFO_RATE = 127,
|
#define RIL_REQUEST_SET_DATA_PROFILE 128
|
||||||
RIL_REQUEST_SET_DATA_PROFILE = 128,
|
#define RIL_REQUEST_SHUTDOWN 129
|
||||||
RIL_REQUEST_SHUTDOWN = 129,
|
#define RIL_REQUEST_GET_RADIO_CAPABILITY 130
|
||||||
RIL_REQUEST_GET_RADIO_CAPABILITY = 130,
|
#define RIL_REQUEST_SET_RADIO_CAPABILITY 131
|
||||||
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 */
|
/* RIL Unsolicited Messages, rild -> ofono */
|
||||||
enum ril_unsol {
|
#define RIL_UNSOL_RESPONSE_BASE 1000
|
||||||
RIL_UNSOL_RESPONSE_BASE = 1000,
|
#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000
|
||||||
RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000,
|
#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001
|
||||||
RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001,
|
#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002
|
||||||
RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002,
|
#define RIL_UNSOL_RESPONSE_NEW_SMS 1003
|
||||||
RIL_UNSOL_RESPONSE_NEW_SMS = 1003,
|
#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004
|
||||||
RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004,
|
#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005
|
||||||
RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005,
|
#define RIL_UNSOL_ON_USSD 1006
|
||||||
RIL_UNSOL_ON_USSD = 1006,
|
#define RIL_UNSOL_ON_USSD_REQUEST 1007
|
||||||
RIL_UNSOL_ON_USSD_REQUEST = 1007,
|
#define RIL_UNSOL_NITZ_TIME_RECEIVED 1008
|
||||||
RIL_UNSOL_NITZ_TIME_RECEIVED = 1008,
|
#define RIL_UNSOL_SIGNAL_STRENGTH 1009
|
||||||
RIL_UNSOL_SIGNAL_STRENGTH = 1009,
|
#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010
|
||||||
RIL_UNSOL_DATA_CALL_LIST_CHANGED = 1010,
|
#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011
|
||||||
RIL_UNSOL_SUPP_SVC_NOTIFICATION = 1011,
|
#define RIL_UNSOL_STK_SESSION_END 1012
|
||||||
RIL_UNSOL_STK_SESSION_END = 1012,
|
#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013
|
||||||
RIL_UNSOL_STK_PROACTIVE_COMMAND = 1013,
|
#define RIL_UNSOL_STK_EVENT_NOTIFY 1014
|
||||||
RIL_UNSOL_STK_EVENT_NOTIFY = 1014,
|
#define RIL_UNSOL_STK_CALL_SETUP 1015
|
||||||
RIL_UNSOL_STK_CALL_SETUP = 1015,
|
#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016
|
||||||
RIL_UNSOL_SIM_SMS_STORAGE_FULL = 1016,
|
#define RIL_UNSOL_SIM_REFRESH 1017
|
||||||
RIL_UNSOL_SIM_REFRESH = 1017,
|
#define RIL_UNSOL_CALL_RING 1018
|
||||||
RIL_UNSOL_CALL_RING = 1018,
|
#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019
|
||||||
RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED = 1019,
|
#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020
|
||||||
RIL_UNSOL_RESPONSE_CDMA_NEW_SMS = 1020,
|
#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021
|
||||||
RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS = 1021,
|
#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022
|
||||||
RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL = 1022,
|
#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023
|
||||||
RIL_UNSOL_RESTRICTED_STATE_CHANGED = 1023,
|
#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024
|
||||||
RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE = 1024,
|
#define RIL_UNSOL_CDMA_CALL_WAITING 1025
|
||||||
RIL_UNSOL_CDMA_CALL_WAITING = 1025,
|
#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026
|
||||||
RIL_UNSOL_CDMA_OTA_PROVISION_STATUS = 1026,
|
#define RIL_UNSOL_CDMA_INFO_REC 1027
|
||||||
RIL_UNSOL_CDMA_INFO_REC = 1027,
|
#define RIL_UNSOL_OEM_HOOK_RAW 1028
|
||||||
RIL_UNSOL_OEM_HOOK_RAW = 1028,
|
#define RIL_UNSOL_RINGBACK_TONE 1029
|
||||||
RIL_UNSOL_RINGBACK_TONE = 1029,
|
#define RIL_UNSOL_RESEND_INCALL_MUTE 1030
|
||||||
RIL_UNSOL_RESEND_INCALL_MUTE = 1030,
|
#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031
|
||||||
RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1031,
|
#define RIL_UNSOL_CDMA_PRL_CHANGED 1032
|
||||||
RIL_UNSOL_CDMA_PRL_CHANGED = 1032,
|
#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033
|
||||||
RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE = 1033,
|
#define RIL_UNSOL_RIL_CONNECTED 1034
|
||||||
RIL_UNSOL_RIL_CONNECTED = 1034,
|
#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035
|
||||||
RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035,
|
#define RIL_UNSOL_CELL_INFO_LIST 1036
|
||||||
RIL_UNSOL_CELL_INFO_LIST = 1036,
|
#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037
|
||||||
RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1037,
|
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038
|
||||||
RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED = 1038,
|
#define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039
|
||||||
RIL_UNSOL_SRVCC_STATE_NOTIFY = 1039,
|
#define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040
|
||||||
RIL_UNSOL_HARDWARE_CONFIG_CHANGED = 1040,
|
#define RIL_UNSOL_DC_RT_INFO_CHANGED 1041
|
||||||
RIL_UNSOL_DC_RT_INFO_CHANGED = 1041,
|
#define RIL_UNSOL_RADIO_CAPABILITY 1042
|
||||||
RIL_UNSOL_RADIO_CAPABILITY = 1042,
|
#define RIL_UNSOL_ON_SS 1043
|
||||||
RIL_UNSOL_ON_SS = 1043,
|
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044
|
||||||
RIL_UNSOL_STK_CC_ALPHA_NOTIFY = 1044
|
|
||||||
};
|
/* A special request, ofono -> rild */
|
||||||
|
#define RIL_RESPONSE_ACKNOWLEDGEMENT 800
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017-2019 Jolla Ltd.
|
* Copyright (C) 2017-2018 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -88,7 +88,6 @@ struct sailfish_cell_info_proc {
|
|||||||
gulong (*add_cells_changed_handler)(struct sailfish_cell_info *info,
|
gulong (*add_cells_changed_handler)(struct sailfish_cell_info *info,
|
||||||
sailfish_cell_info_cb_t cb, void *arg);
|
sailfish_cell_info_cb_t cb, void *arg);
|
||||||
void (*remove_handler)(struct sailfish_cell_info *info, gulong id);
|
void (*remove_handler)(struct sailfish_cell_info *info, gulong id);
|
||||||
void (*set_update_interval)(struct sailfish_cell_info *info, int ms);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
@@ -105,8 +104,6 @@ gulong sailfish_cell_info_add_cells_changed_handler
|
|||||||
sailfish_cell_info_cb_t cb, void *arg);
|
sailfish_cell_info_cb_t cb, void *arg);
|
||||||
void sailfish_cell_info_remove_handler(struct sailfish_cell_info *info,
|
void sailfish_cell_info_remove_handler(struct sailfish_cell_info *info,
|
||||||
gulong id);
|
gulong id);
|
||||||
void sailfish_cell_info_set_update_interval(struct sailfish_cell_info *info,
|
|
||||||
int ms);
|
|
||||||
|
|
||||||
#endif /* SAILFISH_CELINFO_H */
|
#endif /* SAILFISH_CELINFO_H */
|
||||||
|
|
||||||
@@ -26,15 +26,37 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <ofono/types.h>
|
#include <ofono/types.h>
|
||||||
|
|
||||||
struct ofono_sim_auth;
|
struct ofono_sim_auth;
|
||||||
|
|
||||||
struct ofono_sim_auth *ofono_sim_auth_create(struct ofono_modem *modem);
|
typedef void (*ofono_sim_list_apps_cb_t)(const struct ofono_error *error,
|
||||||
|
const unsigned char *dataobj,
|
||||||
|
int len, void *data);
|
||||||
|
|
||||||
|
struct ofono_sim_auth_driver {
|
||||||
|
const char *name;
|
||||||
|
int (*probe)(struct ofono_sim_auth *sa, unsigned int vendor,
|
||||||
|
void *data);
|
||||||
|
void (*remove)(struct ofono_sim_auth *sa);
|
||||||
|
|
||||||
|
void (*list_apps)(struct ofono_sim_auth *sa,
|
||||||
|
ofono_sim_list_apps_cb_t cb, void *data);
|
||||||
|
};
|
||||||
|
|
||||||
|
int ofono_sim_auth_driver_register(const struct ofono_sim_auth_driver *d);
|
||||||
|
void ofono_sim_auth_driver_unregister(const struct ofono_sim_auth_driver *d);
|
||||||
|
|
||||||
|
struct ofono_sim_auth *ofono_sim_auth_create(struct ofono_modem *modem,
|
||||||
|
unsigned int vendor,
|
||||||
|
const char *driver, void *data);
|
||||||
|
|
||||||
|
void ofono_sim_auth_register(struct ofono_sim_auth *sa);
|
||||||
void ofono_sim_auth_remove(struct ofono_sim_auth *sa);
|
void ofono_sim_auth_remove(struct ofono_sim_auth *sa);
|
||||||
|
|
||||||
|
void ofono_sim_auth_set_data(struct ofono_sim_auth *sa, void *data);
|
||||||
|
void *ofono_sim_auth_get_data(struct ofono_sim_auth *sa);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -126,17 +126,6 @@ typedef void (*ofono_sim_lock_unlock_cb_t)(const struct ofono_error *error,
|
|||||||
typedef void (*ofono_query_facility_lock_cb_t)(const struct ofono_error *error,
|
typedef void (*ofono_query_facility_lock_cb_t)(const struct ofono_error *error,
|
||||||
ofono_bool_t status, void *data);
|
ofono_bool_t status, void *data);
|
||||||
|
|
||||||
typedef void (*ofono_sim_list_apps_cb_t)(const struct ofono_error *error,
|
|
||||||
const unsigned char *dataobj,
|
|
||||||
int len, void *data);
|
|
||||||
typedef void (*ofono_sim_open_channel_cb_t)(const struct ofono_error *error,
|
|
||||||
int session_id, void *data);
|
|
||||||
typedef void (*ofono_sim_close_channel_cb_t)(const struct ofono_error *error,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
typedef void (*ofono_sim_logical_access_cb_t)(const struct ofono_error *error,
|
|
||||||
const unsigned char *resp, unsigned int len, void *data);
|
|
||||||
|
|
||||||
struct ofono_sim_driver {
|
struct ofono_sim_driver {
|
||||||
const char *name;
|
const char *name;
|
||||||
int (*probe)(struct ofono_sim *sim, unsigned int vendor, void *data);
|
int (*probe)(struct ofono_sim *sim, unsigned int vendor, void *data);
|
||||||
@@ -189,27 +178,6 @@ struct ofono_sim_driver {
|
|||||||
void (*query_facility_lock)(struct ofono_sim *sim,
|
void (*query_facility_lock)(struct ofono_sim *sim,
|
||||||
enum ofono_sim_password_type lock,
|
enum ofono_sim_password_type lock,
|
||||||
ofono_query_facility_lock_cb_t cb, void *data);
|
ofono_query_facility_lock_cb_t cb, void *data);
|
||||||
void (*list_apps)(struct ofono_sim *sim,
|
|
||||||
ofono_sim_list_apps_cb_t cb, void *data);
|
|
||||||
void (*open_channel)(struct ofono_sim *sim, const unsigned char *aid,
|
|
||||||
ofono_sim_open_channel_cb_t cb, void *data);
|
|
||||||
void (*close_channel)(struct ofono_sim *sim, int session_id,
|
|
||||||
ofono_sim_close_channel_cb_t cb, void *data);
|
|
||||||
void (*session_read_binary)(struct ofono_sim *sim, int session,
|
|
||||||
int fileid, int start, int length,
|
|
||||||
const unsigned char *path, unsigned int path_len,
|
|
||||||
ofono_sim_read_cb_t cb, void *data);
|
|
||||||
void (*session_read_record)(struct ofono_sim *sim, int session_id,
|
|
||||||
int fileid, int record, int length,
|
|
||||||
const unsigned char *path, unsigned int path_len,
|
|
||||||
ofono_sim_read_cb_t cb, void *data);
|
|
||||||
void (*session_read_info)(struct ofono_sim *sim, int session_id,
|
|
||||||
int fileid, const unsigned char *path,
|
|
||||||
unsigned int path_len, ofono_sim_file_info_cb_t cb,
|
|
||||||
void *data);
|
|
||||||
void (*logical_access)(struct ofono_sim *sim, int session_id,
|
|
||||||
const unsigned char *pdu, unsigned int len,
|
|
||||||
ofono_sim_logical_access_cb_t cb, void *data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int ofono_sim_driver_register(const struct ofono_sim_driver *d);
|
int ofono_sim_driver_register(const struct ofono_sim_driver *d);
|
||||||
@@ -268,26 +236,9 @@ unsigned int ofono_sim_add_imsi_watch(struct ofono_sim *sim,
|
|||||||
|
|
||||||
void ofono_sim_remove_imsi_watch(struct ofono_sim *sim, unsigned int id);
|
void ofono_sim_remove_imsi_watch(struct ofono_sim *sim, unsigned int id);
|
||||||
|
|
||||||
/*
|
|
||||||
* It is assumed that when ofono_sim_inserted_notify is called, the SIM is
|
|
||||||
* ready to be queried for files that are always available even if SIM
|
|
||||||
* PIN has not been entered. This is EFiccid and a few others
|
|
||||||
*/
|
|
||||||
void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted);
|
void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted);
|
||||||
|
|
||||||
/*
|
|
||||||
* When the SIM PIN has been entered, many devices require some time to
|
|
||||||
* initialize the SIM and calls to CPIN? will return a SIM BUSY error. Or
|
|
||||||
* sometimes report ready but fail in any subsequent SIM requests. This is
|
|
||||||
* used to notify oFono core when the SIM / firmware is truly ready
|
|
||||||
*/
|
|
||||||
void ofono_sim_initialized_notify(struct ofono_sim *sim);
|
|
||||||
|
|
||||||
struct ofono_sim_context *ofono_sim_context_create(struct ofono_sim *sim);
|
struct ofono_sim_context *ofono_sim_context_create(struct ofono_sim *sim);
|
||||||
|
|
||||||
struct ofono_sim_context *ofono_sim_context_create_isim(
|
|
||||||
struct ofono_sim *sim);
|
|
||||||
|
|
||||||
void ofono_sim_context_free(struct ofono_sim_context *context);
|
void ofono_sim_context_free(struct ofono_sim_context *context);
|
||||||
|
|
||||||
/* This will queue an operation to read all available records with id from the
|
/* This will queue an operation to read all available records with id from the
|
||||||
@@ -334,10 +285,6 @@ unsigned int ofono_sim_add_file_watch(struct ofono_sim_context *context,
|
|||||||
void ofono_sim_remove_file_watch(struct ofono_sim_context *context,
|
void ofono_sim_remove_file_watch(struct ofono_sim_context *context,
|
||||||
unsigned int id);
|
unsigned int id);
|
||||||
|
|
||||||
int ofono_sim_logical_access(struct ofono_sim *sim, int session_id,
|
|
||||||
unsigned char *pdu, unsigned int len,
|
|
||||||
ofono_sim_logical_access_cb_t cb, void *data);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
* Copyright (C) 2014-2019 Jolla Ltd.
|
* Copyright (C) 2014 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -135,16 +135,6 @@ struct ofono_voicecall_driver {
|
|||||||
ofono_voicecall_cb_t cb, void *data);
|
ofono_voicecall_cb_t cb, void *data);
|
||||||
void (*send_tones)(struct ofono_voicecall *vc, const char *tones,
|
void (*send_tones)(struct ofono_voicecall *vc, const char *tones,
|
||||||
ofono_voicecall_cb_t cb, void *data);
|
ofono_voicecall_cb_t cb, void *data);
|
||||||
|
|
||||||
/* Dials the last number again, this handles the hfp profile last number
|
|
||||||
* dialing with the +BLDN AT command
|
|
||||||
*/
|
|
||||||
void (*dial_last)(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb,
|
|
||||||
void *data);
|
|
||||||
/* dials a number at a given memory location */
|
|
||||||
void (*dial_memory)(struct ofono_voicecall *vc,
|
|
||||||
unsigned int memory_location, ofono_voicecall_cb_t cb,
|
|
||||||
void *data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ofono_voicecall_en_list_notify(struct ofono_voicecall *vc,
|
void ofono_voicecall_en_list_notify(struct ofono_voicecall *vc,
|
||||||
|
|||||||
@@ -420,8 +420,7 @@ static void gemalto_pre_sim(struct ofono_modem *modem)
|
|||||||
|
|
||||||
ofono_devinfo_create(modem, 0, "atmodem", data->app);
|
ofono_devinfo_create(modem, 0, "atmodem", data->app);
|
||||||
ofono_location_reporting_create(modem, 0, "gemaltomodem", data->app);
|
ofono_location_reporting_create(modem, 0, "gemaltomodem", data->app);
|
||||||
sim = ofono_sim_create(modem, OFONO_VENDOR_CINTERION, "atmodem",
|
sim = ofono_sim_create(modem, 0, "atmodem", data->app);
|
||||||
data->app);
|
|
||||||
|
|
||||||
if (sim && data->have_sim == TRUE)
|
if (sim && data->have_sim == TRUE)
|
||||||
ofono_sim_inserted_notify(sim, TRUE);
|
ofono_sim_inserted_notify(sim, TRUE);
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
#include <ofono/ussd.h>
|
#include <ofono/ussd.h>
|
||||||
#include <ofono/gprs.h>
|
#include <ofono/gprs.h>
|
||||||
#include <ofono/gprs-context.h>
|
#include <ofono/gprs-context.h>
|
||||||
#include <ofono/lte.h>
|
|
||||||
#include <ofono/radio-settings.h>
|
#include <ofono/radio-settings.h>
|
||||||
#include <ofono/location-reporting.h>
|
#include <ofono/location-reporting.h>
|
||||||
#include <ofono/log.h>
|
#include <ofono/log.h>
|
||||||
@@ -255,15 +254,6 @@ error:
|
|||||||
shutdown_device(modem);
|
shutdown_device(modem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_shared_dms(void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user_data;
|
|
||||||
struct gobi_data *data = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
qmi_service_create_shared(data->device, QMI_SERVICE_DMS,
|
|
||||||
create_dms_cb, modem, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void discover_cb(uint8_t count, const struct qmi_version *list,
|
static void discover_cb(uint8_t count, const struct qmi_version *list,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
@@ -326,10 +316,8 @@ static void discover_cb(uint8_t count, const struct qmi_version *list,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qmi_device_is_sync_supported(data->device))
|
qmi_service_create_shared(data->device, QMI_SERVICE_DMS,
|
||||||
qmi_device_sync(data->device, create_shared_dms, modem);
|
create_dms_cb, modem, NULL);
|
||||||
else
|
|
||||||
create_shared_dms(modem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gobi_enable(struct ofono_modem *modem)
|
static int gobi_enable(struct ofono_modem *modem)
|
||||||
@@ -484,8 +472,6 @@ static void gobi_post_sim(struct ofono_modem *modem)
|
|||||||
|
|
||||||
DBG("%p", modem);
|
DBG("%p", modem);
|
||||||
|
|
||||||
ofono_lte_create(modem, "qmimodem", data->device);
|
|
||||||
|
|
||||||
if (data->features & GOBI_CAT)
|
if (data->features & GOBI_CAT)
|
||||||
ofono_stk_create(modem, 0, "qmimodem", data->device);
|
ofono_stk_create(modem, 0, "qmimodem", data->device);
|
||||||
else if (data->features & GOBI_CAT_OLD)
|
else if (data->features & GOBI_CAT_OLD)
|
||||||
|
|||||||
@@ -152,7 +152,10 @@ static void ifx_set_sim_state(struct ifx_data *data, int state)
|
|||||||
break;
|
break;
|
||||||
case 2: /* PIN verification not needed – Ready */
|
case 2: /* PIN verification not needed – Ready */
|
||||||
case 3: /* PIN verified – Ready */
|
case 3: /* PIN verified – Ready */
|
||||||
ofono_sim_initialized_notify(data->sim);
|
/*
|
||||||
|
* State 3 is handled in the SIM atom driver
|
||||||
|
* while for state 2 we should be waiting for state 7
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
case 10: /* SIM Reactivating */
|
case 10: /* SIM Reactivating */
|
||||||
case 11: /* SIM Reactivated */
|
case 11: /* SIM Reactivated */
|
||||||
|
|||||||
@@ -1,434 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* oFono - Open Source Telephony
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 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
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
|
||||||
#include <ofono/plugin.h>
|
|
||||||
#include <ofono/modem.h>
|
|
||||||
#include <ofono/log.h>
|
|
||||||
#include <ofono/devinfo.h>
|
|
||||||
#include <ofono/sim.h>
|
|
||||||
#include <ofono/netreg.h>
|
|
||||||
#include <ofono/sms.h>
|
|
||||||
#include <ofono/gprs.h>
|
|
||||||
#include <ofono/gprs-context.h>
|
|
||||||
|
|
||||||
#include <ell/ell.h>
|
|
||||||
|
|
||||||
#include <drivers/mbimmodem/mbim.h>
|
|
||||||
#include <drivers/mbimmodem/mbim-message.h>
|
|
||||||
#include <drivers/mbimmodem/mbim-desc.h>
|
|
||||||
#include <drivers/mbimmodem/util.h>
|
|
||||||
|
|
||||||
struct mbim_data {
|
|
||||||
struct mbim_device *device;
|
|
||||||
uint16_t max_segment;
|
|
||||||
uint8_t max_outstanding;
|
|
||||||
uint8_t max_sessions;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mbim_debug(const char *str, void *user_data)
|
|
||||||
{
|
|
||||||
const char *prefix = user_data;
|
|
||||||
|
|
||||||
ofono_info("%s%s", prefix, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_parse_descriptors(struct mbim_data *md, const char *file)
|
|
||||||
{
|
|
||||||
void *data;
|
|
||||||
size_t len;
|
|
||||||
const struct mbim_desc *desc = NULL;
|
|
||||||
const struct mbim_extended_desc *ext_desc = NULL;
|
|
||||||
|
|
||||||
data = l_file_get_contents(file, &len);
|
|
||||||
if (!data)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
if (!mbim_find_descriptors(data, len, &desc, &ext_desc)) {
|
|
||||||
l_free(data);
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc)
|
|
||||||
md->max_segment = L_LE16_TO_CPU(desc->wMaxControlMessage);
|
|
||||||
|
|
||||||
if (ext_desc)
|
|
||||||
md->max_outstanding = ext_desc->bMaxOutstandingCommandMessages;
|
|
||||||
|
|
||||||
l_free(data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_probe(struct ofono_modem *modem)
|
|
||||||
{
|
|
||||||
const char *descriptors;
|
|
||||||
struct mbim_data *data;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
descriptors = ofono_modem_get_string(modem, "DescriptorFile");
|
|
||||||
|
|
||||||
if (!descriptors)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
data = l_new(struct mbim_data, 1);
|
|
||||||
data->max_outstanding = 1;
|
|
||||||
|
|
||||||
err = mbim_parse_descriptors(data, descriptors);
|
|
||||||
if (err < 0) {
|
|
||||||
DBG("Warning, unable to load descriptors, setting defaults");
|
|
||||||
data->max_segment = 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG("MaxSegment: %d, MaxOutstanding: %d",
|
|
||||||
data->max_segment, data->max_outstanding);
|
|
||||||
|
|
||||||
ofono_modem_set_data(modem, data);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_remove(struct ofono_modem *modem)
|
|
||||||
{
|
|
||||||
struct mbim_data *data = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
mbim_device_unref(data->device);
|
|
||||||
|
|
||||||
ofono_modem_set_data(modem, NULL);
|
|
||||||
l_free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_radio_state_init_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user;
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
uint32_t hw_state;
|
|
||||||
uint32_t sw_state;
|
|
||||||
bool r;
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
r = mbim_message_get_arguments(message, "uu",
|
|
||||||
&hw_state, &sw_state);
|
|
||||||
if (!r)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* TODO: How to handle HwRadioState != 1 */
|
|
||||||
DBG("HwRadioState: %u, SwRadioState: %u", hw_state, sw_state);
|
|
||||||
ofono_modem_set_powered(modem, TRUE);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
mbim_device_shutdown(md->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_device_subscribe_list_set_cb(struct mbim_message *message,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user;
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_RADIO_STATE,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
|
|
||||||
mbim_message_set_arguments(message, "u", 0);
|
|
||||||
if (mbim_device_send(md->device, 0, message,
|
|
||||||
mbim_radio_state_init_cb, modem, NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
mbim_device_shutdown(md->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_device_caps_info_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user;
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
uint32_t device_type;
|
|
||||||
uint32_t cellular_class;
|
|
||||||
uint32_t voice_class;
|
|
||||||
uint32_t sim_class;
|
|
||||||
uint32_t data_class;
|
|
||||||
uint32_t sms_caps;
|
|
||||||
uint32_t control_caps;
|
|
||||||
uint32_t max_sessions;
|
|
||||||
char *custom_data_class;
|
|
||||||
char *device_id;
|
|
||||||
char *firmware_info;
|
|
||||||
char *hardware_info;
|
|
||||||
bool r;
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
r = mbim_message_get_arguments(message, "uuuuuuuussss",
|
|
||||||
&device_type, &cellular_class,
|
|
||||||
&voice_class, &sim_class, &data_class,
|
|
||||||
&sms_caps, &control_caps, &max_sessions,
|
|
||||||
&custom_data_class, &device_id,
|
|
||||||
&firmware_info, &hardware_info);
|
|
||||||
if (!r)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
md->max_sessions = max_sessions;
|
|
||||||
|
|
||||||
DBG("DeviceId: %s", device_id);
|
|
||||||
DBG("FirmwareInfo: %s", firmware_info);
|
|
||||||
DBG("HardwareInfo: %s", hardware_info);
|
|
||||||
|
|
||||||
ofono_modem_set_string(modem, "DeviceId", device_id);
|
|
||||||
ofono_modem_set_string(modem, "FirmwareInfo", firmware_info);
|
|
||||||
|
|
||||||
l_free(custom_data_class);
|
|
||||||
l_free(device_id);
|
|
||||||
l_free(firmware_info);
|
|
||||||
l_free(hardware_info);
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_DEVICE_SERVICE_SUBSCRIBE_LIST,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
|
|
||||||
mbim_message_set_arguments(message, "av", 2,
|
|
||||||
"16yuuuuuuu",
|
|
||||||
mbim_uuid_basic_connect, 6,
|
|
||||||
MBIM_CID_SUBSCRIBER_READY_STATUS,
|
|
||||||
MBIM_CID_RADIO_STATE,
|
|
||||||
MBIM_CID_REGISTER_STATE,
|
|
||||||
MBIM_CID_PACKET_SERVICE,
|
|
||||||
MBIM_CID_SIGNAL_STATE,
|
|
||||||
MBIM_CID_CONNECT,
|
|
||||||
"16yuuuu", mbim_uuid_sms, 3,
|
|
||||||
MBIM_CID_SMS_CONFIGURATION,
|
|
||||||
MBIM_CID_SMS_READ,
|
|
||||||
MBIM_CID_SMS_MESSAGE_STORE_STATUS);
|
|
||||||
|
|
||||||
if (mbim_device_send(md->device, 0, message,
|
|
||||||
mbim_device_subscribe_list_set_cb,
|
|
||||||
modem, NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
mbim_device_shutdown(md->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_device_closed(void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user_data;
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
mbim_device_unref(md->device);
|
|
||||||
md->device = NULL;
|
|
||||||
|
|
||||||
ofono_modem_set_powered(modem, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_device_ready(void *user_data)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user_data;
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
struct mbim_message *message =
|
|
||||||
mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
1, MBIM_COMMAND_TYPE_QUERY);
|
|
||||||
|
|
||||||
mbim_message_set_arguments(message, "");
|
|
||||||
mbim_device_send(md->device, 0, message,
|
|
||||||
mbim_device_caps_info_cb, modem, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_enable(struct ofono_modem *modem)
|
|
||||||
{
|
|
||||||
const char *device;
|
|
||||||
int fd;
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
device = ofono_modem_get_string(modem, "Device");
|
|
||||||
if (!device)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
DBG("%p", device);
|
|
||||||
fd = open(device, O_EXCL | O_NONBLOCK | O_RDWR);
|
|
||||||
if (fd < 0)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
md->device = mbim_device_new(fd, md->max_segment);
|
|
||||||
|
|
||||||
mbim_device_set_close_on_unref(md->device, true);
|
|
||||||
mbim_device_set_max_outstanding(md->device, md->max_outstanding);
|
|
||||||
mbim_device_set_ready_handler(md->device,
|
|
||||||
mbim_device_ready, modem, NULL);
|
|
||||||
mbim_device_set_disconnect_handler(md->device,
|
|
||||||
mbim_device_closed, modem, NULL);
|
|
||||||
mbim_device_set_debug(md->device, mbim_debug, "MBIM:", NULL);
|
|
||||||
|
|
||||||
return -EINPROGRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_radio_off_for_disable(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user;
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
mbim_device_shutdown(md->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mbim_disable(struct ofono_modem *modem)
|
|
||||||
{
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_RADIO_STATE,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "u", 0);
|
|
||||||
|
|
||||||
if (mbim_device_send(md->device, 0, message,
|
|
||||||
mbim_radio_off_for_disable, modem, NULL) > 0)
|
|
||||||
return -EINPROGRESS;
|
|
||||||
|
|
||||||
mbim_device_closed(modem);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_set_online_cb(struct mbim_message *message, void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbd = user;
|
|
||||||
ofono_modem_online_cb_t cb = cbd->cb;
|
|
||||||
|
|
||||||
if (mbim_message_get_error(message) != 0)
|
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
||||||
else
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_set_online(struct ofono_modem *modem, ofono_bool_t online,
|
|
||||||
ofono_modem_online_cb_t cb, void *user_data)
|
|
||||||
{
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
||||||
struct mbim_message *message;
|
|
||||||
|
|
||||||
DBG("%p %s", modem, online ? "online" : "offline");
|
|
||||||
|
|
||||||
message = mbim_message_new(mbim_uuid_basic_connect,
|
|
||||||
MBIM_CID_RADIO_STATE,
|
|
||||||
MBIM_COMMAND_TYPE_SET);
|
|
||||||
mbim_message_set_arguments(message, "u", online ? 1 : 0);
|
|
||||||
|
|
||||||
if (mbim_device_send(md->device, 0, message,
|
|
||||||
mbim_set_online_cb, cbd, l_free) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_free(cbd);
|
|
||||||
CALLBACK_WITH_FAILURE(cb, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_pre_sim(struct ofono_modem *modem)
|
|
||||||
{
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
ofono_devinfo_create(modem, 0, "mbim", NULL);
|
|
||||||
ofono_sim_create(modem, 0, "mbim", md->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_post_sim(struct ofono_modem *modem)
|
|
||||||
{
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
struct ofono_gprs *gprs;
|
|
||||||
struct ofono_gprs_context *gc;
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
ofono_sms_create(modem, 0, "mbim", md->device);
|
|
||||||
gprs = ofono_gprs_create(modem, 0, "mbim", md->device);
|
|
||||||
|
|
||||||
ofono_gprs_set_cid_range(gprs, 0, md->max_sessions);
|
|
||||||
|
|
||||||
gc = ofono_gprs_context_create(modem, 0, "mbim", md->device);
|
|
||||||
if (gc) {
|
|
||||||
ofono_gprs_context_set_type(gc,
|
|
||||||
OFONO_GPRS_CONTEXT_TYPE_INTERNET);
|
|
||||||
ofono_gprs_add_context(gprs, gc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_post_online(struct ofono_modem *modem)
|
|
||||||
{
|
|
||||||
struct mbim_data *md = ofono_modem_get_data(modem);
|
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
ofono_netreg_create(modem, 0, "mbim", md->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ofono_modem_driver mbim_driver = {
|
|
||||||
.name = "mbim",
|
|
||||||
.probe = mbim_probe,
|
|
||||||
.remove = mbim_remove,
|
|
||||||
.enable = mbim_enable,
|
|
||||||
.disable = mbim_disable,
|
|
||||||
.set_online = mbim_set_online,
|
|
||||||
.pre_sim = mbim_pre_sim,
|
|
||||||
.post_sim = mbim_post_sim,
|
|
||||||
.post_online = mbim_post_online,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int mbim_init(void)
|
|
||||||
{
|
|
||||||
return ofono_modem_driver_register(&mbim_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mbim_exit(void)
|
|
||||||
{
|
|
||||||
ofono_modem_driver_unregister(&mbim_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
OFONO_PLUGIN_DEFINE(mbim, "MBIM modem driver", VERSION,
|
|
||||||
OFONO_PLUGIN_PRIORITY_DEFAULT, mbim_init, mbim_exit)
|
|
||||||
@@ -47,7 +47,6 @@
|
|||||||
#include <ofono/radio-settings.h>
|
#include <ofono/radio-settings.h>
|
||||||
#include <ofono/log.h>
|
#include <ofono/log.h>
|
||||||
#include <ofono/location-reporting.h>
|
#include <ofono/location-reporting.h>
|
||||||
#include <ofono/sim-auth.h>
|
|
||||||
|
|
||||||
#include <drivers/atmodem/atutil.h>
|
#include <drivers/atmodem/atutil.h>
|
||||||
#include <drivers/atmodem/vendor.h>
|
#include <drivers/atmodem/vendor.h>
|
||||||
@@ -225,15 +224,6 @@ static void cfun_query(gboolean ok, GAtResult *result, gpointer user_data)
|
|||||||
cfun_enable(TRUE, NULL, modem);
|
cfun_enable(TRUE, NULL, modem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void epev_notify(GAtResult *result, gpointer user_data)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = user_data;
|
|
||||||
struct ofono_sim *sim = ofono_modem_get_sim(modem);
|
|
||||||
|
|
||||||
if (sim)
|
|
||||||
ofono_sim_initialized_notify(sim);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void emrdy_notifier(GAtResult *result, gpointer user_data)
|
static void emrdy_notifier(GAtResult *result, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = user_data;
|
struct ofono_modem *modem = user_data;
|
||||||
@@ -356,10 +346,6 @@ static int mbm_enable(struct ofono_modem *modem)
|
|||||||
g_at_chat_send(data->modem_port, "AT*EMRDY?", none_prefix,
|
g_at_chat_send(data->modem_port, "AT*EMRDY?", none_prefix,
|
||||||
emrdy_query, modem, NULL);
|
emrdy_query, modem, NULL);
|
||||||
|
|
||||||
g_at_chat_send(data->modem_port, "AT*EPEE=1", NULL, NULL, NULL, NULL);
|
|
||||||
g_at_chat_register(data->modem_port, "*EPEV", epev_notify,
|
|
||||||
FALSE, modem, NULL);
|
|
||||||
|
|
||||||
return -EINPROGRESS;
|
return -EINPROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,7 +438,6 @@ static void mbm_post_sim(struct ofono_modem *modem)
|
|||||||
ofono_radio_settings_create(modem, 0, "stemodem", data->modem_port);
|
ofono_radio_settings_create(modem, 0, "stemodem", data->modem_port);
|
||||||
|
|
||||||
ofono_sms_create(modem, 0, "atmodem", data->modem_port);
|
ofono_sms_create(modem, 0, "atmodem", data->modem_port);
|
||||||
ofono_sim_auth_create(modem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mbm_post_online(struct ofono_modem *modem)
|
static void mbm_post_online(struct ofono_modem *modem)
|
||||||
|
|||||||
@@ -143,6 +143,13 @@ static int file_exists(char const *filename)
|
|||||||
return stat(filename, &st) == 0;
|
return stat(filename, &st) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dir_exists(char const *filename)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
return stat(filename, &st) == 0 && S_ISDIR(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
static int file_write(char const *filename, char const *output)
|
static int file_write(char const *filename, char const *output)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -625,15 +632,74 @@ static void phonet_status_cb(GIsiModem *idx, enum GIsiPhonetLinkState state,
|
|||||||
|
|
||||||
static int gpio_probe_links(void)
|
static int gpio_probe_links(void)
|
||||||
{
|
{
|
||||||
|
char const *gpiodir = "/sys/class/gpio";
|
||||||
char const *cmtdir = "/dev/cmt";
|
char const *cmtdir = "/dev/cmt";
|
||||||
|
DIR *gpio;
|
||||||
|
struct dirent *d;
|
||||||
|
|
||||||
if (!file_exists(cmtdir)) {
|
if (file_exists(cmtdir)) {
|
||||||
DBG("%s: %s", cmtdir, strerror(errno));
|
DBG("Using %s", cmtdir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("Using %s: trying to make links to %s", gpiodir, cmtdir);
|
||||||
|
|
||||||
|
if (!dir_exists(cmtdir)) {
|
||||||
|
if (mkdir(cmtdir, 0755) == -1) {
|
||||||
|
DBG("%s: %s", cmtdir, strerror(errno));
|
||||||
|
return -(errno = ENODEV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio = opendir(gpiodir);
|
||||||
|
if (gpio == NULL) {
|
||||||
|
DBG("%s: %s", "gpiodir", strerror(errno));
|
||||||
return -(errno = ENODEV);
|
return -(errno = ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("Using %s", cmtdir);
|
while ((d = readdir(gpio)) != NULL) {
|
||||||
return 0;
|
char nn[PATH_MAX], name[PATH_MAX], from[PATH_MAX], to[PATH_MAX];
|
||||||
|
FILE *nf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
snprintf(nn, sizeof nn, "%s/%s/name", gpiodir, d->d_name);
|
||||||
|
|
||||||
|
nf = fopen(nn, "rb");
|
||||||
|
if (nf == NULL) {
|
||||||
|
DBG("%s: %s", nn, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = fread(name, sizeof name, 1, nf);
|
||||||
|
|
||||||
|
if (ferror(nf)) {
|
||||||
|
DBG("read from %s: %s", nn, strerror(errno));
|
||||||
|
fclose(nf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(nf);
|
||||||
|
|
||||||
|
if (len < 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
name[--len] = '\0';
|
||||||
|
|
||||||
|
if (strncmp(name, "cmt_", 4))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf(from, sizeof from, "%s/%s", gpiodir, d->d_name);
|
||||||
|
snprintf(to, sizeof to, "%s/%s", cmtdir, name);
|
||||||
|
|
||||||
|
if (symlink(from, to) == -1)
|
||||||
|
DBG("%s: %s", to, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("%s: %s", "/sys/class/gpio", strerror(errno));
|
||||||
|
|
||||||
|
(void) closedir(gpio);
|
||||||
|
|
||||||
|
return -(errno = ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,6 @@
|
|||||||
#include <ofono/gnss.h>
|
#include <ofono/gnss.h>
|
||||||
#include <ofono/handsfree.h>
|
#include <ofono/handsfree.h>
|
||||||
#include <ofono/siri.h>
|
#include <ofono/siri.h>
|
||||||
#include <ofono/sim-auth.h>
|
|
||||||
|
|
||||||
#include <drivers/atmodem/vendor.h>
|
#include <drivers/atmodem/vendor.h>
|
||||||
#include <drivers/atmodem/atutil.h>
|
#include <drivers/atmodem/atutil.h>
|
||||||
@@ -861,7 +860,6 @@ static void phonesim_post_sim(struct ofono_modem *modem)
|
|||||||
ofono_sms_create(modem, 0, "atmodem", data->chat);
|
ofono_sms_create(modem, 0, "atmodem", data->chat);
|
||||||
|
|
||||||
ofono_radio_settings_create(modem, 0, "phonesim", data->chat);
|
ofono_radio_settings_create(modem, 0, "phonesim", data->chat);
|
||||||
ofono_sim_auth_create(modem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void phonesim_post_online(struct ofono_modem *modem)
|
static void phonesim_post_online(struct ofono_modem *modem)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017-2019 Jolla Ltd.
|
* Copyright (C) 2017 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* 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 {
|
} else {
|
||||||
const struct sailfish_cell_info_lte *l1 =
|
const struct sailfish_cell_info_lte *l1 =
|
||||||
&c1->info.lte;
|
&c1->info.lte;
|
||||||
const struct sailfish_cell_info_lte *l2 =
|
const struct sailfish_cell_info_lte *l2 =
|
||||||
&c2->info.lte;
|
&c2->info.lte;
|
||||||
|
|
||||||
GASSERT(c1->type == SAILFISH_CELL_TYPE_LTE);
|
GASSERT(c1->type == SAILFISH_CELL_TYPE_LTE);
|
||||||
l1 = &c1->info.lte;
|
l1 = &c1->info.lte;
|
||||||
@@ -120,14 +120,6 @@ 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:
|
* Local Variables:
|
||||||
* mode: C
|
* mode: C
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017-2020 Jolla Ltd.
|
* Copyright (C) 2017-2019 Jolla Ltd.
|
||||||
* Copyright (C) 2019-2020 Open Mobile Platform LLC.
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -23,7 +22,6 @@
|
|||||||
#include <gutil_macros.h>
|
#include <gutil_macros.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <ofono/storage.h>
|
|
||||||
#include <ofono/watch.h>
|
#include <ofono/watch.h>
|
||||||
|
|
||||||
#include "src/ofono.h"
|
#include "src/ofono.h"
|
||||||
@@ -46,12 +44,6 @@ enum ofono_watch_events {
|
|||||||
WATCH_EVENT_COUNT
|
WATCH_EVENT_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sim_auto_select {
|
|
||||||
SIM_AUTO_SELECT_OFF,
|
|
||||||
SIM_AUTO_SELECT_ON,
|
|
||||||
SIM_AUTO_SELECT_ONCE
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sailfish_manager_priv {
|
struct sailfish_manager_priv {
|
||||||
struct sailfish_manager pub; /* Public part */
|
struct sailfish_manager pub; /* Public part */
|
||||||
struct sailfish_slot_driver_reg *drivers;
|
struct sailfish_slot_driver_reg *drivers;
|
||||||
@@ -60,8 +52,6 @@ struct sailfish_manager_priv {
|
|||||||
struct sailfish_slot_priv *data_slot;
|
struct sailfish_slot_priv *data_slot;
|
||||||
struct sailfish_slot_priv *mms_slot;
|
struct sailfish_slot_priv *mms_slot;
|
||||||
sailfish_slot_ptr *slots;
|
sailfish_slot_ptr *slots;
|
||||||
enum sim_auto_select auto_data_sim;
|
|
||||||
gboolean auto_data_sim_done;
|
|
||||||
int slot_count;
|
int slot_count;
|
||||||
guint init_countdown;
|
guint init_countdown;
|
||||||
guint init_id;
|
guint init_id;
|
||||||
@@ -109,11 +99,6 @@ struct sailfish_slot_priv {
|
|||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Read-only config */
|
|
||||||
#define SF_CONFIG_FILE "main.conf"
|
|
||||||
#define SF_CONFIG_GROUP "ModemManager"
|
|
||||||
#define SF_CONFIG_KEY_AUTO_DATA_SIM "AutoSelectDataSim"
|
|
||||||
|
|
||||||
/* "ril" is used for historical reasons */
|
/* "ril" is used for historical reasons */
|
||||||
#define SF_STORE "ril"
|
#define SF_STORE "ril"
|
||||||
#define SF_STORE_GROUP "Settings"
|
#define SF_STORE_GROUP "Settings"
|
||||||
@@ -121,7 +106,6 @@ struct sailfish_slot_priv {
|
|||||||
#define SF_STORE_DEFAULT_VOICE_SIM "DefaultVoiceSim"
|
#define SF_STORE_DEFAULT_VOICE_SIM "DefaultVoiceSim"
|
||||||
#define SF_STORE_DEFAULT_DATA_SIM "DefaultDataSim"
|
#define SF_STORE_DEFAULT_DATA_SIM "DefaultDataSim"
|
||||||
#define SF_STORE_SLOTS_SEP ","
|
#define SF_STORE_SLOTS_SEP ","
|
||||||
#define SF_STORE_AUTO_DATA_SIM_DONE "AutoSelectDataSimDone"
|
|
||||||
|
|
||||||
/* The file where error statistics is stored. Again "rilerror" is historical */
|
/* The file where error statistics is stored. Again "rilerror" is historical */
|
||||||
#define SF_ERROR_STORAGE "rilerror" /* File name */
|
#define SF_ERROR_STORAGE "rilerror" /* File name */
|
||||||
@@ -161,50 +145,6 @@ static inline void sailfish_slot_set_data_role(struct sailfish_slot_priv *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean sailfish_config_get_enum(GKeyFile *file, const char *group,
|
|
||||||
const char *key, int *result,
|
|
||||||
const char *name, int value, ...)
|
|
||||||
{
|
|
||||||
char *str = g_key_file_get_string(file, group, key, NULL);
|
|
||||||
|
|
||||||
if (str) {
|
|
||||||
/*
|
|
||||||
* Some people are thinking that # is a comment
|
|
||||||
* anywhere on the line, not just at the beginning
|
|
||||||
*/
|
|
||||||
char *comment = strchr(str, '#');
|
|
||||||
|
|
||||||
if (comment) *comment = 0;
|
|
||||||
g_strstrip(str);
|
|
||||||
if (strcasecmp(str, name)) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, value);
|
|
||||||
while ((name = va_arg(args, char*)) != NULL) {
|
|
||||||
value = va_arg(args, int);
|
|
||||||
if (!strcasecmp(str, name)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
ofono_error("Invalid %s config value (%s)", key, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(str);
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
if (result) {
|
|
||||||
*result = value;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update modem paths and emit D-Bus signal if necessary */
|
/* Update modem paths and emit D-Bus signal if necessary */
|
||||||
static void sailfish_manager_update_modem_paths_full
|
static void sailfish_manager_update_modem_paths_full
|
||||||
(struct sailfish_manager_priv *p)
|
(struct sailfish_manager_priv *p)
|
||||||
@@ -648,27 +588,6 @@ static struct sailfish_slot_priv *sailfish_manager_find_slot_imsi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean sailfish_manager_all_sims_are_initialized_proc
|
|
||||||
(struct sailfish_slot_priv *s, void *user_data)
|
|
||||||
{
|
|
||||||
if (s->pub.sim_present && s->pub.enabled && !s->watch->imsi) {
|
|
||||||
*((gboolean*)user_data) = FALSE;
|
|
||||||
return SF_LOOP_DONE;
|
|
||||||
} else {
|
|
||||||
return SF_LOOP_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean sailfish_manager_all_sims_are_initialized
|
|
||||||
(struct sailfish_manager_priv *p)
|
|
||||||
{
|
|
||||||
gboolean result = TRUE;
|
|
||||||
|
|
||||||
sailfish_manager_foreach_slot(p,
|
|
||||||
sailfish_manager_all_sims_are_initialized_proc, &result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the event mask to be passed to sailfish_manager_dbus_signal.
|
/* Returns the event mask to be passed to sailfish_manager_dbus_signal.
|
||||||
* The caller has a chance to OR it with other bits */
|
* The caller has a chance to OR it with other bits */
|
||||||
static int sailfish_manager_update_modem_paths(struct sailfish_manager_priv *p)
|
static int sailfish_manager_update_modem_paths(struct sailfish_manager_priv *p)
|
||||||
@@ -696,7 +615,7 @@ static int sailfish_manager_update_modem_paths(struct sailfish_manager_priv *p)
|
|||||||
* previously selected voice SIM is inserted, we will switch
|
* previously selected voice SIM is inserted, we will switch
|
||||||
* back to it.
|
* back to it.
|
||||||
*
|
*
|
||||||
* A similar behavior can be configured for data SIM too.
|
* There is no such fallback for the data.
|
||||||
*/
|
*/
|
||||||
if (!slot) {
|
if (!slot) {
|
||||||
slot = sailfish_manager_find_slot_imsi(p, NULL);
|
slot = sailfish_manager_find_slot_imsi(p, NULL);
|
||||||
@@ -729,36 +648,11 @@ static int sailfish_manager_update_modem_paths(struct sailfish_manager_priv *p)
|
|||||||
slot = sailfish_manager_find_slot_imsi(p, NULL);
|
slot = sailfish_manager_find_slot_imsi(p, NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
slot = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we need to auto-select data SIM (always or once) */
|
|
||||||
if (!slot && (p->auto_data_sim == SIM_AUTO_SELECT_ON ||
|
|
||||||
(p->auto_data_sim == SIM_AUTO_SELECT_ONCE &&
|
|
||||||
!p->auto_data_sim_done))) {
|
|
||||||
/*
|
/*
|
||||||
* To actually make a selection we need all present SIMs
|
* Should we automatically select the default data sim
|
||||||
* to be initialized. Otherwise we may end up endlessly
|
* on a multisim phone that has only one sim inserted?
|
||||||
* switching data SIMs back and forth.
|
|
||||||
*/
|
*/
|
||||||
if (sailfish_manager_all_sims_are_initialized(p)) {
|
slot = NULL;
|
||||||
slot = sailfish_manager_find_slot_imsi(p, NULL);
|
|
||||||
if (slot && slot->watch->online &&
|
|
||||||
p->auto_data_sim == SIM_AUTO_SELECT_ONCE) {
|
|
||||||
/*
|
|
||||||
* Data SIM only needs to be auto-selected
|
|
||||||
* once and it's done. Write that down.
|
|
||||||
*/
|
|
||||||
p->auto_data_sim_done = TRUE;
|
|
||||||
g_key_file_set_boolean(p->storage,
|
|
||||||
SF_STORE_GROUP,
|
|
||||||
SF_STORE_AUTO_DATA_SIM_DONE,
|
|
||||||
p->auto_data_sim_done);
|
|
||||||
storage_sync(NULL, SF_STORE, p->storage);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG("Skipping auto-selection of data SIM");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot && !slot->watch->online) {
|
if (slot && !slot->watch->online) {
|
||||||
@@ -1380,29 +1274,6 @@ static struct sailfish_manager_priv *sailfish_manager_priv_new()
|
|||||||
|
|
||||||
struct sailfish_manager_priv *p =
|
struct sailfish_manager_priv *p =
|
||||||
g_slice_new0(struct sailfish_manager_priv);
|
g_slice_new0(struct sailfish_manager_priv);
|
||||||
GKeyFile *conf = g_key_file_new();
|
|
||||||
char* fn = g_build_filename(ofono_config_dir(), SF_CONFIG_FILE, NULL);
|
|
||||||
|
|
||||||
/* Load config */
|
|
||||||
if (g_key_file_load_from_file(conf, fn, 0, NULL)) {
|
|
||||||
int ival;
|
|
||||||
|
|
||||||
DBG("Loading configuration file %s", fn);
|
|
||||||
if (sailfish_config_get_enum(conf, SF_CONFIG_GROUP,
|
|
||||||
SF_CONFIG_KEY_AUTO_DATA_SIM, &ival,
|
|
||||||
"off", SIM_AUTO_SELECT_OFF,
|
|
||||||
"once", SIM_AUTO_SELECT_ONCE,
|
|
||||||
"always", SIM_AUTO_SELECT_ON,
|
|
||||||
"on", SIM_AUTO_SELECT_ON, NULL)) {
|
|
||||||
DBG("Automatic data SIM selection: %s",
|
|
||||||
ival == SIM_AUTO_SELECT_ONCE ? "once":
|
|
||||||
ival == SIM_AUTO_SELECT_ON ? "on":
|
|
||||||
"off");
|
|
||||||
p->auto_data_sim = ival;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_key_file_free(conf);
|
|
||||||
g_free(fn);
|
|
||||||
|
|
||||||
/* Load settings */
|
/* Load settings */
|
||||||
p->storage = storage_open(NULL, SF_STORE);
|
p->storage = storage_open(NULL, SF_STORE);
|
||||||
@@ -1412,8 +1283,6 @@ static struct sailfish_manager_priv *sailfish_manager_priv_new()
|
|||||||
p->pub.default_data_imsi = p->default_data_imsi =
|
p->pub.default_data_imsi = p->default_data_imsi =
|
||||||
g_key_file_get_string(p->storage, SF_STORE_GROUP,
|
g_key_file_get_string(p->storage, SF_STORE_GROUP,
|
||||||
SF_STORE_DEFAULT_DATA_SIM, NULL);
|
SF_STORE_DEFAULT_DATA_SIM, NULL);
|
||||||
p->auto_data_sim_done = g_key_file_get_boolean(p->storage,
|
|
||||||
SF_STORE_GROUP, SF_STORE_AUTO_DATA_SIM_DONE, NULL);
|
|
||||||
|
|
||||||
DBG("Default voice sim is %s", p->default_voice_imsi ?
|
DBG("Default voice sim is %s", p->default_voice_imsi ?
|
||||||
p->default_voice_imsi : "(auto)");
|
p->default_voice_imsi : "(auto)");
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user