forked from sailfishos/ofono
Compare commits
3 Commits
mer/1.16+g
...
mer/1.14+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72395683a1 | ||
|
|
f595d0fae0 | ||
|
|
a170c3a01e |
@@ -92,10 +92,3 @@ Jesper Larsen <jesper.larsen@ixonos.com>
|
||||
Slava Monich <slava.monich@jolla.com>
|
||||
Andrew Earl <andrewx.earl@intel.com>
|
||||
Krzysztof Wilk <krzysztofx.wilk@intel.com>
|
||||
Tony Espy <espy@canonical.com>
|
||||
Martin Pitt <martin.pitt@ubuntu.com>
|
||||
Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>
|
||||
Jussi Pakkanen <jussi.pakkanen@canonical.com>
|
||||
Sergio Checa Blanco <sergio.checa@bmw-carit.de>
|
||||
Philip Paeps <philip@paeps.cx>
|
||||
Kuba Pawlak <kubax.t.pawlak@intel.com>
|
||||
|
||||
@@ -1,23 +1,3 @@
|
||||
ver 1.16:
|
||||
Fix issue with PIN retry handling.
|
||||
Fix issue with HFP and multiple calls.
|
||||
Add support for Distracted Driving Reduction.
|
||||
Add support for available technologies property.
|
||||
Add support for Telit location reporting driver.
|
||||
Add support for u-blox SARA-U270 modems.
|
||||
Add support for Quectel UC15 modems.
|
||||
|
||||
ver 1.15:
|
||||
Fix issue with EF_PNN access affecting PLMN display.
|
||||
Fix issue with SIM detection and Telit HE910 modems.
|
||||
Fix issue with Mobile Provider Database provisioning.
|
||||
Fix issue with bit-shifting and ID mapping allocations.
|
||||
Fix issue with Handsfree and unsolicited notifications.
|
||||
Fix issue with Handsfree and three way calling feature.
|
||||
Add support for Handsfree subscriber number feature.
|
||||
Add support for Handsfree multiple DTMF characters.
|
||||
Add support for PAP authentication.
|
||||
|
||||
ver 1.14:
|
||||
Add support for Apple Siri specific Handsfree commands.
|
||||
Add support for provisioning of MMSC and Message Proxy.
|
||||
|
||||
@@ -21,9 +21,8 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
|
||||
include/cdma-connman.h include/gnss.h \
|
||||
include/private-network.h include/cdma-netreg.h \
|
||||
include/cdma-provision.h include/handsfree.h \
|
||||
include/handsfree-audio.h \
|
||||
include/sim-mnclength.h include/oemraw.h \
|
||||
include/siri.h
|
||||
include/handsfree-audio.h include/sim-mnclength.h \
|
||||
include/oemraw.h include/siri.h
|
||||
|
||||
nodist_pkginclude_HEADERS = include/version.h
|
||||
|
||||
@@ -121,9 +120,6 @@ endif
|
||||
if RILMODEM
|
||||
builtin_sources += $(gril_sources)
|
||||
|
||||
builtin_modules += rildev
|
||||
builtin_sources += plugins/rildev.c
|
||||
|
||||
builtin_modules += ril
|
||||
builtin_sources += plugins/ril.c
|
||||
|
||||
@@ -147,8 +143,7 @@ builtin_sources += drivers/rilmodem/rilmodem.h \
|
||||
drivers/rilmodem/call-forwarding.c \
|
||||
drivers/rilmodem/cbs.c \
|
||||
drivers/rilmodem/oemraw-messages.c \
|
||||
drivers/rilmodem/call-barring.c \
|
||||
drivers/rilmodem/stk.c
|
||||
drivers/rilmodem/call-barring.c
|
||||
|
||||
endif
|
||||
|
||||
@@ -313,12 +308,6 @@ builtin_sources += drivers/atmodem/atutil.h \
|
||||
drivers/mbmmodem/stk.c \
|
||||
drivers/mbmmodem/location-reporting.c
|
||||
|
||||
builtin_modules += telitmodem
|
||||
builtin_sources += drivers/atmodem/atutil.h \
|
||||
drivers/telitmodem/telitmodem.h \
|
||||
drivers/telitmodem/telitmodem.c \
|
||||
drivers/telitmodem/location-reporting.c
|
||||
|
||||
builtin_modules += hsomodem
|
||||
builtin_sources += drivers/atmodem/atutil.h \
|
||||
drivers/hsomodem/hsomodem.h \
|
||||
@@ -468,20 +457,14 @@ builtin_sources += plugins/samsung.c
|
||||
|
||||
builtin_modules += sim900
|
||||
builtin_sources += plugins/sim900.c
|
||||
|
||||
builtin_modules += quectel
|
||||
builtin_sources += plugins/quectel.c
|
||||
|
||||
builtin_modules += ublox
|
||||
builtin_sources += plugins/ublox.c
|
||||
|
||||
builtin_modules += he910
|
||||
builtin_sources += plugins/he910.c
|
||||
endif
|
||||
|
||||
builtin_modules += connman
|
||||
builtin_sources += plugins/connman.c
|
||||
|
||||
builtin_modules += he910
|
||||
builtin_sources += plugins/he910.c
|
||||
|
||||
if BLUETOOTH
|
||||
if BLUEZ4
|
||||
builtin_modules += bluez4
|
||||
@@ -530,7 +513,7 @@ if PROVISION
|
||||
builtin_sources += plugins/mbpi.h plugins/mbpi.c
|
||||
|
||||
builtin_modules += provision
|
||||
builtin_sources += plugins/provision.h plugins/provision.c
|
||||
builtin_sources += plugins/provision.c
|
||||
|
||||
builtin_modules += cdma_provision
|
||||
builtin_sources += plugins/cdma-provision.c
|
||||
@@ -557,9 +540,6 @@ builtin_sources += examples/private-network.c
|
||||
|
||||
builtin_modules += stktest
|
||||
builtin_sources += plugins/stktest.c
|
||||
|
||||
builtin_modules += emulator_fuzz
|
||||
builtin_sources += plugins/emulator_fuzz.c
|
||||
endif
|
||||
|
||||
builtin_modules += smart_messaging
|
||||
@@ -568,13 +548,6 @@ builtin_sources += plugins/smart-messaging.c
|
||||
builtin_modules += push_notification
|
||||
builtin_sources += plugins/push-notification.c
|
||||
|
||||
if PUSHFORWARDER
|
||||
builtin_modules += push_forwarder
|
||||
builtin_sources += plugins/push-forwarder.c
|
||||
builtin_cflags += @WSPCODEC_CFLAGS@
|
||||
builtin_libadd += @WSPCODEC_LIBS@
|
||||
endif
|
||||
|
||||
builtin_modules += sms_history
|
||||
builtin_sources += plugins/smshistory.c
|
||||
|
||||
@@ -605,8 +578,8 @@ src_ofonod_SOURCES = $(builtin_sources) src/ofono.ver \
|
||||
src/cdma-sms.c src/private-network.c src/cdma-netreg.c \
|
||||
src/cdma-provision.c src/handsfree.c \
|
||||
src/handsfree-audio.c src/bluetooth.h \
|
||||
src/sim-mnclength.c src/oemraw.c src/voicecallagent.c \
|
||||
src/hfp.h src/siri.c
|
||||
src/hfp.h src/sim-mnclength.c src/oemraw.c \
|
||||
src/siri.c
|
||||
|
||||
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
||||
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
|
||||
@@ -649,10 +622,9 @@ doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
|
||||
doc/sim-api.txt doc/stk-api.txt \
|
||||
doc/audio-settings-api.txt doc/text-telephony-api.txt \
|
||||
doc/calypso-modem.txt doc/message-api.txt \
|
||||
doc/location-reporting-api.txt \
|
||||
doc/smshistory-api.txt doc/oemraw-api.txt \
|
||||
doc/certification.txt doc/siri-api.txt \
|
||||
doc/telit-modem.txt
|
||||
doc/location-reporting-api.txt doc/smshistory-api.txt \
|
||||
doc/oemraw-api.txt \
|
||||
doc/certification.txt doc/siri-api.txt
|
||||
|
||||
|
||||
test_scripts = test/backtrace \
|
||||
@@ -740,17 +712,13 @@ test_scripts = test/backtrace \
|
||||
test/set-context-property \
|
||||
test/test-gnss \
|
||||
test/swap-calls \
|
||||
test/transfer-call \
|
||||
test/release-and-answer \
|
||||
test/release-and-swap \
|
||||
test/hold-and-answer \
|
||||
test/hangup-multiparty \
|
||||
test/hangup-call \
|
||||
test/display-icon \
|
||||
test/set-msisdn \
|
||||
test/test-voicecallagent \
|
||||
test/get-network-time \
|
||||
test/set-ddr
|
||||
test/set-msisdn
|
||||
|
||||
if TEST
|
||||
testdir = $(pkglibdir)/test
|
||||
@@ -771,8 +739,7 @@ unit_tests = unit/test-common unit/test-util unit/test-idmap \
|
||||
unit/test-grilrequest \
|
||||
unit/test-grilreply \
|
||||
unit/test-grilunsol \
|
||||
unit/test-sms unit/test-cdmasms \
|
||||
unit/test-provision
|
||||
unit/test-sms unit/test-cdmasms
|
||||
|
||||
noinst_PROGRAMS = $(unit_tests) \
|
||||
unit/test-sms-root unit/test-mux unit/test-caif
|
||||
@@ -839,13 +806,6 @@ unit_test_grilunsol_SOURCES = unit/test-grilunsol.c $(gril_sources) \
|
||||
unit_test_grilunsol_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_grilunsol_OBJECTS)
|
||||
|
||||
unit_test_provision_SOURCES = unit/test-provision.c \
|
||||
plugins/provision.h plugins/provision.c \
|
||||
plugins/mbpi.c src/gprs-provision.c \
|
||||
src/log.c
|
||||
unit_test_provision_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_provision_OBJECTS)
|
||||
|
||||
TESTS = $(unit_tests)
|
||||
|
||||
if TOOLS
|
||||
|
||||
@@ -12,7 +12,7 @@ AC_DEFUN([AC_PROG_CC_PIE], [
|
||||
|
||||
AC_DEFUN([COMPILER_FLAGS], [
|
||||
if (test "${CFLAGS}" = ""); then
|
||||
CFLAGS="-Wall -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2"
|
||||
CFLAGS="-Wall -O2 -D_FORTIFY_SOURCE=2"
|
||||
fi
|
||||
if (test "$USE_MAINTAINER_MODE" = "yes"); then
|
||||
CFLAGS="$CFLAGS -Werror -Wextra"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(ofono, 1.16)
|
||||
AC_INIT(ofono, 1.14)
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
@@ -192,10 +192,7 @@ AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
|
||||
AC_ARG_ENABLE(nettime, AC_HELP_STRING([--disable-nettime],
|
||||
[disable Nettime plugin]),
|
||||
[enable_nettime=${enableval}])
|
||||
if (test "${enable_nettime}" != "no"); then
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
fi
|
||||
AM_CONDITIONAL(NETTIME, test "${enable_nettime}" != "no")
|
||||
AM_CONDITIONAL(NETTIME, test "${enable_netttime}" != "no")
|
||||
|
||||
AC_ARG_WITH([provisiondb], AC_HELP_STRING([--with-provisiondb=FILE],
|
||||
[location of provision database]), [path_provisiondb=${withval}])
|
||||
@@ -226,17 +223,6 @@ AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
|
||||
[enable_datafiles=${enableval}])
|
||||
AM_CONDITIONAL(DATAFILES, test "${enable_datafiles}" != "no")
|
||||
|
||||
AC_ARG_ENABLE(pushforwarder, AC_HELP_STRING([--disable-pushforwarder],
|
||||
[disable Push Forwarder plugin]),
|
||||
[enable_pushforwarder=${enableval}])
|
||||
AM_CONDITIONAL(PUSHFORWARDER, test "${enable_pushforwarder}" != "no")
|
||||
if (test "${enable_pushforwarder}" != "no"); then
|
||||
PKG_CHECK_MODULES(WSPCODEC, libwspcodec >= 2.0, dummy=yes,
|
||||
AC_MSG_ERROR(WSP decoder is required))
|
||||
AC_SUBST(WSPCODEC_CFLAGS)
|
||||
AC_SUBST(WSPCODEC_LIBS)
|
||||
fi
|
||||
|
||||
if (test "${prefix}" = "NONE"); then
|
||||
dnl no prefix and no localstatedir, so default to /var
|
||||
if (test "$localstatedir" = '${prefix}/var'); then
|
||||
|
||||
@@ -155,15 +155,6 @@ Methods dict GetProperties()
|
||||
[service].Error.AttachInProgress
|
||||
[service].Error.NotImplemented
|
||||
|
||||
Methods void ProvisionContext()
|
||||
Resets all properties back to default. Fails to make
|
||||
any changes to the context if it is active or in the
|
||||
process of being activated or deactivated.
|
||||
|
||||
Possible Errors: [service].Error.Failed
|
||||
[service].Error.InProgress
|
||||
[service].Error.NotAvailable
|
||||
|
||||
Signals PropertyChanged(string property, variant value)
|
||||
|
||||
This signal indicates a changed value of the given
|
||||
@@ -189,10 +180,6 @@ Properties boolean Active [readwrite]
|
||||
"wap" - Used by WAP related services
|
||||
"ims" - Used by IMS related services
|
||||
|
||||
string AuthenticationMethod [readwrite]
|
||||
Holds the PPP authentication method to use. Valid
|
||||
values are "pap" and "chap". Defaults to "chap".
|
||||
|
||||
string Username [readwrite]
|
||||
|
||||
Holds the username to be used for authentication
|
||||
|
||||
@@ -19,8 +19,6 @@ Methods dict GetProperties()
|
||||
|
||||
Possible Errors: [service].Error.InProgress
|
||||
[service].Error.InvalidArguments
|
||||
[service].Error.NotImplemented
|
||||
[service].Error.NotSupported
|
||||
|
||||
string RequestPhoneNumber()
|
||||
|
||||
@@ -47,13 +45,6 @@ Properties array{string} Features [readonly]
|
||||
"voice-recognition"
|
||||
"attach-voice-tag"
|
||||
"echo-canceling-and-noise-reduction"
|
||||
"three-way-calling"
|
||||
"release-all-held"
|
||||
"release-specified-active-call"
|
||||
"private-chat"
|
||||
"create-multiparty"
|
||||
"transfer"
|
||||
"hf-indicators"
|
||||
|
||||
boolean InbandRinging [readonly]
|
||||
|
||||
@@ -66,7 +57,7 @@ Properties array{string} Features [readonly]
|
||||
to activate or deactivate the function from the HF, or
|
||||
the AG could autonomously initiate it.
|
||||
|
||||
boolean EchoCancelingNoiseReduction [readwrite, optional]
|
||||
boolean EchoCancelingNoiseReduction [readwrite]
|
||||
|
||||
Non-persistent Boolean property representing whether
|
||||
echo canceling and noise reduction is enabled in the
|
||||
@@ -79,14 +70,3 @@ Properties array{string} Features [readonly]
|
||||
|
||||
The current charge level of the battery. The value
|
||||
can be between 0 and 5 respectively.
|
||||
|
||||
array{string} SubscriberNumbers [readonly]
|
||||
|
||||
List of subscriber numbers provided by the AG.
|
||||
|
||||
boolean DistractedDrivingReduction [readwrite, optional]
|
||||
|
||||
Non-persistent property representing whether
|
||||
distracted driving reduction mode should be enabled in
|
||||
the AG. Support for this feature is optional on the
|
||||
AG.
|
||||
|
||||
@@ -57,11 +57,6 @@ Signals PropertyChanged(string property, variant value)
|
||||
This signal indicates a changed value of the given
|
||||
property.
|
||||
|
||||
OperatorsChanged(array{object,dict})
|
||||
|
||||
Signal that gets emitted when operator list has
|
||||
changed. It contains the current list of operators.
|
||||
|
||||
Properties string Mode [readonly]
|
||||
|
||||
The current registration mode. The default of this
|
||||
|
||||
@@ -45,11 +45,6 @@ Properties string TechnologyPreference [readwrite]
|
||||
"umts" Only UMTS used for radio access.
|
||||
"lte" Only LTE used for radio access.
|
||||
|
||||
array{string} AvailableTechnologies [readonly, optional]
|
||||
|
||||
List of values for TechnologyPreference property
|
||||
supported by the modem.
|
||||
|
||||
string GsmBand [readwrite, optional]
|
||||
|
||||
Frequency band in which the modem is allowed to
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
oFono - Open Source Telephony
|
||||
*****************************
|
||||
|
||||
Purpose
|
||||
=======
|
||||
The purpose of this document is to identify issues and configuration
|
||||
requirements with Telit's modems.
|
||||
|
||||
HE910
|
||||
=====
|
||||
|
||||
GPS:
|
||||
To enable location reporting on the Telit HE910 the modem needs to be
|
||||
switched to Port Configuration #8. Please refer to Telit's
|
||||
'HE910 UE910 Family Ports Arrangements' section 4.1.3 for rationale and
|
||||
'AT Commands Reference Guide' section 3.5.7.1.96 for specific AT command.
|
||||
After setting the configuration, a power cycle is required.
|
||||
Port Configiuration #8 is available since firmware 12.00.004. Firmware version
|
||||
can be checked using 'AT+CGMR'.
|
||||
@@ -198,25 +198,6 @@ Methods dict GetProperties()
|
||||
[service].Error.InvalidFormat
|
||||
[service].Error.Failed
|
||||
|
||||
void RegisterVoicecallAgent(object path)
|
||||
|
||||
Registers an agent which will be called whenever a
|
||||
specific voice call related event requiring a client
|
||||
action occurs. Currently, the only such action is
|
||||
playing a ringback tone locally.
|
||||
|
||||
Possible Errors: [service].Error.InProgress
|
||||
[service].Error.InvalidArguments
|
||||
[service].Error.InvalidFormat
|
||||
[service].Error.Failed
|
||||
|
||||
void UnregisterVoicecallAgent(object path)
|
||||
|
||||
Unregisters an agent.
|
||||
|
||||
Possible Errors: [service].Error.InvalidArguments
|
||||
[service].Error.Failed
|
||||
|
||||
Signals CallAdded(object path, dict properties)
|
||||
|
||||
Signal that is sent when a new call is added. It
|
||||
@@ -276,26 +257,3 @@ Properties array{string} EmergencyNumbers [readonly]
|
||||
of numbers provided by the specification and any
|
||||
extra numbers provisioned by the carrier on the
|
||||
SIM.
|
||||
|
||||
VoiceCallAgent Hierarchy
|
||||
========================
|
||||
|
||||
Service unique name
|
||||
Interface org.ofono.VoiceCallAgent
|
||||
Object path freely definable
|
||||
|
||||
Methods void RingbackTone(boolean playTone)
|
||||
|
||||
Requests the client to generate an alerting tone locally
|
||||
(3GPP 24.008; 5.2.1.5). This can happen when an outgoing
|
||||
voice call is made and network is not providing the
|
||||
alerting tone. Value 0 stands for "stop playing ringback
|
||||
tone" and 1 for "start playing ringback tone".
|
||||
|
||||
void Release() [noreply]
|
||||
|
||||
Agent is being released, possibly because of oFono
|
||||
terminating, voicecall interface is being torn down or
|
||||
modem is switched off. No UnregisterVoicecallAgent
|
||||
call is needed.
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ enum state {
|
||||
struct gprs_context_data {
|
||||
GAtChat *chat;
|
||||
unsigned int active_context;
|
||||
GAtPPPAuthMethod auth_method;
|
||||
char username[OFONO_GPRS_MAX_USERNAME_LENGTH + 1];
|
||||
char password[OFONO_GPRS_MAX_PASSWORD_LENGTH + 1];
|
||||
GAtPPP *ppp;
|
||||
@@ -155,7 +154,6 @@ static gboolean setup_ppp(struct ofono_gprs_context *gc)
|
||||
if (getenv("OFONO_PPP_DEBUG"))
|
||||
g_at_ppp_set_debug(gcd->ppp, ppp_debug, "PPP");
|
||||
|
||||
g_at_ppp_set_auth_method(gcd->ppp, gcd->auth_method);
|
||||
g_at_ppp_set_credentials(gcd->ppp, gcd->username, gcd->password);
|
||||
|
||||
/* set connect and disconnect callbacks */
|
||||
@@ -245,18 +243,6 @@ static void at_gprs_activate_primary(struct ofono_gprs_context *gc,
|
||||
memcpy(gcd->username, ctx->username, sizeof(ctx->username));
|
||||
memcpy(gcd->password, ctx->password, sizeof(ctx->password));
|
||||
|
||||
/* We only support CHAP and PAP */
|
||||
switch (ctx->auth_method) {
|
||||
case OFONO_GPRS_AUTH_METHOD_CHAP:
|
||||
gcd->auth_method = G_AT_PPP_AUTH_METHOD_CHAP;
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_PAP:
|
||||
gcd->auth_method = G_AT_PPP_AUTH_METHOD_PAP;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
gcd->state = STATE_ENABLING;
|
||||
|
||||
if (gcd->vendor == OFONO_VENDOR_ZTE) {
|
||||
@@ -282,34 +268,9 @@ static void at_gprs_activate_primary(struct ofono_gprs_context *gc,
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", ctx->cid);
|
||||
|
||||
if (ctx->apn) {
|
||||
switch (gcd->vendor) {
|
||||
case OFONO_VENDOR_UBLOX:
|
||||
/*
|
||||
* U-blox modems require a magic prefix to the APN to
|
||||
* specify the authentication method to use in the
|
||||
* network. See UBX-13002752 - R21.
|
||||
*
|
||||
* As the response of the read command omits this magic
|
||||
* prefix, this is the least invasive place to set it.
|
||||
*/
|
||||
switch (ctx->auth_method) {
|
||||
case OFONO_GPRS_AUTH_METHOD_CHAP:
|
||||
snprintf(buf + len, sizeof(buf) - len - 3,
|
||||
",\"CHAP:%s\"", ctx->apn);
|
||||
break;
|
||||
case OFONO_GPRS_AUTH_METHOD_PAP:
|
||||
snprintf(buf + len, sizeof(buf) - len - 3,
|
||||
",\"PAP:%s\"", ctx->apn);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"",
|
||||
ctx->apn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ctx->apn)
|
||||
snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"",
|
||||
ctx->apn);
|
||||
|
||||
if (g_at_chat_send(gcd->chat, buf, none_prefix,
|
||||
at_cgdcont_cb, gc, NULL) > 0)
|
||||
|
||||
@@ -282,44 +282,6 @@ static void telit_mode_notify(GAtResult *result, gpointer user_data)
|
||||
ofono_gprs_bearer_notify(gprs, bearer);
|
||||
}
|
||||
|
||||
static void ublox_ureg_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_gprs *gprs = user_data;
|
||||
GAtResultIter iter;
|
||||
gint state, bearer;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+UREG:"))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &state))
|
||||
return;
|
||||
|
||||
switch (state) {
|
||||
case 4:
|
||||
bearer = 5;
|
||||
break;
|
||||
case 5:
|
||||
bearer = 4;
|
||||
break;
|
||||
case 7:
|
||||
/* XXX: reserved - assume none. */
|
||||
bearer = 0;
|
||||
break;
|
||||
case 8:
|
||||
bearer = 1;
|
||||
break;
|
||||
case 9:
|
||||
bearer = 2;
|
||||
break;
|
||||
default:
|
||||
bearer = state;
|
||||
}
|
||||
|
||||
ofono_gprs_bearer_notify(gprs, bearer);
|
||||
}
|
||||
|
||||
static void cpsb_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_gprs *gprs = user_data;
|
||||
@@ -354,12 +316,6 @@ static void gprs_initialized(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
g_at_chat_register(gd->chat, "^MODE:", huawei_mode_notify,
|
||||
FALSE, gprs, NULL);
|
||||
break;
|
||||
case OFONO_VENDOR_UBLOX:
|
||||
g_at_chat_register(gd->chat, "+UREG:", ublox_ureg_notify,
|
||||
FALSE, gprs, NULL);
|
||||
g_at_chat_send(gd->chat, "AT+UREG=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
break;
|
||||
case OFONO_VENDOR_TELIT:
|
||||
g_at_chat_register(gd->chat, "#PSNT:", telit_mode_notify,
|
||||
FALSE, gprs, NULL);
|
||||
|
||||
@@ -67,8 +67,6 @@ static const char *epin_prefix[] = { "*EPIN:", NULL };
|
||||
static const char *spic_prefix[] = { "+SPIC:", NULL };
|
||||
static const char *pct_prefix[] = { "#PCT:", NULL };
|
||||
static const char *pnnm_prefix[] = { "+PNNM:", NULL };
|
||||
static const char *qpinc_prefix[] = { "+QPINC:", NULL };
|
||||
static const char *upincnt_prefix[] = { "+UPINCNT:", NULL };
|
||||
static const char *none_prefix[] = { NULL };
|
||||
|
||||
static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
@@ -969,90 +967,6 @@ error:
|
||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
||||
}
|
||||
|
||||
static void at_qpinc_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
while (g_at_result_iter_next(&iter, "+QPINC:")) {
|
||||
const char *name;
|
||||
int pin, puk;
|
||||
|
||||
if (!g_at_result_iter_next_string(&iter, &name))
|
||||
continue;
|
||||
if (!g_at_result_iter_next_number(&iter, &pin))
|
||||
continue;
|
||||
if (!g_at_result_iter_next_number(&iter, &puk))
|
||||
continue;
|
||||
|
||||
if (!strcmp(name, "SC")) {
|
||||
retries[OFONO_SIM_PASSWORD_SIM_PIN] = pin;
|
||||
retries[OFONO_SIM_PASSWORD_SIM_PUK] = puk;
|
||||
} else if (!strcmp(name, "P2")) {
|
||||
retries[OFONO_SIM_PASSWORD_SIM_PIN2] = pin;
|
||||
retries[OFONO_SIM_PASSWORD_SIM_PUK2] = puk;
|
||||
}
|
||||
}
|
||||
|
||||
cb(&error, retries, cbd->data);
|
||||
}
|
||||
|
||||
static void upincnt_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
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;
|
||||
static enum ofono_sim_password_type password_types[] = {
|
||||
OFONO_SIM_PASSWORD_SIM_PIN,
|
||||
OFONO_SIM_PASSWORD_SIM_PIN2,
|
||||
OFONO_SIM_PASSWORD_SIM_PUK,
|
||||
OFONO_SIM_PASSWORD_SIM_PUK2,
|
||||
};
|
||||
|
||||
decode_at_error(&error, final);
|
||||
|
||||
if (!ok) {
|
||||
cb(&error, NULL, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+UPINCNT:"))
|
||||
goto error;
|
||||
|
||||
BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
|
||||
retries);
|
||||
|
||||
cb(&error, retries, cbd->data);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
||||
}
|
||||
|
||||
static void at_pin_retries_query(struct ofono_sim *sim,
|
||||
ofono_sim_pin_retries_cb_t cb,
|
||||
void *data)
|
||||
@@ -1114,16 +1028,6 @@ static void at_pin_retries_query(struct ofono_sim *sim,
|
||||
at_pnnm_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
break;
|
||||
case OFONO_VENDOR_QUECTEL:
|
||||
if (g_at_chat_send(sd->chat, "AT+QPINC?", qpinc_prefix,
|
||||
at_qpinc_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
break;
|
||||
case OFONO_VENDOR_UBLOX:
|
||||
if (g_at_chat_send(sd->chat, "AT+UPINCNT", upincnt_prefix,
|
||||
upincnt_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
if (g_at_chat_send(sd->chat, "AT+CPINR", cpinr_prefixes,
|
||||
at_cpinr_cb, cbd, g_free) > 0)
|
||||
|
||||
@@ -42,7 +42,5 @@ enum ofono_vendor {
|
||||
OFONO_VENDOR_SIMCOM_SIM900,
|
||||
OFONO_VENDOR_ICERA,
|
||||
OFONO_VENDOR_WAVECOM_Q2XXX,
|
||||
OFONO_VENDOR_ALCATEL,
|
||||
OFONO_VENDOR_QUECTEL,
|
||||
OFONO_VENDOR_UBLOX,
|
||||
OFONO_VENDOR_ALCATEL
|
||||
};
|
||||
|
||||
@@ -49,7 +49,6 @@ static const char *bvra_prefix[] = { "+BVRA:", NULL };
|
||||
struct hf_data {
|
||||
GAtChat *chat;
|
||||
unsigned int ag_features;
|
||||
unsigned int ag_chld_features;
|
||||
int battchg_index;
|
||||
guint register_source;
|
||||
};
|
||||
@@ -125,108 +124,6 @@ static void ciev_notify(GAtResult *result, gpointer user_data)
|
||||
ofono_handsfree_battchg_notify(hf, value);
|
||||
}
|
||||
|
||||
static void cnum_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_handsfree_cnum_query_cb_t cb = cbd->cb;
|
||||
GAtResultIter iter;
|
||||
struct ofono_phone_number *list = NULL;
|
||||
int num = 0;
|
||||
struct ofono_error error;
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
|
||||
if (!ok)
|
||||
goto out;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
while (g_at_result_iter_next(&iter, "+CNUM:"))
|
||||
num++;
|
||||
|
||||
if (num == 0)
|
||||
goto out;
|
||||
|
||||
list = g_new0(struct ofono_phone_number, num);
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
for (num = 0; g_at_result_iter_next(&iter, "+CNUM:"); ) {
|
||||
const char *number;
|
||||
int service;
|
||||
int type;
|
||||
|
||||
if (!g_at_result_iter_skip_next(&iter))
|
||||
continue;
|
||||
|
||||
if (!g_at_result_iter_next_string(&iter, &number))
|
||||
continue;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &type))
|
||||
continue;
|
||||
|
||||
if (!g_at_result_iter_skip_next(&iter))
|
||||
continue;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &service))
|
||||
continue;
|
||||
|
||||
/* We are only interested in Voice services */
|
||||
if (service != 4)
|
||||
continue;
|
||||
|
||||
strncpy(list[num].number, number,
|
||||
OFONO_MAX_PHONE_NUMBER_LENGTH);
|
||||
list[num].number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
|
||||
list[num].type = type;
|
||||
|
||||
DBG("cnum_notify:%s", list[num].number);
|
||||
num++;
|
||||
}
|
||||
|
||||
out:
|
||||
cb(&error, num, list, cbd->data);
|
||||
|
||||
g_free(list);
|
||||
|
||||
}
|
||||
|
||||
static void hfp_cnum_query(struct ofono_handsfree *hf,
|
||||
ofono_handsfree_cnum_query_cb_t cb, void *data)
|
||||
{
|
||||
struct hf_data *hd = ofono_handsfree_get_data(hf);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
|
||||
if (g_at_chat_send(hd->chat, "AT+CNUM", NULL,
|
||||
cnum_query_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
g_free(cbd);
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, -1, NULL, data);
|
||||
}
|
||||
|
||||
static void bind_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_handsfree *hf = user_data;
|
||||
int hf_indicator;
|
||||
int active;
|
||||
GAtResultIter iter;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+BIND:"))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &hf_indicator))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &active))
|
||||
return;
|
||||
|
||||
ofono_handsfree_hf_indicator_active_notify(hf, hf_indicator, active);
|
||||
}
|
||||
|
||||
static gboolean hfp_handsfree_register(gpointer user_data)
|
||||
{
|
||||
struct ofono_handsfree *hf = user_data;
|
||||
@@ -237,13 +134,11 @@ static gboolean hfp_handsfree_register(gpointer user_data)
|
||||
g_at_chat_register(hd->chat, "+BSIR:", bsir_notify, FALSE, hf, NULL);
|
||||
g_at_chat_register(hd->chat, "+BVRA:", bvra_notify, FALSE, hf, NULL);
|
||||
g_at_chat_register(hd->chat, "+CIEV:", ciev_notify, FALSE, hf, NULL);
|
||||
g_at_chat_register(hd->chat, "+BIND:", bind_notify, FALSE, hf, NULL);
|
||||
|
||||
if (hd->ag_features & HFP_AG_FEATURE_IN_BAND_RING_TONE)
|
||||
ofono_handsfree_set_inband_ringing(hf, TRUE);
|
||||
|
||||
ofono_handsfree_set_ag_features(hf, hd->ag_features);
|
||||
ofono_handsfree_set_ag_chld_features(hf, hd->ag_chld_features);
|
||||
ofono_handsfree_register(hf);
|
||||
|
||||
return FALSE;
|
||||
@@ -254,13 +149,11 @@ static int hfp_handsfree_probe(struct ofono_handsfree *hf,
|
||||
{
|
||||
struct hfp_slc_info *info = data;
|
||||
struct hf_data *hd;
|
||||
unsigned int i;
|
||||
|
||||
DBG("");
|
||||
hd = g_new0(struct hf_data, 1);
|
||||
hd->chat = g_at_chat_clone(info->chat);
|
||||
hd->ag_features = info->ag_features;
|
||||
hd->ag_chld_features = info->ag_mpty_features;
|
||||
|
||||
ofono_handsfree_set_data(hf, hd);
|
||||
|
||||
@@ -268,14 +161,6 @@ static int hfp_handsfree_probe(struct ofono_handsfree *hf,
|
||||
ofono_handsfree_battchg_notify(hf,
|
||||
info->cind_val[HFP_INDICATOR_BATTCHG]);
|
||||
|
||||
ofono_handsfree_set_hf_indicators(hf, info->hf_indicators,
|
||||
info->num_hf_indicators);
|
||||
|
||||
for (i = 0; i < info->num_hf_indicators; i++)
|
||||
ofono_handsfree_hf_indicator_active_notify(hf,
|
||||
info->hf_indicators[i],
|
||||
info->hf_indicator_active_map & (1 << i));
|
||||
|
||||
hd->register_source = g_idle_add(hfp_handsfree_register, hf);
|
||||
|
||||
return 0;
|
||||
@@ -391,34 +276,13 @@ static void hfp_disable_nrec(struct ofono_handsfree *hf,
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
|
||||
static void hfp_hf_indicator(struct ofono_handsfree *hf,
|
||||
unsigned short indicator, unsigned int value,
|
||||
ofono_handsfree_cb_t cb, void *data)
|
||||
{
|
||||
struct hf_data *hd = ofono_handsfree_get_data(hf);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "AT+BIEV=%u,%u", indicator, value);
|
||||
|
||||
if (g_at_chat_send(hd->chat, buf, NULL, hf_generic_set_cb,
|
||||
cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
g_free(cbd);
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
|
||||
static struct ofono_handsfree_driver driver = {
|
||||
.name = "hfpmodem",
|
||||
.probe = hfp_handsfree_probe,
|
||||
.remove = hfp_handsfree_remove,
|
||||
.cnum_query = hfp_cnum_query,
|
||||
.request_phone_number = hfp_request_phone_number,
|
||||
.voice_recognition = hfp_voice_recognition,
|
||||
.disable_nrec = hfp_disable_nrec,
|
||||
.hf_indicator = hfp_hf_indicator,
|
||||
};
|
||||
|
||||
void hfp_handsfree_init(void)
|
||||
|
||||
@@ -41,12 +41,10 @@
|
||||
#include "hfp.h"
|
||||
#include "slc.h"
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static const char *brsf_prefix[] = { "+BRSF:", NULL };
|
||||
static const char *cind_prefix[] = { "+CIND:", NULL };
|
||||
static const char *cmer_prefix[] = { "+CMER:", NULL };
|
||||
static const char *chld_prefix[] = { "+CHLD:", NULL };
|
||||
static const char *bind_prefix[] = { "+BIND:", NULL };
|
||||
|
||||
struct slc_establish_data {
|
||||
gint ref_count;
|
||||
@@ -78,14 +76,6 @@ void hfp_slc_info_init(struct hfp_slc_info *info, guint16 version)
|
||||
|
||||
info->hf_features |= HFP_HF_FEATURE_CODEC_NEGOTIATION;
|
||||
|
||||
if (version < HFP_VERSION_1_7)
|
||||
goto done;
|
||||
|
||||
info->hf_features |= HFP_HF_FEATURE_HF_INDICATORS;
|
||||
memset(info->hf_indicators, 0, sizeof(info->hf_indicators));
|
||||
info->num_hf_indicators = 0;
|
||||
info->hf_indicator_active_map = 0;
|
||||
|
||||
done:
|
||||
memset(info->cind_val, 0, sizeof(info->cind_val));
|
||||
memset(info->cind_pos, 0, sizeof(info->cind_pos));
|
||||
@@ -117,104 +107,6 @@ static void slc_established(struct slc_establish_data *sed)
|
||||
sed->connect_cb(sed->userdata);
|
||||
}
|
||||
|
||||
static void bind_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct slc_establish_data *sed = user_data;
|
||||
struct hfp_slc_info *info = sed->info;
|
||||
GAtResultIter iter;
|
||||
int hf_indicator;
|
||||
int enabled;
|
||||
unsigned int i;
|
||||
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
while (g_at_result_iter_next(&iter, "+BIND:")) {
|
||||
if (!g_at_result_iter_next_number(&iter, &hf_indicator))
|
||||
goto error;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &enabled))
|
||||
goto error;
|
||||
|
||||
ofono_info("AG wants indicator %d %s",
|
||||
hf_indicator, enabled ? "enabled" : "disabled");
|
||||
|
||||
for (i = 0; i < info->num_hf_indicators; i++) {
|
||||
if (info->hf_indicators[i] != hf_indicator)
|
||||
continue;
|
||||
|
||||
info->hf_indicator_active_map |= enabled << i;
|
||||
}
|
||||
|
||||
ofono_info("Active map: %02x", info->hf_indicator_active_map);
|
||||
}
|
||||
|
||||
slc_established(sed);
|
||||
return;
|
||||
|
||||
error:
|
||||
slc_failed(sed);
|
||||
}
|
||||
|
||||
static void bind_support_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct slc_establish_data *sed = user_data;
|
||||
struct hfp_slc_info *info = sed->info;
|
||||
GAtResultIter iter;
|
||||
int hf_indicator;
|
||||
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+BIND:"))
|
||||
goto error;
|
||||
|
||||
if (!g_at_result_iter_open_list(&iter))
|
||||
goto error;
|
||||
|
||||
while (g_at_result_iter_next_number(&iter, &hf_indicator)) {
|
||||
if (info->num_hf_indicators >= 20)
|
||||
goto error;
|
||||
|
||||
ofono_info("AG supports the following HF indicator: %d",
|
||||
hf_indicator);
|
||||
|
||||
info->hf_indicators[info->num_hf_indicators] = hf_indicator;
|
||||
info->num_hf_indicators += 1;
|
||||
}
|
||||
|
||||
if (!g_at_result_iter_close_list(&iter))
|
||||
goto error;
|
||||
|
||||
slc_establish_data_ref(sed);
|
||||
g_at_chat_send(info->chat, "AT+BIND?", bind_prefix,
|
||||
bind_query_cb, sed, slc_establish_data_unref);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
slc_failed(sed);
|
||||
}
|
||||
|
||||
static void bind_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct slc_establish_data *sed = user_data;
|
||||
struct hfp_slc_info *info = sed->info;
|
||||
|
||||
if (!ok) {
|
||||
slc_failed(sed);
|
||||
return;
|
||||
}
|
||||
|
||||
slc_establish_data_ref(sed);
|
||||
g_at_chat_send(info->chat, "AT+BIND=?", bind_prefix,
|
||||
bind_support_cb, sed, slc_establish_data_unref);
|
||||
}
|
||||
|
||||
static void chld_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct slc_establish_data *sed = user_data;
|
||||
@@ -236,19 +128,19 @@ static void chld_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
|
||||
while (g_at_result_iter_next_unquoted_string(&iter, &str)) {
|
||||
if (!strcmp(str, "0"))
|
||||
ag_mpty_feature |= HFP_AG_CHLD_0;
|
||||
ag_mpty_feature |= AG_CHLD_0;
|
||||
else if (!strcmp(str, "1"))
|
||||
ag_mpty_feature |= HFP_AG_CHLD_1;
|
||||
ag_mpty_feature |= AG_CHLD_1;
|
||||
else if (!strcmp(str, "1x"))
|
||||
ag_mpty_feature |= HFP_AG_CHLD_1x;
|
||||
ag_mpty_feature |= AG_CHLD_1x;
|
||||
else if (!strcmp(str, "2"))
|
||||
ag_mpty_feature |= HFP_AG_CHLD_2;
|
||||
ag_mpty_feature |= AG_CHLD_2;
|
||||
else if (!strcmp(str, "2x"))
|
||||
ag_mpty_feature |= HFP_AG_CHLD_2x;
|
||||
ag_mpty_feature |= AG_CHLD_2x;
|
||||
else if (!strcmp(str, "3"))
|
||||
ag_mpty_feature |= HFP_AG_CHLD_3;
|
||||
ag_mpty_feature |= AG_CHLD_3;
|
||||
else if (!strcmp(str, "4"))
|
||||
ag_mpty_feature |= HFP_AG_CHLD_4;
|
||||
ag_mpty_feature |= AG_CHLD_4;
|
||||
}
|
||||
|
||||
if (!g_at_result_iter_close_list(&iter))
|
||||
@@ -256,14 +148,7 @@ static void chld_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
|
||||
info->ag_mpty_features = ag_mpty_feature;
|
||||
|
||||
if ((info->ag_features & HFP_AG_FEATURE_HF_INDICATORS) &&
|
||||
(info->hf_features & HFP_HF_FEATURE_HF_INDICATORS)) {
|
||||
slc_establish_data_ref(sed);
|
||||
g_at_chat_send(info->chat, "AT+BIND=1", none_prefix,
|
||||
bind_set_cb, sed, slc_establish_data_unref);
|
||||
} else
|
||||
slc_established(sed);
|
||||
|
||||
slc_established(sed);
|
||||
return;
|
||||
|
||||
error:
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define AG_CHLD_0 0x01
|
||||
#define AG_CHLD_1 0x02
|
||||
#define AG_CHLD_1x 0x04
|
||||
#define AG_CHLD_2 0x08
|
||||
#define AG_CHLD_2x 0x10
|
||||
#define AG_CHLD_3 0x20
|
||||
#define AG_CHLD_4 0x40
|
||||
|
||||
enum hfp_indicator {
|
||||
HFP_INDICATOR_SERVICE = 0,
|
||||
HFP_INDICATOR_CALL,
|
||||
@@ -39,9 +47,6 @@ struct hfp_slc_info {
|
||||
unsigned int hf_features;
|
||||
unsigned char cind_pos[HFP_INDICATOR_LAST];
|
||||
unsigned int cind_val[HFP_INDICATOR_LAST];
|
||||
unsigned short hf_indicators[20];
|
||||
unsigned char num_hf_indicators;
|
||||
unsigned int hf_indicator_active_map;
|
||||
};
|
||||
|
||||
void hfp_slc_info_init(struct hfp_slc_info *info, guint16 version);
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <ofono/voicecall.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "hfp.h"
|
||||
|
||||
#include "hfpmodem.h"
|
||||
#include "slc.h"
|
||||
@@ -46,7 +45,6 @@
|
||||
#define POLL_CLCC_DELAY 50
|
||||
#define EXPECT_RELEASE_DELAY 50
|
||||
#define CLIP_TIMEOUT 500
|
||||
#define EXPECT_RING_DELAY 200
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static const char *clcc_prefix[] = { "+CLCC:", NULL };
|
||||
@@ -295,7 +293,7 @@ static void clcc_poll_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
* we won't get indicator update if any of them is released by CHLD=1x.
|
||||
* So we have to poll it.
|
||||
*/
|
||||
if ((num_active > 1 || num_held > 1) && !vd->clcc_source)
|
||||
if (num_active > 1 || num_held > 1)
|
||||
vd->clcc_source = g_timeout_add(POLL_CLCC_INTERVAL, poll_clcc,
|
||||
vc);
|
||||
}
|
||||
@@ -449,7 +447,7 @@ static void hfp_hold_all_active(struct ofono_voicecall *vc,
|
||||
{
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
|
||||
if (vd->ag_mpty_features & HFP_AG_CHLD_2) {
|
||||
if (vd->ag_mpty_features & AG_CHLD_2) {
|
||||
hfp_template("AT+CHLD=2", vc, generic_cb, 0, cb, data);
|
||||
return;
|
||||
}
|
||||
@@ -463,7 +461,7 @@ static void hfp_release_all_held(struct ofono_voicecall *vc,
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
unsigned int held_status = 1 << CALL_STATUS_HELD;
|
||||
|
||||
if (vd->ag_mpty_features & HFP_AG_CHLD_0) {
|
||||
if (vd->ag_mpty_features & AG_CHLD_0) {
|
||||
hfp_template("AT+CHLD=0", vc, generic_cb, held_status,
|
||||
cb, data);
|
||||
return;
|
||||
@@ -478,7 +476,7 @@ static void hfp_set_udub(struct ofono_voicecall *vc,
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
unsigned int incoming_or_waiting = 1 << CALL_STATUS_WAITING;
|
||||
|
||||
if (vd->ag_mpty_features & HFP_AG_CHLD_0) {
|
||||
if (vd->ag_mpty_features & AG_CHLD_0) {
|
||||
hfp_template("AT+CHLD=0", vc, generic_cb, incoming_or_waiting,
|
||||
cb, data);
|
||||
return;
|
||||
@@ -500,19 +498,6 @@ static gboolean expect_release(gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean expect_ring(gpointer user_data)
|
||||
{
|
||||
struct ofono_voicecall *vc = user_data;
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
|
||||
g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
|
||||
clcc_poll_cb, vc, NULL);
|
||||
|
||||
vd->clip_source = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void release_all_active_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -543,7 +528,7 @@ static void hfp_release_all_active(struct ofono_voicecall *vc,
|
||||
{
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
|
||||
if (vd->ag_mpty_features & HFP_AG_CHLD_1) {
|
||||
if (vd->ag_mpty_features & AG_CHLD_1) {
|
||||
hfp_template("AT+CHLD=1", vc, release_all_active_cb, 0x1, cb,
|
||||
data);
|
||||
return;
|
||||
@@ -574,7 +559,7 @@ static void hfp_release_specific(struct ofono_voicecall *vc, int id,
|
||||
struct release_id_req *req = NULL;
|
||||
char buf[32];
|
||||
|
||||
if (!(vd->ag_mpty_features & HFP_AG_CHLD_1x))
|
||||
if (!(vd->ag_mpty_features & AG_CHLD_1x))
|
||||
goto error;
|
||||
|
||||
req = g_try_new0(struct release_id_req, 1);
|
||||
@@ -605,7 +590,7 @@ static void hfp_private_chat(struct ofono_voicecall *vc, int id,
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
char buf[32];
|
||||
|
||||
if (vd->ag_mpty_features & HFP_AG_CHLD_2x) {
|
||||
if (vd->ag_mpty_features & AG_CHLD_2x) {
|
||||
snprintf(buf, sizeof(buf), "AT+CHLD=2%d", id);
|
||||
|
||||
hfp_template(buf, vc, generic_cb, 0, cb, data);
|
||||
@@ -621,7 +606,7 @@ static void hfp_create_multiparty(struct ofono_voicecall *vc,
|
||||
{
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
|
||||
if (vd->ag_mpty_features & HFP_AG_CHLD_3) {
|
||||
if (vd->ag_mpty_features & AG_CHLD_3) {
|
||||
hfp_template("AT+CHLD=3", vc, generic_cb, 0, cb, data);
|
||||
|
||||
return;
|
||||
@@ -640,7 +625,7 @@ static void hfp_transfer(struct ofono_voicecall *vc,
|
||||
*/
|
||||
unsigned int transfer = 0x1 | 0x2 | 0x4 | 0x8;
|
||||
|
||||
if (vd->ag_mpty_features & HFP_AG_CHLD_4) {
|
||||
if (vd->ag_mpty_features & AG_CHLD_4) {
|
||||
hfp_template("AT+CHLD=4", vc, generic_cb, transfer, cb, data);
|
||||
|
||||
return;
|
||||
@@ -654,10 +639,8 @@ static void hfp_send_dtmf(struct ofono_voicecall *vc, const char *dtmf,
|
||||
{
|
||||
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
|
||||
struct change_state_req *req = g_try_new0(struct change_state_req, 1);
|
||||
int len = strlen(dtmf);
|
||||
char *buf;
|
||||
int s;
|
||||
int i;
|
||||
|
||||
if (req == NULL)
|
||||
goto error;
|
||||
@@ -667,15 +650,12 @@ static void hfp_send_dtmf(struct ofono_voicecall *vc, const char *dtmf,
|
||||
req->data = data;
|
||||
req->affected_types = 0;
|
||||
|
||||
/* strlen("AT") + (n-1) * strlen("+VTS=T;") + strlen(+VTS=T) + null */
|
||||
buf = g_try_new(char, len * 7 + 2);
|
||||
/* strlen("AT+VTS=) = 7 + NULL */
|
||||
buf = g_try_new(char, strlen(dtmf) + 8);
|
||||
if (buf == NULL)
|
||||
goto error;
|
||||
|
||||
s = sprintf(buf, "AT+VTS=%c", dtmf[0]);
|
||||
|
||||
for (i = 1; i < len; i++)
|
||||
s += sprintf(buf + s, ";+VTS=%c", dtmf[i]);
|
||||
sprintf(buf, "AT+VTS=%s", dtmf);
|
||||
|
||||
s = g_at_chat_send(vd->chat, buf, none_prefix,
|
||||
generic_cb, req, g_free);
|
||||
@@ -771,11 +751,6 @@ static void ring_notify(GAtResult *result, gpointer user_data)
|
||||
struct ofono_call *call;
|
||||
GSList *waiting;
|
||||
|
||||
if (vd->clip_source) {
|
||||
g_source_remove(vd->clip_source);
|
||||
vd->clip_source = 0;
|
||||
}
|
||||
|
||||
/* RING can repeat, ignore if we already have an incoming call */
|
||||
if (g_slist_find_custom(vd->calls,
|
||||
GINT_TO_POINTER(CALL_STATUS_INCOMING),
|
||||
@@ -1000,15 +975,7 @@ static void ciev_callsetup_notify(struct ofono_voicecall *vc,
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/*
|
||||
* Handled in RING/CCWA most of the time, however sometimes
|
||||
* the call is answered before the RING unsolicited
|
||||
* notification has a chance to be generated on the device.
|
||||
* In this case, we use a failsafe CLCC poll in expect_ring
|
||||
* callback.
|
||||
* */
|
||||
vd->clip_source = g_timeout_add(EXPECT_RING_DELAY,
|
||||
expect_ring, vc);
|
||||
/* Handled in RING/CCWA */
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
@@ -134,9 +134,7 @@ static void routing_resp_cb(const GIsiMessage *msg, void *data)
|
||||
struct cbs_data *cd = ofono_cbs_get_data(cbs);
|
||||
|
||||
if (!check_resp(msg, SMS_GSM_CB_ROUTING_RESP)) {
|
||||
/* on shutdown, cbs is already being removed */
|
||||
if (g_isi_msg_error(msg) != -ESHUTDOWN)
|
||||
ofono_cbs_remove(cbs);
|
||||
ofono_cbs_remove(cbs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ static int ril_call_barring_probe(struct ofono_call_barring *cb,
|
||||
|
||||
bd->ril = g_ril_clone(ril);
|
||||
ofono_call_barring_set_data(cb, bd);
|
||||
bd->timer_id = g_timeout_add_seconds(2, ril_delayed_register, cb);
|
||||
g_timeout_add_seconds(2, ril_delayed_register, cb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2013-2014 Jolla Ltd
|
||||
* Copyright (C) 2013 Jolla Ltd
|
||||
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -94,10 +94,11 @@ static void ril_registration(struct ofono_call_forwarding *cf, int type,
|
||||
* or settings made with bearer class
|
||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||
* BEARER_CLASS_VOICE as per RIL design.
|
||||
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
|
||||
* returns cls:53 i.e. 1+4+16+32 as service class.
|
||||
*/
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = BEARER_CLASS_VOICE;
|
||||
cls = SERVICE_CLASS_NONE;
|
||||
|
||||
parcel_w_int32(&rilp, cls);
|
||||
|
||||
@@ -139,10 +140,11 @@ static void ril_send_forward_cmd(struct ofono_call_forwarding *cf,
|
||||
* or settings made with bearer class
|
||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||
* BEARER_CLASS_VOICE as per RIL design.
|
||||
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
|
||||
* returns cls:53 i.e. 1+4+16+32 as service class.
|
||||
*/
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = BEARER_CLASS_VOICE;
|
||||
cls = SERVICE_CLASS_NONE;
|
||||
|
||||
parcel_w_int32(&rilp, cls); /* Service class */
|
||||
|
||||
@@ -214,7 +216,7 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
|
||||
nmbr_of_resps);
|
||||
|
||||
for (i = 0; i < nmbr_of_resps; i++) {
|
||||
char *str = NULL;
|
||||
const char *str;
|
||||
|
||||
list[i].status = parcel_r_int32(&rilp);
|
||||
|
||||
@@ -225,16 +227,19 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
|
||||
list[i].phone_number.type = parcel_r_int32(&rilp);
|
||||
|
||||
str = parcel_r_string(&rilp);
|
||||
|
||||
if (str) {
|
||||
|
||||
strncpy(list[i].phone_number.number,
|
||||
str,
|
||||
OFONO_MAX_PHONE_NUMBER_LENGTH);
|
||||
|
||||
list[i].phone_number.number[
|
||||
OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
|
||||
g_free(str);
|
||||
|
||||
list[i].time = parcel_r_int32(&rilp);
|
||||
}
|
||||
list[i].time = parcel_r_int32(&rilp);
|
||||
|
||||
}
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, nmbr_of_resps, list, cbd->data);
|
||||
@@ -268,7 +273,8 @@ static void ril_query(struct ofono_call_forwarding *cf, int type, int cls,
|
||||
* or settings made with bearer class
|
||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||
* SERVICE_CLASS_NONE as per RIL design.
|
||||
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
|
||||
* returns cls:53 i.e. 1+4+16+32 as service class.
|
||||
*/
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = SERVICE_CLASS_NONE;
|
||||
|
||||
@@ -42,8 +42,9 @@
|
||||
#include "rilmodem.h"
|
||||
|
||||
/*
|
||||
* TODO: No public RIL api to query manufacturer or model.
|
||||
* Check where to get, could /system/build.prop be updated to have good values?
|
||||
* TODO: The functions in this file are stubbed out, and
|
||||
* will need to be re-worked to talk to the /gril layer
|
||||
* in order to get real values from RILD.
|
||||
*/
|
||||
guint timer_id;
|
||||
|
||||
@@ -51,14 +52,30 @@ static void ril_query_manufacturer(struct ofono_devinfo *info,
|
||||
ofono_devinfo_query_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
CALLBACK_WITH_FAILURE(cb, "", data);
|
||||
const char *attr = "Fake Manufacturer";
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct ofono_error error;
|
||||
decode_ril_error(&error, "OK");
|
||||
|
||||
cb(&error, attr, cbd->data);
|
||||
|
||||
/* Note: this will need to change if cbd passed to gril layer */
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void ril_query_model(struct ofono_devinfo *info,
|
||||
ofono_devinfo_query_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
CALLBACK_WITH_FAILURE(cb, "", data);
|
||||
const char *attr = "Fake Modem Model";
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct ofono_error error;
|
||||
decode_ril_error(&error, "OK");
|
||||
|
||||
cb(&error, attr, cbd->data);
|
||||
|
||||
/* Note: this will need to change if cbd passed to gril layer */
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void query_revision_cb(struct ril_msg *message, gpointer user_data)
|
||||
@@ -81,7 +98,6 @@ static void query_revision_cb(struct ril_msg *message, gpointer user_data)
|
||||
revision = parcel_r_string(&rilp);
|
||||
|
||||
cb(&error, revision, cbd->data);
|
||||
g_free(revision);
|
||||
}
|
||||
|
||||
static void ril_query_revision(struct ofono_devinfo *info,
|
||||
@@ -121,10 +137,10 @@ static void query_serial_cb(struct ril_msg *message, gpointer user_data)
|
||||
}
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
|
||||
imei = parcel_r_string(&rilp);
|
||||
|
||||
cb(&error, imei, cbd->data);
|
||||
g_free(imei);
|
||||
}
|
||||
|
||||
static void ril_query_serial(struct ofono_devinfo *info,
|
||||
|
||||
@@ -43,16 +43,8 @@
|
||||
#include "grilrequest.h"
|
||||
#include "grilunsol.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "rilmodem.h"
|
||||
|
||||
enum data_call_state {
|
||||
DATA_CALL_INACTIVE,
|
||||
DATA_CALL_LINK_DOWN,
|
||||
DATA_CALL_ACTIVE,
|
||||
};
|
||||
|
||||
enum state {
|
||||
STATE_IDLE,
|
||||
STATE_ENABLING,
|
||||
@@ -66,111 +58,24 @@ struct gprs_context_data {
|
||||
gint active_rild_cid;
|
||||
enum state state;
|
||||
guint regid;
|
||||
struct unsol_data_call_list *old_list;
|
||||
guint prev_active_status;
|
||||
};
|
||||
|
||||
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
|
||||
unsigned int id,
|
||||
ofono_gprs_context_cb_t cb, void *data);
|
||||
|
||||
static void set_context_disconnected(struct gprs_context_data *gcd)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
gcd->active_ctx_cid = -1;
|
||||
gcd->active_rild_cid = -1;
|
||||
gcd->state = STATE_IDLE;
|
||||
}
|
||||
|
||||
static void ril_gprs_split_ip_by_protocol(char **ip_array,
|
||||
char ***split_ip_addr,
|
||||
char ***split_ipv6_addr,
|
||||
char **ip_addr)
|
||||
static void disconnect_context(struct ofono_gprs_context *gc)
|
||||
{
|
||||
const char ipv6_delimiter = ':';
|
||||
const char ip_delimiter = '.';
|
||||
int i;
|
||||
|
||||
*split_ipv6_addr = *split_ip_addr = NULL;
|
||||
for (i=0; i< g_strv_length(ip_array); i++) {
|
||||
if (strchr(ip_array[i], ipv6_delimiter)) {
|
||||
if (*split_ipv6_addr == NULL) {
|
||||
*split_ipv6_addr = g_strsplit(
|
||||
ip_array[i], "/",2);
|
||||
}
|
||||
} else if (strchr(ip_array[i], ip_delimiter)) {
|
||||
if (*split_ip_addr == NULL) {
|
||||
*ip_addr = g_strdup(ip_array[i]);
|
||||
*split_ip_addr = g_strsplit(
|
||||
ip_array[i], "/", 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_gprs_split_gw_by_protocol(char **gw_array, char **ip_gw,
|
||||
char **ipv6_gw)
|
||||
{
|
||||
const char ipv6_delimiter = ':';
|
||||
const char ip_delimiter = '.';
|
||||
int i;
|
||||
|
||||
*ip_gw = *ipv6_gw = NULL;
|
||||
for (i=0; i< g_strv_length(gw_array); i++) {
|
||||
if (strchr(gw_array[i],ipv6_delimiter)) {
|
||||
if (*ipv6_gw == NULL) {
|
||||
*ipv6_gw = g_strdup(gw_array[i]);
|
||||
}
|
||||
} else if (strchr(gw_array[i],ip_delimiter)) {
|
||||
if (*ip_gw == NULL)
|
||||
*ip_gw = g_strdup(gw_array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_gprs_split_dns_by_protocol(char **dns_array, char ***dns_addr,
|
||||
char ***dns_ipv6_addr)
|
||||
{
|
||||
const char ipv6_delimiter = ':';
|
||||
const char ip_delimiter = '.';
|
||||
char *temp = NULL;
|
||||
char *temp1 = NULL;
|
||||
char *dnsip = NULL;
|
||||
char *dnsipv6 = NULL;
|
||||
int i, dnsip_len, dnsipv6_len;
|
||||
|
||||
dnsip_len = dnsipv6_len = 0;
|
||||
|
||||
for (i=0; i< g_strv_length(dns_array); i++) {
|
||||
if (strchr(dns_array[i],ipv6_delimiter)) {
|
||||
if (dnsipv6 == NULL) {
|
||||
dnsipv6 = g_strdup(dns_array[i]);
|
||||
} else {
|
||||
temp = g_strconcat(dnsipv6, ",", NULL);
|
||||
g_free(dnsipv6);
|
||||
temp1 = g_strconcat(temp, dns_array[i], NULL);
|
||||
g_free(temp);
|
||||
dnsipv6 = temp1;
|
||||
}
|
||||
dnsipv6_len++;
|
||||
} else if (strchr(dns_array[i],ip_delimiter)) {
|
||||
if (dnsip == NULL) {
|
||||
dnsip = g_strdup(dns_array[i]);
|
||||
} else {
|
||||
temp = g_strconcat(dnsip, ",", NULL);
|
||||
g_free(dnsip);
|
||||
temp1 = g_strconcat(temp, dns_array[i], NULL);
|
||||
g_free(temp);
|
||||
dnsip = temp1;
|
||||
|
||||
}
|
||||
dnsip_len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dnsip)
|
||||
*dns_addr = g_strsplit(dnsip, ",", dnsip_len);
|
||||
|
||||
if (dnsipv6)
|
||||
*dns_ipv6_addr = g_strsplit(dnsipv6, ",", dnsipv6_len);
|
||||
|
||||
g_free(dnsip);
|
||||
g_free(dnsipv6);
|
||||
ril_gprs_context_deactivate_primary(gc, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
@@ -180,8 +85,8 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
||||
struct data_call *call = NULL;
|
||||
struct unsol_data_call_list *unsol;
|
||||
gboolean active_cid_found = FALSE;
|
||||
gboolean disconnect = FALSE;
|
||||
gboolean signal = FALSE;
|
||||
GSList *iterator = NULL;
|
||||
struct ofono_error error;
|
||||
|
||||
@@ -190,164 +95,28 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
if (error.type != OFONO_ERROR_TYPE_NO_ERROR)
|
||||
goto error;
|
||||
|
||||
if (g_ril_unsol_cmp_dcl(unsol,gcd->old_list,gcd->active_rild_cid))
|
||||
goto error;
|
||||
|
||||
g_ril_unsol_free_data_call_list(gcd->old_list);
|
||||
gcd->old_list = unsol;
|
||||
|
||||
DBG("number of call in call_list_changed is: %d", unsol->num);
|
||||
|
||||
for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
|
||||
call = (struct data_call *) iterator->data;
|
||||
|
||||
/*
|
||||
* Every context receives notifications about all data calls
|
||||
* but should only handle its own.
|
||||
*/
|
||||
if (call->cid != gcd->active_rild_cid)
|
||||
continue;
|
||||
if (call->cid == gcd->active_rild_cid) {
|
||||
active_cid_found = TRUE;
|
||||
|
||||
if (call->active == DATA_CALL_LINK_DOWN)
|
||||
gcd->prev_active_status = call->active;
|
||||
|
||||
if (call->status != 0)
|
||||
ofono_info("data call status:%d", call->status);
|
||||
|
||||
if (call->active == DATA_CALL_INACTIVE) {
|
||||
disconnect = TRUE;
|
||||
gcd->prev_active_status = call->active;
|
||||
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
|
||||
break;
|
||||
}
|
||||
|
||||
if (call->active == DATA_CALL_ACTIVE) {
|
||||
int protocol = -1;
|
||||
|
||||
if (gcd->prev_active_status != DATA_CALL_LINK_DOWN)
|
||||
signal = TRUE;
|
||||
|
||||
gcd->prev_active_status = call->active;
|
||||
|
||||
if (call->type)
|
||||
protocol = ril_protocol_string_to_ofono_protocol(call->type);
|
||||
|
||||
if (call->ifname)
|
||||
ofono_gprs_context_set_interface(gc,
|
||||
call->ifname);
|
||||
|
||||
if (call->addresses) {
|
||||
char **split_ip_addr = NULL;
|
||||
char **ip_array = NULL;
|
||||
char **split_ipv6_addr = NULL;
|
||||
char *ip_addr = NULL;
|
||||
|
||||
/*addresses to an array*/
|
||||
ip_array = g_strsplit(call->addresses, " ",-1);
|
||||
|
||||
/*pick 1 address of each protocol*/
|
||||
ril_gprs_split_ip_by_protocol(ip_array,
|
||||
&split_ip_addr,
|
||||
&split_ipv6_addr,
|
||||
&ip_addr);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IPV6)
|
||||
&& split_ipv6_addr != NULL){
|
||||
|
||||
ofono_gprs_context_set_ipv6_address(gc,
|
||||
split_ipv6_addr[0]);
|
||||
}
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IP)
|
||||
&& split_ip_addr != NULL) {
|
||||
|
||||
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||
ril_util_get_netmask(ip_addr));
|
||||
ofono_gprs_context_set_ipv4_address(gc,
|
||||
split_ip_addr[0], TRUE);
|
||||
}
|
||||
|
||||
g_strfreev(split_ip_addr);
|
||||
g_strfreev(split_ipv6_addr);
|
||||
g_strfreev(ip_array);
|
||||
g_free(ip_addr);
|
||||
if (call->active == 0) {
|
||||
disconnect = TRUE;
|
||||
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
|
||||
}
|
||||
|
||||
if (call->gateways) {
|
||||
char **gw_array = NULL;
|
||||
char *ip_gw = NULL;
|
||||
char *ipv6_gw = NULL;
|
||||
/*addresses to an array*/
|
||||
gw_array = g_strsplit(call->gateways, " ", -1);
|
||||
|
||||
/*pick 1 gw for each protocol*/
|
||||
ril_gprs_split_gw_by_protocol(gw_array, &ip_gw,
|
||||
&ipv6_gw);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IPV6)
|
||||
&& ipv6_gw != NULL)
|
||||
ofono_gprs_context_set_ipv6_gateway(gc,
|
||||
ipv6_gw);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IP)
|
||||
&& ip_gw != NULL)
|
||||
ofono_gprs_context_set_ipv4_gateway(gc,
|
||||
ip_gw);
|
||||
|
||||
g_strfreev(gw_array);
|
||||
g_free(ip_gw);
|
||||
g_free(ipv6_gw);
|
||||
}
|
||||
|
||||
if (call->dnses) {
|
||||
char **dns_array = NULL;
|
||||
char **dns_ip = NULL;
|
||||
char **dns_ipv6 = NULL;
|
||||
|
||||
/*addresses to an array*/
|
||||
dns_array = g_strsplit(call->dnses, " ", -1);
|
||||
|
||||
/*split based on protocol*/
|
||||
ril_gprs_split_dns_by_protocol(dns_array,
|
||||
&dns_ip,
|
||||
&dns_ipv6);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IPV6)
|
||||
&& dns_ipv6 != NULL)
|
||||
ofono_gprs_context_set_ipv6_dns_servers(
|
||||
gc, (const char **) dns_ipv6);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IP)
|
||||
&& dns_ip != NULL)
|
||||
ofono_gprs_context_set_ipv4_dns_servers(
|
||||
gc, (const char**)dns_ip);
|
||||
|
||||
g_strfreev(dns_ip);
|
||||
g_strfreev(dns_ipv6);
|
||||
g_strfreev(dns_array);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (disconnect) {
|
||||
if (disconnect || active_cid_found == FALSE) {
|
||||
ofono_error("Clearing active context");
|
||||
set_context_disconnected(gcd);
|
||||
gcd->old_list = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (signal)
|
||||
ofono_gprs_context_signal_change(gc, gcd->active_ctx_cid);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
g_ril_unsol_free_data_call_list(unsol);
|
||||
}
|
||||
@@ -361,12 +130,6 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
struct ofono_error error;
|
||||
struct reply_setup_data_call *reply = NULL;
|
||||
char **split_ip_addr = NULL;
|
||||
char **split_ipv6_addr = NULL;
|
||||
char* ip_addr = NULL;
|
||||
char* ip_gw = NULL;
|
||||
char* ipv6_gw = NULL;
|
||||
char** dns_addr = NULL;
|
||||
char** dns_ipv6_addr = NULL;
|
||||
|
||||
ofono_info("setting up data call");
|
||||
|
||||
@@ -386,7 +149,10 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
gcd->active_rild_cid = reply->cid;
|
||||
|
||||
if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
ofono_error("no active context. disconnect");
|
||||
if (gcd->active_rild_cid != -1) {
|
||||
ofono_error("no active context. disconnect");
|
||||
disconnect_context(gc);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -398,16 +164,24 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
error.type = OFONO_ERROR_TYPE_FAILURE;
|
||||
error.error = reply->status;
|
||||
|
||||
set_context_disconnected(gcd);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*check the ip address protocol*/
|
||||
ril_gprs_split_ip_by_protocol(reply->ip_addrs, &split_ip_addr,
|
||||
&split_ipv6_addr, &ip_addr);
|
||||
/*
|
||||
* TODO: consier moving this into parse_data_reply
|
||||
*
|
||||
* Note - the address may optionally include a prefix size
|
||||
* ( Eg. "/30" ). As this confuses NetworkManager, we
|
||||
* explicitly strip any prefix after calculating the netmask.
|
||||
*/
|
||||
split_ip_addr = g_strsplit(reply->ip_addrs[0], "/", 2);
|
||||
|
||||
if (split_ip_addr == NULL && split_ipv6_addr == NULL) {
|
||||
ofono_error("%s: No IP address returned",
|
||||
__func__);
|
||||
/* TODO: see note above re: invalid messages... */
|
||||
if (split_ip_addr[0] == NULL) {
|
||||
ofono_error("%s: invalid IP address field returned: %s",
|
||||
__func__,
|
||||
reply->ip_addrs[0]);
|
||||
|
||||
error.type = OFONO_ERROR_TYPE_FAILURE;
|
||||
error.error = EINVAL;
|
||||
@@ -420,55 +194,33 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
ofono_gprs_context_set_interface(gc, reply->ifname);
|
||||
|
||||
ril_gprs_split_gw_by_protocol(reply->gateways, &ip_gw, &ipv6_gw);
|
||||
|
||||
ril_gprs_split_dns_by_protocol(reply->dns_addresses, &dns_addr,
|
||||
&dns_ipv6_addr);
|
||||
|
||||
/* TODO:
|
||||
* RILD can return multiple addresses; oFono only supports setting
|
||||
* a single IPv4 and single IPV6 address. At this time, we only use
|
||||
* the first address. It's possible that a RIL may just specify
|
||||
* the end-points of the point-to-point connection, in which case this
|
||||
* code will need to changed to handle such a device.
|
||||
* RILD can return multiple addresses; oFono only supports
|
||||
* setting a single IPv4 address. At this time, we only
|
||||
* use the first address. It's possible that a RIL may
|
||||
* just specify the end-points of the point-to-point
|
||||
* connection, in which case this code will need to
|
||||
* changed to handle such a device.
|
||||
*/
|
||||
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||
ril_util_get_netmask(reply->ip_addrs[0]));
|
||||
|
||||
if (split_ipv6_addr != NULL &&
|
||||
(reply->protocol == OFONO_GPRS_PROTO_IPV6 ||
|
||||
reply->protocol == OFONO_GPRS_PROTO_IPV4V6)) {
|
||||
ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
|
||||
ofono_gprs_context_set_ipv4_gateway(gc, reply->gateways[0]);
|
||||
|
||||
ofono_gprs_context_set_ipv6_address(gc, split_ipv6_addr[0]);
|
||||
ofono_gprs_context_set_ipv6_gateway(gc, ipv6_gw);
|
||||
ofono_gprs_context_set_ipv6_dns_servers(gc,
|
||||
(const char **) dns_ipv6_addr);
|
||||
}
|
||||
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
||||
(const char **) reply->dns_addresses);
|
||||
|
||||
if (split_ip_addr != NULL &&
|
||||
(reply->protocol == OFONO_GPRS_PROTO_IP ||
|
||||
reply->protocol == OFONO_GPRS_PROTO_IPV4V6)) {
|
||||
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||
ril_util_get_netmask(ip_addr));
|
||||
ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
|
||||
ofono_gprs_context_set_ipv4_gateway(gc, ip_gw);
|
||||
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
||||
(const char **) dns_addr);
|
||||
}
|
||||
error:
|
||||
g_ril_reply_free_setup_data_call(reply);
|
||||
g_strfreev(split_ip_addr);
|
||||
g_strfreev(split_ipv6_addr);
|
||||
g_strfreev(dns_addr);
|
||||
g_strfreev(dns_ipv6_addr);
|
||||
g_free(ip_addr);
|
||||
g_free(ip_gw);
|
||||
g_free(ipv6_gw);
|
||||
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
|
||||
const struct ofono_gprs_primary_context *ctx,
|
||||
ofono_gprs_context_cb_t cb, void *data)
|
||||
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 cb_data *cbd = cb_data_new(cb, data);
|
||||
@@ -477,19 +229,9 @@ static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
|
||||
struct ofono_error error;
|
||||
int reqid = RIL_REQUEST_SETUP_DATA_CALL;
|
||||
int ret = 0;
|
||||
int netreg_status;
|
||||
int roaming = NETWORK_REGISTRATION_STATUS_ROAMING;
|
||||
|
||||
ofono_info("Activating context: %d", ctx->cid);
|
||||
|
||||
/* Let's make sure that we aren't connecting when roaming not allowed */
|
||||
netreg_status = get_current_network_status();
|
||||
if (netreg_status == roaming) {
|
||||
if (!ril_roaming_allowed() && (roaming
|
||||
== check_if_really_roaming(netreg_status)))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cbd->user = gc;
|
||||
|
||||
/* TODO: implement radio technology selection. */
|
||||
@@ -503,7 +245,6 @@ static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
|
||||
request.username = g_strdup(ctx->username);
|
||||
request.password = g_strdup(ctx->password);
|
||||
request.auth_type = RIL_AUTH_BOTH;
|
||||
|
||||
request.protocol = ctx->proto;
|
||||
|
||||
if (g_ril_request_setup_data_call(gcd->ril,
|
||||
@@ -532,7 +273,7 @@ error:
|
||||
g_free(request.apn);
|
||||
g_free(request.username);
|
||||
g_free(request.password);
|
||||
exit:
|
||||
|
||||
if (ret <= 0) {
|
||||
ofono_error("Send RIL_REQUEST_SETUP_DATA_CALL failed.");
|
||||
|
||||
@@ -543,8 +284,7 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_deactivate_data_call_cb(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
static void ril_deactivate_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_gprs_context_cb_t cb = cbd->cb;
|
||||
@@ -582,8 +322,7 @@ static void ril_deactivate_data_call_cb(struct ril_msg *message,
|
||||
|
||||
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
|
||||
unsigned int id,
|
||||
ofono_gprs_context_cb_t cb,
|
||||
void *data)
|
||||
ofono_gprs_context_cb_t cb, void *data)
|
||||
{
|
||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
||||
struct cb_data *cbd = NULL;
|
||||
@@ -636,7 +375,6 @@ error:
|
||||
if (ret <= 0) {
|
||||
ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");
|
||||
g_free(cbd);
|
||||
|
||||
if (cb)
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
@@ -664,6 +402,7 @@ static int ril_gprs_context_probe(struct ofono_gprs_context *gc,
|
||||
set_context_disconnected(gcd);
|
||||
|
||||
ofono_gprs_context_set_data(gc, gcd);
|
||||
gcd->regid = -1;
|
||||
|
||||
gcd->regid = g_ril_register(gcd->ril, RIL_UNSOL_DATA_CALL_LIST_CHANGED,
|
||||
ril_gprs_context_call_list_changed, gc);
|
||||
@@ -676,15 +415,14 @@ static void ril_gprs_context_remove(struct ofono_gprs_context *gc)
|
||||
|
||||
DBG("");
|
||||
|
||||
g_ril_unsol_free_data_call_list(gcd->old_list);
|
||||
|
||||
if (gcd->state != STATE_IDLE)
|
||||
if (gcd->state != STATE_IDLE) {
|
||||
ril_gprs_context_detach_shutdown(gc, 0);
|
||||
}
|
||||
|
||||
ofono_gprs_context_set_data(gc, NULL);
|
||||
|
||||
|
||||
if (gcd->regid != -1)
|
||||
g_ril_unregister(gcd->ril, gcd->regid);
|
||||
g_ril_unregister(gcd->ril,gcd->regid);
|
||||
|
||||
g_ril_unref(gcd->ril);
|
||||
g_free(gcd);
|
||||
@@ -694,9 +432,9 @@ static struct ofono_gprs_context_driver driver = {
|
||||
.name = RILMODEM,
|
||||
.probe = ril_gprs_context_probe,
|
||||
.remove = ril_gprs_context_remove,
|
||||
.activate_primary = ril_gprs_context_activate_primary,
|
||||
.deactivate_primary = ril_gprs_context_deactivate_primary,
|
||||
.detach_shutdown = ril_gprs_context_detach_shutdown,
|
||||
.activate_primary = ril_gprs_context_activate_primary,
|
||||
.deactivate_primary = ril_gprs_context_deactivate_primary,
|
||||
.detach_shutdown = ril_gprs_context_detach_shutdown,
|
||||
};
|
||||
|
||||
void ril_gprs_context_init(void)
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
#include "rilmodem.h"
|
||||
|
||||
#include <ofono/netreg.h>
|
||||
#include <ofono/sim.h>
|
||||
#include "storage.h"
|
||||
|
||||
/*
|
||||
* This module is the ofono_gprs_driver implementation for rilmodem.
|
||||
@@ -69,18 +67,12 @@ struct gprs_data {
|
||||
GRil *ril;
|
||||
gboolean ofono_attached;
|
||||
int max_cids;
|
||||
int rild_status; /* Driver Status */
|
||||
int rild_status;
|
||||
gboolean notified;
|
||||
guint registerid;
|
||||
guint timer_id;
|
||||
};
|
||||
|
||||
/* Following constants are purely to improve readability */
|
||||
static const int roaming = NETWORK_REGISTRATION_STATUS_ROAMING;
|
||||
static const int registered = NETWORK_REGISTRATION_STATUS_REGISTERED;
|
||||
|
||||
/*if we have called ofono_gprs_register or not*/
|
||||
static gboolean ofono_registered;
|
||||
|
||||
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
||||
ofono_gprs_status_cb_t cb,
|
||||
void *data);
|
||||
@@ -89,10 +81,7 @@ static void ril_gprs_state_change(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_gprs *gprs = user_data;
|
||||
|
||||
g_assert(message->req ==
|
||||
RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
|
||||
|
||||
DBG("");
|
||||
g_assert(message->req == RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
|
||||
|
||||
/* We need to notify core always to cover situations when
|
||||
* connection drops temporarily for example when user is
|
||||
@@ -108,7 +97,6 @@ static gboolean ril_gprs_set_attached_callback(gpointer user_data)
|
||||
ofono_gprs_cb_t cb = cbd->cb;
|
||||
struct ofono_gprs *gprs = cbd->user;
|
||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
||||
|
||||
DBG("");
|
||||
|
||||
gd->timer_id = 0;
|
||||
@@ -145,6 +133,7 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
|
||||
|
||||
cbd->user = gprs;
|
||||
|
||||
ril_gprs_registration_status(gprs, NULL, NULL);
|
||||
/*
|
||||
* However we cannot respond immediately, since core sets the
|
||||
* value of driver_attached after calling set_attached and that
|
||||
@@ -155,30 +144,6 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
|
||||
cbd);
|
||||
}
|
||||
|
||||
gboolean ril_roaming_allowed()
|
||||
{
|
||||
GError *error;
|
||||
error = NULL;
|
||||
GKeyFile *settings;
|
||||
struct ofono_sim *sim;
|
||||
|
||||
sim = get_sim();
|
||||
const char *imsi = ofono_sim_get_imsi(sim);
|
||||
settings = storage_open(imsi, "gprs");
|
||||
gboolean roaming_allowed = g_key_file_get_boolean(settings,
|
||||
"Settings",
|
||||
"RoamingAllowed",
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
g_error_free(error);
|
||||
|
||||
storage_close(imsi, "gprs", settings, FALSE);
|
||||
|
||||
DBG("roaming_allowed: %d", roaming_allowed);
|
||||
return roaming_allowed;
|
||||
}
|
||||
|
||||
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
@@ -186,9 +151,9 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
struct ofono_gprs *gprs = cbd->user;
|
||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
||||
struct ofono_error error;
|
||||
int lac, ci, tech;
|
||||
int status, lac, ci, tech;
|
||||
int max_cids = 1;
|
||||
int status = -1;
|
||||
int id = RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED;
|
||||
|
||||
if (gd && message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
@@ -197,22 +162,24 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
ril_error_to_string(message->error));
|
||||
decode_ril_error(&error, "FAIL");
|
||||
error.error = message->error;
|
||||
goto exit;
|
||||
status = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ril_util_parse_reg(gd->ril, message, &status,
|
||||
&lac, &ci, &tech, &max_cids) == FALSE) {
|
||||
ofono_error("Failure parsing data registration response.");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
goto exit;
|
||||
status = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (status > 10)
|
||||
status = status - 10;
|
||||
|
||||
if (!ofono_registered) {
|
||||
if (gd->rild_status == -1) {
|
||||
ofono_gprs_register(gprs);
|
||||
ofono_registered = TRUE;
|
||||
|
||||
DBG("Starting to listen network status");
|
||||
gd->registerid = g_ril_register(gd->ril,
|
||||
id, ril_gprs_state_change, gprs);
|
||||
}
|
||||
|
||||
if (max_cids > gd->max_cids) {
|
||||
@@ -221,129 +188,70 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
ofono_gprs_set_cid_range(gprs, 1, max_cids);
|
||||
}
|
||||
|
||||
if (status == roaming)
|
||||
ofono_info("data registration status is %d", status);
|
||||
|
||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||
status = check_if_really_roaming(status);
|
||||
|
||||
/* Let's minimize logging */
|
||||
if (status != gd->rild_status)
|
||||
ofono_info("data reg changes %d (%d), attached %d",
|
||||
status, gd->rild_status, gd->ofono_attached);
|
||||
|
||||
/* Must be attached if registered or roaming */
|
||||
if ((gd->rild_status != registered) && (gd->rild_status != roaming)) {
|
||||
if (status == registered)
|
||||
gd->ofono_attached = TRUE;
|
||||
else if ((status == roaming) && (ril_roaming_allowed() == TRUE))
|
||||
if (gd->ofono_attached && !gd->notified) {
|
||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
|
||||
status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
|
||||
DBG("connection becomes available");
|
||||
gd->ofono_attached = TRUE;
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
gd->notified = TRUE;
|
||||
gd->rild_status = status;
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!ofono_modem_get_online(ofono_gprs_get_modem(gprs)))
|
||||
gd->ofono_attached = FALSE;
|
||||
|
||||
/* if unsolicitated and no state change let's not notify core */
|
||||
if ((status == gd->rild_status) && gd->ofono_attached)
|
||||
goto cb_out;
|
||||
|
||||
if (!gd->ofono_attached) {
|
||||
if (!cb) {
|
||||
if (status == roaming) {
|
||||
if (ril_roaming_allowed() == FALSE)
|
||||
ofono_gprs_detached_notify(gprs);
|
||||
|
||||
/*
|
||||
* This prevents core ending
|
||||
* into eternal loop with driver
|
||||
*/
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
|
||||
} else {
|
||||
if (gd->ofono_attached &&
|
||||
status != NETWORK_REGISTRATION_STATUS_SEARCHING) {
|
||||
DBG("ofono attached, start faking responses");
|
||||
if (status != NETWORK_REGISTRATION_STATUS_ROAMING) {
|
||||
/*
|
||||
* This prevents core ending
|
||||
* into eternal loop with driver
|
||||
*/
|
||||
decode_ril_error(&error, "FAIL");
|
||||
* Only core can succesfully drop the connection
|
||||
* If we drop the connection from here it leads
|
||||
* to race situation where core asks context
|
||||
* deactivation and at the same time we get
|
||||
* Registered notification from modem.
|
||||
*/
|
||||
status = NETWORK_REGISTRATION_STATUS_REGISTERED;
|
||||
}
|
||||
|
||||
gd->rild_status = status;
|
||||
goto exit;
|
||||
}
|
||||
if (gd->registerid != -1)
|
||||
g_ril_unregister(gd->ril, gd->registerid);
|
||||
gd->registerid = -1;
|
||||
} else {
|
||||
/*
|
||||
* Client is not approving succesful result
|
||||
* This covers the situation when context is
|
||||
* active in roaming situation and client closes
|
||||
* it directly by calling RoamingAllowed in API
|
||||
*/
|
||||
DBG("data registration status is %d", status);
|
||||
|
||||
if (!cb)
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
if (status != NETWORK_REGISTRATION_STATUS_SEARCHING) {
|
||||
DBG("ofono not attached, notify core");
|
||||
status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
|
||||
ofono_gprs_detached_notify(gprs);
|
||||
gd->notified = FALSE;
|
||||
gd->ofono_attached = FALSE;
|
||||
} else if (gd->notified) {
|
||||
DBG("hide the searching state");
|
||||
status = NETWORK_REGISTRATION_STATUS_REGISTERED;
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
gd->ofono_attached = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gd->rild_status = status;
|
||||
|
||||
exit:
|
||||
DBG("data reg status %d, rild_status %d, attached %d",
|
||||
status, gd->rild_status, gd->ofono_attached);
|
||||
cb_out:
|
||||
error:
|
||||
if (cb)
|
||||
cb(&error, status, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_data_probe_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_gprs *gprs = cbd->user;
|
||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
||||
struct ofono_error error;
|
||||
int status, lac, ci, tech;
|
||||
int max_cids = 1;
|
||||
int id = RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (!(gd && message->error == RIL_E_SUCCESS)) {
|
||||
ofono_error("ril_data_reg_cb: reply failure: %s",
|
||||
ril_error_to_string(message->error));
|
||||
decode_ril_error(&error, "FAIL");
|
||||
error.error = message->error;
|
||||
status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
decode_ril_error(&error, "OK");
|
||||
status = -1;
|
||||
|
||||
if (ril_util_parse_reg(gd->ril, message, &status,
|
||||
&lac, &ci, &tech, &max_cids) == FALSE) {
|
||||
ofono_error("Failure parsing data registration response.");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
|
||||
if (status == -1)
|
||||
status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (status > 10)
|
||||
status = status - 10;
|
||||
|
||||
ofono_gprs_register(gprs);
|
||||
|
||||
ofono_registered = TRUE;
|
||||
|
||||
if (max_cids > gd->max_cids) {
|
||||
DBG("Setting max cids to %d", max_cids);
|
||||
gd->max_cids = max_cids;
|
||||
ofono_gprs_set_cid_range(gprs, 1, max_cids);
|
||||
}
|
||||
|
||||
if (status == roaming)
|
||||
status = check_if_really_roaming(status);
|
||||
|
||||
out:
|
||||
ofono_info("data reg status probed %d", status);
|
||||
|
||||
gd->registerid = g_ril_register(gd->ril,
|
||||
id, ril_gprs_state_change, gprs);
|
||||
|
||||
gd->rild_status = status;
|
||||
}
|
||||
|
||||
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
||||
ofono_gprs_status_cb_t cb,
|
||||
void *data)
|
||||
@@ -353,27 +261,20 @@ static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
||||
int request = RIL_REQUEST_DATA_REGISTRATION_STATE;
|
||||
guint ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (gd == NULL || cbd == NULL)
|
||||
return;
|
||||
|
||||
cbd->user = gprs;
|
||||
|
||||
ret = g_ril_send(gd->ril, request,
|
||||
NULL, 0,
|
||||
((gd->rild_status == -1)
|
||||
? ril_data_probe_reg_cb
|
||||
: ril_data_reg_cb), cbd, g_free);
|
||||
NULL, 0, ril_data_reg_cb, cbd, g_free);
|
||||
|
||||
g_ril_print_request_no_args(gd->ril, ret, request);
|
||||
|
||||
if (ret <= 0) {
|
||||
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE fail.");
|
||||
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE failed.");
|
||||
g_free(cbd);
|
||||
|
||||
if (cb)
|
||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,11 +292,9 @@ static int ril_gprs_probe(struct ofono_gprs *gprs,
|
||||
gd->ofono_attached = FALSE;
|
||||
gd->max_cids = 0;
|
||||
gd->rild_status = -1;
|
||||
gd->notified = FALSE;
|
||||
gd->registerid = -1;
|
||||
gd->timer_id = 0;
|
||||
|
||||
ofono_registered = FALSE;
|
||||
|
||||
ofono_gprs_set_data(gprs, gd);
|
||||
|
||||
ril_gprs_registration_status(gprs, NULL, NULL);
|
||||
|
||||
@@ -55,7 +55,6 @@ struct netreg_data {
|
||||
guint nitz_timeout;
|
||||
unsigned int vendor;
|
||||
guint timer_id;
|
||||
int corestatus; /* Registration status previously reported to core */
|
||||
};
|
||||
|
||||
/* 27.007 Section 7.3 <stat> */
|
||||
@@ -79,20 +78,25 @@ static void extract_mcc_mnc(const char *str, char *mcc, char *mnc)
|
||||
mnc[OFONO_MAX_MNC_LENGTH] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: The functions in this file are stubbed out, and
|
||||
* will need to be re-worked to talk to the /gril layer
|
||||
* in order to get real values from RILD.
|
||||
*/
|
||||
|
||||
static void ril_creg_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_netreg_status_cb_t cb = cbd->cb;
|
||||
struct netreg_data *nd = cbd->user;
|
||||
struct ofono_error error;
|
||||
int status, logstatus, lac, ci, tech;
|
||||
int status, lac, ci, tech;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (message->error != RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "FAIL");
|
||||
ofono_error("voice registration status query fail");
|
||||
nd->corestatus = -1;
|
||||
ofono_error("Failed to pull registration state");
|
||||
cb(&error, -1, -1, -1, -1, cbd->data);
|
||||
return;
|
||||
}
|
||||
@@ -101,31 +105,20 @@ static void ril_creg_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
if (ril_util_parse_reg(nd->ril, message, &status,
|
||||
&lac, &ci, &tech, NULL) == FALSE) {
|
||||
DBG("voice registration status parsing fail");
|
||||
nd->corestatus = -1;
|
||||
CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("voice registration status is %d", status);
|
||||
|
||||
if (status > 10)
|
||||
status = status - 10;
|
||||
|
||||
logstatus = status;
|
||||
|
||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||
status = check_if_really_roaming(status);
|
||||
|
||||
DBG("status:%d corestatus:%d", status, nd->corestatus);
|
||||
ofono_info("voice registration status is %d", status);
|
||||
|
||||
if (status != logstatus)
|
||||
ofono_info("voice registration modified %d (%d)",
|
||||
status, logstatus);
|
||||
|
||||
if (nd->corestatus != status)
|
||||
ofono_info("voice registration changes %d (%d)",
|
||||
status, nd->corestatus);
|
||||
|
||||
nd->corestatus = status;
|
||||
nd->tech = tech;
|
||||
cb(&error, status, lac, ci, tech, cbd->data);
|
||||
}
|
||||
@@ -135,16 +128,15 @@ static void ril_creg_notify(struct ofono_error *error, int status, int lac,
|
||||
{
|
||||
struct ofono_netreg *netreg = user_data;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
DBG("Error during status notification");
|
||||
return;
|
||||
}
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
DBG("Error during status notification");
|
||||
return;
|
||||
}
|
||||
|
||||
ofono_netreg_status_notify(netreg, status, lac, ci, tech);
|
||||
}
|
||||
|
||||
static void ril_network_state_change(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
static void ril_network_state_change(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_netreg *netreg = user_data;
|
||||
struct netreg_data *nd = ofono_netreg_get_data(netreg);
|
||||
@@ -372,7 +364,6 @@ static void ril_cops_list_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
cb(&error, noperators, list, cbd->data);
|
||||
|
||||
g_free(list);
|
||||
return;
|
||||
|
||||
error:
|
||||
@@ -414,8 +405,7 @@ static void ril_register_cb(struct ril_msg *message, gpointer user_data)
|
||||
g_ril_print_response_no_args(nd->ril, message);
|
||||
|
||||
} else {
|
||||
ofono_error("registration failed, ril result %d",
|
||||
message->error);
|
||||
ofono_error("registration failed");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
@@ -431,8 +421,6 @@ static void ril_register_auto(struct ofono_netreg *netreg,
|
||||
int ret;
|
||||
cbd->user = nd;
|
||||
|
||||
ofono_info("nw select automatic");
|
||||
|
||||
ret = g_ril_send(nd->ril, request,
|
||||
NULL, 0, ril_register_cb, cbd, g_free);
|
||||
|
||||
@@ -456,8 +444,6 @@ static void ril_register_manual(struct ofono_netreg *netreg,
|
||||
int request = RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL;
|
||||
int ret;
|
||||
|
||||
ofono_info("nw select manual: %s%s", mcc, mnc);
|
||||
|
||||
/* add *netreg_data to callback */
|
||||
cbd->user = nd;
|
||||
|
||||
@@ -587,17 +573,6 @@ error:
|
||||
ofono_error("Unable to notify ofono about nitz");
|
||||
}
|
||||
|
||||
gboolean check_if_ok_to_attach()
|
||||
{
|
||||
int status = NETWORK_REGISTRATION_STATUS_SEARCHING;
|
||||
status = ofono_netreg_get_status(current_netreg);
|
||||
if (status == NETWORK_REGISTRATION_STATUS_SEARCHING
|
||||
|| status == NETWORK_REGISTRATION_STATUS_ROAMING
|
||||
|| status == NETWORK_REGISTRATION_STATUS_REGISTERED)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint check_if_really_roaming(gint status)
|
||||
{
|
||||
const char *net_mcc = ofono_netreg_get_mcc(current_netreg);
|
||||
@@ -605,20 +580,14 @@ gint check_if_really_roaming(gint status)
|
||||
struct sim_spdi *spdi = ofono_netreg_get_spdi(current_netreg);
|
||||
|
||||
if (spdi && net_mcc && net_mnc) {
|
||||
if (sim_spdi_lookup(spdi, net_mcc, net_mnc)) {
|
||||
ofono_info("voice reg: not roaming based on spdi");
|
||||
if (sim_spdi_lookup(spdi, net_mcc, net_mnc))
|
||||
return NETWORK_REGISTRATION_STATUS_REGISTERED;
|
||||
} else
|
||||
else
|
||||
return status;
|
||||
} else
|
||||
return status;
|
||||
}
|
||||
|
||||
gint get_current_network_status()
|
||||
{
|
||||
return ofono_netreg_get_status(current_netreg);
|
||||
}
|
||||
|
||||
static gboolean ril_delayed_register(gpointer user_data)
|
||||
{
|
||||
struct ofono_netreg *netreg = user_data;
|
||||
@@ -663,7 +632,6 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
|
||||
nd->time.year = -1;
|
||||
nd->time.dst = 0;
|
||||
nd->time.utcoff = 0;
|
||||
nd->corestatus = -1;
|
||||
current_netreg = netreg;
|
||||
|
||||
ofono_netreg_set_data(netreg, nd);
|
||||
@@ -690,7 +658,6 @@ static void ril_netreg_remove(struct ofono_netreg *netreg)
|
||||
g_source_remove(nd->nitz_timeout);
|
||||
|
||||
ofono_netreg_set_data(netreg, NULL);
|
||||
current_netreg = NULL;
|
||||
|
||||
if (nd->timer_id > 0)
|
||||
g_source_remove(nd->timer_id);
|
||||
|
||||
@@ -38,18 +38,14 @@
|
||||
struct oem_raw_data {
|
||||
GRil *ril;
|
||||
unsigned int vendor;
|
||||
guint timer_id;
|
||||
};
|
||||
|
||||
static gboolean ril_oemraw_delayed_register(gpointer user_data)
|
||||
{
|
||||
struct ofono_oem_raw *raw = user_data;
|
||||
struct oem_raw_data *od = ofono_oem_raw_get_data(raw);
|
||||
|
||||
DBG("");
|
||||
|
||||
od->timer_id = 0;
|
||||
|
||||
ofono_oem_raw_dbus_register(raw);
|
||||
return FALSE; /* This makes the timeout a single-shot */
|
||||
}
|
||||
@@ -68,8 +64,7 @@ static int ril_oemraw_probe(struct ofono_oem_raw *raw, unsigned int vendor,
|
||||
od->vendor = vendor;
|
||||
ofono_oem_raw_set_data(raw, od);
|
||||
|
||||
od->timer_id = g_timeout_add_seconds(1, ril_oemraw_delayed_register,
|
||||
raw);
|
||||
g_timeout_add_seconds(1, ril_oemraw_delayed_register, raw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -84,9 +79,6 @@ static void ril_oemraw_remove(struct ofono_oem_raw *raw)
|
||||
|
||||
ofono_oem_raw_set_data(raw, NULL);
|
||||
|
||||
if (od->timer_id)
|
||||
g_source_remove(od->timer_id);
|
||||
|
||||
g_ril_unref(od->ril);
|
||||
g_free(od);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Copyright (C) ST-Ericsson SA 2010.
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2013 Jolla Ltd
|
||||
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
|
||||
*
|
||||
* 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
|
||||
@@ -161,18 +162,11 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
|
||||
char *number, struct pb_file_info *next_file,
|
||||
struct pb_data *pbd)
|
||||
{
|
||||
uint8_t name_length;
|
||||
uint8_t number_start;
|
||||
const uint8_t name_length = len - 14;
|
||||
const uint8_t number_start = name_length;
|
||||
uint8_t number_length = 0;
|
||||
uint8_t extension_record = UNUSED;
|
||||
uint8_t i, prefix;
|
||||
|
||||
if (len < 14)
|
||||
return;
|
||||
|
||||
name_length = len - 14;
|
||||
number_start = name_length;
|
||||
|
||||
name = sim_string_to_utf8(msg, name_length);
|
||||
/* Length contains also TON&NPI */
|
||||
number_length = msg[number_start];
|
||||
@@ -262,19 +256,15 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
|
||||
}
|
||||
}
|
||||
|
||||
void handle_sne(size_t len, const unsigned char *msg, char *sne)
|
||||
void handle_sne(size_t len,
|
||||
const unsigned char *msg,
|
||||
char *sne)
|
||||
{
|
||||
uint8_t sne_length;
|
||||
uint8_t phonebook_entry_nbr;
|
||||
const uint8_t sne_length = len - 2;
|
||||
uint8_t phonebook_entry_nbr = msg[len - 1];
|
||||
|
||||
DBG("SNE");
|
||||
|
||||
if (len < 2)
|
||||
return;
|
||||
|
||||
sne_length = len - 2;
|
||||
phonebook_entry_nbr = msg[len - 1];
|
||||
|
||||
sne = sim_string_to_utf8(msg, sne_length);
|
||||
|
||||
if (sne) {
|
||||
@@ -309,26 +299,20 @@ void handle_sne(size_t len, const unsigned char *msg, char *sne)
|
||||
}
|
||||
}
|
||||
|
||||
void handle_anr(size_t len,const unsigned char *msg,char *anr,
|
||||
struct pb_file_info *next_file, struct pb_data *pbd)
|
||||
void handle_anr(size_t len,
|
||||
const unsigned char *msg,
|
||||
char *anr,
|
||||
struct pb_file_info *next_file,
|
||||
struct pb_data *pbd)
|
||||
{
|
||||
uint8_t number_length = 0;
|
||||
uint8_t extension_record = UNUSED;
|
||||
uint8_t aas_record = UNUSED;
|
||||
uint8_t i, prefix;
|
||||
uint8_t phonebook_entry_nbr;
|
||||
uint8_t phonebook_entry_nbr = msg[len - 1];
|
||||
GSList *list_entry;
|
||||
|
||||
DBG("ANR");
|
||||
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
if (len < 1)
|
||||
return;
|
||||
|
||||
phonebook_entry_nbr = msg[len - 1];
|
||||
|
||||
if (msg[0] == UNUSED)
|
||||
return;
|
||||
|
||||
@@ -344,7 +328,7 @@ void handle_anr(size_t len,const unsigned char *msg,char *anr,
|
||||
prefix = 0;
|
||||
|
||||
if ((msg[2] & TON_MASK) ==
|
||||
TON_INTERNATIONAL) {
|
||||
TON_INTERNATIONAL) {
|
||||
anr[0] = '+';
|
||||
prefix = 1;
|
||||
}
|
||||
@@ -414,18 +398,11 @@ void handle_anr(size_t len,const unsigned char *msg,char *anr,
|
||||
}
|
||||
}
|
||||
|
||||
void handle_email(size_t len, const unsigned char *msg, char *email)
|
||||
void handle_email(size_t len,
|
||||
const unsigned char *msg,
|
||||
char *email)
|
||||
{
|
||||
uint8_t phonebook_entry_nbr;
|
||||
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
if (len < 1)
|
||||
return;
|
||||
|
||||
phonebook_entry_nbr = msg[len - 1];
|
||||
|
||||
uint8_t phonebook_entry_nbr = msg[len - 1];
|
||||
email = sim_string_to_utf8(msg, len - 2);
|
||||
|
||||
/* GSlist nth counts from 0, PB entries from 1 */
|
||||
@@ -457,13 +434,13 @@ void handle_email(size_t len, const unsigned char *msg, char *email)
|
||||
}
|
||||
}
|
||||
|
||||
void handle_ext1(struct pb_data *pbd, const unsigned char *msg,
|
||||
char *ext_number, struct pb_file_info *next_file)
|
||||
void handle_ext1(struct pb_data *pbd,
|
||||
const unsigned char *msg,
|
||||
char *ext_number,
|
||||
struct pb_file_info *next_file)
|
||||
{
|
||||
uint8_t number_length, i, next_extension_record;
|
||||
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
number_length = msg[1];
|
||||
|
||||
@@ -517,7 +494,7 @@ void handle_ext1(struct pb_data *pbd, const unsigned char *msg,
|
||||
list_entry->data;
|
||||
if (entry) {
|
||||
strcat(entry->anr,
|
||||
ext_number);
|
||||
ext_number);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -633,10 +610,8 @@ static void pb_adn_sim_data_cb(const struct ofono_error *error,
|
||||
file_info = cbd_outer->user;
|
||||
cbd = cbd_outer->data;
|
||||
|
||||
if (!cbd) {
|
||||
g_free(cbd_outer);
|
||||
if (!cbd)
|
||||
return;
|
||||
}
|
||||
|
||||
pb = cbd->user;
|
||||
cb = cbd->cb;
|
||||
@@ -719,10 +694,8 @@ static void pb_adn_sim_data_cb(const struct ofono_error *error,
|
||||
g_slist_free(phonebook_entry_start);
|
||||
g_slist_free(pb_files);
|
||||
g_free(cbd_outer);
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
DBG("Finally all PB data read");
|
||||
CALLBACK_WITH_SUCCESS(cb, pb);
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -747,6 +720,9 @@ static void pb_adn_sim_info_cb(const struct ofono_error *error,
|
||||
if (!cbd)
|
||||
goto error;
|
||||
|
||||
pb = cbd->user;
|
||||
cb = cbd->cb;
|
||||
pbd = ofono_phonebook_get_data(pb);
|
||||
file_info = NULL;
|
||||
|
||||
if (!pbd)
|
||||
@@ -789,12 +765,8 @@ static void pb_adn_sim_info_cb(const struct ofono_error *error,
|
||||
return;
|
||||
error:
|
||||
|
||||
if (cbd){
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
if(cb)
|
||||
CALLBACK_WITH_FAILURE(cb, pb);
|
||||
}
|
||||
if (cb && cbd)
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
|
||||
static gboolean is_reading_required(uint8_t file_type)
|
||||
@@ -827,28 +799,9 @@ static void pb_content_data_cb(const struct ofono_error *error,
|
||||
if (extension_file_info)
|
||||
file_info = decode_read_response(extension_file_info, sdata,
|
||||
length, pb);
|
||||
else {
|
||||
/*
|
||||
* These checks are crash hacks.
|
||||
* AFAIK there's a possibility that we end up here and pb_next is NULL
|
||||
* in case remove has been called while phonebook reading is in
|
||||
* process. If you find better solution to this issue feel free to
|
||||
* change this.
|
||||
*/
|
||||
if (pb_next == NULL) {
|
||||
ofono_error("phonebook reading failed");
|
||||
if (cbd){
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
if(cb && pbd)
|
||||
CALLBACK_WITH_FAILURE(cb, pb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
file_info =
|
||||
decode_read_response(pb_next->data, sdata, length, pb);
|
||||
}
|
||||
|
||||
if (file_info) {
|
||||
DBG("Reading extension file %04X, record %d, structure %d",
|
||||
@@ -865,7 +818,7 @@ static void pb_content_data_cb(const struct ofono_error *error,
|
||||
file_info = pb_next->data;
|
||||
|
||||
if (((file_info->structure ==
|
||||
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
|
||||
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
|
||||
(file_info->structure ==
|
||||
OFONO_SIM_FILE_STRUCTURE_CYCLIC))
|
||||
&& (file_info->record <
|
||||
@@ -902,7 +855,7 @@ static void pb_content_data_cb(const struct ofono_error *error,
|
||||
DBG("All data requested, start vCard creation");
|
||||
while (list_entry) {
|
||||
struct phonebook_entry *entry =
|
||||
list_entry->data;
|
||||
list_entry->data;
|
||||
|
||||
if (entry) {
|
||||
DBG("vCard:\nname=%s\n",
|
||||
@@ -939,10 +892,8 @@ static void pb_content_data_cb(const struct ofono_error *error,
|
||||
|
||||
g_slist_free(phonebook_entry_start);
|
||||
g_slist_free(pb_files);
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
DBG("Finally all PB data read");
|
||||
CALLBACK_WITH_SUCCESS(cb, pb);
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1007,12 +958,8 @@ static void pb_content_data_read(struct pb_data *pbd,
|
||||
return;
|
||||
error:
|
||||
|
||||
if (cbd){
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
if(cb)
|
||||
CALLBACK_WITH_FAILURE(cb, pb);
|
||||
}
|
||||
if (cb && cbd)
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
|
||||
out:
|
||||
DBG("Exiting");
|
||||
@@ -1085,11 +1032,9 @@ static void pb_content_info_cb(const struct ofono_error *error,
|
||||
return;
|
||||
error:
|
||||
|
||||
if (cbd){
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
if(cb)
|
||||
CALLBACK_WITH_FAILURE(cb, pb);
|
||||
if (cb && cbd) {
|
||||
DBG("Error cbd=%p, pbd=%p, file_info=%p", cbd, pbd, file_info);
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1162,27 +1107,15 @@ static void pb_reference_data_cb(const struct ofono_error *error,
|
||||
pbd->pb_reference_file_info.record_length)) {
|
||||
pbd->pb_reference_file_info.record++;
|
||||
DBG("Next EFpbr record %d", pbd->pb_reference_file_info.record);
|
||||
if (RIL_APPTYPE_SIM == ril_get_app_type()) {
|
||||
pbd->sim_driver->read_file_linear(get_sim(),
|
||||
pbd->pb_reference_file_info.
|
||||
file_id,
|
||||
pbd->pb_reference_file_info.
|
||||
record,
|
||||
pbd->pb_reference_file_info.
|
||||
record_length,
|
||||
sim_path, sizeof(sim_path),
|
||||
pb_reference_data_cb, cbd);
|
||||
} else {
|
||||
pbd->sim_driver->read_file_linear(get_sim(),
|
||||
pbd->pb_reference_file_info.
|
||||
file_id,
|
||||
pbd->pb_reference_file_info.
|
||||
record,
|
||||
pbd->pb_reference_file_info.
|
||||
record_length,
|
||||
usim_path, sizeof(usim_path),
|
||||
pb_reference_data_cb, cbd);
|
||||
}
|
||||
pbd->sim_driver->read_file_linear(get_sim(),
|
||||
pbd->pb_reference_file_info.
|
||||
file_id,
|
||||
pbd->pb_reference_file_info.
|
||||
record,
|
||||
pbd->pb_reference_file_info.
|
||||
record_length,
|
||||
NULL, 0,
|
||||
pb_reference_data_cb, cbd);
|
||||
} else {
|
||||
struct pb_file_info *file_info;
|
||||
DBG("All EFpbr records read");
|
||||
@@ -1204,12 +1137,8 @@ static void pb_reference_data_cb(const struct ofono_error *error,
|
||||
return;
|
||||
error:
|
||||
|
||||
if (cbd){
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
if(cb)
|
||||
CALLBACK_WITH_FAILURE(cb, pb);
|
||||
}
|
||||
if (cb && cbd)
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
|
||||
static void pb_reference_info_cb(const struct ofono_error *error,
|
||||
@@ -1260,12 +1189,8 @@ static void pb_reference_info_cb(const struct ofono_error *error,
|
||||
pb_reference_data_cb, cbd);
|
||||
return;
|
||||
error:
|
||||
if (cbd){
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
if(cb)
|
||||
CALLBACK_WITH_FAILURE(cb, pb);
|
||||
}
|
||||
if (cb && cbd)
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_export_entries(struct ofono_phonebook *pb,
|
||||
@@ -1304,12 +1229,10 @@ static void ril_export_entries(struct ofono_phonebook *pb,
|
||||
|
||||
error:
|
||||
|
||||
if (cbd){
|
||||
void *pb = cbd->data;
|
||||
g_free(cbd);
|
||||
if(cb)
|
||||
CALLBACK_WITH_FAILURE(cb, pb);
|
||||
}
|
||||
if (cb && cbd)
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static gboolean ril_delayed_register(gpointer user_data)
|
||||
@@ -1357,7 +1280,7 @@ static struct ofono_phonebook_driver driver = {
|
||||
.name = "rilmodem",
|
||||
.probe = ril_phonebook_probe,
|
||||
.remove = ril_phonebook_remove,
|
||||
.export_entries = ril_export_entries
|
||||
.export_entries = ril_export_entries
|
||||
};
|
||||
|
||||
void ril_phonebook_init(void)
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/radio-settings.h>
|
||||
#include <ofono/sim.h>
|
||||
|
||||
#include "gril.h"
|
||||
#include "grilutil.h"
|
||||
@@ -75,7 +74,7 @@ static void ril_set_rat_mode(struct ofono_radio_settings *rs,
|
||||
int pref = rd->ratmode;
|
||||
int ret = 0;
|
||||
|
||||
ofono_info("rat mode set %d", mode);
|
||||
ofono_info("setting rat mode");
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
@@ -116,8 +115,6 @@ static void ril_force_rat_mode(struct radio_data *rd, int pref)
|
||||
if (pref == rd->ratmode)
|
||||
return;
|
||||
|
||||
DBG("pref ril rat mode %d, ril current %d", pref, rd->ratmode);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 1);
|
||||
parcel_w_int32(&rilp, rd->ratmode);
|
||||
@@ -139,7 +136,7 @@ static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
/* first item in int[] is len so let's skip that */
|
||||
/*first item in int[] is len so let's skip that*/
|
||||
parcel_r_int32(&rilp);
|
||||
pref = parcel_r_int32(&rilp);
|
||||
|
||||
@@ -169,7 +166,6 @@ static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ofono_info("rat mode %d (ril %d)", mode, pref);
|
||||
if (cb)
|
||||
CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
|
||||
} else {
|
||||
@@ -204,17 +200,11 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
||||
{
|
||||
GKeyFile *keyfile;
|
||||
GError *err = NULL;
|
||||
char *config_path = RIL_CONFIG_DIR;
|
||||
char *path = RIL_CONFIG;
|
||||
char **alreadyset = NULL;
|
||||
gboolean needsconfig = FALSE;
|
||||
gboolean value = FALSE;
|
||||
gboolean found = FALSE;
|
||||
rsd->ratmode = PREF_NET_TYPE_GSM_WCDMA_AUTO;
|
||||
GDir *config_dir;
|
||||
const gchar *config_file;
|
||||
gsize length;
|
||||
gchar **codes = NULL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* First we need to check should the LTE be on
|
||||
@@ -225,45 +215,15 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
||||
|
||||
g_key_file_set_list_separator(keyfile, ',');
|
||||
|
||||
config_dir = g_dir_open(config_path, 0, NULL);
|
||||
while ((config_file = g_dir_read_name(config_dir)) != NULL) {
|
||||
char *path = g_strconcat(RIL_CONFIG_DIR "/", config_file, NULL);
|
||||
DBG("Rilconfig handling %s", path);
|
||||
gboolean ok = g_key_file_load_from_file(keyfile, path, 0, &err);
|
||||
|
||||
g_free(path);
|
||||
if (!ok) {
|
||||
g_error_free(err);
|
||||
DBG("Rilconfig file skipped");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_key_file_load_from_file(keyfile, path, 0, &err)) {
|
||||
if (g_key_file_has_group(keyfile, LTE_FLAG))
|
||||
found = TRUE;
|
||||
else if (g_key_file_has_group(keyfile, MCC_LIST)) {
|
||||
codes = g_key_file_get_string_list(keyfile, MCC_LIST,
|
||||
MCC_KEY, &length, NULL);
|
||||
if (codes) {
|
||||
for (i = 0; codes[i]; i++) {
|
||||
if (g_str_equal(codes[i],
|
||||
ofono_sim_get_mcc(get_sim()))
|
||||
== TRUE) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_strfreev(codes);
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
rsd->ratmode = PREF_NET_TYPE_LTE_GSM_WCDMA;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
g_error_free(err);
|
||||
needsconfig = TRUE;
|
||||
}
|
||||
|
||||
g_key_file_free(keyfile);
|
||||
g_dir_close(config_dir);
|
||||
|
||||
/* Then we need to check if it already set */
|
||||
|
||||
@@ -290,7 +250,6 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
||||
|
||||
storage_close(NULL, RIL_STORE, keyfile, TRUE);
|
||||
|
||||
DBG("needsconfig %d, rat mode %d", needsconfig, rsd->ratmode);
|
||||
return needsconfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ static int rilmodem_init(void)
|
||||
ril_call_barring_init();
|
||||
ril_cbs_init();
|
||||
ril_oemraw_init();
|
||||
ril_stk_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -81,7 +80,6 @@ static void rilmodem_exit(void)
|
||||
ril_call_barring_exit();
|
||||
ril_cbs_exit();
|
||||
ril_oemraw_exit();
|
||||
ril_stk_exit();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(rilmodem, "RIL modem driver", VERSION,
|
||||
|
||||
@@ -28,14 +28,9 @@
|
||||
/* Shared constants */
|
||||
#define EF_STATUS_INVALIDATED 0
|
||||
#define EF_STATUS_VALID 1
|
||||
#define RIL_HW_CONFIG "/etc/ofono/ril_subscription.conf"
|
||||
#define RIL_CONFIG_DIR "/etc/ofono/"
|
||||
#define RIL_CONFIG "/etc/ofono/ril_subscription.conf"
|
||||
#define RIL_STORE "rilmodem"
|
||||
#define LTE_FLAG "4gOn"
|
||||
#define MCC_LIST "MCC-whitelist"
|
||||
#define MCC_KEY "Countries"
|
||||
#define UI_LANG "/var/lib/environment/nemo/locale.conf"
|
||||
#define CFG_LANG "LANG="
|
||||
|
||||
extern void ril_devinfo_init(void);
|
||||
extern void ril_devinfo_exit(void);
|
||||
@@ -84,7 +79,3 @@ extern void ril_phonebook_exit(void);
|
||||
|
||||
extern void ril_oemraw_init(void);
|
||||
extern void ril_oemraw_exit(void);
|
||||
|
||||
extern void ril_stk_init(void);
|
||||
extern void ril_stk_exit(void);
|
||||
|
||||
|
||||
@@ -402,25 +402,13 @@ gboolean ril_util_parse_sim_status(GRil *gril,
|
||||
|
||||
apps[i]->app_type = parcel_r_int32(&rilp);
|
||||
apps[i]->app_state = parcel_r_int32(&rilp);
|
||||
|
||||
/*
|
||||
* Consider RIL_APPSTATE_ILLEGAL also READY. Even if app state
|
||||
* is RIL_APPSTATE_ILLEGAL (-1), ICC operations must be
|
||||
* permitted. Network access requests will anyway be rejected
|
||||
* and ME will be in limited service.
|
||||
*/
|
||||
if (apps[i]->app_state == RIL_APPSTATE_ILLEGAL) {
|
||||
DBG("RIL_APPSTATE_ILLEGAL => RIL_APPSTATE_READY");
|
||||
apps[i]->app_state = RIL_APPSTATE_READY;
|
||||
}
|
||||
|
||||
apps[i]->perso_substate = parcel_r_int32(&rilp);
|
||||
|
||||
/* TODO: we need a way to instruct parcel to skip
|
||||
* a string, without allocating memory...
|
||||
*/
|
||||
apps[i]->aid_str = parcel_r_string(&rilp); /* app ID (AID) */
|
||||
apps[i]->app_str = parcel_r_string(&rilp); /* app label */
|
||||
apps[i]->aid_str = parcel_r_string(&rilp); /* application ID (AID) */
|
||||
apps[i]->app_str = parcel_r_string(&rilp); /* application label */
|
||||
|
||||
apps[i]->pin_replaced = parcel_r_int32(&rilp);
|
||||
apps[i]->pin1_state = parcel_r_int32(&rilp);
|
||||
@@ -471,8 +459,7 @@ gboolean ril_util_parse_reg(GRil *gril,
|
||||
* >= 4 for VOICE_REG reply
|
||||
* >= 5 for DATA_REG reply
|
||||
*/
|
||||
tmp = parcel_r_int32(&rilp);
|
||||
if (tmp < 4) {
|
||||
if ((tmp = parcel_r_int32(&rilp)) < 4) {
|
||||
DBG("Size of response array is too small: %d", tmp);
|
||||
goto error;
|
||||
}
|
||||
@@ -495,12 +482,10 @@ gboolean ril_util_parse_reg(GRil *gril,
|
||||
* voice & data response.
|
||||
*/
|
||||
if (tmp--) {
|
||||
/* TODO: different use for CDMA */
|
||||
sreason = parcel_r_string(&rilp);
|
||||
sreason = parcel_r_string(&rilp); /* TODO: different use for CDMA */
|
||||
|
||||
if (tmp--) {
|
||||
/* TODO: different use for CDMA */
|
||||
smax = parcel_r_string(&rilp);
|
||||
smax = parcel_r_string(&rilp); /* TODO: different use for CDMA */
|
||||
|
||||
if (smax && max_calls)
|
||||
*max_calls = atoi(smax);
|
||||
@@ -533,7 +518,7 @@ gboolean ril_util_parse_reg(GRil *gril,
|
||||
|
||||
if (tech) {
|
||||
if (stech) {
|
||||
switch (atoi(stech)) {
|
||||
switch(atoi(stech)) {
|
||||
case RADIO_TECH_UNKNOWN:
|
||||
*tech = -1;
|
||||
break;
|
||||
@@ -674,8 +659,7 @@ gint ril_util_get_signal(GRil *gril, struct ril_msg *message)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps)
|
||||
{
|
||||
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps) {
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < num_apps; i++) {
|
||||
|
||||
@@ -62,6 +62,29 @@ enum at_util_charset {
|
||||
RIL_UTIL_CHARSET_8859_H = 0x10000,
|
||||
};
|
||||
|
||||
/* TODO: consider moving these to ril_constants.h */
|
||||
enum app_state {
|
||||
APPSTATE_UNKNOWN,
|
||||
APPSTATE_DETECTED,
|
||||
APPSTATE_PIN,
|
||||
APPSTATE_PUK,
|
||||
APPSTATE_SUBSCRIPTION_PERSO,
|
||||
APPSTATE_READY,
|
||||
};
|
||||
|
||||
enum perso_state {
|
||||
PERSOSUBSTATE_SIM_NETWORK = 3,
|
||||
PERSOSUBSTATE_SIM_NETWORK_SUBSET,
|
||||
PERSOSUBSTATE_SIM_CORPORATE,
|
||||
PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
|
||||
PERSOSUBSTATE_SIM_SIM,
|
||||
PERSOSUBSTATE_SIM_NETWORK_PUK,
|
||||
PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK,
|
||||
PERSOSUBSTATE_SIM_CORPORATE_PUK,
|
||||
PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
|
||||
PERSOSUBSTATE_SIM_SIM_PUK,
|
||||
};
|
||||
|
||||
#define MAX_UICC_APPS 16
|
||||
|
||||
struct sim_status {
|
||||
@@ -123,12 +146,6 @@ struct ofono_sim *get_sim();
|
||||
|
||||
gint check_if_really_roaming(gint status);
|
||||
|
||||
gboolean ril_roaming_allowed();
|
||||
|
||||
gboolean check_if_ok_to_attach();
|
||||
|
||||
gint get_current_network_status();
|
||||
|
||||
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps);
|
||||
|
||||
struct cb_data {
|
||||
@@ -153,7 +170,7 @@ static inline struct cb_data *cb_data_new2(void *user, void *cb,
|
||||
{
|
||||
struct cb_data *ret;
|
||||
|
||||
ret = g_new0(struct cb_data, 1);
|
||||
ret = g_try_new0(struct cb_data, 1);
|
||||
|
||||
if (ret) {
|
||||
ret->cb = cb;
|
||||
@@ -176,7 +193,7 @@ static inline int ril_util_convert_signal_strength(int strength)
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DECLARE_FAILURE(e) \
|
||||
#define DECLARE_FAILURE(e) \
|
||||
struct ofono_error e; \
|
||||
e.type = OFONO_ERROR_TYPE_FAILURE; \
|
||||
e.error = 0 \
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2013 Canonical, Ltd. All rights reserved.
|
||||
* Copyright (C) 2014 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
|
||||
@@ -103,8 +102,6 @@ struct sim_data {
|
||||
enum ofono_sim_password_type passwd_state;
|
||||
guint card_state;
|
||||
guint idle_id;
|
||||
gboolean initialized;
|
||||
gboolean removed;
|
||||
};
|
||||
|
||||
static void ril_pin_change_state_cb(struct ril_msg *message,
|
||||
@@ -182,15 +179,6 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
DBG("");
|
||||
|
||||
/* In case sim card has been removed prior to this callback has been
|
||||
* called we must not call the core call back method as otherwise the
|
||||
* core will crash.
|
||||
*/
|
||||
if (sd->removed == TRUE) {
|
||||
ofono_error("RIL_CARDSTATE_ABSENT");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
} else {
|
||||
@@ -326,7 +314,7 @@ static void ril_file_io_cb(struct ril_msg *message, gpointer user_data)
|
||||
decode_ril_error(&error, "OK");
|
||||
} else {
|
||||
ofono_error("RILD reply failure: %s",
|
||||
ril_error_to_string(message->error));
|
||||
ril_error_to_string(message->error));
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -562,53 +550,48 @@ static void configure_active_app(struct sim_data *sd,
|
||||
guint index)
|
||||
{
|
||||
sd->app_type = app->app_type;
|
||||
|
||||
g_free(sd->aid_str);
|
||||
sd->aid_str = g_strdup(app->aid_str);
|
||||
|
||||
g_free(sd->app_str);
|
||||
sd->app_str = g_strdup(app->app_str);
|
||||
|
||||
sd->app_index = index;
|
||||
|
||||
DBG("setting aid_str (AID) to: %s", sd->aid_str);
|
||||
switch (app->app_state) {
|
||||
case RIL_APPSTATE_PIN:
|
||||
case APPSTATE_PIN:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
|
||||
break;
|
||||
case RIL_APPSTATE_PUK:
|
||||
case APPSTATE_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
|
||||
break;
|
||||
case RIL_APPSTATE_SUBSCRIPTION_PERSO:
|
||||
case APPSTATE_SUBSCRIPTION_PERSO:
|
||||
switch (app->perso_substate) {
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK:
|
||||
case PERSOSUBSTATE_SIM_NETWORK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PIN;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET:
|
||||
case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PIN;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_CORPORATE:
|
||||
case PERSOSUBSTATE_SIM_CORPORATE:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PIN;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
|
||||
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PIN;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_SIM:
|
||||
case PERSOSUBSTATE_SIM_SIM:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSIM_PIN;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK_PUK:
|
||||
case PERSOSUBSTATE_SIM_NETWORK_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PUK;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
|
||||
case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PUK;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK:
|
||||
case PERSOSUBSTATE_SIM_CORPORATE_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PUK;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
|
||||
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PUK;
|
||||
break;
|
||||
case RIL_PERSOSUBSTATE_SIM_SIM_PUK:
|
||||
case PERSOSUBSTATE_SIM_SIM_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHFSIM_PUK;
|
||||
break;
|
||||
default:
|
||||
@@ -616,11 +599,11 @@ static void configure_active_app(struct sim_data *sd,
|
||||
break;
|
||||
};
|
||||
break;
|
||||
case RIL_APPSTATE_READY:
|
||||
case APPSTATE_READY:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
|
||||
break;
|
||||
case RIL_APPSTATE_UNKNOWN:
|
||||
case RIL_APPSTATE_DETECTED:
|
||||
case APPSTATE_UNKNOWN:
|
||||
case APPSTATE_DETECTED:
|
||||
default:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
|
||||
break;
|
||||
@@ -639,7 +622,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
DBG("");
|
||||
|
||||
if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
|
||||
if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
|
||||
status.num_apps) {
|
||||
|
||||
DBG("num_apps: %d gsm_umts_index: %d", status.num_apps,
|
||||
@@ -675,19 +658,43 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
if (sd->card_state != RIL_CARDSTATE_PRESENT) {
|
||||
ofono_sim_inserted_notify(sim, TRUE);
|
||||
sd->card_state = RIL_CARDSTATE_PRESENT;
|
||||
sd->removed = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
if (current_passwd) {
|
||||
if (!strcmp(current_passwd, defaultpasswd)) {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
} else if (sd->passwd_state !=
|
||||
OFONO_SIM_PASSWORD_SIM_PIN) {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
} else if (sd->passwd_state ==
|
||||
OFONO_SIM_PASSWORD_SIM_PIN) {
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp,
|
||||
ENTER_SIM_PIN_PARAMS);
|
||||
parcel_w_string(&rilp, current_passwd);
|
||||
parcel_w_string(&rilp, sd->aid_str);
|
||||
|
||||
g_ril_send(sd->ril,
|
||||
RIL_REQUEST_ENTER_SIM_PIN,
|
||||
rilp.data, rilp.size, NULL,
|
||||
NULL, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
}
|
||||
} else {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
}
|
||||
|
||||
if (current_online_state == RIL_ONLINE_PREF) {
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 1);
|
||||
parcel_w_int32(&rilp, 1);
|
||||
|
||||
ofono_info("RIL_REQUEST_RADIO_POWER ON");
|
||||
g_ril_send(sd->ril,
|
||||
RIL_REQUEST_RADIO_POWER,
|
||||
rilp.data,
|
||||
@@ -707,13 +714,11 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
if (status.card_state == RIL_CARDSTATE_ABSENT) {
|
||||
DBG("sd->card_state:%u,status.card_state:%u,",
|
||||
sd->card_state, status.card_state);
|
||||
ofono_info("RIL_CARDSTATE_ABSENT");
|
||||
ofono_sim_inserted_notify(sim, FALSE);
|
||||
if (sd->card_state == RIL_CARDSTATE_PRESENT)
|
||||
sd->removed = TRUE;
|
||||
sd->card_state = RIL_CARDSTATE_ABSENT;
|
||||
|
||||
sd->initialized = FALSE;
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, defaultpasswd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,81 +759,16 @@ static void ril_query_pin_retries(struct ofono_sim *sim,
|
||||
CALLBACK_WITH_SUCCESS(cb, sd->retries, data);
|
||||
}
|
||||
|
||||
static void ril_query_passwd_state_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_sim *sim = cbd->user;
|
||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||
ofono_sim_passwd_cb_t cb = cbd->cb;
|
||||
void *data = cbd->data;
|
||||
struct sim_app *apps[MAX_UICC_APPS];
|
||||
struct sim_status status;
|
||||
guint i = 0;
|
||||
guint search_index = -1;
|
||||
gint state = ofono_sim_get_state(sim);
|
||||
|
||||
if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
|
||||
status.num_apps) {
|
||||
|
||||
DBG("num_apps: %d gsm_umts_index: %d", status.num_apps,
|
||||
status.gsm_umts_index);
|
||||
|
||||
/* TODO(CDMA): need some kind of logic to
|
||||
* set the correct app_index,
|
||||
*/
|
||||
search_index = status.gsm_umts_index;
|
||||
|
||||
for (i = 0; i < status.num_apps; i++) {
|
||||
if (i == search_index &&
|
||||
apps[i]->app_type != RIL_APPTYPE_UNKNOWN) {
|
||||
current_active_app = apps[i]->app_type;
|
||||
configure_active_app(sd, apps[i], i);
|
||||
set_pin_lock_state(sim, apps[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ril_util_free_sim_apps(apps, status.num_apps);
|
||||
}
|
||||
DBG("passwd_state %u", sd->passwd_state);
|
||||
|
||||
/* if pin code required cannot be initialized yet*/
|
||||
if (sd->passwd_state == OFONO_SIM_PASSWORD_SIM_PIN)
|
||||
sd->initialized = FALSE;
|
||||
/*
|
||||
* To prevent double call to sim_initialize_after_pin from
|
||||
* sim_pin_query_cb we must prevent calling sim_pin_query_cb
|
||||
* when !OFONO_SIM_STATE_READY && OFONO_SIM_PASSWORD_NONE
|
||||
*/
|
||||
if ((state == OFONO_SIM_STATE_READY) || (sd->initialized == FALSE) ||
|
||||
(sd->passwd_state != OFONO_SIM_PASSWORD_NONE)){
|
||||
|
||||
if (sd->passwd_state == OFONO_SIM_PASSWORD_NONE)
|
||||
sd->initialized = TRUE;
|
||||
|
||||
if (state == OFONO_SIM_STATE_LOCKED_OUT)
|
||||
sd->initialized = FALSE;
|
||||
|
||||
if (sd->passwd_state == OFONO_SIM_PASSWORD_INVALID)
|
||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||
else
|
||||
CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ril_query_passwd_state(struct ofono_sim *sim,
|
||||
ofono_sim_passwd_cb_t cb, void *data)
|
||||
{
|
||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||
struct cb_data *cbd = cb_data_new2(sim, cb, data);
|
||||
int request = RIL_REQUEST_GET_SIM_STATUS;
|
||||
guint ret;
|
||||
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
NULL, 0, ril_query_passwd_state_cb, cbd, g_free);
|
||||
|
||||
g_ril_print_request_no_args(sd->ril, ret, request);
|
||||
DBG("passwd_state %u", sd->passwd_state);
|
||||
|
||||
if (sd->passwd_state == OFONO_SIM_PASSWORD_INVALID)
|
||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||
else
|
||||
CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
|
||||
}
|
||||
|
||||
static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
|
||||
@@ -852,13 +792,17 @@ static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
|
||||
retries[passwd_type] = retry_count;
|
||||
sd->retries[passwd_type] = retries[passwd_type];
|
||||
|
||||
DBG("result=%d passwd_type=%d retry_count=%d",
|
||||
message->error, passwd_type, retry_count);
|
||||
/*
|
||||
* TODO: re-bfactor to not use macro for FAILURE; doesn't return error!
|
||||
*/
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
g_ril_print_response_no_args(sd->ril, message);
|
||||
|
||||
} else {
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, defaultpasswd);
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
|
||||
@@ -876,6 +820,9 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
|
||||
sd->passwd_type = OFONO_SIM_PASSWORD_SIM_PIN;
|
||||
cbd->user = sd;
|
||||
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, passwd);
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp, ENTER_SIM_PIN_PARAMS);
|
||||
@@ -897,53 +844,11 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
|
||||
}
|
||||
}
|
||||
|
||||
static int ril_perso_change_state(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)
|
||||
{
|
||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct parcel rilp;
|
||||
int request = 0;
|
||||
int ret = 0;
|
||||
sd->passwd_type = passwd_type;
|
||||
cbd->user = sd;
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
switch (passwd_type) {
|
||||
case OFONO_SIM_PASSWORD_PHNET_PIN:
|
||||
if (enable) {
|
||||
DBG("Not supported, enable=%d", enable);
|
||||
goto end;
|
||||
}
|
||||
request = RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION;
|
||||
parcel_w_int32(&rilp, RIL_PERSOSUBSTATE_SIM_NETWORK);
|
||||
parcel_w_string(&rilp, (char *) passwd);
|
||||
break;
|
||||
default:
|
||||
DBG("Not supported, type=%d", passwd_type);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
rilp.data, rilp.size, ril_pin_change_state_cb,
|
||||
cbd, g_free);
|
||||
|
||||
g_ril_print_request(sd->ril, ret, request);
|
||||
|
||||
end:
|
||||
parcel_free(&rilp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ril_pin_change_state(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)
|
||||
{
|
||||
DBG("passwd_type=%d", passwd_type);
|
||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct parcel rilp;
|
||||
@@ -963,6 +868,8 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
||||
*/
|
||||
switch (passwd_type) {
|
||||
case OFONO_SIM_PASSWORD_SIM_PIN:
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, passwd);
|
||||
g_ril_append_print_buf(sd->ril, "(SC,");
|
||||
parcel_w_string(&rilp, "SC");
|
||||
break;
|
||||
@@ -979,9 +886,9 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
||||
parcel_w_string(&rilp, "P2");
|
||||
break;
|
||||
case OFONO_SIM_PASSWORD_PHNET_PIN:
|
||||
ret = ril_perso_change_state(sim, passwd_type, enable, passwd,
|
||||
cb, data);
|
||||
goto end;
|
||||
g_ril_append_print_buf(sd->ril, "(PN,");
|
||||
parcel_w_string(&rilp, "PN");
|
||||
break;
|
||||
case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
|
||||
g_ril_append_print_buf(sd->ril, "(PU,");
|
||||
parcel_w_string(&rilp, "PU");
|
||||
@@ -995,7 +902,8 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
||||
parcel_w_string(&rilp, "PC");
|
||||
break;
|
||||
default:
|
||||
goto end;
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
@@ -1022,7 +930,6 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
||||
|
||||
g_ril_print_request(sd->ril, ret, request);
|
||||
|
||||
end:
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
@@ -1044,6 +951,9 @@ static void ril_pin_send_puk(struct ofono_sim *sim,
|
||||
sd->passwd_type = OFONO_SIM_PASSWORD_SIM_PUK;
|
||||
cbd->user = sd;
|
||||
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, passwd);
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp, ENTER_SIM_PUK_PARAMS);
|
||||
@@ -1092,6 +1002,8 @@ static void ril_change_passwd(struct ofono_sim *sim,
|
||||
|
||||
if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
|
||||
request = RIL_REQUEST_CHANGE_SIM_PIN2;
|
||||
else if (current_passwd)
|
||||
g_stpcpy(current_passwd, new_passwd);
|
||||
|
||||
ret = g_ril_send(sd->ril, request, rilp.data, rilp.size,
|
||||
ril_pin_change_state_cb, cbd, g_free);
|
||||
@@ -1140,6 +1052,13 @@ static int ril_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
||||
|
||||
sd = g_new0(struct sim_data, 1);
|
||||
sd->ril = g_ril_clone(ril);
|
||||
sd->aid_str = NULL;
|
||||
sd->app_str = NULL;
|
||||
sd->app_type = RIL_APPTYPE_UNKNOWN;
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
|
||||
sd->passwd_type = OFONO_SIM_PASSWORD_NONE;
|
||||
sd->sim_registered = FALSE;
|
||||
sd->card_state = RIL_CARDSTATE_ABSENT;
|
||||
|
||||
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
|
||||
sd->retries[i] = -1;
|
||||
@@ -1173,8 +1092,6 @@ static void ril_sim_remove(struct ofono_sim *sim)
|
||||
if (sd->idle_id > 0)
|
||||
g_source_remove(sd->idle_id);
|
||||
|
||||
g_free(sd->aid_str);
|
||||
g_free(sd->app_str);
|
||||
g_ril_unref(sd->ril);
|
||||
g_free(sd);
|
||||
}
|
||||
@@ -1195,6 +1112,17 @@ static struct ofono_sim_driver driver = {
|
||||
.change_passwd = ril_change_passwd,
|
||||
.query_pin_retries = ril_query_pin_retries,
|
||||
/*
|
||||
* TODO: Implmenting PIN/PUK support requires defining
|
||||
* the following driver methods.
|
||||
*
|
||||
* In the meanwhile, as long as the SIM card is present,
|
||||
* and unlocked, the core SIM code will check for the
|
||||
* presence of query_passwd_state, and if null, then the
|
||||
* function sim_initialize_after_pin() is called.
|
||||
*
|
||||
* .query_pin_retries = ril_pin_retries_query,
|
||||
* .query_locked = ril_pin_query_enabled,
|
||||
*
|
||||
* TODO: Implementing SIM write file IO support requires
|
||||
* the following functions to be defined.
|
||||
*
|
||||
|
||||
@@ -38,18 +38,10 @@
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/sms.h>
|
||||
#include <ofono/types.h>
|
||||
#include <ofono/sim.h>
|
||||
|
||||
#include "smsutil.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "rilmodem.h"
|
||||
#include "simutil.h"
|
||||
|
||||
#define SIM_EFSMS_FILEID 0x6F3C
|
||||
#define EFSMS_LENGTH 176
|
||||
|
||||
unsigned char path[4] = {0x3F, 0x00, 0x7F, 0x10};
|
||||
|
||||
struct sms_data {
|
||||
GRil *ril;
|
||||
@@ -139,7 +131,7 @@ static void ril_csca_query_cb(struct ril_msg *message, gpointer user_data)
|
||||
sca.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
|
||||
|
||||
DBG("csca_query_cb: %s, %d", sca.number, sca.type);
|
||||
g_free(temp_buf); /*g_utf16_to_utf8 used by parcel_r_string*/
|
||||
|
||||
cb(&error, &sca, cbd->data);
|
||||
} else {
|
||||
ofono_error("return value invalid");
|
||||
@@ -176,14 +168,10 @@ static void submit_sms_cb(struct ril_msg *message, gpointer user_data)
|
||||
int mr;
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
ofono_info("sms sending successful");
|
||||
ofono_info("sms sending succesful");
|
||||
decode_ril_error(&error, "OK");
|
||||
} else if (message->error == RIL_E_GENERIC_FAILURE) {
|
||||
ofono_info("not allowed by MO SMS control, do not retry");
|
||||
error.type = OFONO_ERROR_TYPE_CMS;
|
||||
error.error = 500;
|
||||
} else {
|
||||
ofono_error("sms sending failed, retry");
|
||||
ofono_error("sms sending failed");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
@@ -242,8 +230,6 @@ static void ril_cmgs(struct ofono_sms *sms, const unsigned char *pdu,
|
||||
submit_sms_cb, cbd, g_free);
|
||||
|
||||
g_ril_append_print_buf(sd->ril, "(%s)", tpdu);
|
||||
g_free(tpdu);
|
||||
tpdu = NULL;
|
||||
g_ril_print_request(sd->ril, ret, request);
|
||||
|
||||
parcel_free(&rilp);
|
||||
@@ -262,21 +248,19 @@ static void ril_ack_delivery_cb(struct ril_msg *message, gpointer user_data)
|
||||
"SMS acknowledgement failed: Further SMS reception is not guaranteed");
|
||||
}
|
||||
|
||||
static void ril_ack_delivery(struct ofono_sms *sms, int error)
|
||||
static void ril_ack_delivery(struct ofono_sms *sms)
|
||||
{
|
||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
||||
struct parcel rilp;
|
||||
int ret;
|
||||
int request = RIL_REQUEST_SMS_ACKNOWLEDGE;
|
||||
int code = 0;
|
||||
|
||||
if (!error)
|
||||
code = 0xFF;
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
|
||||
parcel_w_int32(&rilp, error); /* Successful (1)/Failed (0) receipt */
|
||||
parcel_w_int32(&rilp, code); /* error code */
|
||||
parcel_w_int32(&rilp, 1); /* Successful receipt */
|
||||
parcel_w_int32(&rilp, 0); /* error code */
|
||||
|
||||
/* TODO: should ACK be sent for either of the error cases? */
|
||||
|
||||
/* ACK the incoming NEW_SMS */
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
@@ -301,9 +285,6 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
|
||||
long ril_buf_len;
|
||||
guchar *ril_data;
|
||||
|
||||
ril_pdu = NULL;
|
||||
ril_data = NULL;
|
||||
|
||||
DBG("req: %d; data_len: %d", message->req, message->buf_len);
|
||||
|
||||
switch (message->req) {
|
||||
@@ -336,8 +317,6 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
|
||||
ofono_info("sms received, smsc_len is %d", smsc_len);
|
||||
|
||||
g_ril_append_print_buf(sd->ril, "(%s)", ril_pdu);
|
||||
g_free(ril_pdu);
|
||||
ril_pdu = NULL;
|
||||
g_ril_print_unsol(sd->ril, message);
|
||||
|
||||
if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS) {
|
||||
@@ -350,116 +329,14 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
|
||||
ril_buf_len - smsc_len);
|
||||
}
|
||||
|
||||
g_free(ril_data);
|
||||
ril_data = NULL;
|
||||
|
||||
ril_ack_delivery(sms, TRUE);
|
||||
ril_ack_delivery(sms);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
g_free(ril_pdu);
|
||||
ril_pdu = NULL;
|
||||
|
||||
g_free(ril_data);
|
||||
ril_data = NULL;
|
||||
|
||||
ril_ack_delivery(sms, FALSE);
|
||||
|
||||
ofono_error("Unable to parse NEW_SMS notification");
|
||||
}
|
||||
|
||||
static void ril_new_sms_on_sim_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
DBG("");
|
||||
if (message->error == RIL_E_SUCCESS)
|
||||
ofono_info("sms deleted from sim");
|
||||
else
|
||||
ofono_error("deleting sms from sim failed");
|
||||
}
|
||||
|
||||
static void ril_request_delete_sms_om_sim(struct ofono_sms *sms,int record)
|
||||
{
|
||||
struct sms_data *data = ofono_sms_get_data(sms);
|
||||
struct parcel rilp;
|
||||
int request = RIL_REQUEST_DELETE_SMS_ON_SIM;
|
||||
int ret;
|
||||
|
||||
DBG("Deleting record: %d", record);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 1); /* Number of int32 values in array */
|
||||
parcel_w_int32(&rilp, record);
|
||||
|
||||
ret = g_ril_send(data->ril, request, rilp.data,
|
||||
rilp.size, ril_new_sms_on_sim_cb, NULL, NULL);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0)
|
||||
ofono_error("cannot delete sms from sim");
|
||||
}
|
||||
|
||||
static void ril_read_sms_on_sim_cb(const struct ofono_error *error,
|
||||
const unsigned char *sdata,
|
||||
int length, void *data)
|
||||
{
|
||||
struct cb_data *cbd = data;
|
||||
struct ofono_sms *sms = cbd->user;
|
||||
int record;
|
||||
unsigned int smsc_len;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
ofono_error("cannot read sms from sim");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* It seems when reading EFsms RIL returns the whole record including
|
||||
* the first status byte therefore we ignore that as we are only
|
||||
* interested of the following pdu
|
||||
*/
|
||||
/* The first octect in the pdu contains the SMSC address length
|
||||
* which is the X following octects it reads. We add 1 octet to
|
||||
* the read length to take into account this read octet in order
|
||||
* to calculate the proper tpdu length.
|
||||
*/
|
||||
smsc_len = sdata[1] + 1;
|
||||
|
||||
ofono_sms_deliver_notify(sms, sdata + 1, length - 1,
|
||||
length - smsc_len - 1);
|
||||
|
||||
record = (int)cbd->data;
|
||||
ril_request_delete_sms_om_sim(sms,record);
|
||||
|
||||
exit:
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void ril_new_sms_on_sim(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_sms *sms = user_data;
|
||||
struct parcel rilp;
|
||||
int record;
|
||||
|
||||
ofono_info("new sms on sim");
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
|
||||
/* data length of the response */
|
||||
record = parcel_r_int32(&rilp);
|
||||
|
||||
if (record > 0) {
|
||||
record = parcel_r_int32(&rilp);
|
||||
struct cb_data *cbd = cb_data_new2(sms, NULL, (void*)record);
|
||||
DBG(":%d", record);
|
||||
get_sim_driver()->read_file_linear(get_sim(), SIM_EFSMS_FILEID,
|
||||
record, EFSMS_LENGTH, path,
|
||||
sizeof(path),
|
||||
ril_read_sms_on_sim_cb, cbd);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ril_delayed_register(gpointer user_data)
|
||||
{
|
||||
struct ofono_sms *sms = user_data;
|
||||
@@ -475,8 +352,6 @@ static gboolean ril_delayed_register(gpointer user_data)
|
||||
ril_sms_notify, sms);
|
||||
g_ril_register(data->ril, RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
|
||||
ril_sms_notify, sms);
|
||||
g_ril_register(data->ril, RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM,
|
||||
ril_new_sms_on_sim, sms);
|
||||
|
||||
/* This makes the timeout a single-shot */
|
||||
return FALSE;
|
||||
|
||||
@@ -1,342 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2014 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.
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/stk.h>
|
||||
|
||||
#include "gril.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "rilmodem.h"
|
||||
#include "ril_constants.h"
|
||||
|
||||
struct stk_data {
|
||||
GRil *ril;
|
||||
};
|
||||
|
||||
gboolean subscribed;
|
||||
|
||||
static void ril_envelope_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_stk_envelope_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
} else {
|
||||
DBG("Envelope reply failure: %s",
|
||||
ril_error_to_string(message->error));
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
cb(&error, NULL, 0, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_stk_envelope(struct ofono_stk *stk, int length,
|
||||
const unsigned char *command,
|
||||
ofono_stk_envelope_cb_t cb, void *data)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct parcel rilp;
|
||||
char *hex_envelope = NULL;
|
||||
int request = RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND;
|
||||
guint ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
hex_envelope = encode_hex(command, length, 0);
|
||||
DBG("rilmodem envelope: %s", hex_envelope);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_string(&rilp, hex_envelope);
|
||||
g_free(hex_envelope);
|
||||
hex_envelope = NULL;
|
||||
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
rilp.data, rilp.size, ril_envelope_cb,
|
||||
cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, NULL, -1, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_tr_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_stk_generic_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
} else {
|
||||
DBG("Error in sending terminal response");
|
||||
ofono_error("Error in sending terminal response");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_stk_terminal_response(struct ofono_stk *stk, int length,
|
||||
const unsigned char *resp,
|
||||
ofono_stk_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct parcel rilp;
|
||||
char *hex_tr = NULL;
|
||||
int request = RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE;
|
||||
guint ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
hex_tr = encode_hex(resp, length, 0);
|
||||
DBG("rilmodem terminal response: %s", hex_tr);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_string(&rilp, hex_tr);
|
||||
g_free(hex_tr);
|
||||
hex_tr = NULL;
|
||||
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
rilp.data, rilp.size, ril_tr_cb,
|
||||
cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_stk_user_confirmation(struct ofono_stk *stk,
|
||||
ofono_bool_t confirm)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
struct parcel rilp;
|
||||
int request = RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM;
|
||||
int ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
/* Only pcmd needing user confirmation is call set up
|
||||
* RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
|
||||
*/
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 1); /* size of array */
|
||||
parcel_w_int32(&rilp, confirm); /* yes/no */
|
||||
|
||||
/* fire and forget i.e. not waiting for the callback*/
|
||||
ret = g_ril_send(sd->ril, request, rilp.data,
|
||||
rilp.size, NULL, NULL, NULL);
|
||||
|
||||
g_ril_print_request_no_args(sd->ril, ret, request);
|
||||
|
||||
parcel_free(&rilp);
|
||||
}
|
||||
|
||||
static void ril_stk_pcmd_notify(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_stk *stk = user_data;
|
||||
struct parcel rilp;
|
||||
char *pcmd = NULL;
|
||||
guchar *pdu = NULL;
|
||||
long len;
|
||||
|
||||
DBG("");
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
pcmd = parcel_r_string(&rilp);
|
||||
DBG("pcmd: %s", pcmd);
|
||||
|
||||
pdu = decode_hex((const char *) pcmd,
|
||||
strlen(pcmd),
|
||||
&len, -1);
|
||||
|
||||
g_free(pcmd);
|
||||
ofono_stk_proactive_command_notify(stk, len, (const guchar *)pdu);
|
||||
g_free(pdu);
|
||||
}
|
||||
|
||||
static void ril_stk_event_notify(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_stk *stk = user_data;
|
||||
struct parcel rilp;
|
||||
char *pcmd = NULL;
|
||||
guchar *pdu = NULL;
|
||||
long len;
|
||||
|
||||
DBG("");
|
||||
|
||||
/* Proactive command has been handled by the modem. */
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
pcmd = parcel_r_string(&rilp);
|
||||
DBG("pcmd: %s", pcmd);
|
||||
pdu = decode_hex((const char *) pcmd,
|
||||
strlen(pcmd),
|
||||
&len, -1);
|
||||
g_free(pcmd);
|
||||
pcmd = NULL;
|
||||
ofono_stk_proactive_command_handled_notify(stk, len,
|
||||
(const guchar *)pdu);
|
||||
g_free(pdu);
|
||||
}
|
||||
|
||||
static void ril_stk_session_end_notify(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct ofono_stk *stk = user_data;
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_stk_proactive_session_end_notify(stk);
|
||||
}
|
||||
|
||||
static void ril_stk_agent_ready(struct ofono_stk *stk)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
int request = RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING;
|
||||
int ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (!subscribed) {
|
||||
DBG("Subscribing notifications");
|
||||
g_ril_register(sd->ril, RIL_UNSOL_STK_PROACTIVE_COMMAND,
|
||||
ril_stk_pcmd_notify, stk);
|
||||
|
||||
g_ril_register(sd->ril, RIL_UNSOL_STK_SESSION_END,
|
||||
ril_stk_session_end_notify, stk);
|
||||
|
||||
g_ril_register(sd->ril, RIL_UNSOL_STK_EVENT_NOTIFY,
|
||||
ril_stk_event_notify, stk);
|
||||
subscribed = TRUE;
|
||||
}
|
||||
|
||||
/* fire and forget i.e. not waiting for the callback*/
|
||||
ret = g_ril_send(sd->ril, request, NULL, 0,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_ril_print_request_no_args(sd->ril, ret, request);
|
||||
}
|
||||
|
||||
void ril_stk_set_lang()
|
||||
{
|
||||
gchar *contents;
|
||||
GError *err = NULL;
|
||||
|
||||
if (!g_file_get_contents(UI_LANG, &contents, NULL, &err)) {
|
||||
if (err)
|
||||
ofono_error("cannot open %s error: %d: message: %s",
|
||||
UI_LANG, err->code, err->message);
|
||||
g_error_free(err);
|
||||
} else {
|
||||
gchar *pch = g_strrstr(contents, CFG_LANG);
|
||||
/* Set System UI lang to env LANG */
|
||||
if (pch) {
|
||||
setenv("LANG", pch + strlen(CFG_LANG), 1);
|
||||
DBG("LANG %s", getenv("LANG"));
|
||||
}
|
||||
g_free(contents);
|
||||
}
|
||||
}
|
||||
|
||||
static int ril_stk_probe(struct ofono_stk *stk, unsigned int vendor, void *data)
|
||||
{
|
||||
GRil *ril = data;
|
||||
struct stk_data *sd;
|
||||
|
||||
DBG("");
|
||||
|
||||
sd = g_try_new0(struct stk_data, 1);
|
||||
if (sd == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
sd->ril = g_ril_clone(ril);
|
||||
ofono_stk_set_data(stk, sd);
|
||||
|
||||
/* Register interface in this phase for stk agent */
|
||||
ofono_stk_register(stk);
|
||||
|
||||
subscribed = FALSE;
|
||||
|
||||
/* UI language for local info */
|
||||
ril_stk_set_lang();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ril_stk_remove(struct ofono_stk *stk)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_stk_set_data(stk, NULL);
|
||||
|
||||
g_ril_unref(sd->ril);
|
||||
g_free(sd);
|
||||
}
|
||||
|
||||
static struct ofono_stk_driver driver = {
|
||||
.name = "rilmodem",
|
||||
.probe = ril_stk_probe,
|
||||
.remove = ril_stk_remove,
|
||||
.envelope = ril_stk_envelope,
|
||||
.terminal_response = ril_stk_terminal_response,
|
||||
.user_confirmation = ril_stk_user_confirmation,
|
||||
.ready = ril_stk_agent_ready
|
||||
};
|
||||
|
||||
void ril_stk_init(void)
|
||||
{
|
||||
ofono_stk_driver_register(&driver);
|
||||
}
|
||||
|
||||
void ril_stk_exit(void)
|
||||
{
|
||||
ofono_stk_driver_unregister(&driver);
|
||||
}
|
||||
@@ -68,37 +68,19 @@ static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
|
||||
enum sms_charset charset;
|
||||
int ret = -1;
|
||||
|
||||
ofono_info("send ussd, len:%d", len);
|
||||
ofono_info("send ussd");
|
||||
|
||||
if (cbs_dcs_decode(dcs, NULL, NULL, &charset,
|
||||
NULL, NULL, NULL)) {
|
||||
if (charset == SMS_CHARSET_7BIT) {
|
||||
unsigned char unpacked_buf[182] = "";
|
||||
long written;
|
||||
int length;
|
||||
|
||||
unpack_7bit_own_buf(pdu, len, 0, TRUE,
|
||||
sizeof(unpacked_buf), &written, 0,
|
||||
unpacked_buf);
|
||||
|
||||
if (written >= 1) {
|
||||
/*
|
||||
* When USSD was packed, additional CR
|
||||
might have been added (according to
|
||||
23.038 6.1.2.3.1). So if the last
|
||||
character is CR, it should be removed
|
||||
here. And in addition written doesn't
|
||||
contain correct length...
|
||||
|
||||
Over 2 characters long USSD string must
|
||||
end with # (checked in
|
||||
valid_ussd_string() ), so it should be
|
||||
safe to remove extra CR.
|
||||
*/
|
||||
length = strlen((char *)unpacked_buf);
|
||||
if (length > 2 &&
|
||||
unpacked_buf[length-1] == '\r')
|
||||
unpacked_buf[length-1] = 0;
|
||||
struct parcel rilp;
|
||||
parcel_init(&rilp);
|
||||
parcel_w_string(&rilp, (char *)unpacked_buf);
|
||||
@@ -167,9 +149,9 @@ static void ril_ussd_notify(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_ussd *ussd = user_data;
|
||||
struct parcel rilp;
|
||||
gchar *ussd_from_network = NULL;
|
||||
gchar *type = NULL;
|
||||
gint ussdtype = 0;
|
||||
gchar *ussd_from_network;
|
||||
gchar *type;
|
||||
gint ussdtype;
|
||||
|
||||
ofono_info("ussd_received");
|
||||
|
||||
@@ -177,17 +159,13 @@ static void ril_ussd_notify(struct ril_msg *message, gpointer user_data)
|
||||
parcel_r_int32(&rilp);
|
||||
type = parcel_r_string(&rilp);
|
||||
ussdtype = g_ascii_xdigit_value(*type);
|
||||
g_free(type);
|
||||
type = NULL;
|
||||
ussd_from_network = parcel_r_string(&rilp);
|
||||
|
||||
/* ussd_from_network not freed because core does that if dcs is 0xFF */
|
||||
if (ussd_from_network) {
|
||||
DBG("ussd_received, length %d", strlen(ussd_from_network));
|
||||
if (ussd_from_network)
|
||||
ofono_ussd_notify(ussd, ussdtype, 0xFF,
|
||||
(const unsigned char *)ussd_from_network,
|
||||
strlen(ussd_from_network));
|
||||
} else
|
||||
else
|
||||
ofono_ussd_notify(ussd, ussdtype, 0, NULL, 0);
|
||||
|
||||
return;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2012 Canonical Ltd.
|
||||
* Copyright (C) 2014 Jolla Ltd.
|
||||
* Copyright (C) 2013 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -45,7 +45,9 @@
|
||||
|
||||
/* Amount of ms we wait between CLCC calls */
|
||||
#define POLL_CLCC_INTERVAL 300
|
||||
|
||||
#define FLAG_NEED_CLIP 1
|
||||
|
||||
#define MAX_DTMF_BUFFER 32
|
||||
|
||||
struct voicecall_data {
|
||||
@@ -84,21 +86,6 @@ struct lastcause_req {
|
||||
static void send_one_dtmf(struct voicecall_data *vd);
|
||||
static void clear_dtmf_queue(struct voicecall_data *vd);
|
||||
|
||||
/*
|
||||
* structs ofono_voicecall and voicecall are fully defined
|
||||
* in src/voicecall.c; we need (read) access to the
|
||||
* call objects, so partially redefine them here.
|
||||
*/
|
||||
struct ofono_voicecall {
|
||||
GSList *call_list;
|
||||
/* ... */
|
||||
};
|
||||
|
||||
struct voicecall {
|
||||
struct ofono_call *call;
|
||||
/* ... */
|
||||
};
|
||||
|
||||
static void lastcause_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct lastcause_req *reqdata = user_data;
|
||||
@@ -112,38 +99,11 @@ static void lastcause_cb(struct ril_msg *message, gpointer user_data)
|
||||
if (parcel_r_int32(&rilp) > 0)
|
||||
last_cause = parcel_r_int32(&rilp);
|
||||
|
||||
/*
|
||||
* Not all call control cause values specified in 3GPP TS 24.008
|
||||
* "Mobile radio interface Layer 3 specification; Core network protocols",
|
||||
* Annex H, are properly reflected in the RIL API. For example, cause
|
||||
* #21 "call rejected" is mapped to CALL_FAIL_ERROR_UNSPECIFIED, and
|
||||
* thus indistinguishable from a network failure.
|
||||
* We signal disconnect reason "remote" for cause values
|
||||
* - #16 "normal call clearing"
|
||||
* - #17 "user busy"
|
||||
* - UNSPECIFIED for MO calls that are not yet connected
|
||||
* , and disconnect reason "network" otherwise.
|
||||
*/
|
||||
ofono_info("Call %d ended with RIL cause %d", id, last_cause);
|
||||
if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) {
|
||||
reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
|
||||
}
|
||||
|
||||
if (last_cause == CALL_FAIL_ERROR_UNSPECIFIED) {
|
||||
GSList *l;
|
||||
struct voicecall *v;
|
||||
for (l = vc->call_list; l; l = l->next) {
|
||||
v = l->data;
|
||||
if (v->call->id == id) {
|
||||
if (v->call->status == CALL_STATUS_DIALING
|
||||
|| v->call->status == CALL_STATUS_ALERTING) {
|
||||
reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ofono_voicecall_disconnected(vc, id, reason, NULL);
|
||||
}
|
||||
|
||||
@@ -276,8 +236,6 @@ static void generic_cb(struct ril_msg *message, gpointer user_data)
|
||||
int request = RIL_REQUEST_GET_CURRENT_CALLS;
|
||||
int ret;
|
||||
|
||||
ofono_info("request:%d",message->req);
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
} else {
|
||||
@@ -382,17 +340,15 @@ static void ril_dial(struct ofono_voicecall *vc,
|
||||
struct parcel rilp;
|
||||
int request = RIL_REQUEST_DIAL;
|
||||
int ret;
|
||||
char *phstr = NULL;
|
||||
|
||||
phstr = (char *) phone_number_to_string(ph);
|
||||
ofono_info("dialing \"%s\"", phstr);
|
||||
ofono_info("dialing");
|
||||
|
||||
cbd->user = vc;
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
/* Number to dial */
|
||||
parcel_w_string(&rilp, phstr);
|
||||
parcel_w_string(&rilp, (char *) phone_number_to_string(ph));
|
||||
/* CLIR mode */
|
||||
parcel_w_int32(&rilp, clir);
|
||||
/* USS, need it twice for absent */
|
||||
@@ -525,7 +481,6 @@ static void ril_ss_notify(struct ril_msg *message, gpointer user_data)
|
||||
strncpy(number.number, tmp_number,
|
||||
OFONO_MAX_PHONE_NUMBER_LENGTH);
|
||||
|
||||
g_free(tmp_number);
|
||||
DBG("RIL data: MT/MO: %i, code: %i, index: %i",
|
||||
notification_type, code, index);
|
||||
break;
|
||||
@@ -679,13 +634,6 @@ static void ril_create_multiparty(struct ofono_voicecall *vc,
|
||||
cb(&error, data);
|
||||
}
|
||||
|
||||
static void ril_transfer(struct ofono_voicecall *vc,
|
||||
ofono_voicecall_cb_t cb, void *data)
|
||||
{
|
||||
ril_template(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, vc, generic_cb, 0,
|
||||
NULL, 0, cb, data);
|
||||
}
|
||||
|
||||
static void private_chat_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_error error;
|
||||
@@ -779,23 +727,6 @@ static gboolean enable_supp_svc(gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void ril_ringback_tone_notify(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct parcel rilp;
|
||||
struct ofono_voicecall *vc = user_data;
|
||||
gboolean playTone = FALSE;
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
|
||||
if (message->req == RIL_UNSOL_RINGBACK_TONE) {
|
||||
if (parcel_r_int32(&rilp) > 0)
|
||||
playTone = parcel_r_int32(&rilp);
|
||||
DBG("play ringback tone: %d", playTone);
|
||||
ofono_voicecall_ringback_tone_notify(vc, playTone);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ril_delayed_register(gpointer user_data)
|
||||
{
|
||||
struct ofono_voicecall *vc = user_data;
|
||||
@@ -816,10 +747,6 @@ static gboolean ril_delayed_register(gpointer user_data)
|
||||
g_ril_register(vd->ril, RIL_UNSOL_SUPP_SVC_NOTIFICATION,
|
||||
ril_ss_notify, vc);
|
||||
|
||||
/* Register for ringback tone notifications */
|
||||
g_ril_register(vd->ril, RIL_UNSOL_RINGBACK_TONE,
|
||||
ril_ringback_tone_notify, vc);
|
||||
|
||||
/* request supplementary service notifications*/
|
||||
enable_supp_svc(vc);
|
||||
|
||||
@@ -876,7 +803,6 @@ static void ril_voicecall_remove(struct ofono_voicecall *vc)
|
||||
if (vd->timer_id > 0)
|
||||
g_source_remove(vd->timer_id);
|
||||
|
||||
g_free(vd->tone_queue);
|
||||
g_ril_unref(vd->ril);
|
||||
g_free(vd);
|
||||
}
|
||||
@@ -891,13 +817,12 @@ static struct ofono_voicecall_driver driver = {
|
||||
.release_specific = ril_hangup_specific,
|
||||
.send_tones = ril_send_dtmf,
|
||||
.create_multiparty = ril_create_multiparty,
|
||||
.transfer = ril_transfer,
|
||||
.private_chat = ril_private_chat,
|
||||
.swap_without_accept = ril_swap_without_accept,
|
||||
.hold_all_active = ril_hold_all_active,
|
||||
.release_all_held = ril_release_all_held,
|
||||
.set_udub = ril_set_udub,
|
||||
.release_all_active = ril_release_all_active,
|
||||
.release_all_active = ril_release_all_active,
|
||||
};
|
||||
|
||||
void ril_voicecall_init(void)
|
||||
|
||||
@@ -1,315 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2014 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/location-reporting.h>
|
||||
|
||||
#include "gatchat.h"
|
||||
#include "gatresult.h"
|
||||
#include "gattty.h"
|
||||
|
||||
#include "telitmodem.h"
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static const char *portcfg_prefix[] = { "#PORTCFG:", NULL };
|
||||
static const char *gpsctl_prefix[] = { "$GPSP:", NULL };
|
||||
|
||||
struct gps_data {
|
||||
GAtChat *chat;
|
||||
};
|
||||
|
||||
static void telit_gps_disable_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_location_reporting *lr = cbd->user;
|
||||
ofono_location_reporting_disable_cb_t cb = cbd->cb;
|
||||
|
||||
DBG("lr=%p, ok=%d", lr, ok);
|
||||
|
||||
if (!ok) {
|
||||
struct ofono_error error;
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
}
|
||||
|
||||
static void telit_location_reporting_disable(
|
||||
struct ofono_location_reporting *lr,
|
||||
ofono_location_reporting_disable_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct gps_data *gd = ofono_location_reporting_get_data(lr);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
|
||||
DBG("lr=%p", lr);
|
||||
|
||||
cbd->user = lr;
|
||||
|
||||
if (g_at_chat_send(gd->chat, "AT$GPSP=0", none_prefix,
|
||||
telit_gps_disable_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static int enable_data_stream(struct ofono_location_reporting *lr)
|
||||
{
|
||||
struct ofono_modem *modem;
|
||||
const char *gps_dev;
|
||||
GHashTable *options;
|
||||
GIOChannel *channel;
|
||||
int fd;
|
||||
|
||||
modem = ofono_location_reporting_get_modem(lr);
|
||||
gps_dev = ofono_modem_get_string(modem, "GPS");
|
||||
|
||||
options = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
if (options == NULL)
|
||||
return -1;
|
||||
|
||||
g_hash_table_insert(options, "Baud", "115200");
|
||||
|
||||
channel = g_at_tty_open(gps_dev, options);
|
||||
|
||||
g_hash_table_destroy(options);
|
||||
|
||||
if (channel == NULL)
|
||||
return -1;
|
||||
|
||||
fd = g_io_channel_unix_get_fd(channel);
|
||||
|
||||
g_io_channel_set_close_on_unref(channel, FALSE);
|
||||
g_io_channel_unref(channel);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void telit_gps_ctl_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_location_reporting_enable_cb_t cb = cbd->cb;
|
||||
struct ofono_location_reporting *lr = cbd->user;
|
||||
struct ofono_error error;
|
||||
int fd;
|
||||
|
||||
DBG("lr=%p ok=%d", lr, ok);
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
|
||||
if (!ok) {
|
||||
cb(&error, -1, cbd->data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fd = enable_data_stream(lr);
|
||||
|
||||
if (fd < 0) {
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
cb(&error, fd, cbd->data);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void telit_gps_enable_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_location_reporting_enable_cb_t cb = cbd->cb;
|
||||
struct ofono_location_reporting *lr = cbd->user;
|
||||
struct gps_data *gd = ofono_location_reporting_get_data(lr);
|
||||
struct ofono_error error;
|
||||
|
||||
DBG("lr=%p ok=%d", lr, ok);
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
|
||||
if (!ok) {
|
||||
cb(&error, -1, cbd->data);
|
||||
|
||||
g_free(cbd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_at_chat_send(gd->chat, "AT$GPSNMUN=1,0,0,0,0,0,0",
|
||||
none_prefix, telit_gps_ctl_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void telit_portcfg_check_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_location_reporting_enable_cb_t cb = cbd->cb;
|
||||
struct ofono_location_reporting *lr = cbd->user;
|
||||
struct gps_data *gd = ofono_location_reporting_get_data(lr);
|
||||
struct ofono_error error;
|
||||
int requested_portcfg, current_portcfg;
|
||||
GAtResultIter iter;
|
||||
|
||||
DBG("lr=%p ok=%d", lr, ok);
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
|
||||
if (!ok) {
|
||||
cb(&error, -1, cbd->data);
|
||||
|
||||
g_free(cbd);
|
||||
return;
|
||||
}
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "#PORTCFG:"))
|
||||
goto fail;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &requested_portcfg))
|
||||
goto fail;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, ¤t_portcfg))
|
||||
goto fail;
|
||||
|
||||
if (current_portcfg != 8) {
|
||||
ofono_warn("Unable to start GPS, modem configuration invalid");
|
||||
ofono_warn("Refer to doc/telit-modem.txt section HE910/GPS");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (g_at_chat_send(gd->chat, "AT$GPSP=1", none_prefix,
|
||||
telit_gps_enable_cb, cbd, NULL) > 0)
|
||||
return;
|
||||
|
||||
fail:
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void telit_location_reporting_enable(struct ofono_location_reporting *lr,
|
||||
ofono_location_reporting_enable_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct gps_data *gd = ofono_location_reporting_get_data(lr);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
|
||||
DBG("lr=%p", lr);
|
||||
|
||||
cbd->user = lr;
|
||||
|
||||
if (g_at_chat_send(gd->chat, "AT#PORTCFG?", portcfg_prefix,
|
||||
telit_portcfg_check_cb, cbd, NULL) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void telit_location_reporting_support_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct ofono_location_reporting *lr = user_data;
|
||||
|
||||
if (!ok) {
|
||||
ofono_location_reporting_remove(lr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ofono_location_reporting_register(lr);
|
||||
}
|
||||
|
||||
static int telit_location_reporting_probe(struct ofono_location_reporting *lr,
|
||||
unsigned int vendor, void *data)
|
||||
{
|
||||
GAtChat *chat = data;
|
||||
struct gps_data *gd;
|
||||
|
||||
gd = g_try_new0(struct gps_data, 1);
|
||||
if (gd == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
gd->chat = g_at_chat_clone(chat);
|
||||
|
||||
ofono_location_reporting_set_data(lr, gd);
|
||||
|
||||
g_at_chat_send(gd->chat, "AT$GPSP=?", gpsctl_prefix,
|
||||
telit_location_reporting_support_cb,
|
||||
lr, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void telit_location_reporting_remove(struct ofono_location_reporting *lr)
|
||||
{
|
||||
struct gps_data *gd = ofono_location_reporting_get_data(lr);
|
||||
|
||||
ofono_location_reporting_set_data(lr, NULL);
|
||||
|
||||
g_at_chat_unref(gd->chat);
|
||||
g_free(gd);
|
||||
}
|
||||
|
||||
static struct ofono_location_reporting_driver driver = {
|
||||
.name = "telitmodem",
|
||||
.type = OFONO_LOCATION_REPORTING_TYPE_NMEA,
|
||||
.probe = telit_location_reporting_probe,
|
||||
.remove = telit_location_reporting_remove,
|
||||
.enable = telit_location_reporting_enable,
|
||||
.disable = telit_location_reporting_disable,
|
||||
};
|
||||
|
||||
void telit_location_reporting_init()
|
||||
{
|
||||
ofono_location_reporting_driver_register(&driver);
|
||||
}
|
||||
|
||||
void telit_location_reporting_exit()
|
||||
{
|
||||
ofono_location_reporting_driver_unregister(&driver);
|
||||
}
|
||||
@@ -1,49 +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
|
||||
|
||||
#include <glib.h>
|
||||
#include <gatchat.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/types.h>
|
||||
|
||||
#include "telitmodem.h"
|
||||
|
||||
static int telitmodem_init(void)
|
||||
{
|
||||
telit_location_reporting_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void telitmodem_exit(void)
|
||||
{
|
||||
telit_location_reporting_exit();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(telitmodem, "Telit modem driver", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT,
|
||||
telitmodem_init, telitmodem_exit)
|
||||
@@ -1,25 +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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drivers/atmodem/atutil.h>
|
||||
|
||||
extern void telit_location_reporting_init();
|
||||
extern void telit_location_reporting_exit();
|
||||
@@ -1,7 +1,6 @@
|
||||
[Unit]
|
||||
Description=DUN service
|
||||
Requires=dbus.service
|
||||
After=dbus.service
|
||||
After=syslog.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
|
||||
@@ -835,9 +835,6 @@ static gboolean can_write_data(gpointer data)
|
||||
gsize len;
|
||||
char *cr;
|
||||
gboolean wakeup_first = FALSE;
|
||||
#ifdef WRITE_SCHEDULER_DEBUG
|
||||
int limiter;
|
||||
#endif
|
||||
|
||||
/* Grab the first command off the queue and write as
|
||||
* much of it as we can
|
||||
@@ -889,20 +886,13 @@ static gboolean can_write_data(gpointer data)
|
||||
towrite = cr - (cmd->cmd + chat->cmd_bytes_written) + 1;
|
||||
|
||||
#ifdef WRITE_SCHEDULER_DEBUG
|
||||
limiter = towrite;
|
||||
|
||||
if (limiter > 5)
|
||||
limiter = 5;
|
||||
if (towrite > 5)
|
||||
towrite = 5;
|
||||
#endif
|
||||
|
||||
bytes_written = g_at_io_write(chat->io,
|
||||
cmd->cmd + chat->cmd_bytes_written,
|
||||
#ifdef WRITE_SCHEDULER_DEBUG
|
||||
limiter
|
||||
#else
|
||||
towrite
|
||||
#endif
|
||||
);
|
||||
towrite);
|
||||
|
||||
if (bytes_written == 0)
|
||||
return FALSE;
|
||||
|
||||
@@ -64,13 +64,11 @@ struct _GAtPPP {
|
||||
struct pppcp_data *ipcp;
|
||||
struct ppp_net *net;
|
||||
struct ppp_chap *chap;
|
||||
struct ppp_pap *pap;
|
||||
GAtHDLC *hdlc;
|
||||
gint mru;
|
||||
gint mtu;
|
||||
char username[256];
|
||||
char password[256];
|
||||
GAtPPPAuthMethod auth_method;
|
||||
GAtPPPConnectFunc connect_cb;
|
||||
gpointer connect_data;
|
||||
GAtPPPDisconnectFunc disconnect_cb;
|
||||
@@ -152,15 +150,13 @@ static inline gboolean ppp_drop_packet(GAtPPP *ppp, guint16 protocol)
|
||||
return TRUE;
|
||||
break;
|
||||
case PPP_PHASE_AUTHENTICATION:
|
||||
if (protocol != LCP_PROTOCOL && protocol != CHAP_PROTOCOL &&
|
||||
protocol != PAP_PROTOCOL)
|
||||
if (protocol != LCP_PROTOCOL && protocol != CHAP_PROTOCOL)
|
||||
return TRUE;
|
||||
break;
|
||||
case PPP_PHASE_DEAD:
|
||||
return TRUE;
|
||||
case PPP_PHASE_NETWORK:
|
||||
if (protocol != LCP_PROTOCOL && protocol != CHAP_PROTOCOL &&
|
||||
protocol != PAP_PROTOCOL &&
|
||||
protocol != IPCP_PROTO)
|
||||
return TRUE;
|
||||
break;
|
||||
@@ -225,13 +221,6 @@ static void ppp_receive(const unsigned char *buf, gsize len, void *data)
|
||||
break;
|
||||
case IPCP_PROTO:
|
||||
pppcp_process_packet(ppp->ipcp, packet, len - offset);
|
||||
break;
|
||||
case PAP_PROTOCOL:
|
||||
if (ppp->pap)
|
||||
ppp_pap_process_packet(ppp->pap, packet, len - offset);
|
||||
else
|
||||
pppcp_send_protocol_reject(ppp->lcp, buf, len);
|
||||
|
||||
break;
|
||||
case CHAP_PROTOCOL:
|
||||
if (ppp->chap) {
|
||||
@@ -370,12 +359,6 @@ void ppp_set_auth(GAtPPP *ppp, const guint8* auth_data)
|
||||
guint16 proto = get_host_short(auth_data);
|
||||
|
||||
switch (proto) {
|
||||
case PAP_PROTOCOL:
|
||||
if (ppp->pap)
|
||||
ppp_pap_free(ppp->pap);
|
||||
|
||||
ppp->pap = ppp_pap_new(ppp);
|
||||
break;
|
||||
case CHAP_PROTOCOL:
|
||||
if (ppp->chap)
|
||||
ppp_chap_free(ppp->chap);
|
||||
@@ -454,19 +437,10 @@ void ppp_ipcp_finished_notify(GAtPPP *ppp)
|
||||
|
||||
void ppp_lcp_up_notify(GAtPPP *ppp)
|
||||
{
|
||||
/* Wait for the peer to send us a challenge if we expect auth */
|
||||
if (ppp->chap != NULL) {
|
||||
/* Wait for the peer to send us a challenge. */
|
||||
ppp_enter_phase(ppp, PPP_PHASE_AUTHENTICATION);
|
||||
return;
|
||||
} else if (ppp->pap != NULL) {
|
||||
/* Try to send an Authenticate-Request and wait for reply. */
|
||||
if (ppp_pap_start(ppp->pap) == TRUE)
|
||||
ppp_enter_phase(ppp, PPP_PHASE_AUTHENTICATION);
|
||||
else
|
||||
/* It'll never work out. */
|
||||
ppp_auth_notify(ppp, FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise proceed as if auth succeeded */
|
||||
@@ -614,22 +588,6 @@ const char *g_at_ppp_get_password(GAtPPP *ppp)
|
||||
return ppp->password;
|
||||
}
|
||||
|
||||
gboolean g_at_ppp_set_auth_method(GAtPPP *ppp, GAtPPPAuthMethod method)
|
||||
{
|
||||
if (method != G_AT_PPP_AUTH_METHOD_CHAP &&
|
||||
method != G_AT_PPP_AUTH_METHOD_PAP)
|
||||
return FALSE;
|
||||
|
||||
ppp->auth_method = method;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GAtPPPAuthMethod g_at_ppp_get_auth_method(GAtPPP *ppp)
|
||||
{
|
||||
return ppp->auth_method;
|
||||
}
|
||||
|
||||
void g_at_ppp_set_recording(GAtPPP *ppp, const char *filename)
|
||||
{
|
||||
if (ppp == NULL)
|
||||
@@ -769,9 +727,6 @@ void g_at_ppp_unref(GAtPPP *ppp)
|
||||
else if (ppp->fd >= 0)
|
||||
close(ppp->fd);
|
||||
|
||||
if (ppp->pap)
|
||||
ppp_pap_free(ppp->pap);
|
||||
|
||||
if (ppp->chap)
|
||||
ppp_chap_free(ppp->chap);
|
||||
|
||||
@@ -839,9 +794,6 @@ static GAtPPP *ppp_init_common(gboolean is_server, guint32 ip)
|
||||
/* initialize IPCP state */
|
||||
ppp->ipcp = ipcp_new(ppp, is_server, ip);
|
||||
|
||||
/* chap authentication by default */
|
||||
ppp->auth_method = G_AT_PPP_AUTH_METHOD_CHAP;
|
||||
|
||||
return ppp;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,11 +43,6 @@ typedef enum _GAtPPPDisconnectReason {
|
||||
G_AT_PPP_REASON_LOCAL_CLOSE, /* Normal user close */
|
||||
} GAtPPPDisconnectReason;
|
||||
|
||||
typedef enum _GAtPPPAuthMethod {
|
||||
G_AT_PPP_AUTH_METHOD_CHAP,
|
||||
G_AT_PPP_AUTH_METHOD_PAP,
|
||||
} GAtPPPAuthMethod;
|
||||
|
||||
typedef void (*GAtPPPConnectFunc)(const char *iface, const char *local,
|
||||
const char *peer,
|
||||
const char *dns1, const char *dns2,
|
||||
@@ -79,9 +74,6 @@ gboolean g_at_ppp_set_credentials(GAtPPP *ppp, const char *username,
|
||||
const char *g_at_ppp_get_username(GAtPPP *ppp);
|
||||
const char *g_at_ppp_get_password(GAtPPP *ppp);
|
||||
|
||||
gboolean g_at_ppp_set_auth_method(GAtPPP *ppp, GAtPPPAuthMethod method);
|
||||
GAtPPPAuthMethod g_at_ppp_get_auth_method(GAtPPP *ppp);
|
||||
|
||||
void g_at_ppp_set_recording(GAtPPP *ppp, const char *filename);
|
||||
|
||||
void g_at_ppp_set_server_info(GAtPPP *ppp, const char *remote_ip,
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "ppp_cp.h"
|
||||
|
||||
#define LCP_PROTOCOL 0xc021
|
||||
#define PAP_PROTOCOL 0xc023
|
||||
#define CHAP_PROTOCOL 0xc223
|
||||
#define IPCP_PROTO 0x8021
|
||||
#define IPV6CP_PROTO 0x8057
|
||||
@@ -39,7 +38,6 @@
|
||||
|
||||
struct ppp_chap;
|
||||
struct ppp_net;
|
||||
struct ppp_pap;
|
||||
|
||||
struct ppp_header {
|
||||
guint8 address;
|
||||
@@ -111,13 +109,6 @@ void ppp_chap_free(struct ppp_chap *chap);
|
||||
void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet,
|
||||
gsize len);
|
||||
|
||||
/* PAP related functions */
|
||||
struct ppp_pap *ppp_pap_new(GAtPPP *ppp);
|
||||
void ppp_pap_free(struct ppp_pap *pap);
|
||||
gboolean ppp_pap_start(struct ppp_pap *pap);
|
||||
void ppp_pap_process_packet(struct ppp_pap *pap, const guint8 *new_packet,
|
||||
gsize len);
|
||||
|
||||
/* TUN / Network related functions */
|
||||
struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd);
|
||||
const char *ppp_net_get_interface(struct ppp_net *net);
|
||||
|
||||
@@ -54,38 +54,6 @@ enum chap_code {
|
||||
FAILURE
|
||||
};
|
||||
|
||||
struct pap_header {
|
||||
guint8 code;
|
||||
guint8 identifier;
|
||||
guint16 length;
|
||||
guint8 data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ppp_pap {
|
||||
GAtPPP *ppp;
|
||||
struct ppp_header *authreq;
|
||||
guint16 authreq_len;
|
||||
guint retry_timer;
|
||||
guint retries;
|
||||
};
|
||||
|
||||
enum pap_code {
|
||||
PAP_REQUEST = 1,
|
||||
PAP_ACK,
|
||||
PAP_NAK
|
||||
};
|
||||
|
||||
/*
|
||||
* RFC 1334 2.1.1:
|
||||
* The Authenticate-Request packet MUST be repeated until a valid
|
||||
* reply packet is received, or an optional retry counter expires.
|
||||
*
|
||||
* If we don't get a reply after this many attempts, we can safely
|
||||
* assume we're never going to get one.
|
||||
*/
|
||||
#define PAP_MAX_RETRY 3 /* attempts */
|
||||
#define PAP_TIMEOUT 10 /* seconds */
|
||||
|
||||
static void chap_process_challenge(struct ppp_chap *chap, const guint8 *packet)
|
||||
{
|
||||
const struct chap_header *header = (const struct chap_header *) packet;
|
||||
@@ -198,114 +166,3 @@ struct ppp_chap *ppp_chap_new(GAtPPP *ppp, guint8 method)
|
||||
|
||||
return chap;
|
||||
}
|
||||
|
||||
void ppp_pap_process_packet(struct ppp_pap *pap, const guint8 *new_packet,
|
||||
gsize len)
|
||||
{
|
||||
guint8 code;
|
||||
|
||||
if (len < sizeof(struct pap_header))
|
||||
return;
|
||||
|
||||
code = new_packet[0];
|
||||
|
||||
switch (code) {
|
||||
case PAP_ACK:
|
||||
g_source_remove(pap->retry_timer);
|
||||
pap->retry_timer = 0;
|
||||
ppp_auth_notify(pap->ppp, TRUE);
|
||||
break;
|
||||
case PAP_NAK:
|
||||
g_source_remove(pap->retry_timer);
|
||||
pap->retry_timer = 0;
|
||||
ppp_auth_notify(pap->ppp, FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ppp_pap_timeout(gpointer user_data)
|
||||
{
|
||||
struct ppp_pap *pap = (struct ppp_pap *)user_data;
|
||||
struct pap_header *authreq;
|
||||
|
||||
if (++pap->retries >= PAP_MAX_RETRY) {
|
||||
pap->retry_timer = 0;
|
||||
ppp_auth_notify(pap->ppp, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 1334 2.2.1:
|
||||
* The Identifier field MUST be changed each time an
|
||||
* Authenticate-Request packet is issued.
|
||||
*/
|
||||
authreq = (struct pap_header *)&pap->authreq->info;
|
||||
authreq->identifier++;
|
||||
|
||||
ppp_transmit(pap->ppp, (guint8 *)pap->authreq, pap->authreq_len);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean ppp_pap_start(struct ppp_pap *pap)
|
||||
{
|
||||
struct pap_header *authreq;
|
||||
struct ppp_header *packet;
|
||||
const char *username = g_at_ppp_get_username(pap->ppp);
|
||||
const char *password = g_at_ppp_get_password(pap->ppp);
|
||||
guint16 length;
|
||||
|
||||
length = sizeof(*authreq) + strlen(username) + strlen(password) + 2;
|
||||
|
||||
packet = ppp_packet_new(length, PAP_PROTOCOL);
|
||||
if (packet == NULL)
|
||||
return FALSE;
|
||||
|
||||
pap->authreq = packet;
|
||||
pap->authreq_len = length;
|
||||
|
||||
authreq = (struct pap_header *)&packet->info;
|
||||
authreq->code = PAP_REQUEST;
|
||||
authreq->identifier = 1;
|
||||
authreq->length = htons(length);
|
||||
|
||||
authreq->data[0] = (unsigned char) strlen(username);
|
||||
memcpy(authreq->data + 1, username, strlen(username));
|
||||
authreq->data[strlen(username) + 1] = (unsigned char)strlen(password);
|
||||
memcpy(authreq->data + 1 + strlen(username) + 1, password,
|
||||
strlen(password));
|
||||
|
||||
/* Transmit the packet and schedule a retry. */
|
||||
ppp_transmit(pap->ppp, (guint8 *)packet, length);
|
||||
pap->retries = 0;
|
||||
pap->retry_timer = g_timeout_add_seconds(PAP_TIMEOUT,
|
||||
ppp_pap_timeout, pap);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ppp_pap_free(struct ppp_pap *pap)
|
||||
{
|
||||
if (pap->retry_timer != 0)
|
||||
g_source_remove(pap->retry_timer);
|
||||
|
||||
if (pap->authreq != NULL)
|
||||
g_free(pap->authreq);
|
||||
|
||||
g_free(pap);
|
||||
}
|
||||
|
||||
struct ppp_pap *ppp_pap_new(GAtPPP *ppp)
|
||||
{
|
||||
struct ppp_pap *pap;
|
||||
|
||||
pap = g_try_new0(struct ppp_pap, 1);
|
||||
if (pap == NULL)
|
||||
return NULL;
|
||||
|
||||
pap->ppp = ppp;
|
||||
|
||||
return pap;
|
||||
}
|
||||
|
||||
@@ -238,49 +238,25 @@ static enum rcr_result lcp_rcr(struct pppcp_data *pppcp,
|
||||
guint8 method = option_data[2];
|
||||
guint8 *option;
|
||||
|
||||
switch (g_at_ppp_get_auth_method(ppp)) {
|
||||
case G_AT_PPP_AUTH_METHOD_CHAP:
|
||||
if (proto == CHAP_PROTOCOL && method == MD5)
|
||||
break;
|
||||
if ((proto == CHAP_PROTOCOL) && (method == MD5))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Try to suggest CHAP/MD5.
|
||||
* Just reject if we run out of memory.
|
||||
*/
|
||||
option = g_try_malloc0(5);
|
||||
if (option == NULL)
|
||||
return RCR_REJECT;
|
||||
/*
|
||||
* try to suggest CHAP & MD5. If we are out
|
||||
* of memory, just reject.
|
||||
*/
|
||||
|
||||
option[0] = AUTH_PROTO;
|
||||
option[1] = 5;
|
||||
put_network_short(&option[2], CHAP_PROTOCOL);
|
||||
option[4] = MD5;
|
||||
*new_options = option;
|
||||
*new_len = 5;
|
||||
option = g_try_malloc0(5);
|
||||
if (option == NULL)
|
||||
return RCR_REJECT;
|
||||
|
||||
return RCR_NAK;
|
||||
|
||||
case G_AT_PPP_AUTH_METHOD_PAP:
|
||||
if (proto == PAP_PROTOCOL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Try to suggest PAP.
|
||||
* Just reject if we run out of memory.
|
||||
*/
|
||||
option = g_try_malloc0(4);
|
||||
if (option == NULL)
|
||||
return RCR_REJECT;
|
||||
|
||||
option[0] = AUTH_PROTO;
|
||||
option[1] = 4;
|
||||
put_network_short(&option[2], PAP_PROTOCOL);
|
||||
*new_options = option;
|
||||
*new_len = 4;
|
||||
|
||||
return RCR_NAK;
|
||||
}
|
||||
break;
|
||||
option[0] = AUTH_PROTO;
|
||||
option[1] = 5;
|
||||
put_network_short(&option[2], CHAP_PROTOCOL);
|
||||
option[4] = MD5;
|
||||
*new_options = option;
|
||||
*new_len = 5;
|
||||
return RCR_NAK;
|
||||
}
|
||||
case ACCM:
|
||||
case PFC:
|
||||
|
||||
@@ -51,14 +51,11 @@ struct GDBusClient {
|
||||
GDBusWatchFunction connect_func;
|
||||
void *connect_data;
|
||||
GDBusWatchFunction disconn_func;
|
||||
gboolean connected;
|
||||
void *disconn_data;
|
||||
GDBusMessageFunction signal_func;
|
||||
void *signal_data;
|
||||
GDBusProxyFunction proxy_added;
|
||||
GDBusProxyFunction proxy_removed;
|
||||
GDBusClientFunction ready;
|
||||
void *ready_data;
|
||||
GDBusPropertyFunction property_changed;
|
||||
void *user_data;
|
||||
GList *proxy_list;
|
||||
@@ -728,93 +725,6 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
|
||||
const char *name, int type, const void *value,
|
||||
size_t size, GDBusResultFunction function,
|
||||
void *user_data, GDBusDestroyFunction destroy)
|
||||
{
|
||||
struct set_property_data *data;
|
||||
GDBusClient *client;
|
||||
DBusMessage *msg;
|
||||
DBusMessageIter iter, variant, array;
|
||||
DBusPendingCall *call;
|
||||
char array_sig[3];
|
||||
char type_sig[2];
|
||||
|
||||
if (!proxy || !name || !value)
|
||||
return FALSE;
|
||||
|
||||
if (!dbus_type_is_basic(type))
|
||||
return FALSE;
|
||||
|
||||
client = proxy->client;
|
||||
if (!client)
|
||||
return FALSE;
|
||||
|
||||
data = g_try_new0(struct set_property_data, 1);
|
||||
if (!data)
|
||||
return FALSE;
|
||||
|
||||
data->function = function;
|
||||
data->user_data = user_data;
|
||||
data->destroy = destroy;
|
||||
|
||||
msg = dbus_message_new_method_call(client->service_name,
|
||||
proxy->obj_path,
|
||||
DBUS_INTERFACE_PROPERTIES,
|
||||
"Set");
|
||||
if (!msg) {
|
||||
g_free(data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
array_sig[0] = DBUS_TYPE_ARRAY;
|
||||
array_sig[1] = (char) type;
|
||||
array_sig[2] = '\0';
|
||||
|
||||
type_sig[0] = (char) type;
|
||||
type_sig[1] = '\0';
|
||||
|
||||
dbus_message_iter_init_append(msg, &iter);
|
||||
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
|
||||
&proxy->interface);
|
||||
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
|
||||
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
|
||||
array_sig, &variant);
|
||||
|
||||
dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
|
||||
type_sig, &array);
|
||||
|
||||
if (dbus_type_is_fixed(type))
|
||||
dbus_message_iter_append_fixed_array(&array, type, &value,
|
||||
size);
|
||||
else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
|
||||
const char **str = (const char **) value;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
dbus_message_iter_append_basic(&array, type, &str[i]);
|
||||
}
|
||||
|
||||
dbus_message_iter_close_container(&variant, &array);
|
||||
dbus_message_iter_close_container(&iter, &variant);
|
||||
|
||||
if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
|
||||
&call, -1) == FALSE) {
|
||||
dbus_message_unref(msg);
|
||||
g_free(data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dbus_pending_call_set_notify(call, set_property_reply, data, g_free);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
dbus_message_unref(msg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct method_call_data {
|
||||
GDBusReturnFunction function;
|
||||
void *user_data;
|
||||
@@ -1072,9 +982,6 @@ static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
|
||||
|
||||
dbus_message_iter_next(&dict);
|
||||
}
|
||||
|
||||
if (client->ready)
|
||||
client->ready(client, client->ready_data);
|
||||
}
|
||||
|
||||
static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
|
||||
@@ -1147,8 +1054,6 @@ static void service_connect(DBusConnection *conn, void *user_data)
|
||||
|
||||
get_managed_objects(client);
|
||||
|
||||
client->connected = TRUE;
|
||||
|
||||
g_dbus_client_unref(client);
|
||||
}
|
||||
|
||||
@@ -1159,10 +1064,8 @@ static void service_disconnect(DBusConnection *conn, void *user_data)
|
||||
g_list_free_full(client->proxy_list, proxy_free);
|
||||
client->proxy_list = NULL;
|
||||
|
||||
if (client->disconn_func) {
|
||||
if (client->disconn_func)
|
||||
client->disconn_func(conn, client->disconn_data);
|
||||
client->connected = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static DBusHandlerResult message_filter(DBusConnection *connection,
|
||||
@@ -1215,7 +1118,6 @@ GDBusClient *g_dbus_client_new(DBusConnection *connection,
|
||||
client->dbus_conn = dbus_connection_ref(connection);
|
||||
client->service_name = g_strdup(service);
|
||||
client->base_path = g_strdup(path);
|
||||
client->connected = FALSE;
|
||||
|
||||
client->match_rules = g_ptr_array_sized_new(1);
|
||||
g_ptr_array_set_free_func(client->match_rules, g_free);
|
||||
@@ -1290,11 +1192,7 @@ void g_dbus_client_unref(GDBusClient *client)
|
||||
|
||||
g_list_free_full(client->proxy_list, proxy_free);
|
||||
|
||||
/*
|
||||
* Don't call disconn_func twice if disconnection
|
||||
* was previously reported.
|
||||
*/
|
||||
if (client->disconn_func && client->connected)
|
||||
if (client->disconn_func)
|
||||
client->disconn_func(client->dbus_conn, client->disconn_data);
|
||||
|
||||
g_dbus_remove_watch(client->dbus_conn, client->watch);
|
||||
@@ -1345,18 +1243,6 @@ gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
|
||||
GDBusClientFunction ready, void *user_data)
|
||||
{
|
||||
if (client == NULL)
|
||||
return FALSE;
|
||||
|
||||
client->ready = ready;
|
||||
client->ready_data = user_data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
|
||||
GDBusProxyFunction proxy_added,
|
||||
GDBusProxyFunction proxy_removed,
|
||||
|
||||
@@ -329,11 +329,6 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
|
||||
GDBusResultFunction function, void *user_data,
|
||||
GDBusDestroyFunction destroy);
|
||||
|
||||
gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
|
||||
const char *name, int type, const void *value,
|
||||
size_t size, GDBusResultFunction function,
|
||||
void *user_data, GDBusDestroyFunction destroy);
|
||||
|
||||
typedef void (* GDBusSetupFunction) (DBusMessageIter *iter, void *user_data);
|
||||
typedef void (* GDBusReturnFunction) (DBusMessage *message, void *user_data);
|
||||
|
||||
@@ -342,7 +337,6 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
|
||||
GDBusReturnFunction function, void *user_data,
|
||||
GDBusDestroyFunction destroy);
|
||||
|
||||
typedef void (* GDBusClientFunction) (GDBusClient *client, void *user_data);
|
||||
typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
|
||||
typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
|
||||
DBusMessageIter *iter, void *user_data);
|
||||
@@ -365,8 +359,7 @@ gboolean g_dbus_client_set_disconnect_watch(GDBusClient *client,
|
||||
GDBusWatchFunction function, void *user_data);
|
||||
gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
|
||||
GDBusMessageFunction function, void *user_data);
|
||||
gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
|
||||
GDBusClientFunction ready, void *user_data);
|
||||
|
||||
gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
|
||||
GDBusProxyFunction proxy_added,
|
||||
GDBusProxyFunction proxy_removed,
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#include "gdbus.h"
|
||||
|
||||
#define DISPATCH_TIMEOUT 0
|
||||
|
||||
#define info(fmt...)
|
||||
#define error(fmt...)
|
||||
#define debug(fmt...)
|
||||
@@ -68,6 +70,8 @@ static gboolean message_dispatch(void *data)
|
||||
{
|
||||
DBusConnection *conn = data;
|
||||
|
||||
dbus_connection_ref(conn);
|
||||
|
||||
/* Dispatch messages */
|
||||
while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
|
||||
|
||||
@@ -80,7 +84,7 @@ static inline void queue_dispatch(DBusConnection *conn,
|
||||
DBusDispatchStatus status)
|
||||
{
|
||||
if (status == DBUS_DISPATCH_DATA_REMAINS)
|
||||
g_idle_add(message_dispatch, dbus_connection_ref(conn));
|
||||
g_timeout_add(DISPATCH_TIMEOUT, message_dispatch, conn);
|
||||
}
|
||||
|
||||
static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
|
||||
@@ -90,14 +94,13 @@ static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
|
||||
DBusDispatchStatus status;
|
||||
DBusConnection *conn;
|
||||
|
||||
conn = dbus_connection_ref(info->conn);
|
||||
|
||||
if (cond & G_IO_IN) flags |= DBUS_WATCH_READABLE;
|
||||
if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
|
||||
if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
|
||||
if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;
|
||||
|
||||
/* Protect connection from being destroyed by dbus_watch_handle */
|
||||
conn = dbus_connection_ref(info->conn);
|
||||
|
||||
dbus_watch_handle(info->watch, flags);
|
||||
|
||||
status = dbus_connection_get_dispatch_status(conn);
|
||||
|
||||
@@ -1088,6 +1088,7 @@ static const GDBusMethodTable introspect_methods[] = {
|
||||
static void append_interfaces(struct generic_data *data, DBusMessageIter *iter)
|
||||
{
|
||||
DBusMessageIter array;
|
||||
GSList *l;
|
||||
|
||||
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
|
||||
@@ -1099,7 +1100,12 @@ static void append_interfaces(struct generic_data *data, DBusMessageIter *iter)
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
|
||||
|
||||
g_slist_foreach(data->interfaces, append_interface, &array);
|
||||
for (l = data->interfaces; l != NULL; l = l->next) {
|
||||
if (g_slist_find(data->added, l->data))
|
||||
continue;
|
||||
|
||||
append_interface(l->data, &array);
|
||||
}
|
||||
|
||||
dbus_message_iter_close_container(iter, &array);
|
||||
}
|
||||
@@ -1247,8 +1253,6 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
|
||||
|
||||
if (!dbus_connection_register_object_path(connection, path,
|
||||
&generic_table, data)) {
|
||||
dbus_connection_unref(data->conn);
|
||||
g_free(data->path);
|
||||
g_free(data->introspect);
|
||||
g_free(data);
|
||||
return NULL;
|
||||
|
||||
@@ -362,7 +362,6 @@ static void service_data_free(struct service_data *data)
|
||||
callback->data = NULL;
|
||||
}
|
||||
|
||||
/* Returns TRUE if data is freed */
|
||||
static gboolean filter_data_remove_callback(struct filter_data *data,
|
||||
struct filter_callback *cb)
|
||||
{
|
||||
@@ -384,7 +383,7 @@ static gboolean filter_data_remove_callback(struct filter_data *data,
|
||||
/* Don't remove the filter if other callbacks exist or data is lock
|
||||
* processing callbacks */
|
||||
if (data->callbacks || data->lock)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
|
||||
if (data->registered && !remove_match(data))
|
||||
return FALSE;
|
||||
@@ -406,9 +405,7 @@ static DBusHandlerResult signal_filter(DBusConnection *connection,
|
||||
|
||||
if (cb->signal_func && !cb->signal_func(connection, message,
|
||||
cb->user_data)) {
|
||||
if (filter_data_remove_callback(data, cb))
|
||||
break;
|
||||
|
||||
filter_data_remove_callback(data, cb);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -492,9 +489,7 @@ static DBusHandlerResult service_filter(DBusConnection *connection,
|
||||
/* Only auto remove if it is a bus name watch */
|
||||
if (data->argument[0] == ':' &&
|
||||
(cb->conn_func == NULL || cb->disc_func == NULL)) {
|
||||
if (filter_data_remove_callback(data, cb))
|
||||
break;
|
||||
|
||||
filter_data_remove_callback(data, cb);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -591,6 +586,7 @@ static gboolean update_service(void *user_data)
|
||||
struct filter_callback *cb = data->callback;
|
||||
DBusConnection *conn;
|
||||
|
||||
update_name_cache(data->name, data->owner);
|
||||
conn = dbus_connection_ref(data->conn);
|
||||
service_data_free(data);
|
||||
|
||||
@@ -699,8 +695,7 @@ guint g_dbus_add_service_watch(DBusConnection *connection, const char *name,
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
||||
data = filter_data_get(connection, service_filter,
|
||||
DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
|
||||
data = filter_data_get(connection, service_filter, NULL, NULL,
|
||||
DBUS_INTERFACE_DBUS, "NameOwnerChanged",
|
||||
name);
|
||||
if (data == NULL)
|
||||
|
||||
@@ -85,7 +85,6 @@ struct ril_s {
|
||||
guint next_cmd_id; /* Next command id */
|
||||
guint next_notify_id; /* Next notify id */
|
||||
guint next_gid; /* Next group id */
|
||||
int sk; /* Socket */
|
||||
GRilIO *io; /* GRil IO */
|
||||
GQueue *command_queue; /* Command queue */
|
||||
GQueue *out_queue; /* Commands sent/been sent */
|
||||
@@ -356,8 +355,7 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
||||
int i;
|
||||
guint len, id;
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
g_assert(count > 0);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
req = g_queue_peek_nth(p->command_queue, i);
|
||||
@@ -375,13 +373,13 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
||||
message->error));
|
||||
|
||||
req = g_queue_pop_nth(p->command_queue, i);
|
||||
if (req->callback)
|
||||
if (req->callback) {
|
||||
req->callback(message, req->user_data);
|
||||
}
|
||||
|
||||
len = g_queue_get_length(p->out_queue);
|
||||
for (i = 0; i < len; i++) {
|
||||
id = *(guint *) g_queue_peek_nth(
|
||||
p->out_queue, i);
|
||||
id = *(guint *) g_queue_peek_nth(p->out_queue, i);
|
||||
if (id == req->id) {
|
||||
g_queue_pop_nth(p->out_queue, i);
|
||||
break;
|
||||
@@ -405,21 +403,14 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
||||
|
||||
}
|
||||
|
||||
static void notify_call_callback(gpointer data, gpointer user_data)
|
||||
{
|
||||
struct ril_notify_node *node = data;
|
||||
struct ril_msg *message = user_data;
|
||||
|
||||
node->callback(message, node->user_data);
|
||||
}
|
||||
|
||||
static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
struct ril_notify *notify;
|
||||
int req_key;
|
||||
gpointer key, value;
|
||||
GSList *list_item;
|
||||
GList *list_item;
|
||||
struct ril_notify_node *node;
|
||||
gboolean found = FALSE;
|
||||
|
||||
if (p->notify_list == NULL)
|
||||
@@ -439,12 +430,15 @@ static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
|
||||
if (req_key != message->req)
|
||||
continue;
|
||||
|
||||
list_item = notify->nodes;
|
||||
list_item = (GList *) notify->nodes;
|
||||
|
||||
if (list_item)
|
||||
while (list_item != NULL) {
|
||||
node = list_item->data;
|
||||
|
||||
node->callback(message, node->user_data);
|
||||
found = TRUE;
|
||||
|
||||
g_slist_foreach(notify->nodes, notify_call_callback, message);
|
||||
list_item = (GList *) g_slist_next(list_item);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only log events not being listended for... */
|
||||
@@ -588,8 +582,9 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
|
||||
while (p->suspended == FALSE && (p->read_so_far < len)) {
|
||||
gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
|
||||
|
||||
if (rbytes < 4)
|
||||
if (rbytes < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* this function attempts to read the next full length
|
||||
* fixed message from the stream. if not all bytes are
|
||||
@@ -600,8 +595,9 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
|
||||
message = read_fixed_record(p, buf, &rbytes);
|
||||
|
||||
/* wait for the rest of the record... */
|
||||
if (message == NULL)
|
||||
if (message == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
buf += rbytes;
|
||||
p->read_so_far += rbytes;
|
||||
@@ -646,8 +642,7 @@ static gboolean can_write_data(gpointer data)
|
||||
for (i = 0; i < qlen; i++) {
|
||||
req = g_queue_peek_nth(ril->command_queue, i);
|
||||
if (req) {
|
||||
id = *(guint *) g_queue_peek_head(
|
||||
ril->out_queue);
|
||||
id = *(guint *) g_queue_peek_head(ril->out_queue);
|
||||
if (req->id == id)
|
||||
goto out;
|
||||
} else {
|
||||
@@ -787,7 +782,6 @@ static void ril_unref(struct ril_s *ril)
|
||||
g_ril_io_unref(ril->io);
|
||||
ril->io = NULL;
|
||||
ril_cleanup(ril);
|
||||
close(ril->sk);
|
||||
}
|
||||
|
||||
if (ril->in_read_handler)
|
||||
@@ -812,6 +806,7 @@ static struct ril_s *create_ril()
|
||||
{
|
||||
struct ril_s *ril;
|
||||
struct sockaddr_un addr;
|
||||
int sk;
|
||||
GIOChannel *io;
|
||||
GKeyFile *keyfile;
|
||||
char **subscriptions = NULL;
|
||||
@@ -832,10 +827,10 @@ static struct ril_s *create_ril()
|
||||
ril->trace = FALSE;
|
||||
ril->connected = FALSE;
|
||||
|
||||
ril->sk = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (ril->sk < 0) {
|
||||
ofono_error("%s: can't create unix socket: %s (%d)\n",
|
||||
__func__, strerror(errno), errno);
|
||||
sk = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sk < 0) {
|
||||
ofono_error("create_ril: can't create unix socket: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -843,16 +838,16 @@ static struct ril_s *create_ril()
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, RILD_CMD_SOCKET, sizeof(addr.sun_path) - 1);
|
||||
|
||||
if (connect(ril->sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
ofono_error("%s: can't connect to RILD: %s (%d)\n",
|
||||
__func__, strerror(errno), errno);
|
||||
if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
io = g_io_channel_unix_new(ril->sk);
|
||||
io = g_io_channel_unix_new(sk);
|
||||
if (io == NULL) {
|
||||
ofono_error("%s: can't connect to RILD: %s (%d)\n",
|
||||
__func__, strerror(errno), errno);
|
||||
ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -861,7 +856,7 @@ static struct ril_s *create_ril()
|
||||
|
||||
ril->io = g_ril_io_new(io);
|
||||
if (ril->io == NULL) {
|
||||
ofono_error("%s: can't create ril->io", __func__);
|
||||
ofono_error("create_ril: can't create ril->io");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -869,13 +864,13 @@ static struct ril_s *create_ril()
|
||||
|
||||
ril->command_queue = g_queue_new();
|
||||
if (ril->command_queue == NULL) {
|
||||
ofono_error("%s: Couldn't create command_queue.", __func__);
|
||||
ofono_error("create_ril: Couldn't create command_queue.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
ril->out_queue = g_queue_new();
|
||||
if (ril->out_queue == NULL) {
|
||||
ofono_error("%s: Couldn't create out_queue.", __func__);
|
||||
ofono_error("create_ril: Couldn't create out_queue.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -905,6 +900,9 @@ static struct ril_s *create_ril()
|
||||
g_strfreev(subscriptions);
|
||||
}
|
||||
|
||||
current_passwd = g_try_malloc(16);
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, defaultpasswd);
|
||||
current_online_state = RIL_OFFLINE;
|
||||
|
||||
return ril;
|
||||
|
||||
@@ -138,6 +138,7 @@ guint g_ril_register(GRil *ril, const int req,
|
||||
gboolean g_ril_unregister(GRil *ril, guint id);
|
||||
gboolean g_ril_unregister_all(GRil *ril);
|
||||
|
||||
gchar *current_passwd;
|
||||
guint current_online_state;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -73,7 +73,6 @@ static void read_watcher_destroy_notify(gpointer user_data)
|
||||
io->read_handler = NULL;
|
||||
io->read_data = NULL;
|
||||
|
||||
g_io_channel_unref(io->channel);
|
||||
io->channel = NULL;
|
||||
|
||||
if (io->destroyed)
|
||||
|
||||
@@ -159,8 +159,19 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
|
||||
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
* RILD can return multiple addresses; oFono only supports
|
||||
* setting a single IPv4 address. At this time, we only
|
||||
* use the first address. It's possible that a RIL may
|
||||
* just specify the end-points of the point-to-point
|
||||
* connection, in which case this code will need to
|
||||
* changed to handle such a device.
|
||||
*
|
||||
* For now split into a maximum of three, and only use
|
||||
* the first address for the remaining operations.
|
||||
*/
|
||||
if (raw_ip_addrs)
|
||||
reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", -1);
|
||||
reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", 3);
|
||||
else
|
||||
reply->ip_addrs = NULL;
|
||||
|
||||
@@ -180,7 +191,7 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
|
||||
* setting a single IPv4 gateway.
|
||||
*/
|
||||
if (raw_gws)
|
||||
reply->gateways = g_strsplit(raw_gws, " ", -1);
|
||||
reply->gateways = g_strsplit(raw_gws, " ", 3);
|
||||
else
|
||||
reply->gateways = NULL;
|
||||
|
||||
@@ -192,7 +203,7 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
|
||||
|
||||
/* Split DNS addresses */
|
||||
if (dnses)
|
||||
reply->dns_addresses = g_strsplit(dnses, " ", -1);
|
||||
reply->dns_addresses = g_strsplit(dnses, " ", 3);
|
||||
else
|
||||
reply->dns_addresses = NULL;
|
||||
|
||||
|
||||
@@ -77,58 +77,6 @@ void g_ril_unsol_free_data_call_list(struct unsol_data_call_list *unsol)
|
||||
}
|
||||
}
|
||||
|
||||
gboolean g_ril_unsol_cmp_dcl(struct unsol_data_call_list *current,
|
||||
struct unsol_data_call_list *old,
|
||||
gint cid)
|
||||
{
|
||||
GSList *nl,*ol;
|
||||
struct data_call *new_call, *old_call;
|
||||
|
||||
new_call = old_call = NULL;
|
||||
gboolean no_cid = TRUE;
|
||||
|
||||
|
||||
if (!current || !old)
|
||||
return FALSE;
|
||||
|
||||
if (current->num != old->num)
|
||||
return FALSE;
|
||||
|
||||
for (nl = current->call_list; nl; nl = nl->next) {
|
||||
new_call = (struct data_call *) nl->data;
|
||||
|
||||
if (new_call->cid != cid)
|
||||
continue;
|
||||
|
||||
for (ol = old->call_list; ol; ol = ol->next) {
|
||||
old_call = (struct data_call *) ol->data;
|
||||
if(new_call->cid == old_call->cid) {
|
||||
no_cid = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (no_cid)
|
||||
return FALSE;
|
||||
|
||||
if (new_call->active != old_call->active)
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->type,old_call->type))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->ifname,old_call->ifname))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->addresses,old_call->addresses))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->dnses,old_call->dnses))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->gateways,old_call->gateways))
|
||||
return FALSE;
|
||||
}
|
||||
if (no_cid)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
|
||||
struct ril_msg *message,
|
||||
struct ofono_error *error)
|
||||
|
||||
@@ -51,9 +51,6 @@ struct data_call {
|
||||
|
||||
void g_ril_unsol_free_data_call_list(struct unsol_data_call_list *unsol);
|
||||
|
||||
gboolean g_ril_unsol_cmp_dcl(struct unsol_data_call_list *current,
|
||||
struct unsol_data_call_list *old, gint cid);
|
||||
|
||||
struct unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
|
||||
struct ril_msg *message,
|
||||
struct ofono_error *error);
|
||||
|
||||
@@ -191,7 +191,6 @@
|
||||
#define RIL_PERSOSUBSTATE_RUIM_RUIM_PUK 24
|
||||
|
||||
/* SIM - App states */
|
||||
#define RIL_APPSTATE_ILLEGAL -1
|
||||
#define RIL_APPSTATE_UNKNOWN 0
|
||||
#define RIL_APPSTATE_DETECTED 1
|
||||
#define RIL_APPSTATE_PIN 2
|
||||
|
||||
@@ -80,29 +80,29 @@ extern "C" {
|
||||
DBusConnection *ofono_dbus_get_connection(void);
|
||||
|
||||
void ofono_dbus_dict_append(DBusMessageIter *dict, const char *key, int type,
|
||||
const void *value);
|
||||
void *value);
|
||||
|
||||
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||
int type, const void *val);
|
||||
int type, void *val);
|
||||
|
||||
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
||||
int type, const void *val);
|
||||
int type, void *val);
|
||||
|
||||
int ofono_dbus_signal_property_changed(DBusConnection *conn, const char *path,
|
||||
const char *interface, const char *name,
|
||||
int type, const void *value);
|
||||
int type, void *value);
|
||||
|
||||
int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name, int type,
|
||||
const void *value);
|
||||
void *value);
|
||||
|
||||
int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name, int type,
|
||||
const void *value);
|
||||
void *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -104,9 +104,6 @@ enum ofono_emulator_request_type ofono_emulator_request_get_type(
|
||||
|
||||
void ofono_emulator_set_indicator(struct ofono_emulator *em,
|
||||
const char *name, int value);
|
||||
void ofono_emulator_set_hf_indicator_active(struct ofono_emulator *em,
|
||||
int indicator,
|
||||
ofono_bool_t active);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -48,11 +48,6 @@ enum ofono_gprs_context_type {
|
||||
OFONO_GPRS_CONTEXT_TYPE_IMS,
|
||||
};
|
||||
|
||||
enum ofono_gprs_auth_method {
|
||||
OFONO_GPRS_AUTH_METHOD_CHAP = 0,
|
||||
OFONO_GPRS_AUTH_METHOD_PAP,
|
||||
};
|
||||
|
||||
struct ofono_gprs_primary_context {
|
||||
unsigned int cid;
|
||||
int direction;
|
||||
@@ -60,7 +55,6 @@ struct ofono_gprs_primary_context {
|
||||
char username[OFONO_GPRS_MAX_USERNAME_LENGTH + 1];
|
||||
char password[OFONO_GPRS_MAX_PASSWORD_LENGTH + 1];
|
||||
enum ofono_gprs_proto proto;
|
||||
enum ofono_gprs_auth_method auth_method;
|
||||
};
|
||||
|
||||
typedef void (*ofono_gprs_context_cb_t)(const struct ofono_error *error,
|
||||
@@ -123,10 +117,6 @@ void ofono_gprs_context_set_ipv6_gateway(struct ofono_gprs_context *gc,
|
||||
const char *gateway);
|
||||
void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
|
||||
const char **dns);
|
||||
|
||||
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
||||
unsigned int cid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -31,13 +31,10 @@ extern "C" {
|
||||
struct ofono_gprs_provision_data {
|
||||
enum ofono_gprs_context_type type;
|
||||
enum ofono_gprs_proto proto;
|
||||
char *provider_name;
|
||||
ofono_bool_t provider_primary;
|
||||
char *name;
|
||||
char *apn;
|
||||
char *username;
|
||||
char *password;
|
||||
enum ofono_gprs_auth_method auth_method;
|
||||
char *message_proxy;
|
||||
char *message_center;
|
||||
};
|
||||
|
||||
@@ -78,8 +78,6 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
|
||||
void ofono_gprs_add_context(struct ofono_gprs *gprs,
|
||||
struct ofono_gprs_context *gc);
|
||||
|
||||
struct ofono_modem *ofono_gprs_get_modem(struct ofono_gprs *gprs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -36,18 +36,12 @@ typedef void (*ofono_handsfree_cb_t)(const struct ofono_error *error,
|
||||
typedef void (*ofono_handsfree_phone_cb_t)(const struct ofono_error *error,
|
||||
const struct ofono_phone_number *number,
|
||||
void *data);
|
||||
typedef void (*ofono_handsfree_cnum_query_cb_t)(const struct ofono_error *error,
|
||||
int total,
|
||||
const struct ofono_phone_number *numbers,
|
||||
void *data);
|
||||
|
||||
struct ofono_handsfree_driver {
|
||||
const char *name;
|
||||
int (*probe)(struct ofono_handsfree *hf, unsigned int vendor,
|
||||
void *data);
|
||||
void (*remove)(struct ofono_handsfree *hf);
|
||||
void (*cnum_query)(struct ofono_handsfree *hf,
|
||||
ofono_handsfree_cnum_query_cb_t cb, void *data);
|
||||
void (*request_phone_number) (struct ofono_handsfree *hf,
|
||||
ofono_handsfree_phone_cb_t cb,
|
||||
void *data);
|
||||
@@ -56,27 +50,15 @@ struct ofono_handsfree_driver {
|
||||
ofono_handsfree_cb_t cb, void *data);
|
||||
void (*disable_nrec)(struct ofono_handsfree *hf,
|
||||
ofono_handsfree_cb_t cb, void *data);
|
||||
void (*hf_indicator)(struct ofono_handsfree *hf,
|
||||
unsigned short indicator, unsigned int value,
|
||||
ofono_handsfree_cb_t cb, void *data);
|
||||
};
|
||||
|
||||
void ofono_handsfree_set_ag_features(struct ofono_handsfree *hf,
|
||||
unsigned int ag_features);
|
||||
void ofono_handsfree_set_ag_chld_features(struct ofono_handsfree *hf,
|
||||
unsigned int ag_chld_features);
|
||||
void ofono_handsfree_set_inband_ringing(struct ofono_handsfree *hf,
|
||||
ofono_bool_t enabled);
|
||||
void ofono_handsfree_voice_recognition_notify(struct ofono_handsfree *hf,
|
||||
ofono_bool_t enabled);
|
||||
|
||||
void ofono_handsfree_set_hf_indicators(struct ofono_handsfree *hf,
|
||||
const unsigned short *indicators,
|
||||
unsigned int num);
|
||||
void ofono_handsfree_hf_indicator_active_notify(struct ofono_handsfree *hf,
|
||||
unsigned int indicator,
|
||||
ofono_bool_t active);
|
||||
|
||||
void ofono_handsfree_battchg_notify(struct ofono_handsfree *hf,
|
||||
unsigned char level);
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@ extern "C" {
|
||||
#include <ofono/types.h>
|
||||
|
||||
enum ofono_radio_access_mode {
|
||||
OFONO_RADIO_ACCESS_MODE_ANY = 0x0,
|
||||
OFONO_RADIO_ACCESS_MODE_GSM = 0x1,
|
||||
OFONO_RADIO_ACCESS_MODE_UMTS = 0x2,
|
||||
OFONO_RADIO_ACCESS_MODE_LTE = 0x4,
|
||||
OFONO_RADIO_ACCESS_MODE_ANY = 0,
|
||||
OFONO_RADIO_ACCESS_MODE_GSM = 1,
|
||||
OFONO_RADIO_ACCESS_MODE_UMTS = 2,
|
||||
OFONO_RADIO_ACCESS_MODE_LTE = 3,
|
||||
};
|
||||
|
||||
enum ofono_radio_band_gsm {
|
||||
@@ -80,11 +80,6 @@ typedef void (*ofono_radio_settings_fast_dormancy_query_cb_t)(
|
||||
ofono_bool_t enable,
|
||||
void *data);
|
||||
|
||||
typedef void (*ofono_radio_settings_available_rats_query_cb_t)(
|
||||
const struct ofono_error *error,
|
||||
unsigned int available_rats,
|
||||
void *data);
|
||||
|
||||
struct ofono_radio_settings_driver {
|
||||
const char *name;
|
||||
int (*probe)(struct ofono_radio_settings *rs, unsigned int vendor,
|
||||
@@ -112,9 +107,6 @@ struct ofono_radio_settings_driver {
|
||||
ofono_bool_t enable,
|
||||
ofono_radio_settings_fast_dormancy_set_cb_t,
|
||||
void *data);
|
||||
void (*query_available_rats)(struct ofono_radio_settings *rs,
|
||||
ofono_radio_settings_available_rats_query_cb_t cb,
|
||||
void *data);
|
||||
};
|
||||
|
||||
int ofono_radio_settings_driver_register(
|
||||
|
||||
@@ -48,7 +48,6 @@ struct ofono_stk_driver {
|
||||
int length, const unsigned char *resp,
|
||||
ofono_stk_generic_cb_t cb, void *data);
|
||||
void (*user_confirmation)(struct ofono_stk *stk, ofono_bool_t confirm);
|
||||
void (*ready)(struct ofono_stk *stk);
|
||||
};
|
||||
|
||||
int ofono_stk_driver_register(const struct ofono_stk_driver *d);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2014 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
|
||||
@@ -172,9 +171,6 @@ void ofono_voicecall_ssn_mt_notify(struct ofono_voicecall *vc, unsigned int id,
|
||||
int code, int index,
|
||||
const struct ofono_phone_number *ph);
|
||||
|
||||
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
|
||||
const ofono_bool_t playTone);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2014 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <glib.h>
|
||||
#include <ofono.h>
|
||||
#include <gdbus.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/emulator.h>
|
||||
|
||||
#include "hfp.h"
|
||||
|
||||
#define EMULATOR_FUZZ_INTERFACE "org.ofono.test.EmulatorFuzz"
|
||||
#define EMULATOR_FUZZ_PATH "/test"
|
||||
|
||||
static void emulator_set_indicator(struct ofono_atom *atom, void *data)
|
||||
{
|
||||
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
||||
ofono_bool_t active = GPOINTER_TO_INT(data);
|
||||
|
||||
ofono_emulator_set_hf_indicator_active(em,
|
||||
HFP_HF_INDICATOR_ENHANCED_SAFETY, active);
|
||||
}
|
||||
|
||||
static void modem_set_indicators(struct ofono_modem *modem, void *user)
|
||||
{
|
||||
__ofono_modem_foreach_registered_atom(modem,
|
||||
OFONO_ATOM_TYPE_EMULATOR_HFP,
|
||||
emulator_set_indicator,
|
||||
user);
|
||||
}
|
||||
|
||||
static DBusMessage *set_indicator_active(DBusConnection *conn,
|
||||
DBusMessage *msg, void *user_data)
|
||||
{
|
||||
const char *indicator;
|
||||
dbus_bool_t active;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &indicator,
|
||||
DBUS_TYPE_BOOLEAN, &active,
|
||||
DBUS_TYPE_INVALID) == FALSE)
|
||||
goto invalid;
|
||||
|
||||
DBG("%s,%d", indicator, active);
|
||||
|
||||
if (strcmp(indicator, "DistractedDrivingReduction"))
|
||||
goto invalid;
|
||||
|
||||
__ofono_modem_foreach(modem_set_indicators, GINT_TO_POINTER(active));
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
|
||||
invalid:
|
||||
return g_dbus_create_error(msg, "org.ofono.test.Error",
|
||||
"Invalid arguments in method call");
|
||||
}
|
||||
|
||||
static const GDBusMethodTable emulator_fuzz_methods[] = {
|
||||
{ GDBUS_ASYNC_METHOD("SetIndicatorActive",
|
||||
GDBUS_ARGS({ "indicator", "s" }, { "active", "b" }),
|
||||
NULL, set_indicator_active) },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int emulator_fuzz_init(void)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
DBG("");
|
||||
|
||||
if (!g_dbus_register_interface(conn, EMULATOR_FUZZ_PATH,
|
||||
EMULATOR_FUZZ_INTERFACE,
|
||||
emulator_fuzz_methods, NULL,
|
||||
NULL, NULL, NULL)) {
|
||||
ofono_error("Register Profile interface failed: %s",
|
||||
EMULATOR_FUZZ_PATH);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void emulator_fuzz_exit(void)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
DBG("");
|
||||
|
||||
g_dbus_unregister_interface(conn, EMULATOR_FUZZ_PATH,
|
||||
EMULATOR_FUZZ_INTERFACE);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(emulator_fuzz, "Emulator Fuzz",
|
||||
VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
|
||||
emulator_fuzz_init, emulator_fuzz_exit)
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2014 Intel Corporation. All rights reserved.
|
||||
* 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
|
||||
@@ -46,7 +46,6 @@
|
||||
#include <ofono/call-settings.h>
|
||||
#include <ofono/devinfo.h>
|
||||
#include <ofono/message-waiting.h>
|
||||
#include <ofono/location-reporting.h>
|
||||
#include <ofono/netreg.h>
|
||||
#include <ofono/phonebook.h>
|
||||
#include <ofono/sim.h>
|
||||
@@ -60,7 +59,6 @@
|
||||
#include <drivers/atmodem/vendor.h>
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static const char *qss_prefix[] = { "#QSS:", NULL };
|
||||
|
||||
struct he910_data {
|
||||
GAtChat *chat; /* AT chat */
|
||||
@@ -103,7 +101,7 @@ static GAtChat *open_device(struct ofono_modem *modem,
|
||||
if (channel == NULL)
|
||||
return NULL;
|
||||
|
||||
syntax = g_at_syntax_new_gsm_permissive();
|
||||
syntax = g_at_syntax_new_gsmv1();
|
||||
chat = g_at_chat_new(channel, syntax);
|
||||
g_at_syntax_unref(syntax);
|
||||
g_io_channel_unref(channel);
|
||||
@@ -169,31 +167,6 @@ static void he910_qss_notify(GAtResult *result, gpointer user_data)
|
||||
switch_sim_state_status(modem, status);
|
||||
}
|
||||
|
||||
static void qss_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
int status, mode;
|
||||
GAtResultIter iter;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "#QSS:"))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &mode))
|
||||
return;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &status))
|
||||
return;
|
||||
|
||||
switch_sim_state_status(modem, status);
|
||||
}
|
||||
|
||||
static void cfun_enable_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
@@ -231,15 +204,6 @@ static void cfun_enable_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
g_at_chat_send(data->chat, "AT#AUTOATT=0", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* Follow sim state */
|
||||
g_at_chat_register(data->chat, "#QSS:", he910_qss_notify,
|
||||
FALSE, modem, NULL);
|
||||
|
||||
/* Enable sim state notification */
|
||||
g_at_chat_send(data->chat, "AT#QSS=2", none_prefix, NULL, NULL, NULL);
|
||||
|
||||
g_at_chat_send(data->chat, "AT#QSS?", qss_prefix,
|
||||
qss_query_cb, modem, NULL);
|
||||
}
|
||||
|
||||
static int he910_enable(struct ofono_modem *modem)
|
||||
@@ -268,6 +232,13 @@ static int he910_enable(struct ofono_modem *modem)
|
||||
g_at_chat_send(data->chat, "ATE0 +CMEE=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* Follow sim state */
|
||||
g_at_chat_register(data->chat, "#QSS:", he910_qss_notify,
|
||||
FALSE, modem, NULL);
|
||||
|
||||
/* Enable sim state notification */
|
||||
g_at_chat_send(data->chat, "AT#QSS=2", none_prefix, NULL, NULL, NULL);
|
||||
|
||||
/* Set phone functionality */
|
||||
g_at_chat_send(data->chat, "AT+CFUN=1", none_prefix,
|
||||
cfun_enable_cb, modem, NULL);
|
||||
@@ -319,7 +290,6 @@ static void he910_pre_sim(struct ofono_modem *modem)
|
||||
ofono_devinfo_create(modem, 0, "atmodem", data->chat);
|
||||
data->sim = ofono_sim_create(modem, OFONO_VENDOR_TELIT, "atmodem",
|
||||
data->chat);
|
||||
ofono_location_reporting_create(modem, 0, "telitmodem", data->chat);
|
||||
}
|
||||
|
||||
static void he910_post_online(struct ofono_modem *modem)
|
||||
|
||||
@@ -232,7 +232,7 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *data)
|
||||
if (modems->next != NULL)
|
||||
return;
|
||||
|
||||
bt_register_profile(conn, HFP_AG_UUID, HFP_VERSION_1_7, "hfp_ag",
|
||||
bt_register_profile(conn, HFP_AG_UUID, HFP_VERSION_1_5, "hfp_ag",
|
||||
HFP_AG_EXT_PROFILE_PATH, NULL, 0);
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ static void voicecall_watch(struct ofono_atom *atom,
|
||||
if (modems->next != NULL)
|
||||
return;
|
||||
|
||||
bt_register_profile(conn, HFP_AG_UUID, HFP_VERSION_1_7, "hfp_ag",
|
||||
bt_register_profile(conn, HFP_AG_UUID, HFP_VERSION_1_5, "hfp_ag",
|
||||
HFP_AG_EXT_PROFILE_PATH, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#include <ofono/handsfree.h>
|
||||
#include <ofono/handsfree-audio.h>
|
||||
#include <ofono/siri.h>
|
||||
#include <ofono.h>
|
||||
|
||||
#include <drivers/atmodem/atutil.h>
|
||||
#include <drivers/hfpmodem/slc.h>
|
||||
@@ -72,7 +71,6 @@ struct hfp {
|
||||
struct ofono_handsfree_card *card;
|
||||
};
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static GDBusClient *bluez = NULL;
|
||||
|
||||
static void hfp_debug(const char *str, void *user_data)
|
||||
@@ -349,7 +347,7 @@ static void bcs_notify(GAtResult *result, gpointer user_data)
|
||||
sprintf(str, "AT+BCS=%d", value);
|
||||
|
||||
done:
|
||||
g_at_chat_send(info->chat, str, none_prefix, NULL, NULL, NULL);
|
||||
g_at_chat_send(info->chat, str, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static int hfp16_card_probe(struct ofono_handsfree_card *card,
|
||||
@@ -644,7 +642,7 @@ static void connect_handler(DBusConnection *conn, void *user_data)
|
||||
|
||||
DBG("Registering External Profile handler ...");
|
||||
|
||||
bt_register_profile(conn, HFP_HS_UUID, HFP_VERSION_1_7, "hfp_hf",
|
||||
bt_register_profile(conn, HFP_HS_UUID, HFP_VERSION_1_6, "hfp_hf",
|
||||
HFP_EXT_PROFILE_PATH, NULL, features);
|
||||
}
|
||||
|
||||
@@ -764,8 +762,6 @@ static int hfp_init(void)
|
||||
if (DBUS_TYPE_UNIX_FD < 0)
|
||||
return -EBADF;
|
||||
|
||||
__ofono_handsfree_audio_manager_init();
|
||||
|
||||
/* Registers External Profile handler */
|
||||
if (!g_dbus_register_interface(conn, HFP_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE,
|
||||
@@ -821,8 +817,6 @@ static void hfp_exit(void)
|
||||
g_dbus_client_unref(bluez);
|
||||
|
||||
ofono_handsfree_audio_unref();
|
||||
|
||||
__ofono_handsfree_audio_manager_cleanup();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(hfp_bluez5, "External Hands-Free Profile Plugin", VERSION,
|
||||
|
||||
@@ -53,8 +53,6 @@ enum MBPI_ERROR {
|
||||
struct gsm_data {
|
||||
const char *match_mcc;
|
||||
const char *match_mnc;
|
||||
char *provider_name;
|
||||
gboolean provider_primary;
|
||||
GSList *apns;
|
||||
gboolean match_found;
|
||||
gboolean allow_duplicates;
|
||||
@@ -86,7 +84,6 @@ static GQuark mbpi_error_quark(void)
|
||||
|
||||
void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
g_free(ap->provider_name);
|
||||
g_free(ap->name);
|
||||
g_free(ap->apn);
|
||||
g_free(ap->username);
|
||||
@@ -120,7 +117,6 @@ static void text_handler(GMarkupParseContext *context,
|
||||
{
|
||||
char **string = userdata;
|
||||
|
||||
g_free(*string);
|
||||
*string = g_strndup(text, text_len);
|
||||
}
|
||||
|
||||
@@ -132,37 +128,6 @@ static const GMarkupParser text_parser = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void authentication_start(GMarkupParseContext *context,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
enum ofono_gprs_auth_method *auth_method,
|
||||
GError **error)
|
||||
{
|
||||
const char *text = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; attribute_names[i]; i++)
|
||||
if (g_str_equal(attribute_names[i], "method") == TRUE)
|
||||
text = attribute_values[i];
|
||||
|
||||
if (text == NULL) {
|
||||
mbpi_g_set_error(context, error, G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"Missing attribute: method");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(text, "chap") == 0)
|
||||
*auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;
|
||||
else if (strcmp(text, "pap") == 0)
|
||||
*auth_method = OFONO_GPRS_AUTH_METHOD_PAP;
|
||||
else
|
||||
mbpi_g_set_error(context, error, G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
"Unknown authentication method: %s",
|
||||
text);
|
||||
}
|
||||
|
||||
static void usage_start(GMarkupParseContext *context,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
@@ -209,9 +174,6 @@ static void apn_start(GMarkupParseContext *context, const gchar *element_name,
|
||||
else if (g_str_equal(element_name, "password"))
|
||||
g_markup_parse_context_push(context, &text_parser,
|
||||
&apn->password);
|
||||
else if (g_str_equal(element_name, "authentication"))
|
||||
authentication_start(context, attribute_names,
|
||||
attribute_values, &apn->auth_method, error);
|
||||
else if (g_str_equal(element_name, "mmsc"))
|
||||
g_markup_parse_context_push(context, &text_parser,
|
||||
&apn->message_center);
|
||||
@@ -228,9 +190,7 @@ static void apn_end(GMarkupParseContext *context, const gchar *element_name,
|
||||
{
|
||||
if (g_str_equal(element_name, "name") ||
|
||||
g_str_equal(element_name, "username") ||
|
||||
g_str_equal(element_name, "password") ||
|
||||
g_str_equal(element_name, "mmsc") ||
|
||||
g_str_equal(element_name, "mmsproxy"))
|
||||
g_str_equal(element_name, "password"))
|
||||
g_markup_parse_context_pop(context);
|
||||
}
|
||||
|
||||
@@ -326,13 +286,9 @@ static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
|
||||
}
|
||||
|
||||
ap = g_new0(struct ofono_gprs_provision_data, 1);
|
||||
ap->provider_name = g_strdup(gsm->provider_name);
|
||||
ap->provider_primary = gsm->provider_primary;
|
||||
|
||||
ap->apn = g_strdup(apn);
|
||||
ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
|
||||
ap->proto = OFONO_GPRS_PROTO_IP;
|
||||
ap->auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;
|
||||
|
||||
g_markup_parse_context_push(context, &apn_parser, ap);
|
||||
}
|
||||
@@ -496,68 +452,27 @@ static const GMarkupParser provider_parser = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void gsm_provider_start(GMarkupParseContext *context,
|
||||
static void toplevel_gsm_start(GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **atribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer userdata, GError **error)
|
||||
{
|
||||
struct gsm_data *gsm = userdata;
|
||||
|
||||
if (g_str_equal(element_name, "name")) {
|
||||
g_free(gsm->provider_name);
|
||||
gsm->provider_name = NULL;
|
||||
g_markup_parse_context_push(context, &text_parser,
|
||||
&gsm->provider_name);
|
||||
} else if (g_str_equal(element_name, "gsm")) {
|
||||
if (g_str_equal(element_name, "gsm")) {
|
||||
gsm->match_found = FALSE;
|
||||
g_markup_parse_context_push(context, &gsm_parser, gsm);
|
||||
} else if (g_str_equal(element_name, "cdma"))
|
||||
g_markup_parse_context_push(context, &skip_parser, NULL);
|
||||
}
|
||||
|
||||
static void gsm_provider_end(GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer userdata, GError **error)
|
||||
{
|
||||
if (g_str_equal(element_name, "name") ||
|
||||
g_str_equal(element_name, "gsm") ||
|
||||
g_str_equal(element_name, "cdma"))
|
||||
g_markup_parse_context_pop(context);
|
||||
}
|
||||
|
||||
static const GMarkupParser gsm_provider_parser = {
|
||||
gsm_provider_start,
|
||||
gsm_provider_end,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void toplevel_gsm_start(GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer userdata, GError **error)
|
||||
{
|
||||
struct gsm_data *gsm = userdata;
|
||||
|
||||
if (g_str_equal(element_name, "provider")) {
|
||||
g_markup_collect_attributes(element_name, attribute_names,
|
||||
attribute_values, error,
|
||||
G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL,
|
||||
"primary", &gsm->provider_primary,
|
||||
G_MARKUP_COLLECT_INVALID);
|
||||
|
||||
g_markup_parse_context_push(context, &gsm_provider_parser, gsm);
|
||||
}
|
||||
}
|
||||
|
||||
static void toplevel_gsm_end(GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer userdata, GError **error)
|
||||
{
|
||||
if (g_str_equal(element_name, "provider"))
|
||||
if (g_str_equal(element_name, "gsm") ||
|
||||
g_str_equal(element_name, "cdma"))
|
||||
g_markup_parse_context_pop(context);
|
||||
}
|
||||
|
||||
@@ -571,7 +486,7 @@ static const GMarkupParser toplevel_gsm_parser = {
|
||||
|
||||
static void toplevel_cdma_start(GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **atribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer userdata, GError **error)
|
||||
{
|
||||
@@ -674,7 +589,6 @@ GSList *mbpi_lookup_apn(const char *mcc, const char *mnc,
|
||||
gsm.apns = NULL;
|
||||
}
|
||||
|
||||
g_free(gsm.provider_name);
|
||||
return gsm.apns;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,11 +188,11 @@ static int nettime_probe(struct ofono_nettime_context *context)
|
||||
NULL, // GDBusPropertyTable *properties
|
||||
NULL, // user data
|
||||
NULL)) { // GDBusDestroyFunction destroy
|
||||
ofono_error("Network time: Could not register interface %s, path %s",
|
||||
ofono_error("Networkt time: Could not register interface %s, path %s",
|
||||
OFONO_NETWORK_TIME_INTERFACE, path);
|
||||
return 1;
|
||||
} else {
|
||||
ofono_info("Network time: Registered interface %s, path %s",
|
||||
ofono_info("Network time: Registered inteface %s, path %s",
|
||||
OFONO_NETWORK_TIME_INTERFACE, path);
|
||||
}
|
||||
|
||||
@@ -235,12 +235,6 @@ static void nettime_info_received(struct ofono_nettime_context *context,
|
||||
|
||||
netreg = __ofono_atom_get_data(__ofono_modem_find_atom(
|
||||
context->modem, OFONO_ATOM_TYPE_NETREG));
|
||||
|
||||
if (!(ofono_netreg_get_mcc(netreg) && ofono_netreg_get_mnc(netreg))) {
|
||||
DBG("Incomplete network time received, ignoring");
|
||||
return;
|
||||
}
|
||||
|
||||
ntd->path = ofono_modem_get_path(context->modem);
|
||||
ntd->mcc = ofono_netreg_get_mcc(netreg);
|
||||
ntd->mnc = ofono_netreg_get_mnc(netreg);
|
||||
|
||||
@@ -351,65 +351,6 @@ static void phonesim_ctm_set(struct ofono_ctm *ctm, ofono_bool_t enable,
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static gboolean phonesim_radio_settings_register(gpointer user)
|
||||
{
|
||||
struct ofono_radio_settings *rs = user;
|
||||
|
||||
ofono_radio_settings_register(rs);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int phonesim_radio_settings_probe(struct ofono_radio_settings *rs,
|
||||
unsigned int vendor, void *data)
|
||||
{
|
||||
GAtChat *chat;
|
||||
|
||||
DBG("");
|
||||
|
||||
chat = g_at_chat_clone(data);
|
||||
|
||||
ofono_radio_settings_set_data(rs, chat);
|
||||
g_idle_add(phonesim_radio_settings_register, rs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void phonesim_radio_settings_remove(struct ofono_radio_settings *rs)
|
||||
{
|
||||
GAtChat *chat = ofono_radio_settings_get_data(rs);
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_radio_settings_set_data(rs, NULL);
|
||||
|
||||
g_at_chat_unref(chat);
|
||||
}
|
||||
|
||||
static void phonesim_query_rat_mode(struct ofono_radio_settings *rs,
|
||||
ofono_radio_settings_rat_mode_query_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, OFONO_RADIO_ACCESS_MODE_ANY, data);
|
||||
}
|
||||
|
||||
static void phonesim_query_available_rats(struct ofono_radio_settings *rs,
|
||||
ofono_radio_settings_available_rats_query_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
uint32_t techs = 0;
|
||||
|
||||
DBG("");
|
||||
|
||||
techs |= OFONO_RADIO_ACCESS_MODE_GSM;
|
||||
techs |= OFONO_RADIO_ACCESS_MODE_UMTS;
|
||||
techs |= OFONO_RADIO_ACCESS_MODE_LTE;
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, techs, data);
|
||||
}
|
||||
|
||||
static struct ofono_gprs_context_driver context_driver = {
|
||||
.name = "phonesim",
|
||||
.probe = phonesim_context_probe,
|
||||
@@ -418,14 +359,6 @@ static struct ofono_gprs_context_driver context_driver = {
|
||||
.deactivate_primary = phonesim_deactivate_primary,
|
||||
};
|
||||
|
||||
static struct ofono_radio_settings_driver radio_settings_driver = {
|
||||
.name = "phonesim",
|
||||
.probe = phonesim_radio_settings_probe,
|
||||
.remove = phonesim_radio_settings_remove,
|
||||
.query_rat_mode = phonesim_query_rat_mode,
|
||||
.query_available_rats = phonesim_query_available_rats,
|
||||
};
|
||||
|
||||
static struct ofono_ctm_driver ctm_driver = {
|
||||
.name = "phonesim",
|
||||
.probe = phonesim_ctm_probe,
|
||||
@@ -858,8 +791,6 @@ static void phonesim_post_sim(struct ofono_modem *modem)
|
||||
|
||||
if (!data->calypso)
|
||||
ofono_sms_create(modem, 0, "atmodem", data->chat);
|
||||
|
||||
ofono_radio_settings_create(modem, 0, "phonesim", data->chat);
|
||||
}
|
||||
|
||||
static void phonesim_post_online(struct ofono_modem *modem)
|
||||
@@ -1140,7 +1071,6 @@ done:
|
||||
static int phonesim_init(void)
|
||||
{
|
||||
int err;
|
||||
char *conf_override = getenv("OFONO_PHONESIM_CONFIG");
|
||||
|
||||
err = ofono_modem_driver_register(&phonesim_driver);
|
||||
if (err < 0)
|
||||
@@ -1150,12 +1080,8 @@ static int phonesim_init(void)
|
||||
|
||||
ofono_gprs_context_driver_register(&context_driver);
|
||||
ofono_ctm_driver_register(&ctm_driver);
|
||||
ofono_radio_settings_driver_register(&radio_settings_driver);
|
||||
|
||||
if (conf_override)
|
||||
parse_config(conf_override);
|
||||
else
|
||||
parse_config(CONFIGDIR "/phonesim.conf");
|
||||
parse_config(CONFIGDIR "/phonesim.conf");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1173,7 +1099,6 @@ static void phonesim_exit(void)
|
||||
g_slist_free(modem_list);
|
||||
modem_list = NULL;
|
||||
|
||||
ofono_radio_settings_driver_unregister(&radio_settings_driver);
|
||||
ofono_ctm_driver_unregister(&ctm_driver);
|
||||
|
||||
ofono_gprs_context_driver_unregister(&context_driver);
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -37,134 +36,9 @@
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/gprs-provision.h>
|
||||
|
||||
#include "provision.h"
|
||||
#include "mbpi.h"
|
||||
|
||||
/* Returns the list containing exactly one INTERNET and one MMS access point */
|
||||
static GSList *provision_normalize_apn_list(GSList *apns, const char* spn)
|
||||
{
|
||||
struct ofono_gprs_provision_data *best_internet = NULL;
|
||||
struct ofono_gprs_provision_data *best_mms = NULL;
|
||||
struct ofono_gprs_provision_data *second_best_internet = NULL;
|
||||
struct ofono_gprs_provision_data *second_best_mms = NULL;
|
||||
GSList *best_apns = NULL;
|
||||
GSList *l;
|
||||
|
||||
/* 1. save the first found internet APN and the first MMS APN */
|
||||
l = apns;
|
||||
while (l != NULL) {
|
||||
GSList *next = l->next;
|
||||
struct ofono_gprs_provision_data *ap = l->data;
|
||||
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
|
||||
&& !best_internet) {
|
||||
best_internet = ap;
|
||||
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
|
||||
&& !best_mms) {
|
||||
best_mms = ap;
|
||||
}
|
||||
l = next;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. look for a "primary" provider (i.e. an MNO, not
|
||||
* an MVNO on the same radio network)
|
||||
*/
|
||||
second_best_internet = best_internet;
|
||||
best_internet = NULL;
|
||||
second_best_mms = best_mms;
|
||||
best_mms = NULL;
|
||||
|
||||
l = apns;
|
||||
while (l != NULL) {
|
||||
GSList *next = l->next;
|
||||
struct ofono_gprs_provision_data *ap = l->data;
|
||||
|
||||
if (ap->provider_primary) {
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
|
||||
&& !best_internet) {
|
||||
best_internet = ap;
|
||||
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
|
||||
&& !best_mms) {
|
||||
best_mms = ap;
|
||||
}
|
||||
}
|
||||
l = next;
|
||||
}
|
||||
|
||||
/* no better match found */
|
||||
if (!best_internet)
|
||||
best_internet = second_best_internet;
|
||||
if (!best_mms)
|
||||
best_mms = second_best_mms;
|
||||
|
||||
/*
|
||||
* 3. if there is an SPN given, save the first internet APN and the
|
||||
* first MMS APN matching the SPN (partially, case-insensitively)
|
||||
* */
|
||||
if (spn) {
|
||||
second_best_internet = best_internet;
|
||||
best_internet = NULL;
|
||||
second_best_mms = best_mms;
|
||||
best_mms = NULL;
|
||||
|
||||
l = apns;
|
||||
while (l != NULL) {
|
||||
GSList *next = l->next;
|
||||
struct ofono_gprs_provision_data *ap = l->data;
|
||||
|
||||
if ((ap->provider_name && strcasestr(ap->provider_name, spn))
|
||||
|| (ap->name && strcasestr(ap->name, spn))
|
||||
|| (ap->apn && strcasestr(ap->apn, spn))) {
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
|
||||
&& !best_internet) {
|
||||
best_internet = ap;
|
||||
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
|
||||
&& !best_mms) {
|
||||
best_mms = ap;
|
||||
}
|
||||
}
|
||||
l = next;
|
||||
}
|
||||
|
||||
/* no better match found */
|
||||
if (!best_internet)
|
||||
best_internet = second_best_internet;
|
||||
if (!best_mms)
|
||||
best_mms = second_best_mms;
|
||||
}
|
||||
|
||||
/* 4. if none found yet, create APNs with default values */
|
||||
if (!best_internet) {
|
||||
best_internet = g_try_new0(struct ofono_gprs_provision_data, 1);
|
||||
if (best_internet) {
|
||||
best_internet->type =
|
||||
OFONO_GPRS_CONTEXT_TYPE_INTERNET;
|
||||
best_internet->name =
|
||||
g_strdup("Internet");
|
||||
best_internet->apn =
|
||||
g_strdup("internet");
|
||||
}
|
||||
}
|
||||
|
||||
if (!best_mms) {
|
||||
best_mms = g_try_new0(struct ofono_gprs_provision_data, 1);
|
||||
if (best_mms) {
|
||||
best_mms->type =
|
||||
OFONO_GPRS_CONTEXT_TYPE_MMS;
|
||||
best_mms->name =
|
||||
g_strdup("MMS");
|
||||
best_mms->apn =
|
||||
g_strdup("mms");
|
||||
}
|
||||
}
|
||||
|
||||
best_apns = g_slist_append(best_apns, best_internet);
|
||||
best_apns = g_slist_append(best_apns, best_mms);
|
||||
return best_apns;
|
||||
}
|
||||
|
||||
int provision_get_settings(const char *mcc, const char *mnc,
|
||||
static int provision_get_settings(const char *mcc, const char *mnc,
|
||||
const char *spn,
|
||||
struct ofono_gprs_provision_data **settings,
|
||||
int *count)
|
||||
@@ -175,26 +49,36 @@ int provision_get_settings(const char *mcc, const char *mnc,
|
||||
int ap_count;
|
||||
int i;
|
||||
|
||||
ofono_info("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
|
||||
DBG("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
|
||||
|
||||
/*
|
||||
* Passing FALSE to mbpi_lookup_apn() would return
|
||||
* an empty list if duplicates are found.
|
||||
* TODO: review with upstream. Default behavior was to
|
||||
* disallow duplicate APN entries, which unfortunately exist
|
||||
* in the mobile-broadband-provider-info db.
|
||||
*/
|
||||
apns = mbpi_lookup_apn(mcc, mnc, TRUE, &error);
|
||||
if (error != NULL) {
|
||||
ofono_error("%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
if (apns == NULL) {
|
||||
if (error != NULL) {
|
||||
ofono_error("%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
ofono_info("Found %d APs in MBPI", g_slist_length(apns));
|
||||
apns = provision_normalize_apn_list(apns, spn);
|
||||
if (apns == NULL)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ap_count = g_slist_length(apns);
|
||||
|
||||
ofono_info("Provisioning %d APs", ap_count);
|
||||
ofono_info("GPRS Provisioning found %d matching APNs for SPN: %s MCC: %s MNC: %s",
|
||||
ap_count, spn, mcc, mnc);
|
||||
/*
|
||||
* Only keep the first APN found.
|
||||
*
|
||||
* This allows auto-provisioning to work most of the time vs.
|
||||
* passing FALSE to mbpi_lookup_apn() which would return an
|
||||
* an empty list if duplicates are found.
|
||||
*/
|
||||
if (ap_count > 1)
|
||||
ap_count = 1;
|
||||
|
||||
*settings = g_try_new0(struct ofono_gprs_provision_data, ap_count);
|
||||
if (*settings == NULL) {
|
||||
@@ -213,16 +97,25 @@ int provision_get_settings(const char *mcc, const char *mnc,
|
||||
for (l = apns, i = 0; l; l = l->next, i++) {
|
||||
struct ofono_gprs_provision_data *ap = l->data;
|
||||
|
||||
ofono_info("Name: '%s'", ap->name);
|
||||
ofono_info("APN: '%s'", ap->apn);
|
||||
ofono_info("Type: %s", mbpi_ap_type(ap->type));
|
||||
ofono_info("Username: '%s'", ap->username);
|
||||
ofono_info("Password: '%s'", ap->password);
|
||||
/*
|
||||
* Only create a data context for the first matching APN.
|
||||
* See comment above that restricts restricts apn_count.
|
||||
*/
|
||||
if (i == 0) {
|
||||
ofono_info("Name: '%s'", ap->name);
|
||||
ofono_info("APN: '%s'", ap->apn);
|
||||
ofono_info("Type: %s", mbpi_ap_type(ap->type));
|
||||
ofono_info("Username: '%s'", ap->username);
|
||||
ofono_info("Password: '%s'", ap->password);
|
||||
|
||||
memcpy(*settings + i, ap,
|
||||
sizeof(struct ofono_gprs_provision_data));
|
||||
memcpy(*settings + i, ap,
|
||||
sizeof(struct ofono_gprs_provision_data));
|
||||
|
||||
g_free(ap);
|
||||
} else {
|
||||
mbpi_ap_free(ap);
|
||||
}
|
||||
|
||||
g_free(ap);
|
||||
}
|
||||
|
||||
g_slist_free(apns);
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2014 Jolla. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* 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 ofono_gprs_provision_data;
|
||||
|
||||
int provision_get_settings(const char *mcc, const char *mnc,
|
||||
const char *spn,
|
||||
struct ofono_gprs_provision_data **settings,
|
||||
int *count);
|
||||
|
||||
@@ -1,541 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <wspcodec.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono.h>
|
||||
#include <plugin.h>
|
||||
|
||||
/*
|
||||
* Push forwarder plugin is looking for configuration files in
|
||||
* /etc/ofono/push_forwarder.d directory. Confiration files are
|
||||
* glib key files that look like this:
|
||||
*
|
||||
* [Jolla MMS Handler]
|
||||
* ContentType = application/vnd.wap.mms-message
|
||||
* Interface = com.jolla.MmsEngine.
|
||||
* Service = com.jolla.MmsEngine
|
||||
* Method = HandlePush
|
||||
* Path = /
|
||||
*
|
||||
* Only files with .conf suffix are loaded. In addition to the keys
|
||||
* from the above example, SourcePort and DestinationPort port keys
|
||||
* are supported. All other keys are ignored. One file may describe
|
||||
* several push handlers. See pf_parse_config() function for details.
|
||||
*
|
||||
* When push fowarder receives a WAP push, it goes through the list
|
||||
* of registered handlers and invokes all of them that match content
|
||||
* type and/or port numbers. The rest is up to the D-Bus service
|
||||
* handling the call.
|
||||
*/
|
||||
|
||||
#define PF_CONFIG_DIR CONFIGDIR "/push_forwarder.d"
|
||||
|
||||
struct pf_modem {
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_sms *sms;
|
||||
struct ofono_sim *sim;
|
||||
unsigned int sim_watch_id;
|
||||
unsigned int sms_watch_id;
|
||||
unsigned int push_watch_id;
|
||||
};
|
||||
|
||||
struct push_datagram_handler {
|
||||
char *name;
|
||||
char *content_type;
|
||||
char *interface;
|
||||
char *service;
|
||||
char *method;
|
||||
char *path;
|
||||
int dst_port;
|
||||
int src_port;
|
||||
};
|
||||
|
||||
static GSList *handlers;
|
||||
static GSList *modems;
|
||||
static unsigned int modem_watch_id;
|
||||
static int inotify_fd = -1;
|
||||
static int inotify_watch_id = -1;
|
||||
static guint inotify_watch_source_id;
|
||||
static GIOChannel *inotify_watch_channel;
|
||||
|
||||
static void pf_notify_handler(struct push_datagram_handler *h,
|
||||
const char *imsi, const char *from, const struct tm *remote,
|
||||
const struct tm *local, int dst, int src,
|
||||
const char *ct, const void *data, unsigned int len)
|
||||
{
|
||||
struct tm remote_tm = *remote;
|
||||
struct tm local_tm = *local;
|
||||
dbus_uint32_t remote_time_arg = mktime(&remote_tm);
|
||||
dbus_uint32_t local_time_arg = mktime(&local_tm);
|
||||
dbus_int32_t dst_arg = dst;
|
||||
dbus_int32_t src_arg = src;
|
||||
DBusMessageIter iter, array;
|
||||
DBusMessage *msg = dbus_message_new_method_call(h->service,
|
||||
h->path, h->interface, h->method);
|
||||
|
||||
dbus_message_append_args(msg,
|
||||
DBUS_TYPE_STRING, &imsi,
|
||||
DBUS_TYPE_STRING, &from,
|
||||
DBUS_TYPE_UINT32, &remote_time_arg,
|
||||
DBUS_TYPE_UINT32, &local_time_arg,
|
||||
DBUS_TYPE_INT32, &dst_arg,
|
||||
DBUS_TYPE_INT32, &src_arg,
|
||||
DBUS_TYPE_STRING, &ct,
|
||||
DBUS_TYPE_INVALID);
|
||||
dbus_message_iter_init_append(msg, &iter);
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_BYTE_AS_STRING, &array);
|
||||
dbus_message_iter_append_fixed_array(&array,
|
||||
DBUS_TYPE_BYTE, &data, len);
|
||||
dbus_message_iter_close_container(&iter, &array);
|
||||
dbus_message_set_no_reply(msg, TRUE);
|
||||
dbus_connection_send(ofono_dbus_get_connection(), msg, NULL);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static gboolean pf_match_port(int port, int expected_port)
|
||||
{
|
||||
if (expected_port < 0)
|
||||
return TRUE;
|
||||
|
||||
if (expected_port == port)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean pf_match_handler(struct push_datagram_handler *h,
|
||||
const char *ct, int dst, int src)
|
||||
{
|
||||
if (pf_match_port(dst, h->dst_port) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
if (pf_match_port(src, h->src_port) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
if (h->content_type == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (strcmp(h->content_type, ct) == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void pf_handle_datagram(const char *from,
|
||||
const struct tm *remote, const struct tm *local, int dst,
|
||||
int src, const unsigned char *buffer, unsigned int len,
|
||||
void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
guint remain;
|
||||
const guint8 *data;
|
||||
unsigned int hdrlen;
|
||||
unsigned int off;
|
||||
const void *ct;
|
||||
const char *imsi;
|
||||
GSList *link;
|
||||
|
||||
DBG("received push of size: %u", len);
|
||||
|
||||
if (pm->sim == NULL)
|
||||
return;
|
||||
|
||||
imsi = ofono_sim_get_imsi(pm->sim);
|
||||
if (len < 3)
|
||||
return;
|
||||
|
||||
if (buffer[1] != 6)
|
||||
return;
|
||||
|
||||
remain = len - 2;
|
||||
data = buffer + 2;
|
||||
|
||||
if (wsp_decode_uintvar(data, remain, &hdrlen, &off) == FALSE)
|
||||
return;
|
||||
|
||||
if ((off + hdrlen) > remain)
|
||||
return;
|
||||
|
||||
data += off;
|
||||
remain -= off;
|
||||
|
||||
DBG(" WAP header %u bytes", hdrlen);
|
||||
|
||||
if (wsp_decode_content_type(data, hdrlen, &ct, &off, NULL) == FALSE)
|
||||
return;
|
||||
|
||||
data += hdrlen;
|
||||
remain -= hdrlen;
|
||||
|
||||
DBG(" content type %s", (char *)ct);
|
||||
DBG(" imsi %s", imsi);
|
||||
DBG(" data size %u", remain);
|
||||
|
||||
link = handlers;
|
||||
|
||||
while (link) {
|
||||
struct push_datagram_handler *h = link->data;
|
||||
|
||||
if (pf_match_handler(h, ct, dst, src) != FALSE) {
|
||||
DBG("notifying %s", h->name);
|
||||
pf_notify_handler(h, imsi, from, remote, local, dst,
|
||||
src, ct, data, remain);
|
||||
}
|
||||
link = link->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_sms_watch(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
DBG("registered");
|
||||
pm->sms = __ofono_atom_get_data(atom);
|
||||
pm->push_watch_id = __ofono_sms_datagram_watch_add(pm->sms,
|
||||
pf_handle_datagram, -1, -1, pm, NULL);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG("unregistered");
|
||||
pm->sms = NULL;
|
||||
pm->push_watch_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_sms_watch_done(void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
pm->sms_watch_id = 0;
|
||||
}
|
||||
|
||||
static void pf_sim_watch(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
DBG("registered");
|
||||
pm->sim = __ofono_atom_get_data(atom);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG("unregistered");
|
||||
pm->sim = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_sim_watch_done(void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
pm->sim_watch_id = 0;
|
||||
}
|
||||
|
||||
static void pf_free_modem(struct pf_modem *pm)
|
||||
{
|
||||
if (pm == NULL)
|
||||
return;
|
||||
|
||||
if (pm->push_watch_id != 0)
|
||||
__ofono_sms_datagram_watch_remove(pm->sms, pm->push_watch_id);
|
||||
|
||||
if (pm->sim_watch_id != 0)
|
||||
__ofono_modem_remove_atom_watch(pm->modem, pm->sim_watch_id);
|
||||
|
||||
if (pm->sms_watch_id != 0)
|
||||
__ofono_modem_remove_atom_watch(pm->modem, pm->sms_watch_id);
|
||||
|
||||
g_free(pm);
|
||||
}
|
||||
|
||||
static void pf_modem_watch(struct ofono_modem *modem,
|
||||
gboolean added, void *userdata)
|
||||
{
|
||||
DBG("modem: %p, added: %d", modem, added);
|
||||
if (added != FALSE) {
|
||||
struct pf_modem *pm;
|
||||
|
||||
pm = g_try_new0(struct pf_modem, 1);
|
||||
if (pm == NULL)
|
||||
return;
|
||||
|
||||
pm->modem = modem;
|
||||
pm->sms_watch_id = __ofono_modem_add_atom_watch(modem,
|
||||
OFONO_ATOM_TYPE_SMS, pf_sms_watch, pm,
|
||||
pf_sms_watch_done);
|
||||
pm->sim_watch_id = __ofono_modem_add_atom_watch(modem,
|
||||
OFONO_ATOM_TYPE_SIM, pf_sim_watch, pm,
|
||||
pf_sim_watch_done);
|
||||
modems = g_slist_append(modems, pm);
|
||||
} else {
|
||||
GSList *link = modems;
|
||||
|
||||
while (link) {
|
||||
struct pf_modem *pm = link->data;
|
||||
|
||||
if (pm->modem == modem) {
|
||||
modems = g_slist_delete_link(modems, link);
|
||||
pf_free_modem(pm);
|
||||
break;
|
||||
}
|
||||
link = link->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_modem_init(struct ofono_modem *modem,
|
||||
void *userdata)
|
||||
{
|
||||
pf_modem_watch(modem, TRUE, NULL);
|
||||
}
|
||||
|
||||
static void pf_free_handler(void *data)
|
||||
{
|
||||
struct push_datagram_handler *h = data;
|
||||
|
||||
g_free(h->content_type);
|
||||
g_free(h->interface);
|
||||
g_free(h->service);
|
||||
g_free(h->method);
|
||||
g_free(h->path);
|
||||
g_free(h->name);
|
||||
g_free(h);
|
||||
}
|
||||
|
||||
static void pf_parse_handler(GKeyFile *conf, const char *g)
|
||||
{
|
||||
GError *err = NULL;
|
||||
struct push_datagram_handler *h;
|
||||
char *interface;
|
||||
char *service;
|
||||
char *method;
|
||||
char *path;
|
||||
|
||||
interface = g_key_file_get_string(conf, g, "Interface", NULL);
|
||||
if (interface == NULL)
|
||||
goto no_interface;
|
||||
|
||||
service = g_key_file_get_string(conf, g, "Service", NULL);
|
||||
if (service == NULL)
|
||||
goto no_service;
|
||||
|
||||
method = g_key_file_get_string(conf, g, "Method", NULL);
|
||||
if (method == NULL)
|
||||
goto no_method;
|
||||
|
||||
path = g_key_file_get_string(conf, g, "Path", NULL);
|
||||
if (path == NULL)
|
||||
goto no_path;
|
||||
|
||||
h = g_try_new0(struct push_datagram_handler, 1);
|
||||
if (h == NULL)
|
||||
goto no_memory;
|
||||
|
||||
h->name = g_strdup(g);
|
||||
h->interface = interface;
|
||||
h->service = service;
|
||||
h->method = method;
|
||||
h->path = path;
|
||||
h->content_type = g_key_file_get_string(conf, g, "ContentType", NULL);
|
||||
h->dst_port = g_key_file_get_integer(conf, g, "DestinationPort", &err);
|
||||
if (h->dst_port == 0 && err != NULL) {
|
||||
h->dst_port = -1;
|
||||
g_error_free(err);
|
||||
err = NULL;
|
||||
}
|
||||
h->src_port = g_key_file_get_integer(conf, g, "SourcePort", &err);
|
||||
if (h->src_port == 0 && err != NULL) {
|
||||
h->src_port = -1;
|
||||
g_error_free(err);
|
||||
err = NULL;
|
||||
}
|
||||
DBG("registered %s", h->name);
|
||||
if (h->content_type != NULL)
|
||||
DBG(" ContentType: %s", h->content_type);
|
||||
if (h->dst_port >= 0)
|
||||
DBG(" DestinationPort: %d", h->dst_port);
|
||||
if (h->src_port >= 0)
|
||||
DBG(" SourcePort: %d", h->src_port);
|
||||
DBG(" Interface: %s", interface);
|
||||
DBG(" Service: %s", service);
|
||||
DBG(" Method: %s", method);
|
||||
DBG(" Path: %s", path);
|
||||
handlers = g_slist_append(handlers, h);
|
||||
return;
|
||||
|
||||
no_memory:
|
||||
g_free(path);
|
||||
|
||||
no_path:
|
||||
g_free(method);
|
||||
|
||||
no_method:
|
||||
g_free(service);
|
||||
|
||||
no_service:
|
||||
g_free(interface);
|
||||
|
||||
no_interface:
|
||||
return;
|
||||
}
|
||||
|
||||
static void pf_parse_config(void)
|
||||
{
|
||||
GDir *dir;
|
||||
const gchar *file;
|
||||
|
||||
g_slist_free_full(handlers, pf_free_handler);
|
||||
handlers = NULL;
|
||||
|
||||
dir = g_dir_open(PF_CONFIG_DIR, 0, NULL);
|
||||
if (dir == NULL) {
|
||||
DBG(PF_CONFIG_DIR " not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("loading configuration from " PF_CONFIG_DIR);
|
||||
while ((file = g_dir_read_name(dir)) != NULL) {
|
||||
GError *err;
|
||||
GKeyFile *conf;
|
||||
char *path;
|
||||
|
||||
if (g_str_has_suffix(file, ".conf") == FALSE)
|
||||
continue;
|
||||
|
||||
err = NULL;
|
||||
conf = g_key_file_new();
|
||||
path = g_strconcat(PF_CONFIG_DIR "/", file, NULL);
|
||||
DBG("reading %s", file);
|
||||
|
||||
if (g_key_file_load_from_file(conf, path, 0, &err) != FALSE) {
|
||||
gsize i, n;
|
||||
char **names = g_key_file_get_groups(conf, &n);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
pf_parse_handler(conf, names[i]);
|
||||
g_strfreev(names);
|
||||
} else {
|
||||
ofono_warn("%s", err->message);
|
||||
g_error_free(err);
|
||||
}
|
||||
|
||||
g_key_file_free(conf);
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
g_dir_close(dir);
|
||||
}
|
||||
|
||||
static gboolean pf_inotify(GIOChannel *gio, GIOCondition c, gpointer data)
|
||||
{
|
||||
int avail;
|
||||
gsize len;
|
||||
void *buf;
|
||||
GError *error;
|
||||
|
||||
if (ioctl(inotify_fd, FIONREAD, &avail) < 0)
|
||||
return FALSE;
|
||||
|
||||
buf = g_try_malloc(avail);
|
||||
if (buf == NULL)
|
||||
return FALSE;
|
||||
|
||||
error = NULL;
|
||||
if (g_io_channel_read_chars(gio, buf, avail, &len, &error) !=
|
||||
G_IO_STATUS_NORMAL) {
|
||||
g_free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pf_parse_config();
|
||||
g_free(buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int pf_plugin_init(void)
|
||||
{
|
||||
DBG("");
|
||||
pf_parse_config();
|
||||
modem_watch_id = __ofono_modemwatch_add(pf_modem_watch, NULL, NULL);
|
||||
__ofono_modem_foreach(pf_modem_init, NULL);
|
||||
inotify_fd = inotify_init();
|
||||
if (inotify_fd < 0)
|
||||
return 0;
|
||||
|
||||
inotify_watch_id = inotify_add_watch(inotify_fd,
|
||||
PF_CONFIG_DIR,
|
||||
IN_CLOSE_WRITE | IN_DELETE | IN_MOVE);
|
||||
if (inotify_watch_id < 0)
|
||||
goto no_inotify_watch_id;
|
||||
|
||||
inotify_watch_channel = g_io_channel_unix_new(inotify_fd);
|
||||
if (inotify_watch_channel == NULL)
|
||||
goto no_inotify_watch_channel;
|
||||
|
||||
g_io_channel_set_encoding(inotify_watch_channel, NULL, NULL);
|
||||
g_io_channel_set_buffered(inotify_watch_channel, FALSE);
|
||||
inotify_watch_source_id = g_io_add_watch(inotify_watch_channel,
|
||||
G_IO_IN, pf_inotify, NULL);
|
||||
if (inotify_watch_source_id != 0)
|
||||
return 0;
|
||||
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
|
||||
no_inotify_watch_channel:
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
|
||||
no_inotify_watch_id:
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pf_plugin_exit(void)
|
||||
{
|
||||
DBG("");
|
||||
__ofono_modemwatch_remove(modem_watch_id);
|
||||
modem_watch_id = 0;
|
||||
g_slist_free_full(modems, (GDestroyNotify)pf_free_modem);
|
||||
modems = NULL;
|
||||
g_slist_free_full(handlers, pf_free_handler);
|
||||
handlers = NULL;
|
||||
if (inotify_watch_source_id == 0)
|
||||
return;
|
||||
|
||||
g_source_remove(inotify_watch_source_id);
|
||||
inotify_watch_source_id = 0;
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(push_forwarder, "Push Forwarder Plugin", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, pf_plugin_init,
|
||||
pf_plugin_exit)
|
||||
@@ -1,376 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2014 Philip Paeps. 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 <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gatchat.h>
|
||||
#include <gattty.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/devinfo.h>
|
||||
#include <ofono/netreg.h>
|
||||
#include <ofono/sim.h>
|
||||
#include <ofono/gprs.h>
|
||||
#include <ofono/gprs-context.h>
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include <drivers/atmodem/atutil.h>
|
||||
#include <drivers/atmodem/vendor.h>
|
||||
|
||||
static const char *cfun_prefix[] = { "+CFUN:", NULL };
|
||||
static const char *cpin_prefix[] = { "+CPIN:", NULL };
|
||||
static const char *none_prefix[] = { NULL };
|
||||
|
||||
struct quectel_data {
|
||||
GAtChat *modem;
|
||||
GAtChat *aux;
|
||||
guint cpin_ready;
|
||||
gboolean have_sim;
|
||||
};
|
||||
|
||||
static void quectel_debug(const char *str, void *user_data)
|
||||
{
|
||||
const char *prefix = user_data;
|
||||
|
||||
ofono_info("%s%s", prefix, str);
|
||||
}
|
||||
|
||||
static int quectel_probe(struct ofono_modem *modem)
|
||||
{
|
||||
struct quectel_data *data;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
data = g_try_new0(struct quectel_data, 1);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ofono_modem_set_data(modem, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void quectel_remove(struct ofono_modem *modem)
|
||||
{
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
if (data->cpin_ready != 0)
|
||||
g_at_chat_unregister(data->aux, data->cpin_ready);
|
||||
|
||||
ofono_modem_set_data(modem, NULL);
|
||||
g_at_chat_unref(data->aux);
|
||||
g_at_chat_unref(data->modem);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static GAtChat *open_device(struct ofono_modem *modem,
|
||||
const char *key, char *debug)
|
||||
{
|
||||
const char *device;
|
||||
GAtSyntax *syntax;
|
||||
GIOChannel *channel;
|
||||
GAtChat *chat;
|
||||
|
||||
device = ofono_modem_get_string(modem, key);
|
||||
if (device == NULL)
|
||||
return NULL;
|
||||
|
||||
DBG("%s %s", key, device);
|
||||
|
||||
channel = g_at_tty_open(device, NULL);
|
||||
if (channel == NULL)
|
||||
return NULL;
|
||||
|
||||
syntax = g_at_syntax_new_gsm_permissive();
|
||||
chat = g_at_chat_new(channel, syntax);
|
||||
g_at_syntax_unref(syntax);
|
||||
|
||||
g_io_channel_unref(channel);
|
||||
|
||||
if (chat == NULL)
|
||||
return NULL;
|
||||
|
||||
if (getenv("OFONO_AT_DEBUG"))
|
||||
g_at_chat_set_debug(chat, quectel_debug, debug);
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
static void cpin_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
const char *sim_inserted;
|
||||
GAtResultIter iter;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+CPIN:"))
|
||||
return;
|
||||
|
||||
g_at_result_iter_next_unquoted_string(&iter, &sim_inserted);
|
||||
|
||||
if (g_strcmp0(sim_inserted, "NOT INSERTED") != 0)
|
||||
data->have_sim = TRUE;
|
||||
|
||||
ofono_modem_set_powered(modem, TRUE);
|
||||
|
||||
/* Turn off the radio. */
|
||||
g_at_chat_send(data->aux, "AT+CFUN=4", none_prefix, NULL, NULL, NULL);
|
||||
|
||||
g_at_chat_unregister(data->aux, data->cpin_ready);
|
||||
data->cpin_ready = 0;
|
||||
}
|
||||
|
||||
static void cpin_query(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
DBG("ok %d", ok);
|
||||
|
||||
if (ok)
|
||||
cpin_notify(result, user_data);
|
||||
}
|
||||
|
||||
static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("ok %d", ok);
|
||||
|
||||
if (!ok) {
|
||||
g_at_chat_unref(data->aux);
|
||||
data->aux = NULL;
|
||||
g_at_chat_unref(data->modem);
|
||||
data->modem = NULL;
|
||||
ofono_modem_set_powered(modem, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
data->cpin_ready = g_at_chat_register(data->aux, "+CPIN", cpin_notify,
|
||||
FALSE, modem, NULL);
|
||||
g_at_chat_send(data->aux, "AT+CPIN?", cpin_prefix, cpin_query,
|
||||
modem, NULL);
|
||||
}
|
||||
|
||||
static void cfun_query(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
GAtResultIter iter;
|
||||
int status;
|
||||
|
||||
DBG("ok %d", ok);
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (g_at_result_iter_next(&iter, "+CFUN:") == FALSE)
|
||||
return;
|
||||
|
||||
g_at_result_iter_next_number(&iter, &status);
|
||||
|
||||
/*
|
||||
* The modem firmware powers up in CFUN=1 but will respond to AT+CFUN=4
|
||||
* with ERROR until some amount of time (which varies with temperature)
|
||||
* passes. Empirical evidence suggests that the firmware will report an
|
||||
* unsolicited +CPIN: notification when it is ready to be useful.
|
||||
*
|
||||
* Work around this feature by only transitioning to CFUN=4 after we've
|
||||
* received an unsolicited +CPIN: notification.
|
||||
*/
|
||||
|
||||
if (status != 1) {
|
||||
g_at_chat_send(data->aux, "AT+CFUN=4", none_prefix,
|
||||
cfun_enable, modem, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
cfun_enable(TRUE, NULL, modem);
|
||||
}
|
||||
|
||||
static int quectel_enable(struct ofono_modem *modem)
|
||||
{
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
data->modem = open_device(modem, "Modem", "Modem: ");
|
||||
if (data->modem == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
data->aux = open_device(modem, "Aux", "Aux: ");
|
||||
if (data->aux == NULL) {
|
||||
g_at_chat_unref(data->modem);
|
||||
data->modem = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
g_at_chat_set_slave(data->modem, data->aux);
|
||||
|
||||
g_at_chat_send(data->modem, "ATE0 &C0 +CMEE=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
g_at_chat_send(data->aux, "ATE0 &C0 +CMEE=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_at_chat_send(data->aux, "AT+CFUN?", cfun_prefix,
|
||||
cfun_query, modem, NULL);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("");
|
||||
|
||||
g_at_chat_unref(data->aux);
|
||||
data->aux = NULL;
|
||||
|
||||
if (ok)
|
||||
ofono_modem_set_powered(modem, FALSE);
|
||||
}
|
||||
|
||||
static int quectel_disable(struct ofono_modem *modem)
|
||||
{
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
g_at_chat_cancel_all(data->modem);
|
||||
g_at_chat_unregister_all(data->modem);
|
||||
|
||||
g_at_chat_unref(data->modem);
|
||||
data->modem = NULL;
|
||||
|
||||
g_at_chat_cancel_all(data->aux);
|
||||
g_at_chat_unregister_all(data->aux);
|
||||
|
||||
g_at_chat_send(data->aux, "AT+CFUN=0", cfun_prefix,
|
||||
cfun_disable, modem, NULL);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_modem_online_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void quectel_set_online(struct ofono_modem *modem, ofono_bool_t online,
|
||||
ofono_modem_online_cb_t cb, void *user_data)
|
||||
{
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
||||
char const *command = online ? "AT+CFUN=1" : "AT+CFUN=4";
|
||||
|
||||
DBG("modem %p %s", modem, online ? "online" : "offline");
|
||||
|
||||
if (g_at_chat_send(data->aux, command, cfun_prefix, set_online_cb,
|
||||
cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void quectel_pre_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_sim *sim;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
ofono_devinfo_create(modem, 0, "atmodem", data->aux);
|
||||
sim = ofono_sim_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
|
||||
data->aux);
|
||||
|
||||
if (sim && data->have_sim == TRUE)
|
||||
ofono_sim_inserted_notify(sim, TRUE);
|
||||
}
|
||||
|
||||
static void quectel_post_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_gprs *gprs;
|
||||
struct ofono_gprs_context *gc;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
gprs = ofono_gprs_create(modem, 0, "atmodem", data->aux);
|
||||
gc = ofono_gprs_context_create(modem, 0, "atmodem", data->modem);
|
||||
|
||||
if (gprs && gc)
|
||||
ofono_gprs_add_context(gprs, gc);
|
||||
}
|
||||
|
||||
static void quectel_post_online(struct ofono_modem *modem)
|
||||
{
|
||||
struct quectel_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
ofono_netreg_create(modem, 0, "atmodem", data->aux);
|
||||
}
|
||||
|
||||
static struct ofono_modem_driver quectel_driver = {
|
||||
.name = "quectel",
|
||||
.probe = quectel_probe,
|
||||
.remove = quectel_remove,
|
||||
.enable = quectel_enable,
|
||||
.disable = quectel_disable,
|
||||
.set_online = quectel_set_online,
|
||||
.pre_sim = quectel_pre_sim,
|
||||
.post_sim = quectel_post_sim,
|
||||
.post_online = quectel_post_online,
|
||||
};
|
||||
|
||||
static int quectel_init(void)
|
||||
{
|
||||
return ofono_modem_driver_register(&quectel_driver);
|
||||
}
|
||||
|
||||
static void quectel_exit(void)
|
||||
{
|
||||
ofono_modem_driver_unregister(&quectel_driver);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(quectel, "Quectel driver", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, quectel_init, quectel_exit)
|
||||
@@ -63,28 +63,13 @@
|
||||
#include <ofono/types.h>
|
||||
#include <ofono/message-waiting.h>
|
||||
#include <ofono/oemraw.h>
|
||||
#include <ofono/stk.h>
|
||||
|
||||
#include "rildev.h"
|
||||
#include "drivers/rilmodem/rilmodem.h"
|
||||
|
||||
#define MAX_POWER_ON_RETRIES 5
|
||||
#define MAX_SIM_STATUS_RETRIES 15
|
||||
#define RADIO_ID 1001
|
||||
#define MAX_PDP_CONTEXTS 2
|
||||
|
||||
/* MCE definitions */
|
||||
#define MCE_SERVICE "com.nokia.mce"
|
||||
#define MCE_SIGNAL_IF "com.nokia.mce.signal"
|
||||
|
||||
/* MCE signal definitions */
|
||||
#define MCE_DISPLAY_SIG "display_status_ind"
|
||||
|
||||
#define MCE_DISPLAY_ON_STRING "on"
|
||||
|
||||
/* transitional state between ON and OFF (3 seconds) */
|
||||
#define MCE_DISPLAY_DIM_STRING "dimmed"
|
||||
#define MCE_DISPLAY_OFF_STRING "off"
|
||||
#define MAX_POWER_ON_RETRIES 5
|
||||
#define MAX_SIM_STATUS_RETRIES 15
|
||||
#define RADIO_ID 1001
|
||||
#define MAX_PDP_CONTEXTS 2
|
||||
|
||||
struct ril_data {
|
||||
GRil *modem;
|
||||
@@ -97,12 +82,25 @@ struct ril_data {
|
||||
guint timer_id;
|
||||
};
|
||||
|
||||
/* MCE definitions */
|
||||
#define MCE_SERVICE "com.nokia.mce"
|
||||
#define MCE_SIGNAL_IF "com.nokia.mce.signal"
|
||||
|
||||
/* MCE signal definitions */
|
||||
#define MCE_DISPLAY_SIG "display_status_ind"
|
||||
|
||||
#define MCE_DISPLAY_ON_STRING "on"
|
||||
/* transitional state between ON and OFF (3 seconds) */
|
||||
#define MCE_DISPLAY_DIM_STRING "dimmed"
|
||||
#define MCE_DISPLAY_OFF_STRING "off"
|
||||
|
||||
static guint mce_daemon_watch;
|
||||
static guint signal_watch;
|
||||
static DBusConnection *connection;
|
||||
|
||||
static int ril_init(void);
|
||||
static void ril_exit(void);
|
||||
guint reconnect_timer;
|
||||
|
||||
static int send_get_sim_status(struct ofono_modem *modem);
|
||||
|
||||
static void ril_debug(const char *str, void *user_data)
|
||||
@@ -114,12 +112,13 @@ static void ril_debug(const char *str, void *user_data)
|
||||
|
||||
static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
DBG("error=%d", message->error);
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
struct sim_status status;
|
||||
struct sim_app *apps[MAX_UICC_APPS];
|
||||
|
||||
DBG("");
|
||||
|
||||
/*
|
||||
* ril.h claims this should NEVER fail!
|
||||
* However this isn't quite true. So,
|
||||
@@ -189,7 +188,6 @@ static int send_get_sim_status(struct ofono_modem *modem)
|
||||
|
||||
static int ril_probe(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("modem: %p", modem);
|
||||
struct ril_data *ril = NULL;
|
||||
|
||||
ril = g_try_new0(struct ril_data, 1);
|
||||
@@ -213,7 +211,7 @@ error:
|
||||
static void ril_remove(struct ofono_modem *modem)
|
||||
{
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
DBG("modem: %p ril: %p", modem, ril);
|
||||
|
||||
|
||||
ofono_modem_set_data(modem, NULL);
|
||||
|
||||
@@ -223,19 +221,17 @@ static void ril_remove(struct ofono_modem *modem)
|
||||
if (ril->timer_id > 0)
|
||||
g_source_remove(ril->timer_id);
|
||||
|
||||
if (reconnect_timer > 0)
|
||||
g_source_remove(ril->timer_id);
|
||||
|
||||
g_ril_unref(ril->modem);
|
||||
|
||||
g_free(ril);
|
||||
|
||||
g_dbus_remove_watch(connection, mce_daemon_watch);
|
||||
|
||||
if (signal_watch > 0)
|
||||
g_dbus_remove_watch(connection, signal_watch);
|
||||
}
|
||||
|
||||
static void ril_pre_sim(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("");
|
||||
DBG("enter");
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
struct ofono_sim *sim;
|
||||
|
||||
@@ -248,7 +244,6 @@ static void ril_pre_sim(struct ofono_modem *modem)
|
||||
|
||||
static void ril_post_sim(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("");
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
struct ofono_gprs *gprs;
|
||||
struct ofono_gprs_context *gc;
|
||||
@@ -275,7 +270,6 @@ static void ril_post_sim(struct ofono_modem *modem)
|
||||
ofono_phonebook_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_call_forwarding_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_call_barring_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_stk_create(modem, 0, "rilmodem", ril->modem);
|
||||
|
||||
mw = ofono_message_waiting_create(modem);
|
||||
if (mw)
|
||||
@@ -284,7 +278,7 @@ static void ril_post_sim(struct ofono_modem *modem)
|
||||
|
||||
static void ril_post_online(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("");
|
||||
DBG("enter");
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
|
||||
ofono_call_volume_create(modem, 0, "rilmodem", ril->modem);
|
||||
@@ -292,12 +286,13 @@ static void ril_post_online(struct ofono_modem *modem)
|
||||
ofono_netreg_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_ussd_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_call_settings_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_cbs_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_oem_raw_create(modem, 0, "rilmodem", ril->modem);
|
||||
}
|
||||
|
||||
static void ril_set_online_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
DBG("");
|
||||
DBG("enter");
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_modem_online_cb_t cb = cbd->cb;
|
||||
|
||||
@@ -319,13 +314,12 @@ static void ril_set_online(struct ofono_modem *modem, ofono_bool_t online,
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 1); /* Number of params */
|
||||
parcel_w_int32(&rilp, online); /* Radio ON = 1, Radio OFF = 0 */
|
||||
|
||||
ofono_info("%s: RIL_REQUEST_RADIO_POWER %d", __func__, online);
|
||||
DBG("1");
|
||||
ret = g_ril_send(ril->modem, RIL_REQUEST_RADIO_POWER, rilp.data,
|
||||
rilp.size, ril_set_online_cb, cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
DBG("RIL_REQUEST_RADIO_POWER done");
|
||||
DBG("2");
|
||||
if (ret <= 0) {
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(callback, data);
|
||||
@@ -363,7 +357,6 @@ static int ril_screen_state(struct ofono_modem *modem, ofono_bool_t state)
|
||||
static gboolean display_changed(DBusConnection *conn,
|
||||
DBusMessage *message, void *user_data)
|
||||
{
|
||||
DBG("");
|
||||
struct ofono_modem *modem = user_data;
|
||||
DBusMessageIter iter;
|
||||
const char *value;
|
||||
@@ -386,7 +379,6 @@ static gboolean display_changed(DBusConnection *conn,
|
||||
|
||||
static void mce_connect(DBusConnection *conn, void *user_data)
|
||||
{
|
||||
DBG("");
|
||||
signal_watch = g_dbus_add_signal_watch(conn,
|
||||
MCE_SERVICE, NULL,
|
||||
MCE_SIGNAL_IF,
|
||||
@@ -397,26 +389,20 @@ static void mce_connect(DBusConnection *conn, void *user_data)
|
||||
|
||||
static void mce_disconnect(DBusConnection *conn, void *user_data)
|
||||
{
|
||||
DBG("");
|
||||
g_dbus_remove_watch(conn, signal_watch);
|
||||
signal_watch = 0;
|
||||
}
|
||||
|
||||
static void ril_connected(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
struct ofono_modem *modem = (struct ofono_modem *) user_data;
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
int ril_version = 0;
|
||||
struct parcel rilp;
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
ril_version = parcel_r_int32(&rilp);
|
||||
ofono_debug("%s: [UNSOL]< %s, RIL_VERSION %d",
|
||||
__func__, ril_unsol_request_to_string(message->req),
|
||||
ril_version);
|
||||
/* TODO: make conditional */
|
||||
ofono_debug("[UNSOL]< %s", ril_unsol_request_to_string(message->req));
|
||||
/* TODO: make conditional */
|
||||
|
||||
/* TODO: need a disconnect function to restart things! */
|
||||
ril->connected = TRUE;
|
||||
|
||||
send_get_sim_status(modem);
|
||||
@@ -426,51 +412,37 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
|
||||
mce_connect, mce_disconnect, modem, NULL);
|
||||
}
|
||||
|
||||
static int create_gril(struct ofono_modem *modem);
|
||||
|
||||
static gboolean connect_rild(gpointer user_data)
|
||||
|
||||
static gboolean ril_re_init(gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = (struct ofono_modem *) user_data;
|
||||
|
||||
ofono_info("%s: Connecting %p to rild...", __func__, modem);
|
||||
|
||||
if (create_gril(modem) < 0) {
|
||||
DBG("Connecting %p to rild failed, retry timer continues...",
|
||||
modem);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
ril_init();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* RIL socket callback from g_io channel */
|
||||
static void gril_disconnected(gpointer user_data)
|
||||
{
|
||||
/* Signal clients modem going down */
|
||||
struct ofono_modem *modem = user_data;
|
||||
ofono_error("%s: modem: %p", __func__, modem);
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
if (ofono_modem_is_registered(modem)) {
|
||||
if (modem) {
|
||||
ofono_modem_remove(modem);
|
||||
mce_disconnect(conn, user_data);
|
||||
ril_modem_remove(modem);
|
||||
reconnect_timer = g_timeout_add_seconds(2, ril_re_init, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ril_switchUser()
|
||||
{
|
||||
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0)
|
||||
ofono_error("%s: prctl(PR_SET_KEEPCAPS) failed:%s,%d",
|
||||
__func__, strerror(errno), errno);
|
||||
ofono_error("prctl(PR_SET_KEEPCAPS) failed:%s,%d",
|
||||
strerror(errno), errno);
|
||||
|
||||
if (setgid(RADIO_ID) < 0)
|
||||
ofono_error("%s: setgid(%d) failed:%s,%d",
|
||||
__func__, RADIO_ID, strerror(errno), errno);
|
||||
ofono_error("setgid(%d) failed:%s,%d",
|
||||
RADIO_ID, strerror(errno), errno);
|
||||
if (setuid(RADIO_ID) < 0)
|
||||
ofono_error("%s: setuid(%d) failed:%s,%d",
|
||||
__func__, RADIO_ID, strerror(errno), errno);
|
||||
ofono_error("setuid(%d) failed:%s,%d",
|
||||
RADIO_ID, strerror(errno), errno);
|
||||
|
||||
struct __user_cap_header_struct header;
|
||||
struct __user_cap_data_struct cap;
|
||||
@@ -481,14 +453,14 @@ void ril_switchUser()
|
||||
cap.inheritable = 0;
|
||||
|
||||
if (syscall(SYS_capset, &header, &cap) < 0)
|
||||
ofono_error("%s: syscall(SYS_capset) failed:%s,%d",
|
||||
__func__, strerror(errno), errno);
|
||||
ofono_error("syscall(SYS_capset) failed:%s,%d",
|
||||
strerror(errno), errno);
|
||||
|
||||
}
|
||||
|
||||
static int create_gril(struct ofono_modem *modem)
|
||||
static int ril_enable(struct ofono_modem *modem)
|
||||
{
|
||||
DBG(" modem: %p", modem);
|
||||
DBG("enter");
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
|
||||
ril->have_sim = FALSE;
|
||||
@@ -497,7 +469,6 @@ static int create_gril(struct ofono_modem *modem)
|
||||
ril_switchUser();
|
||||
|
||||
ril->modem = g_ril_new();
|
||||
|
||||
g_ril_set_disconnect_function(ril->modem, gril_disconnected, modem);
|
||||
|
||||
/* NOTE: Since AT modems open a tty, and then call
|
||||
@@ -510,6 +481,7 @@ static int create_gril(struct ofono_modem *modem)
|
||||
|
||||
if (ril->modem == NULL) {
|
||||
DBG("g_ril_new() failed to create modem!");
|
||||
gril_disconnected(modem);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -524,39 +496,22 @@ static int create_gril(struct ofono_modem *modem)
|
||||
|
||||
ofono_devinfo_create(modem, 0, "rilmodem", ril->modem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ril_enable(struct ofono_modem *modem)
|
||||
{
|
||||
int ret;
|
||||
DBG("");
|
||||
|
||||
ret = create_gril(modem);
|
||||
if (ret < 0) {
|
||||
DBG("create gril: %d, queue reconnect", ret);
|
||||
g_timeout_add_seconds(2,
|
||||
connect_rild, modem);
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static int ril_disable(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("%p", modem);
|
||||
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
struct parcel rilp;
|
||||
int request = RIL_REQUEST_RADIO_POWER;
|
||||
guint ret;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 1); /* size of array */
|
||||
parcel_w_int32(&rilp, 0); /* POWER=OFF */
|
||||
|
||||
ofono_info("%s: RIL_REQUEST_RADIO_POWER OFF", __func__);
|
||||
/* fire and forget i.e. not waiting for the callback*/
|
||||
ret = g_ril_send(ril->modem, request, rilp.data,
|
||||
rilp.size, NULL, NULL, NULL);
|
||||
@@ -566,10 +521,6 @@ static int ril_disable(struct ofono_modem *modem)
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
/* this will trigger the cleanup of g_io_channel */
|
||||
g_ril_unref(ril->modem);
|
||||
ril->modem = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -585,19 +536,84 @@ static struct ofono_modem_driver ril_driver = {
|
||||
.set_online = ril_set_online,
|
||||
};
|
||||
|
||||
/*
|
||||
* Note - as an aal+ container doesn't include a running udev,
|
||||
* the udevng plugin will never detect a modem, and thus modem
|
||||
* creation for a RIL-based modem needs to be hard-coded.
|
||||
*
|
||||
* Typically, udevng would create the modem, which in turn would
|
||||
* lead to this plugin's probe function being called.
|
||||
*
|
||||
* This is a first attempt at registering like this.
|
||||
*
|
||||
* IMPORTANT - this code relies on the fact that the 'rilmodem' is
|
||||
* added to top-level Makefile's builtin_modules *after* 'ril'.
|
||||
* This has means 'rilmodem' will already be registered before we try
|
||||
* to create and register the modem. In standard ofono, 'udev'/'udevng'
|
||||
* is initialized last due to the fact that it's the first module
|
||||
* added in the top-level Makefile.
|
||||
*/
|
||||
static int ril_init(void)
|
||||
{
|
||||
int retval = ofono_modem_driver_register(&ril_driver);
|
||||
if (retval)
|
||||
DBG("enter");
|
||||
int retval = 0;
|
||||
struct ofono_modem *modem;
|
||||
|
||||
if ((retval = ofono_modem_driver_register(&ril_driver))) {
|
||||
DBG("ofono_modem_driver_register returned: %d", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* everything after _modem_driver_register, is
|
||||
* non-standard ( see udev comment above ).
|
||||
* usually called by undevng::create_modem
|
||||
*
|
||||
* args are name (optional) & type
|
||||
*/
|
||||
modem = ofono_modem_create("ril_0", "ril");
|
||||
if (modem == NULL) {
|
||||
DBG("ofono_modem_create failed for ril");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* This causes driver->probe() to be called... */
|
||||
retval = ofono_modem_register(modem);
|
||||
DBG("ofono_modem_register returned: %d", retval);
|
||||
|
||||
/* kickstart the modem:
|
||||
* causes core modem code to call
|
||||
* - set_powered(TRUE) - which in turn
|
||||
* calls driver->enable()
|
||||
*
|
||||
* - driver->pre_sim()
|
||||
*
|
||||
* Could also be done via:
|
||||
*
|
||||
* - a DBus call to SetProperties w/"Powered=TRUE" *1
|
||||
* - sim_state_watch ( handles SIM removal? LOCKED states? **2
|
||||
* - ofono_modem_set_powered()
|
||||
*/
|
||||
ofono_modem_reset(modem);
|
||||
|
||||
reconnect_timer = 0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ril_exit(void)
|
||||
{
|
||||
DBG("");
|
||||
if (current_passwd)
|
||||
g_free(current_passwd);
|
||||
|
||||
g_dbus_remove_watch(connection, mce_daemon_watch);
|
||||
|
||||
if (signal_watch > 0)
|
||||
g_dbus_remove_watch(connection, signal_watch);
|
||||
|
||||
ofono_modem_driver_unregister(&ril_driver);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(ril, "RIL modem plugin", VERSION,
|
||||
OFONO_PLUGIN_DEFINE(ril, "RIL modem driver", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, ril_init, ril_exit)
|
||||
|
||||
|
||||
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2014 Canonical Ltd.
|
||||
* Copyright (C) 2015 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.
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include "rildev.h"
|
||||
|
||||
#define EVENT_SIZE (sizeof(struct inotify_event))
|
||||
/*
|
||||
* As a best guess use a buffer size of 100 inotify events.
|
||||
* NAME_MAX+1 from inotify documentation.
|
||||
*/
|
||||
#define IBUF_LEN (100*(EVENT_SIZE + NAME_MAX + 1))
|
||||
|
||||
static int inotify_fd = -1;
|
||||
static int inotify_watch_id = -1;
|
||||
static guint inotify_watch_source_id;
|
||||
static GIOChannel *inotify_watch_channel;
|
||||
|
||||
static GSList *modem_list;
|
||||
static int watch_for_rild_socket(void);
|
||||
static void detect_rild(void);
|
||||
|
||||
static struct ofono_modem *find_ril_modem(int slot)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
for (list = modem_list; list; list = list->next) {
|
||||
struct ofono_modem *modem = list->data;
|
||||
int ril_slot = ofono_modem_get_integer(modem, "Slot");
|
||||
|
||||
if (ril_slot == slot)
|
||||
return modem;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void remove_watchers(void)
|
||||
{
|
||||
DBG("");
|
||||
if (inotify_watch_channel == NULL)
|
||||
return;
|
||||
|
||||
g_source_remove(inotify_watch_source_id);
|
||||
inotify_watch_source_id = 0;
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
}
|
||||
|
||||
/* Removes a RIL modem and initiates a sequence to create a new one */
|
||||
void ril_modem_remove(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("modem: %p", modem);
|
||||
struct ofono_modem *list_modem;
|
||||
int slot = -1;
|
||||
list_modem = NULL;
|
||||
|
||||
if (modem)
|
||||
slot = ofono_modem_get_integer(modem, "Slot");
|
||||
|
||||
if (slot >= 0)
|
||||
list_modem = find_ril_modem(slot);
|
||||
|
||||
if (list_modem) {
|
||||
ofono_modem_remove(modem);
|
||||
modem_list = g_slist_remove(modem_list, list_modem);
|
||||
}
|
||||
|
||||
detect_rild();
|
||||
}
|
||||
|
||||
/* return: 0 if successful or modem already exists, otherwise and error */
|
||||
static int create_rilmodem(const char *ril_type, int slot)
|
||||
{
|
||||
struct ofono_modem *modem;
|
||||
char dev_name[64];
|
||||
int retval;
|
||||
DBG("");
|
||||
snprintf(dev_name, sizeof(dev_name), "ril_%d", slot);
|
||||
|
||||
/* Check that not created already */
|
||||
if (find_ril_modem(slot))
|
||||
return 0;
|
||||
|
||||
/* Currently there is only one ril implementation, create always */
|
||||
modem = ofono_modem_create(dev_name, ril_type);
|
||||
if (modem == NULL) {
|
||||
DBG("ofono_modem_create failed for type: %s", ril_type);
|
||||
return -ENODEV;
|
||||
}
|
||||
DBG("created modem: %p", modem);
|
||||
|
||||
modem_list = g_slist_prepend(modem_list, modem);
|
||||
|
||||
ofono_modem_set_integer(modem, "Slot", slot);
|
||||
|
||||
/* This causes driver->probe() to be called */
|
||||
retval = ofono_modem_register(modem);
|
||||
if (retval != 0) {
|
||||
ofono_error("%s: ofono_modem_register error: %d",
|
||||
__func__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try creating a ril modem
|
||||
* return: false if failed, true successful or modem already exists.
|
||||
*/
|
||||
static gboolean try_create_modem()
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
int ares = access(RILD_CMD_SOCKET, F_OK);
|
||||
if (ares != -1)
|
||||
result = !create_rilmodem("ril", 0);
|
||||
else
|
||||
DBG("problems accessing rild socket: %d", ares);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean rild_inotify(GIOChannel *gio, GIOCondition c,
|
||||
gpointer data)
|
||||
{
|
||||
DBG("");
|
||||
struct inotify_event *event = 0;
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
char *ievents = 0; /* inotify event buffer */
|
||||
gboolean result = TRUE;
|
||||
|
||||
ievents = g_try_malloc(IBUF_LEN);
|
||||
if (!ievents) {
|
||||
/* Continue observing so don't set "result" false here */
|
||||
goto end;
|
||||
}
|
||||
|
||||
length = read(inotify_fd, ievents, IBUF_LEN);
|
||||
/*
|
||||
* If iNotify fd read returns an error, just keep on watching for
|
||||
* read events.
|
||||
*/
|
||||
while (i < length) {
|
||||
event = (struct inotify_event *) &ievents[i];
|
||||
|
||||
if (event->len && (event->mask & IN_CREATE)
|
||||
&& (!(event->mask & IN_ISDIR))) {
|
||||
|
||||
DBG("File created: %s", event->name);
|
||||
if (!strcmp(event->name, RILD_SOCKET_FILE)) {
|
||||
result = !try_create_modem();
|
||||
/*
|
||||
* On modem create fail continue observing
|
||||
* events so don't set result false here.
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
i += EVENT_SIZE + event->len;
|
||||
}
|
||||
|
||||
end:
|
||||
/* "if" works around potential glib runtime warning */
|
||||
if (ievents)
|
||||
g_free(ievents);
|
||||
|
||||
if (!result)
|
||||
remove_watchers();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* return 0 if successful, otherwise an error */
|
||||
static int watch_for_rild_socket(void)
|
||||
{
|
||||
DBG("");
|
||||
inotify_fd = inotify_init();
|
||||
if (inotify_fd < 0)
|
||||
return -EIO;
|
||||
|
||||
inotify_watch_channel = g_io_channel_unix_new(inotify_fd);
|
||||
if (inotify_watch_channel == NULL) {
|
||||
ofono_error("%s: rildev gio chan creation fail!", __func__);
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
inotify_watch_id = inotify_add_watch(inotify_fd, RILD_SOCKET_DIR,
|
||||
IN_CREATE);
|
||||
if (inotify_watch_id < 0) {
|
||||
ofono_error("%s: inotify says: %d, errno: %d",
|
||||
__func__, inotify_watch_id, errno);
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
inotify_watch_source_id = g_io_add_watch(inotify_watch_channel,
|
||||
G_IO_IN,
|
||||
rild_inotify, NULL);
|
||||
if (inotify_watch_source_id <= 0) {
|
||||
ofono_error("%s: rildev add gio watch fail!", __func__);
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void detect_rild(void)
|
||||
{
|
||||
DBG("");
|
||||
gboolean created = try_create_modem();
|
||||
if (!created)
|
||||
watch_for_rild_socket();
|
||||
|
||||
/* Let's re-check if we just missed the notification */
|
||||
if (!created && try_create_modem())
|
||||
remove_watchers();
|
||||
}
|
||||
|
||||
static int detect_init(void)
|
||||
{
|
||||
DBG("");
|
||||
detect_rild();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void detect_exit(void)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
DBG("");
|
||||
|
||||
for (list = modem_list; list; list = list->next) {
|
||||
struct ofono_modem *modem = list->data;
|
||||
|
||||
ofono_modem_remove(modem);
|
||||
}
|
||||
|
||||
g_slist_free(modem_list);
|
||||
modem_list = NULL;
|
||||
remove_watchers();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(rildev, "RIL type detection", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, detect_init, detect_exit)
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2015 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.
|
||||
*
|
||||
* 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 __RILDEV_H
|
||||
#define __RILDEV_H
|
||||
|
||||
#define RILD_CMD_SOCKET "/dev/socket/rild"
|
||||
#define RILD_SOCKET_DIR "/dev/socket"
|
||||
#define RILD_SOCKET_FILE "rild"
|
||||
|
||||
|
||||
void ril_modem_remove(struct ofono_modem *modem);
|
||||
|
||||
#endif /* __RILDEV_H */
|
||||
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2014 Philip Paeps. 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 <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gatchat.h>
|
||||
#include <gattty.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/devinfo.h>
|
||||
#include <ofono/netreg.h>
|
||||
#include <ofono/sim.h>
|
||||
#include <ofono/gprs.h>
|
||||
#include <ofono/gprs-context.h>
|
||||
|
||||
#include <drivers/atmodem/atutil.h>
|
||||
#include <drivers/atmodem/vendor.h>
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
|
||||
struct ublox_data {
|
||||
GAtChat *modem;
|
||||
GAtChat *aux;
|
||||
};
|
||||
|
||||
static void ublox_debug(const char *str, void *user_data)
|
||||
{
|
||||
const char *prefix = user_data;
|
||||
|
||||
ofono_info("%s%s", prefix, str);
|
||||
}
|
||||
|
||||
static int ublox_probe(struct ofono_modem *modem)
|
||||
{
|
||||
struct ublox_data *data;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
data = g_try_new0(struct ublox_data, 1);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ofono_modem_set_data(modem, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ublox_remove(struct ofono_modem *modem)
|
||||
{
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
ofono_modem_set_data(modem, NULL);
|
||||
g_at_chat_unref(data->aux);
|
||||
g_at_chat_unref(data->modem);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static GAtChat *open_device(struct ofono_modem *modem,
|
||||
const char *key, char *debug)
|
||||
{
|
||||
const char *device;
|
||||
GAtSyntax *syntax;
|
||||
GIOChannel *channel;
|
||||
GAtChat *chat;
|
||||
|
||||
device = ofono_modem_get_string(modem, key);
|
||||
if (device == NULL)
|
||||
return NULL;
|
||||
|
||||
DBG("%s %s", key, device);
|
||||
|
||||
channel = g_at_tty_open(device, NULL);
|
||||
if (channel == NULL)
|
||||
return NULL;
|
||||
|
||||
syntax = g_at_syntax_new_gsm_permissive();
|
||||
chat = g_at_chat_new(channel, syntax);
|
||||
g_at_syntax_unref(syntax);
|
||||
|
||||
g_io_channel_unref(channel);
|
||||
|
||||
if (chat == NULL)
|
||||
return NULL;
|
||||
|
||||
if (getenv("OFONO_AT_DEBUG"))
|
||||
g_at_chat_set_debug(chat, ublox_debug, debug);
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct ublox_data * data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("ok %d", ok);
|
||||
|
||||
if (!ok) {
|
||||
g_at_chat_unref(data->aux);
|
||||
data->aux = NULL;
|
||||
g_at_chat_unref(data->modem);
|
||||
data->modem = NULL;
|
||||
ofono_modem_set_powered(modem, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
ofono_modem_set_powered(modem, TRUE);
|
||||
}
|
||||
|
||||
static int ublox_enable(struct ofono_modem *modem)
|
||||
{
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
data->modem = open_device(modem, "Modem", "Modem: ");
|
||||
if (data->modem == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
data->aux = open_device(modem, "Aux", "Aux: ");
|
||||
if (data->aux == NULL) {
|
||||
g_at_chat_unref(data->modem);
|
||||
data->modem = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
g_at_chat_set_slave(data->modem, data->aux);
|
||||
|
||||
g_at_chat_send(data->modem, "ATE0 +CMEE=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
g_at_chat_send(data->aux, "ATE0 +CMEE=1", none_prefix,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_at_chat_send(data->aux, "AT+CFUN=4", none_prefix,
|
||||
cfun_enable, modem, NULL);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("");
|
||||
|
||||
g_at_chat_unref(data->aux);
|
||||
data->aux = NULL;
|
||||
|
||||
if (ok)
|
||||
ofono_modem_set_powered(modem, FALSE);
|
||||
}
|
||||
|
||||
static int ublox_disable(struct ofono_modem *modem)
|
||||
{
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
g_at_chat_cancel_all(data->modem);
|
||||
g_at_chat_unregister_all(data->modem);
|
||||
g_at_chat_unref(data->modem);
|
||||
data->modem = NULL;
|
||||
|
||||
g_at_chat_cancel_all(data->aux);
|
||||
g_at_chat_unregister_all(data->aux);
|
||||
|
||||
g_at_chat_send(data->aux, "AT+CFUN=0", none_prefix,
|
||||
cfun_disable, modem, NULL);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_modem_online_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void ublox_set_online(struct ofono_modem *modem, ofono_bool_t online,
|
||||
ofono_modem_online_cb_t cb, void *user_data)
|
||||
{
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
struct cb_data *cbd = cb_data_new(cb, user_data);
|
||||
char const *command = online ? "AT+CFUN=1" : "AT+CFUN=4";
|
||||
|
||||
DBG("modem %p %s", modem, online ? "online" : "offline");
|
||||
|
||||
if (g_at_chat_send(data->aux, command, none_prefix, set_online_cb,
|
||||
cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static void ublox_pre_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_sim *sim;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
ofono_devinfo_create(modem, 0, "atmodem", data->aux);
|
||||
sim = ofono_sim_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
|
||||
data->aux);
|
||||
|
||||
if (sim)
|
||||
ofono_sim_inserted_notify(sim, TRUE);
|
||||
}
|
||||
|
||||
static void ublox_post_sim(struct ofono_modem *modem)
|
||||
{
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
struct ofono_gprs *gprs;
|
||||
struct ofono_gprs_context *gc;
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
gprs = ofono_gprs_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
|
||||
data->aux);
|
||||
gc = ofono_gprs_context_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
|
||||
data->modem);
|
||||
|
||||
if (gprs && gc)
|
||||
ofono_gprs_add_context(gprs, gc);
|
||||
}
|
||||
|
||||
static void ublox_post_online(struct ofono_modem *modem)
|
||||
{
|
||||
struct ublox_data *data = ofono_modem_get_data(modem);
|
||||
|
||||
ofono_netreg_create(modem, 0, "atmodem", data->aux);
|
||||
}
|
||||
|
||||
static struct ofono_modem_driver ublox_driver = {
|
||||
.name = "ublox",
|
||||
.probe = ublox_probe,
|
||||
.remove = ublox_remove,
|
||||
.enable = ublox_enable,
|
||||
.disable = ublox_disable,
|
||||
.set_online = ublox_set_online,
|
||||
.pre_sim = ublox_pre_sim,
|
||||
.post_sim = ublox_post_sim,
|
||||
.post_online = ublox_post_online,
|
||||
};
|
||||
|
||||
static int ublox_init(void)
|
||||
{
|
||||
return ofono_modem_driver_register(&ublox_driver);
|
||||
}
|
||||
|
||||
static void ublox_exit(void)
|
||||
{
|
||||
ofono_modem_driver_unregister(&ublox_driver);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(ublox, "u-blox modem driver", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, ublox_init, ublox_exit)
|
||||
@@ -636,7 +636,7 @@ static gboolean setup_telit(struct modem_info *modem)
|
||||
|
||||
static gboolean setup_he910(struct modem_info *modem)
|
||||
{
|
||||
const char *mdm = NULL, *aux = NULL, *gps = NULL;
|
||||
const char *mdm = NULL, *aux = NULL;
|
||||
GSList *list;
|
||||
|
||||
DBG("%s", modem->syspath);
|
||||
@@ -652,19 +652,16 @@ static gboolean setup_he910(struct modem_info *modem)
|
||||
mdm = info->devnode;
|
||||
else if (g_strcmp0(info->number, "06") == 0)
|
||||
aux = info->devnode;
|
||||
else if (g_strcmp0(info->number, "0a") == 0)
|
||||
gps = info->devnode;
|
||||
}
|
||||
}
|
||||
|
||||
if (aux == NULL || mdm == NULL)
|
||||
return FALSE;
|
||||
|
||||
DBG("modem=%s aux=%s gps=%s", mdm, aux, gps);
|
||||
DBG("modem=%s aux=%s", mdm, aux);
|
||||
|
||||
ofono_modem_set_string(modem->modem, "Modem", mdm);
|
||||
ofono_modem_set_string(modem->modem, "Aux", aux);
|
||||
ofono_modem_set_string(modem->modem, "GPS", gps);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -794,86 +791,6 @@ static gboolean setup_samsung(struct modem_info *modem)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean setup_quectel(struct modem_info *modem)
|
||||
{
|
||||
const char *aux = NULL, *mdm = NULL;
|
||||
GSList *list;
|
||||
|
||||
DBG("%s", modem->syspath);
|
||||
|
||||
for (list = modem->devices; list; list = list->next) {
|
||||
struct device_info *info = list->data;
|
||||
|
||||
DBG("%s %s %s %s", info->devnode, info->interface,
|
||||
info->number, info->label);
|
||||
|
||||
if (g_strcmp0(info->label, "aux") == 0) {
|
||||
aux = info->devnode;
|
||||
if (mdm != NULL)
|
||||
break;
|
||||
} else if (g_strcmp0(info->label, "modem") == 0) {
|
||||
mdm = info->devnode;
|
||||
if (aux != NULL)
|
||||
break;
|
||||
} else if (g_strcmp0(info->interface, "255/255/255") == 0) {
|
||||
if (g_strcmp0(info->number, "02") == 0)
|
||||
aux = info->devnode;
|
||||
else if (g_strcmp0(info->number, "03") == 0)
|
||||
mdm = info->devnode;
|
||||
}
|
||||
}
|
||||
|
||||
if (aux == NULL || mdm == NULL)
|
||||
return FALSE;
|
||||
|
||||
DBG("aux=%s modem=%s", aux, mdm);
|
||||
|
||||
ofono_modem_set_string(modem->modem, "Aux", aux);
|
||||
ofono_modem_set_string(modem->modem, "Modem", mdm);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean setup_ublox(struct modem_info *modem)
|
||||
{
|
||||
const char *aux = NULL, *mdm = NULL;
|
||||
GSList *list;
|
||||
|
||||
DBG("%s", modem->syspath);
|
||||
|
||||
for (list = modem->devices; list; list = list->next) {
|
||||
struct device_info *info = list->data;
|
||||
|
||||
DBG("%s %s %s %s", info->devnode, info->interface,
|
||||
info->number, info->label);
|
||||
|
||||
if (g_strcmp0(info->label, "aux") == 0) {
|
||||
aux = info->devnode;
|
||||
if (mdm != NULL)
|
||||
break;
|
||||
} else if (g_strcmp0(info->label, "modem") == 0) {
|
||||
mdm = info->devnode;
|
||||
if (aux != NULL)
|
||||
break;
|
||||
} else if (g_strcmp0(info->interface, "2/2/1") == 0) {
|
||||
if (g_strcmp0(info->number, "02") == 0)
|
||||
aux = info->devnode;
|
||||
else if (g_strcmp0(info->number, "00") == 0)
|
||||
mdm = info->devnode;
|
||||
}
|
||||
}
|
||||
|
||||
if (aux == NULL || mdm == NULL)
|
||||
return FALSE;
|
||||
|
||||
DBG("aux=%s modem=%s", aux, mdm);
|
||||
|
||||
ofono_modem_set_string(modem->modem, "Aux", aux);
|
||||
ofono_modem_set_string(modem->modem, "Modem", mdm);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
gboolean (*setup)(struct modem_info *modem);
|
||||
@@ -898,8 +815,6 @@ static struct {
|
||||
{ "zte", setup_zte },
|
||||
{ "icera", setup_icera },
|
||||
{ "samsung", setup_samsung },
|
||||
{ "quectel", setup_quectel },
|
||||
{ "ublox", setup_ublox },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1111,8 +1026,6 @@ static struct {
|
||||
{ "nokia", "option", "0421", "0623" },
|
||||
{ "samsung", "option", "04e8", "6889" },
|
||||
{ "samsung", "kalmia" },
|
||||
{ "quectel", "option", "05c6", "9090" },
|
||||
{ "ublox", "cdc_acm", "1546", "1102" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -411,12 +411,9 @@ static void set_new_cond_list(struct ofono_call_forwarding *cf,
|
||||
number = phone_number_to_string(
|
||||
&lc->phone_number);
|
||||
|
||||
snprintf(attr, sizeof(attr), "%s%s",
|
||||
bearer_class_to_string(lc->cls), cf_type_lut[i]);
|
||||
|
||||
ofono_dbus_signal_property_changed(conn, path,
|
||||
OFONO_CALL_FORWARDING_INTERFACE,
|
||||
attr,
|
||||
cf_type_lut[i],
|
||||
DBUS_TYPE_STRING, &number);
|
||||
}
|
||||
|
||||
@@ -716,12 +713,8 @@ static DBusMessage *set_property_request(struct ofono_call_forwarding *cf,
|
||||
if (ph->number[0] != '\0')
|
||||
cf->driver->registration(cf, type, cls, ph, timeout,
|
||||
set_property_callback, cf);
|
||||
else {
|
||||
if (cf->query_next == CALL_FORWARDING_TYPE_UNCONDITIONAL)
|
||||
cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
|
||||
|
||||
else
|
||||
cf->driver->erasure(cf, type, cls, set_property_callback, cf);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ struct error_mapping_entry cme_errors_mapping[] = {
|
||||
};
|
||||
|
||||
static void append_variant(DBusMessageIter *iter,
|
||||
int type, const void *value)
|
||||
int type, void *value)
|
||||
{
|
||||
char sig[2];
|
||||
DBusMessageIter valueiter;
|
||||
@@ -65,7 +65,7 @@ static void append_variant(DBusMessageIter *iter,
|
||||
}
|
||||
|
||||
void ofono_dbus_dict_append(DBusMessageIter *dict,
|
||||
const char *key, int type, const void *value)
|
||||
const char *key, int type, void *value)
|
||||
{
|
||||
DBusMessageIter keyiter;
|
||||
|
||||
@@ -85,8 +85,7 @@ void ofono_dbus_dict_append(DBusMessageIter *dict,
|
||||
dbus_message_iter_close_container(dict, &keyiter);
|
||||
}
|
||||
|
||||
static void append_array_variant(DBusMessageIter *iter, int type,
|
||||
const void *val)
|
||||
static void append_array_variant(DBusMessageIter *iter, int type, void *val)
|
||||
{
|
||||
DBusMessageIter variant, array;
|
||||
char typesig[2];
|
||||
@@ -114,7 +113,7 @@ static void append_array_variant(DBusMessageIter *iter, int type,
|
||||
}
|
||||
|
||||
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||
int type, const void *val)
|
||||
int type, void *val)
|
||||
{
|
||||
DBusMessageIter entry;
|
||||
|
||||
@@ -128,8 +127,7 @@ void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||
dbus_message_iter_close_container(dict, &entry);
|
||||
}
|
||||
|
||||
static void append_dict_variant(DBusMessageIter *iter, int type,
|
||||
const void *val)
|
||||
static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
|
||||
{
|
||||
DBusMessageIter variant, array, entry;
|
||||
char typesig[5];
|
||||
@@ -184,7 +182,7 @@ static void append_dict_variant(DBusMessageIter *iter, int type,
|
||||
}
|
||||
|
||||
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
||||
int type, const void *val)
|
||||
int type, void *val)
|
||||
{
|
||||
DBusMessageIter entry;
|
||||
|
||||
@@ -202,7 +200,7 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, const void *value)
|
||||
int type, void *value)
|
||||
{
|
||||
DBusMessage *signal;
|
||||
DBusMessageIter iter;
|
||||
@@ -227,7 +225,7 @@ int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, const void *value)
|
||||
int type, void *value)
|
||||
|
||||
{
|
||||
DBusMessage *signal;
|
||||
@@ -253,7 +251,7 @@ int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, const void *value)
|
||||
int type, void *value)
|
||||
|
||||
{
|
||||
DBusMessage *signal;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@@ -43,18 +42,17 @@ struct ofono_emulator {
|
||||
enum ofono_emulator_type type;
|
||||
GAtServer *server;
|
||||
GAtPPP *ppp;
|
||||
gboolean slc;
|
||||
int l_features;
|
||||
int r_features;
|
||||
int events_mode;
|
||||
gboolean events_ind;
|
||||
unsigned char cmee_mode;
|
||||
GSList *indicators;
|
||||
guint callsetup_source;
|
||||
gboolean clip;
|
||||
gboolean ccwa;
|
||||
int pns_id;
|
||||
bool slc : 1;
|
||||
unsigned int events_mode : 2;
|
||||
bool events_ind : 1;
|
||||
unsigned int cmee_mode : 2;
|
||||
bool clip : 1;
|
||||
bool ccwa : 1;
|
||||
bool ddr_active : 1;
|
||||
};
|
||||
|
||||
struct indicator {
|
||||
@@ -455,7 +453,7 @@ static void brsf_cb(GAtServer *server, GAtServerRequestType type,
|
||||
if (g_at_result_iter_next_number(&iter, &val) == FALSE)
|
||||
goto fail;
|
||||
|
||||
if (val < 0 || val > 0xffff)
|
||||
if (val < 0 || val > 255)
|
||||
goto fail;
|
||||
|
||||
em->r_features = val;
|
||||
@@ -638,8 +636,7 @@ done:
|
||||
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
|
||||
|
||||
__ofono_emulator_slc_condition(em,
|
||||
OFONO_EMULATOR_SLC_CONDITION_CMER);
|
||||
em->slc = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -829,113 +826,6 @@ fail:
|
||||
}
|
||||
}
|
||||
|
||||
static void bind_cb(GAtServer *server, GAtServerRequestType type,
|
||||
GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_emulator *em = user_data;
|
||||
char buf[128];
|
||||
|
||||
switch (type) {
|
||||
case G_AT_SERVER_REQUEST_TYPE_QUERY:
|
||||
g_at_server_send_info(em->server, "+BIND: 1,1", TRUE);
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
|
||||
|
||||
__ofono_emulator_slc_condition(em,
|
||||
OFONO_EMULATOR_SLC_CONDITION_BIND);
|
||||
break;
|
||||
|
||||
case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
|
||||
sprintf(buf, "+BIND: (1)");
|
||||
g_at_server_send_info(em->server, buf, TRUE);
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
|
||||
break;
|
||||
|
||||
case G_AT_SERVER_REQUEST_TYPE_SET:
|
||||
{
|
||||
GAtResultIter iter;
|
||||
int hf_indicator;
|
||||
int num_hf_indicators = 0;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
g_at_result_iter_next(&iter, "");
|
||||
|
||||
/* check validity of the request */
|
||||
while (num_hf_indicators < 20 &&
|
||||
g_at_result_iter_next_number(&iter,
|
||||
&hf_indicator)) {
|
||||
if (hf_indicator > 0xffff)
|
||||
goto fail;
|
||||
|
||||
num_hf_indicators += 1;
|
||||
}
|
||||
|
||||
/* Check that we have nothing extra in the stream */
|
||||
if (g_at_result_iter_skip_next(&iter) == TRUE)
|
||||
goto fail;
|
||||
|
||||
/* request is valid, update the indicator activation status */
|
||||
g_at_result_iter_init(&iter, result);
|
||||
g_at_result_iter_next(&iter, "");
|
||||
|
||||
while (g_at_result_iter_next_number(&iter, &hf_indicator))
|
||||
ofono_info("HF supports indicator: 0x%04x",
|
||||
hf_indicator);
|
||||
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fail:
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void biev_cb(GAtServer *server, GAtServerRequestType type,
|
||||
GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct ofono_emulator *em = user_data;
|
||||
|
||||
switch (type) {
|
||||
case G_AT_SERVER_REQUEST_TYPE_SET:
|
||||
{
|
||||
GAtResultIter iter;
|
||||
int hf_indicator;
|
||||
int val;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
g_at_result_iter_next(&iter, "");
|
||||
|
||||
if (g_at_result_iter_next_number(&iter, &hf_indicator) == FALSE)
|
||||
goto fail;
|
||||
|
||||
if (hf_indicator != HFP_HF_INDICATOR_ENHANCED_SAFETY)
|
||||
goto fail;
|
||||
|
||||
if (em->ddr_active == FALSE)
|
||||
goto fail;
|
||||
|
||||
if (g_at_result_iter_next_number(&iter, &val) == FALSE)
|
||||
goto fail;
|
||||
|
||||
if (val < 0 || val > 1)
|
||||
goto fail;
|
||||
|
||||
ofono_info("Enhanced Safety indicator: %d", val);
|
||||
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fail:
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void emulator_add_indicator(struct ofono_emulator *em, const char* name,
|
||||
int min, int max, int dflt,
|
||||
gboolean mandatory)
|
||||
@@ -1016,8 +906,6 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
em);
|
||||
|
||||
if (em->type == OFONO_EMULATOR_TYPE_HFP) {
|
||||
em->ddr_active = true;
|
||||
|
||||
emulator_add_indicator(em, OFONO_EMULATOR_IND_SERVICE, 0, 1, 0,
|
||||
FALSE);
|
||||
emulator_add_indicator(em, OFONO_EMULATOR_IND_CALL, 0, 1, 0,
|
||||
@@ -1040,8 +928,6 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
g_at_server_register(em->server, "+CCWA", ccwa_cb, em, NULL);
|
||||
g_at_server_register(em->server, "+CMEE", cmee_cb, em, NULL);
|
||||
g_at_server_register(em->server, "+BIA", bia_cb, em, NULL);
|
||||
g_at_server_register(em->server, "+BIND", bind_cb, em, NULL);
|
||||
g_at_server_register(em->server, "+BIEV", biev_cb, em, NULL);
|
||||
}
|
||||
|
||||
__ofono_atom_register(em->atom, emulator_unregister);
|
||||
@@ -1095,7 +981,6 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
||||
em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_STATUS;
|
||||
em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_CONTROL;
|
||||
em->l_features |= HFP_AG_FEATURE_EXTENDED_RES_CODE;
|
||||
em->l_features |= HFP_AG_FEATURE_HF_INDICATORS;
|
||||
em->events_mode = 3; /* default mode is forwarding events */
|
||||
em->cmee_mode = 0; /* CME ERROR disabled by default */
|
||||
|
||||
@@ -1187,11 +1072,16 @@ struct ofono_emulator_request {
|
||||
};
|
||||
|
||||
static void handler_proxy(GAtServer *server, GAtServerRequestType type,
|
||||
GAtResult *result, gpointer userdata)
|
||||
GAtResult *result, gpointer userdata)
|
||||
{
|
||||
struct handler *h = userdata;
|
||||
struct ofono_emulator_request req;
|
||||
|
||||
if (h->em->type == OFONO_EMULATOR_TYPE_HFP && h->em->slc == FALSE) {
|
||||
g_at_server_send_final(h->em->server, G_AT_SERVER_RESULT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
|
||||
req.type = OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY;
|
||||
@@ -1212,33 +1102,6 @@ static void handler_proxy(GAtServer *server, GAtServerRequestType type,
|
||||
h->cb(h->em, &req, h->data);
|
||||
}
|
||||
|
||||
static void handler_proxy_need_slc(GAtServer *server,
|
||||
GAtServerRequestType type,
|
||||
GAtResult *result, gpointer userdata)
|
||||
{
|
||||
struct handler *h = userdata;
|
||||
|
||||
if (h->em->slc == FALSE) {
|
||||
g_at_server_send_final(h->em->server, G_AT_SERVER_RESULT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
handler_proxy(server, type, result, userdata);
|
||||
}
|
||||
|
||||
static void handler_proxy_chld(GAtServer *server, GAtServerRequestType type,
|
||||
GAtResult *result, gpointer userdata)
|
||||
{
|
||||
struct handler *h = userdata;
|
||||
|
||||
if (h->em->slc == FALSE && type != G_AT_SERVER_REQUEST_TYPE_SUPPORT) {
|
||||
g_at_server_send_final(h->em->server, G_AT_SERVER_RESULT_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
handler_proxy(server, type, result, userdata);
|
||||
}
|
||||
|
||||
static void handler_destroy(gpointer userdata)
|
||||
{
|
||||
struct handler *h = userdata;
|
||||
@@ -1255,7 +1118,6 @@ ofono_bool_t ofono_emulator_add_handler(struct ofono_emulator *em,
|
||||
void *data, ofono_destroy_func destroy)
|
||||
{
|
||||
struct handler *h;
|
||||
GAtServerNotifyFunc func = handler_proxy;
|
||||
|
||||
h = g_new0(struct handler, 1);
|
||||
h->cb = cb;
|
||||
@@ -1263,14 +1125,7 @@ ofono_bool_t ofono_emulator_add_handler(struct ofono_emulator *em,
|
||||
h->destroy = destroy;
|
||||
h->em = em;
|
||||
|
||||
if (em->type == OFONO_EMULATOR_TYPE_HFP) {
|
||||
func = handler_proxy_need_slc;
|
||||
|
||||
if (!strcmp(prefix, "+CHLD"))
|
||||
func = handler_proxy_chld;
|
||||
}
|
||||
|
||||
if (g_at_server_register(em->server, prefix, func, h,
|
||||
if (g_at_server_register(em->server, prefix, handler_proxy, h,
|
||||
handler_destroy) == TRUE)
|
||||
return TRUE;
|
||||
|
||||
@@ -1411,52 +1266,3 @@ void __ofono_emulator_set_indicator_forced(struct ofono_emulator *em,
|
||||
ind->deferred = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void __ofono_emulator_slc_condition(struct ofono_emulator *em,
|
||||
enum ofono_emulator_slc_condition cond)
|
||||
{
|
||||
if (em->slc == TRUE)
|
||||
return;
|
||||
|
||||
switch (cond) {
|
||||
case OFONO_EMULATOR_SLC_CONDITION_CMER:
|
||||
if ((em->r_features & HFP_HF_FEATURE_3WAY) &&
|
||||
(em->l_features & HFP_AG_FEATURE_3WAY))
|
||||
return;
|
||||
/* Fall Through */
|
||||
|
||||
case OFONO_EMULATOR_SLC_CONDITION_CHLD:
|
||||
if ((em->r_features & HFP_HF_FEATURE_HF_INDICATORS) &&
|
||||
(em->l_features & HFP_HF_FEATURE_HF_INDICATORS))
|
||||
return;
|
||||
/* Fall Through */
|
||||
|
||||
case OFONO_EMULATOR_SLC_CONDITION_BIND:
|
||||
ofono_info("SLC reached");
|
||||
em->slc = TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_emulator_set_hf_indicator_active(struct ofono_emulator *em,
|
||||
int indicator,
|
||||
ofono_bool_t active)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (!(em->l_features & HFP_HF_FEATURE_HF_INDICATORS))
|
||||
return;
|
||||
|
||||
if (!(em->r_features & HFP_HF_FEATURE_HF_INDICATORS))
|
||||
return;
|
||||
|
||||
if (indicator != HFP_HF_INDICATOR_ENHANCED_SAFETY)
|
||||
return;
|
||||
|
||||
em->ddr_active = active;
|
||||
|
||||
sprintf(buf, "+BIND: %d,%d", HFP_HF_INDICATOR_ENHANCED_SAFETY, active);
|
||||
g_at_server_send_unsolicited(em->server, buf);
|
||||
}
|
||||
|
||||
411
ofono/src/gprs.c
411
ofono/src/gprs.c
@@ -57,8 +57,6 @@
|
||||
#define MAX_MESSAGE_CENTER_LENGTH 255
|
||||
#define MAX_CONTEXTS 256
|
||||
#define SUSPEND_TIMEOUT 8
|
||||
#define MAX_MMS_MTU 1280
|
||||
#define MAX_GPRS_MTU 1280
|
||||
|
||||
/* 27.007 Section 7.29 */
|
||||
enum packet_bearer {
|
||||
@@ -151,8 +149,6 @@ struct pri_context {
|
||||
|
||||
static void gprs_netreg_update(struct ofono_gprs *gprs);
|
||||
static void gprs_deactivate_next(struct ofono_gprs *gprs);
|
||||
static void write_context_settings(struct ofono_gprs *gprs,
|
||||
struct pri_context *context);
|
||||
|
||||
static GSList *g_drivers = NULL;
|
||||
static GSList *g_context_drivers = NULL;
|
||||
@@ -268,32 +264,6 @@ static gboolean gprs_proto_from_string(const char *str,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const char *gprs_auth_method_to_string(enum ofono_gprs_auth_method auth)
|
||||
{
|
||||
switch (auth) {
|
||||
case OFONO_GPRS_AUTH_METHOD_CHAP:
|
||||
return "chap";
|
||||
case OFONO_GPRS_AUTH_METHOD_PAP:
|
||||
return "pap";
|
||||
};
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean gprs_auth_method_from_string(const char *str,
|
||||
enum ofono_gprs_auth_method *auth)
|
||||
{
|
||||
if (g_str_equal(str, "chap")) {
|
||||
*auth = OFONO_GPRS_AUTH_METHOD_CHAP;
|
||||
return TRUE;
|
||||
} else if (g_str_equal(str, "pap")) {
|
||||
*auth = OFONO_GPRS_AUTH_METHOD_PAP;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static unsigned int gprs_cid_alloc(struct ofono_gprs *gprs)
|
||||
{
|
||||
return idmap_alloc(gprs->cid_map);
|
||||
@@ -589,16 +559,13 @@ static void pri_context_signal_settings(struct pri_context *ctx,
|
||||
context_settings_append_ipv6);
|
||||
}
|
||||
|
||||
static gboolean pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
static void pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
{
|
||||
char *scheme, *host, *port, *path;
|
||||
|
||||
if (proxy[0] == 0)
|
||||
return FALSE;
|
||||
|
||||
scheme = g_strdup(proxy);
|
||||
if (scheme == NULL)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
host = strstr(scheme, "://");
|
||||
if (host != NULL) {
|
||||
@@ -611,7 +578,7 @@ static gboolean pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
ctx->proxy_port = 80;
|
||||
else {
|
||||
g_free(scheme);
|
||||
return FALSE;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
host = scheme;
|
||||
@@ -633,16 +600,10 @@ static gboolean pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
}
|
||||
}
|
||||
|
||||
if (host[0] == 0) {
|
||||
g_free(scheme);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free(ctx->proxy_host);
|
||||
ctx->proxy_host = g_strdup(host);
|
||||
|
||||
g_free(scheme);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void pri_ifupdown(const char *interface, ofono_bool_t active)
|
||||
@@ -728,16 +689,11 @@ static void pri_setproxy(const char *interface, const char *proxy)
|
||||
{
|
||||
struct rtentry rt;
|
||||
struct sockaddr_in addr;
|
||||
in_addr_t proxy_addr;
|
||||
int sk;
|
||||
|
||||
if (interface == NULL)
|
||||
return;
|
||||
|
||||
proxy_addr = inet_addr(proxy);
|
||||
if (proxy_addr == INADDR_NONE)
|
||||
return;
|
||||
|
||||
sk = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (sk < 0)
|
||||
return;
|
||||
@@ -748,7 +704,7 @@ static void pri_setproxy(const char *interface, const char *proxy)
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = proxy_addr;
|
||||
addr.sin_addr.s_addr = inet_addr(proxy);
|
||||
memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
@@ -802,31 +758,6 @@ static void pri_reset_context_settings(struct pri_context *ctx)
|
||||
g_free(interface);
|
||||
}
|
||||
|
||||
static void pri_limit_mtu(const char *interface, int max_mtu)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int sk;
|
||||
|
||||
if (interface == NULL)
|
||||
return;
|
||||
|
||||
sk = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (sk < 0)
|
||||
return;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, interface, IFNAMSIZ);
|
||||
|
||||
if (ioctl(sk, SIOCGIFMTU, &ifr) < 0 || ifr.ifr_mtu > max_mtu) {
|
||||
ifr.ifr_mtu = max_mtu;
|
||||
|
||||
if (ioctl(sk, SIOCSIFMTU, &ifr) < 0)
|
||||
ofono_error("Failed to set MTU");
|
||||
}
|
||||
|
||||
close(sk);
|
||||
}
|
||||
|
||||
static void pri_update_mms_context_settings(struct pri_context *ctx)
|
||||
{
|
||||
struct ofono_gprs_context *gc = ctx->context_driver;
|
||||
@@ -835,8 +766,7 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
|
||||
if (ctx->message_proxy)
|
||||
settings->ipv4->proxy = g_strdup(ctx->message_proxy);
|
||||
|
||||
if (!pri_parse_proxy(ctx, ctx->message_proxy))
|
||||
pri_parse_proxy(ctx, ctx->message_center);
|
||||
pri_parse_proxy(ctx, ctx->message_proxy);
|
||||
|
||||
DBG("proxy %s port %u", ctx->proxy_host, ctx->proxy_port);
|
||||
|
||||
@@ -844,195 +774,6 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
|
||||
|
||||
if (ctx->proxy_host)
|
||||
pri_setproxy(settings->interface, ctx->proxy_host);
|
||||
|
||||
pri_limit_mtu(settings->interface, MAX_MMS_MTU);
|
||||
}
|
||||
|
||||
static gboolean pri_str_changed(const char *val, const char *newval)
|
||||
{
|
||||
return newval ? (strcmp(val, newval) != 0) : (val[0] != 0);
|
||||
}
|
||||
|
||||
static gboolean pri_str_update(char *val, const char *newval,
|
||||
const int maxlen)
|
||||
{
|
||||
DBG("oldval: %s, newval: %s, mmaxlen: %d", val, newval, maxlen);
|
||||
|
||||
if (newval) {
|
||||
if (strcmp(val, newval)) {
|
||||
strncpy(val, newval, maxlen);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (val[0]) {
|
||||
val[0] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void pri_str_signal_change(struct pri_context *ctx,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
ofono_dbus_signal_property_changed(ofono_dbus_get_connection(),
|
||||
ctx->path, OFONO_CONNECTION_CONTEXT_INTERFACE,
|
||||
name, DBUS_TYPE_STRING, &value);
|
||||
}
|
||||
|
||||
static void pri_reset_context_properties(struct pri_context *ctx,
|
||||
const struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
struct ofono_gprs *gprs = ctx->gprs;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
DBG("%s", ctx->path);
|
||||
|
||||
if (strcmp(ctx->context.apn, ap->apn)) {
|
||||
changed = TRUE;
|
||||
strcpy(ctx->context.apn, ap->apn);
|
||||
pri_str_signal_change(ctx, "AccessPointName",
|
||||
ctx->context.apn);
|
||||
}
|
||||
if (ap->name && pri_str_update(ctx->name, ap->name,
|
||||
sizeof(ctx->name))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Name", ctx->name);
|
||||
}
|
||||
|
||||
if (pri_str_update(ctx->context.username, ap->username,
|
||||
sizeof(ctx->context.username))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Username", ctx->context.username);
|
||||
}
|
||||
|
||||
if (pri_str_update(ctx->context.password, ap->password,
|
||||
sizeof(ctx->context.password))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Password", ctx->context.password);
|
||||
}
|
||||
|
||||
if (ctx->context.proto != ap->proto) {
|
||||
ctx->context.proto = ap->proto;
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Protocol",
|
||||
gprs_proto_to_string(ctx->context.proto));
|
||||
}
|
||||
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||
if (pri_str_update(ctx->message_proxy, ap->message_proxy,
|
||||
sizeof(ctx->message_proxy))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "MessageProxy",
|
||||
ctx->message_proxy);
|
||||
}
|
||||
|
||||
if (pri_str_update(ctx->message_center, ap->message_center,
|
||||
sizeof(ctx->message_center))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "MessageCenter",
|
||||
ctx->message_center);
|
||||
}
|
||||
}
|
||||
|
||||
if (gprs->settings && changed) {
|
||||
write_context_settings(gprs, ctx);
|
||||
storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ap_valid(const struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
if (!ap->apn || strlen(ap->apn) > OFONO_GPRS_MAX_APN_LENGTH ||
|
||||
!is_valid_apn(ap->apn))
|
||||
return FALSE;
|
||||
|
||||
if (ap->username &&
|
||||
strlen(ap->username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
if (ap->password &&
|
||||
strlen(ap->password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
if (ap->message_proxy &&
|
||||
strlen(ap->message_proxy) > MAX_MESSAGE_PROXY_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
if (ap->message_center &&
|
||||
strlen(ap->message_center) > MAX_MESSAGE_CENTER_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean pri_deactivation_required(struct pri_context *ctx,
|
||||
const struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
if (ctx->context.proto != ap->proto)
|
||||
return TRUE;
|
||||
|
||||
if (strcmp(ctx->context.apn, ap->apn))
|
||||
return TRUE;
|
||||
|
||||
if (pri_str_changed(ctx->context.username, ap->username))
|
||||
return TRUE;
|
||||
|
||||
if (pri_str_changed(ctx->context.password, ap->password))
|
||||
return TRUE;
|
||||
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||
if (pri_str_changed(ctx->message_proxy, ap->message_proxy))
|
||||
return TRUE;
|
||||
|
||||
if (pri_str_changed(ctx->message_center, ap->message_center))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static DBusMessage *pri_provision_context(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
DBG("");
|
||||
struct pri_context *ctx = data;
|
||||
struct ofono_gprs *gprs = ctx->gprs;
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
|
||||
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
|
||||
struct ofono_gprs_provision_data *settings;
|
||||
DBusMessage *reply = NULL;
|
||||
int i, count = 0;
|
||||
|
||||
if (sim == NULL)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
if (__ofono_gprs_provision_get_settings(ofono_sim_get_mcc(sim),
|
||||
ofono_sim_get_mnc(sim), ofono_sim_get_spn(sim),
|
||||
&settings, &count) == FALSE)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const struct ofono_gprs_provision_data *ap = settings + i;
|
||||
if (ap->type == ctx->type && ap_valid(ap)) {
|
||||
if ((!ctx->active &&
|
||||
!ctx->pending && !ctx->gprs->pending) ||
|
||||
!pri_deactivation_required(ctx, ap)) {
|
||||
/* Re-provision the context */
|
||||
pri_reset_context_properties(ctx, ap);
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
} else {
|
||||
/* Context should be inactive */
|
||||
if (ctx->gprs->pending || ctx->pending)
|
||||
reply = __ofono_error_busy(msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__ofono_gprs_provision_free_settings(settings, count);
|
||||
|
||||
return reply ? reply : __ofono_error_not_available(msg);
|
||||
}
|
||||
|
||||
static void append_context_properties(struct pri_context *ctx,
|
||||
@@ -1066,10 +807,6 @@ static void append_context_properties(struct pri_context *ctx,
|
||||
ofono_dbus_dict_append(dict, "Password", DBUS_TYPE_STRING,
|
||||
&strvalue);
|
||||
|
||||
strvalue = gprs_auth_method_to_string(ctx->context.auth_method);
|
||||
ofono_dbus_dict_append(dict, "AuthenticationMethod", DBUS_TYPE_STRING,
|
||||
&strvalue);
|
||||
|
||||
if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||
strvalue = ctx->message_proxy;
|
||||
ofono_dbus_dict_append(dict, "MessageProxy",
|
||||
@@ -1144,9 +881,6 @@ static void pri_activate_callback(const struct ofono_error *error, void *data)
|
||||
|
||||
pri_context_signal_settings(ctx, gc->settings->ipv4 != NULL,
|
||||
gc->settings->ipv6 != NULL);
|
||||
|
||||
if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET)
|
||||
pri_limit_mtu(gc->settings->interface, MAX_GPRS_MTU);
|
||||
}
|
||||
|
||||
value = ctx->active;
|
||||
@@ -1415,37 +1149,6 @@ static DBusMessage *pri_set_message_center(struct pri_context *ctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DBusMessage *pri_set_auth_method(struct pri_context *ctx,
|
||||
DBusConnection *conn,
|
||||
DBusMessage *msg, const char *str)
|
||||
{
|
||||
GKeyFile *settings = ctx->gprs->settings;
|
||||
enum ofono_gprs_auth_method auth;
|
||||
|
||||
if (gprs_auth_method_from_string(str, &auth) == FALSE)
|
||||
return __ofono_error_invalid_format(msg);
|
||||
|
||||
if (ctx->context.auth_method == auth)
|
||||
return dbus_message_new_method_return(msg);
|
||||
|
||||
ctx->context.auth_method = auth;
|
||||
|
||||
if (settings) {
|
||||
g_key_file_set_string(settings, ctx->key,
|
||||
"AuthenticationMethod", str);
|
||||
storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
|
||||
}
|
||||
|
||||
g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
|
||||
|
||||
ofono_dbus_signal_property_changed(conn, ctx->path,
|
||||
OFONO_CONNECTION_CONTEXT_INTERFACE,
|
||||
"AuthenticationMethod",
|
||||
DBUS_TYPE_STRING, &str);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DBusMessage *pri_set_property(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
@@ -1556,13 +1259,6 @@ static DBusMessage *pri_set_property(DBusConnection *conn,
|
||||
dbus_message_iter_get_basic(&var, &str);
|
||||
|
||||
return pri_set_name(ctx, conn, msg, str);
|
||||
} else if (!strcmp(property, "AuthenticationMethod")) {
|
||||
if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
dbus_message_iter_get_basic(&var, &str);
|
||||
|
||||
return pri_set_auth_method(ctx, conn, msg, str);
|
||||
}
|
||||
|
||||
if (ctx->type != OFONO_GPRS_CONTEXT_TYPE_MMS)
|
||||
@@ -1594,8 +1290,6 @@ static const GDBusMethodTable context_methods[] = {
|
||||
{ GDBUS_ASYNC_METHOD("SetProperty",
|
||||
GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
|
||||
NULL, pri_set_property) },
|
||||
{ GDBUS_METHOD("ProvisionContext", NULL, NULL,
|
||||
pri_provision_context) },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -2050,8 +1744,6 @@ static DBusMessage *gprs_set_property(DBusConnection *conn,
|
||||
static void write_context_settings(struct ofono_gprs *gprs,
|
||||
struct pri_context *context)
|
||||
{
|
||||
const char *auth_method;
|
||||
|
||||
g_key_file_set_string(gprs->settings, context->key,
|
||||
"Name", context->name);
|
||||
g_key_file_set_string(gprs->settings, context->key,
|
||||
@@ -2060,11 +1752,6 @@ static void write_context_settings(struct ofono_gprs *gprs,
|
||||
"Username", context->context.username);
|
||||
g_key_file_set_string(gprs->settings, context->key,
|
||||
"Password", context->context.password);
|
||||
|
||||
auth_method = gprs_auth_method_to_string(context->context.auth_method);
|
||||
g_key_file_set_string(gprs->settings, context->key,
|
||||
"AuthenticationMethod", auth_method);
|
||||
|
||||
g_key_file_set_string(gprs->settings, context->key, "Type",
|
||||
gprs_context_type_to_string(context->type));
|
||||
g_key_file_set_string(gprs->settings, context->key, "Protocol",
|
||||
@@ -2831,29 +2518,6 @@ void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
|
||||
settings->ipv6->dns = g_strdupv((char **) dns);
|
||||
}
|
||||
|
||||
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
||||
unsigned int cid)
|
||||
{
|
||||
GSList *l;
|
||||
struct pri_context *ctx;
|
||||
|
||||
if (gc->gprs == NULL)
|
||||
return;
|
||||
|
||||
for (l = gc->gprs->contexts; l; l = l->next) {
|
||||
ctx = l->data;
|
||||
|
||||
if (ctx->context.cid != cid)
|
||||
continue;
|
||||
|
||||
if (ctx->active == FALSE)
|
||||
break;
|
||||
|
||||
pri_context_signal_settings(ctx, gc->settings->ipv4 != NULL,
|
||||
gc->settings->ipv6 != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int ofono_gprs_driver_register(const struct ofono_gprs_driver *d)
|
||||
{
|
||||
DBG("driver: %p, name: %s", d, d->name);
|
||||
@@ -3034,13 +2698,11 @@ static gboolean load_context(struct ofono_gprs *gprs, const char *group)
|
||||
char *apn = NULL;
|
||||
char *msgproxy = NULL;
|
||||
char *msgcenter = NULL;
|
||||
char *authstr = NULL;
|
||||
gboolean ret = FALSE;
|
||||
gboolean legacy = FALSE;
|
||||
struct pri_context *context;
|
||||
enum ofono_gprs_context_type type;
|
||||
enum ofono_gprs_proto proto;
|
||||
enum ofono_gprs_auth_method auth;
|
||||
unsigned int id;
|
||||
|
||||
if (sscanf(group, "context%d", &id) != 1) {
|
||||
@@ -3085,14 +2747,6 @@ static gboolean load_context(struct ofono_gprs *gprs, const char *group)
|
||||
if (password == NULL)
|
||||
goto error;
|
||||
|
||||
authstr = g_key_file_get_string(gprs->settings, group,
|
||||
"AuthenticationMethod", NULL);
|
||||
if (authstr == NULL)
|
||||
authstr = g_strdup("chap");
|
||||
|
||||
if (gprs_auth_method_from_string(authstr, &auth) == FALSE)
|
||||
goto error;
|
||||
|
||||
if (strlen(password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
|
||||
goto error;
|
||||
|
||||
@@ -3129,7 +2783,6 @@ static gboolean load_context(struct ofono_gprs *gprs, const char *group)
|
||||
strcpy(context->context.password, password);
|
||||
strcpy(context->context.apn, apn);
|
||||
context->context.proto = proto;
|
||||
context->context.auth_method = auth;
|
||||
|
||||
if (msgproxy != NULL)
|
||||
strcpy(context->message_proxy, msgproxy);
|
||||
@@ -3159,7 +2812,6 @@ error:
|
||||
g_free(apn);
|
||||
g_free(msgproxy);
|
||||
g_free(msgcenter);
|
||||
g_free(authstr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -3291,8 +2943,6 @@ static void provision_context(const struct ofono_gprs_provision_data *ap,
|
||||
if (ap->password != NULL)
|
||||
strcpy(context->context.password, ap->password);
|
||||
|
||||
context->context.auth_method = ap->auth_method;
|
||||
|
||||
strcpy(context->context.apn, ap->apn);
|
||||
context->context.proto = ap->proto;
|
||||
|
||||
@@ -3366,56 +3016,14 @@ static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
|
||||
__ofono_atom_register(gprs->atom, gprs_unregister);
|
||||
}
|
||||
|
||||
static gboolean mms_context_configured(struct ofono_gprs *gprs)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = gprs->contexts; l; l = l->next) {
|
||||
struct pri_context *ctx = l->data;
|
||||
|
||||
if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void provision_mms_context(struct ofono_gprs *gprs, const char *mcc,
|
||||
const char *mnc, const char *spn)
|
||||
{
|
||||
struct ofono_gprs_provision_data *settings;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
|
||||
&settings, &count) == FALSE) {
|
||||
ofono_warn("Provisioning failed");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (settings[i].type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||
provision_context(&settings[i], gprs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__ofono_gprs_provision_free_settings(settings, count);
|
||||
}
|
||||
|
||||
static void spn_read_cb(const char *spn, const char *dc, void *data)
|
||||
{
|
||||
struct ofono_gprs *gprs = data;
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
|
||||
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
|
||||
|
||||
if (gprs->contexts == NULL) {
|
||||
provision_contexts(gprs, ofono_sim_get_mcc(sim),
|
||||
provision_contexts(gprs, ofono_sim_get_mcc(sim),
|
||||
ofono_sim_get_mnc(sim), spn);
|
||||
} else if (!mms_context_configured(gprs)) {
|
||||
provision_mms_context(gprs, ofono_sim_get_mcc(sim),
|
||||
ofono_sim_get_mnc(sim), spn);
|
||||
}
|
||||
|
||||
ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
|
||||
|
||||
@@ -3432,7 +3040,7 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
|
||||
|
||||
gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
|
||||
|
||||
if (mms_context_configured(gprs))
|
||||
if (gprs->contexts)
|
||||
goto finish;
|
||||
|
||||
ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
|
||||
@@ -3456,8 +3064,3 @@ void *ofono_gprs_get_data(struct ofono_gprs *gprs)
|
||||
{
|
||||
return gprs->driver_data;
|
||||
}
|
||||
|
||||
struct ofono_modem *ofono_gprs_get_modem(struct ofono_gprs *gprs)
|
||||
{
|
||||
return __ofono_atom_get_modem(gprs->atom);
|
||||
}
|
||||
|
||||
@@ -72,10 +72,10 @@ static ofono_bool_t transparent_sco = FALSE;
|
||||
static uint16_t codec2setting(uint8_t codec)
|
||||
{
|
||||
switch (codec) {
|
||||
case HFP_CODEC_CVSD:
|
||||
return BT_VOICE_CVSD_16BIT;
|
||||
default:
|
||||
return BT_VOICE_TRANSPARENT;
|
||||
case HFP_CODEC_CVSD:
|
||||
return BT_VOICE_CVSD_16BIT;
|
||||
default:
|
||||
return BT_VOICE_TRANSPARENT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,40 +44,25 @@
|
||||
|
||||
static GSList *g_drivers = NULL;
|
||||
|
||||
#define HANDSFREE_FLAG_CACHED 0x1
|
||||
|
||||
struct ofono_handsfree {
|
||||
ofono_bool_t nrec;
|
||||
ofono_bool_t inband_ringing;
|
||||
ofono_bool_t voice_recognition;
|
||||
ofono_bool_t voice_recognition_pending;
|
||||
|
||||
ofono_bool_t ddr;
|
||||
ofono_bool_t ddr_pending;
|
||||
ofono_bool_t have_ddr;
|
||||
ofono_bool_t ddr_active;
|
||||
|
||||
unsigned int ag_features;
|
||||
unsigned int ag_chld_features;
|
||||
unsigned char battchg;
|
||||
GSList *subscriber_numbers;
|
||||
|
||||
const struct ofono_handsfree_driver *driver;
|
||||
void *driver_data;
|
||||
struct ofono_atom *atom;
|
||||
DBusMessage *pending;
|
||||
int flags;
|
||||
};
|
||||
|
||||
static const char **ag_features_list(unsigned int features,
|
||||
unsigned int chld_features)
|
||||
static const char **ag_features_list(unsigned int features)
|
||||
{
|
||||
static const char *list[10];
|
||||
static const char *list[33];
|
||||
unsigned int i = 0;
|
||||
|
||||
if (features & HFP_AG_FEATURE_3WAY)
|
||||
list[i++] = "three-way-calling";
|
||||
|
||||
if (features & HFP_AG_FEATURE_ECNR)
|
||||
list[i++] = "echo-canceling-and-noise-reduction";
|
||||
|
||||
@@ -87,24 +72,6 @@ static const char **ag_features_list(unsigned int features,
|
||||
if (features & HFP_AG_FEATURE_ATTACH_VOICE_TAG)
|
||||
list[i++] = "attach-voice-tag";
|
||||
|
||||
if (chld_features & HFP_AG_CHLD_0)
|
||||
list[i++] = "release-all-held";
|
||||
|
||||
if (chld_features & HFP_AG_CHLD_1x)
|
||||
list[i++] = "release-specified-active-call";
|
||||
|
||||
if (chld_features & HFP_AG_CHLD_2x)
|
||||
list[i++] = "private-chat";
|
||||
|
||||
if (chld_features & HFP_AG_CHLD_3)
|
||||
list[i++] = "create-multiparty";
|
||||
|
||||
if (chld_features & HFP_AG_CHLD_4)
|
||||
list[i++] = "transfer";
|
||||
|
||||
if (features & HFP_AG_FEATURE_HF_INDICATORS)
|
||||
list[i++] = "hf-indicators";
|
||||
|
||||
list[i] = NULL;
|
||||
|
||||
return list;
|
||||
@@ -158,15 +125,6 @@ void ofono_handsfree_set_ag_features(struct ofono_handsfree *hf,
|
||||
hf->ag_features = ag_features;
|
||||
}
|
||||
|
||||
void ofono_handsfree_set_ag_chld_features(struct ofono_handsfree *hf,
|
||||
unsigned int ag_chld_features)
|
||||
{
|
||||
if (hf == NULL)
|
||||
return;
|
||||
|
||||
hf->ag_chld_features = ag_chld_features;
|
||||
}
|
||||
|
||||
void ofono_handsfree_battchg_notify(struct ofono_handsfree *hf,
|
||||
unsigned char level)
|
||||
{
|
||||
@@ -190,44 +148,10 @@ void ofono_handsfree_battchg_notify(struct ofono_handsfree *hf,
|
||||
&level);
|
||||
}
|
||||
|
||||
static void append_subscriber_numbers(GSList *subscriber_numbers,
|
||||
DBusMessageIter *iter)
|
||||
{
|
||||
DBusMessageIter entry;
|
||||
DBusMessageIter variant, array;
|
||||
GSList *l;
|
||||
const char *subscriber_number_string;
|
||||
char arraysig[3];
|
||||
const char *key = "SubscriberNumbers";
|
||||
|
||||
arraysig[0] = DBUS_TYPE_ARRAY;
|
||||
arraysig[1] = DBUS_TYPE_STRING;
|
||||
arraysig[2] = '\0';
|
||||
|
||||
dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
|
||||
NULL, &entry);
|
||||
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
|
||||
&key);
|
||||
dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
|
||||
arraysig, &variant);
|
||||
dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_STRING_AS_STRING, &array);
|
||||
|
||||
for (l = subscriber_numbers; l; l = l->next) {
|
||||
subscriber_number_string = phone_number_to_string(l->data);
|
||||
dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING,
|
||||
&subscriber_number_string);
|
||||
}
|
||||
|
||||
dbus_message_iter_close_container(&variant, &array);
|
||||
|
||||
dbus_message_iter_close_container(&entry, &variant);
|
||||
dbus_message_iter_close_container(iter, &entry);
|
||||
}
|
||||
|
||||
static DBusMessage *generate_get_properties_reply(struct ofono_handsfree *hf,
|
||||
DBusMessage *msg)
|
||||
static DBusMessage *handsfree_get_properties(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct ofono_handsfree *hf = data;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter dict;
|
||||
@@ -253,98 +177,22 @@ static DBusMessage *generate_get_properties_reply(struct ofono_handsfree *hf,
|
||||
ofono_dbus_dict_append(&dict, "EchoCancelingNoiseReduction",
|
||||
DBUS_TYPE_BOOLEAN, &hf->nrec);
|
||||
|
||||
if (hf->ag_features & HFP_AG_FEATURE_HF_INDICATORS)
|
||||
ofono_dbus_dict_append(&dict, "DistractedDrivingReduction",
|
||||
DBUS_TYPE_BOOLEAN, &hf->ddr);
|
||||
|
||||
voice_recognition = hf->voice_recognition;
|
||||
ofono_dbus_dict_append(&dict, "VoiceRecognition", DBUS_TYPE_BOOLEAN,
|
||||
&voice_recognition);
|
||||
|
||||
features = ag_features_list(hf->ag_features, hf->ag_chld_features);
|
||||
features = ag_features_list(hf->ag_features);
|
||||
ofono_dbus_dict_append_array(&dict, "Features", DBUS_TYPE_STRING,
|
||||
&features);
|
||||
|
||||
ofono_dbus_dict_append(&dict, "BatteryChargeLevel", DBUS_TYPE_BYTE,
|
||||
&hf->battchg);
|
||||
|
||||
if (hf->subscriber_numbers)
|
||||
append_subscriber_numbers(hf->subscriber_numbers, &dict);
|
||||
|
||||
dbus_message_iter_close_container(&iter, &dict);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static void hf_cnum_callback(const struct ofono_error *error, int total,
|
||||
const struct ofono_phone_number *numbers,
|
||||
void *data)
|
||||
{
|
||||
struct ofono_handsfree *hf = data;
|
||||
int num;
|
||||
struct ofono_phone_number *subscriber_number;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
|
||||
goto out;
|
||||
|
||||
for (num = 0; num < total; num++) {
|
||||
subscriber_number = g_new0(struct ofono_phone_number, 1);
|
||||
|
||||
subscriber_number->type = numbers[num].type;
|
||||
strncpy(subscriber_number->number, numbers[num].number,
|
||||
OFONO_MAX_PHONE_NUMBER_LENGTH + 1);
|
||||
|
||||
hf->subscriber_numbers = g_slist_prepend(hf->subscriber_numbers,
|
||||
subscriber_number);
|
||||
}
|
||||
|
||||
hf->subscriber_numbers = g_slist_reverse(hf->subscriber_numbers);
|
||||
|
||||
out:
|
||||
hf->flags |= HANDSFREE_FLAG_CACHED;
|
||||
|
||||
if (hf->pending) {
|
||||
DBusMessage *reply =
|
||||
generate_get_properties_reply(hf, hf->pending);
|
||||
__ofono_dbus_pending_reply(&hf->pending, reply);
|
||||
}
|
||||
}
|
||||
|
||||
static void query_cnum(struct ofono_handsfree *hf)
|
||||
{
|
||||
DBusMessage *reply;
|
||||
|
||||
if (hf->driver->cnum_query != NULL) {
|
||||
hf->driver->cnum_query(hf, hf_cnum_callback, hf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hf->pending == NULL)
|
||||
return;
|
||||
|
||||
reply = generate_get_properties_reply(hf, hf->pending);
|
||||
__ofono_dbus_pending_reply(&hf->pending, reply);
|
||||
}
|
||||
|
||||
static DBusMessage *handsfree_get_properties(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct ofono_handsfree *hf = data;
|
||||
|
||||
if (hf->pending != NULL)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
if (hf->flags & HANDSFREE_FLAG_CACHED)
|
||||
return generate_get_properties_reply(hf, msg);
|
||||
|
||||
/* Query the settings and report back */
|
||||
hf->pending = dbus_message_ref(msg);
|
||||
|
||||
query_cnum(hf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void voicerec_set_cb(const struct ofono_error *error, void *data)
|
||||
{
|
||||
struct ofono_handsfree *hf = data;
|
||||
@@ -369,82 +217,6 @@ static void voicerec_set_cb(const struct ofono_error *error, void *data)
|
||||
&hf->voice_recognition);
|
||||
}
|
||||
|
||||
static void ddr_set_cb(const struct ofono_error *error, void *data)
|
||||
{
|
||||
struct ofono_handsfree *hf = data;
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
const char *path = __ofono_atom_get_path(hf->atom);
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
__ofono_dbus_pending_reply(&hf->pending,
|
||||
__ofono_error_failed(hf->pending));
|
||||
return;
|
||||
}
|
||||
|
||||
hf->ddr = hf->ddr_pending;
|
||||
|
||||
__ofono_dbus_pending_reply(&hf->pending,
|
||||
dbus_message_new_method_return(hf->pending));
|
||||
|
||||
ofono_dbus_signal_property_changed(conn, path,
|
||||
OFONO_HANDSFREE_INTERFACE,
|
||||
"DistractedDrivingReduction",
|
||||
DBUS_TYPE_BOOLEAN,
|
||||
&hf->voice_recognition);
|
||||
}
|
||||
|
||||
void ofono_handsfree_set_hf_indicators(struct ofono_handsfree *hf,
|
||||
const unsigned short *indicators,
|
||||
unsigned int num)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
switch (indicators[i]) {
|
||||
case HFP_HF_INDICATOR_ENHANCED_SAFETY:
|
||||
hf->have_ddr = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ddr_update_cb(const struct ofono_error *error, void *data)
|
||||
{
|
||||
if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
|
||||
return;
|
||||
|
||||
ofono_info("Failed to update DDR indicator");
|
||||
}
|
||||
|
||||
void ofono_handsfree_hf_indicator_active_notify(struct ofono_handsfree *hf,
|
||||
unsigned int indicator,
|
||||
ofono_bool_t active)
|
||||
{
|
||||
DBG("%d, %d", indicator, active);
|
||||
|
||||
if (active)
|
||||
active = TRUE;
|
||||
else
|
||||
active = FALSE;
|
||||
|
||||
switch (indicator) {
|
||||
case HFP_HF_INDICATOR_ENHANCED_SAFETY:
|
||||
if (!hf->have_ddr)
|
||||
return;
|
||||
|
||||
if (hf->ddr_active == active)
|
||||
return;
|
||||
|
||||
hf->ddr_active = active;
|
||||
|
||||
if (hf->ddr_active && hf->driver && hf->driver->hf_indicator)
|
||||
hf->driver->hf_indicator(hf,
|
||||
HFP_HF_INDICATOR_ENHANCED_SAFETY,
|
||||
hf->ddr, ddr_update_cb, hf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void nrec_set_cb(const struct ofono_error *error, void *data)
|
||||
{
|
||||
struct ofono_handsfree *hf = data;
|
||||
@@ -523,37 +295,6 @@ static DBusMessage *handsfree_set_property(DBusConnection *conn,
|
||||
|
||||
hf->pending = dbus_message_ref(msg);
|
||||
hf->driver->disable_nrec(hf, nrec_set_cb, hf);
|
||||
} else if (g_str_equal(name, "DistractedDrivingReduction") == TRUE) {
|
||||
if (!(hf->ag_features & HFP_AG_FEATURE_HF_INDICATORS))
|
||||
return __ofono_error_not_supported(msg);
|
||||
|
||||
if (!hf->driver->hf_indicator)
|
||||
return __ofono_error_not_implemented(msg);
|
||||
|
||||
if (!hf->have_ddr)
|
||||
return __ofono_error_not_supported(msg);
|
||||
|
||||
if (hf->ddr == enabled)
|
||||
return dbus_message_new_method_return(msg);
|
||||
|
||||
if (!hf->ddr_active) {
|
||||
hf->ddr = enabled;
|
||||
|
||||
g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
|
||||
|
||||
ofono_dbus_signal_property_changed(conn,
|
||||
__ofono_atom_get_path(hf->atom),
|
||||
OFONO_HANDSFREE_INTERFACE,
|
||||
"DistractedDrivingReduction",
|
||||
DBUS_TYPE_BOOLEAN,
|
||||
&hf->voice_recognition);
|
||||
} else {
|
||||
hf->pending = dbus_message_ref(msg);
|
||||
hf->ddr_pending = enabled;
|
||||
hf->driver->hf_indicator(hf,
|
||||
HFP_HF_INDICATOR_ENHANCED_SAFETY,
|
||||
enabled, ddr_set_cb, hf);
|
||||
}
|
||||
} else
|
||||
return __ofono_error_invalid_args(msg);
|
||||
|
||||
@@ -683,10 +424,6 @@ static void handsfree_unregister(struct ofono_atom *atom)
|
||||
__ofono_dbus_pending_reply(&hf->pending, reply);
|
||||
}
|
||||
|
||||
g_slist_foreach(hf->subscriber_numbers, (GFunc) g_free, NULL);
|
||||
g_slist_free(hf->subscriber_numbers);
|
||||
hf->subscriber_numbers = NULL;
|
||||
|
||||
ofono_modem_remove_interface(modem, OFONO_HANDSFREE_INTERFACE);
|
||||
g_dbus_unregister_interface(conn, path,
|
||||
OFONO_HANDSFREE_INTERFACE);
|
||||
|
||||
@@ -31,7 +31,6 @@ enum hfp_ag_feature {
|
||||
HFP_AG_FEATURE_ENHANCED_CALL_CONTROL = 0x80,
|
||||
HFP_AG_FEATURE_EXTENDED_RES_CODE = 0x100,
|
||||
HFP_AG_FEATURE_CODEC_NEGOTIATION = 0x200,
|
||||
HFP_AG_FEATURE_HF_INDICATORS = 0x400,
|
||||
};
|
||||
|
||||
/* HFP HF supported features bitmap. Bluetooth HFP 1.6 spec page 88 */
|
||||
@@ -44,18 +43,6 @@ enum hfp_hf_feature {
|
||||
HFP_HF_FEATURE_ENHANCED_CALL_STATUS = 0x20,
|
||||
HFP_HF_FEATURE_ENHANCED_CALL_CONTROL = 0x40,
|
||||
HFP_HF_FEATURE_CODEC_NEGOTIATION = 0x80,
|
||||
HFP_HF_FEATURE_HF_INDICATORS = 0x100,
|
||||
};
|
||||
|
||||
/* HFP AG supported call hold and multiparty services bitmap. Bluetooth HFP 1.6 spec page 76 */
|
||||
enum hfp_ag_chld_feature {
|
||||
HFP_AG_CHLD_0 = 0x1,
|
||||
HFP_AG_CHLD_1 = 0x2,
|
||||
HFP_AG_CHLD_1x = 0x4,
|
||||
HFP_AG_CHLD_2 = 0x8,
|
||||
HFP_AG_CHLD_2x = 0x10,
|
||||
HFP_AG_CHLD_3 = 0x20,
|
||||
HFP_AG_CHLD_4 = 0x40,
|
||||
};
|
||||
|
||||
enum hfp_sdp_hf_features {
|
||||
@@ -85,10 +72,5 @@ enum hfp_codec {
|
||||
enum hfp_version {
|
||||
HFP_VERSION_1_5 = 0x0105,
|
||||
HFP_VERSION_1_6 = 0x0106,
|
||||
HFP_VERSION_1_7 = 0x0107,
|
||||
HFP_VERSION_LATEST = HFP_VERSION_1_7,
|
||||
};
|
||||
|
||||
enum hfp_hf_indicator {
|
||||
HFP_HF_INDICATOR_ENHANCED_SAFETY = 0x0001,
|
||||
HFP_VERSION_LATEST = HFP_VERSION_1_6,
|
||||
};
|
||||
|
||||
@@ -135,7 +135,7 @@ void idmap_put(struct idmap *idmap, unsigned int id)
|
||||
|
||||
id %= BITS_PER_LONG;
|
||||
|
||||
idmap->bits[offset] &= ~(1UL << id);
|
||||
idmap->bits[offset] &= ~(1 << id);
|
||||
}
|
||||
|
||||
unsigned int idmap_alloc(struct idmap *idmap)
|
||||
@@ -149,7 +149,7 @@ unsigned int idmap_alloc(struct idmap *idmap)
|
||||
return idmap->max + 1;
|
||||
|
||||
offset = bit / BITS_PER_LONG;
|
||||
idmap->bits[offset] |= 1UL << (bit % BITS_PER_LONG);
|
||||
idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG);
|
||||
|
||||
return bit + idmap->min;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ void idmap_take(struct idmap *idmap, unsigned int id)
|
||||
return;
|
||||
|
||||
offset = bit / BITS_PER_LONG;
|
||||
idmap->bits[offset] |= 1UL << (bit % BITS_PER_LONG);
|
||||
idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -186,7 +186,7 @@ unsigned int idmap_alloc_next(struct idmap *idmap, unsigned int last)
|
||||
return idmap_alloc(idmap);
|
||||
|
||||
offset = bit / BITS_PER_LONG;
|
||||
idmap->bits[offset] |= 1UL << (bit % BITS_PER_LONG);
|
||||
idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG);
|
||||
|
||||
return bit + idmap->min;
|
||||
}
|
||||
|
||||
@@ -289,8 +289,7 @@ void __ofono_log_enable(struct ofono_debug_desc *start,
|
||||
}
|
||||
|
||||
int __ofono_log_init(const char *program, const char *debug,
|
||||
ofono_bool_t detach,
|
||||
ofono_bool_t backtrace)
|
||||
ofono_bool_t detach)
|
||||
{
|
||||
static char path[PATH_MAX];
|
||||
int option = LOG_NDELAY | LOG_PID;
|
||||
@@ -306,8 +305,7 @@ int __ofono_log_init(const char *program, const char *debug,
|
||||
if (detach == FALSE)
|
||||
option |= LOG_PERROR;
|
||||
|
||||
if (backtrace == TRUE)
|
||||
signal_setup(signal_handler);
|
||||
signal_setup(signal_handler);
|
||||
|
||||
openlog(basename(program), option, LOG_DAEMON);
|
||||
|
||||
@@ -316,14 +314,13 @@ int __ofono_log_init(const char *program, const char *debug,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __ofono_log_cleanup(ofono_bool_t backtrace)
|
||||
void __ofono_log_cleanup(void)
|
||||
{
|
||||
syslog(LOG_INFO, "Exit");
|
||||
|
||||
closelog();
|
||||
|
||||
if (backtrace == TRUE)
|
||||
signal_setup(SIG_DFL);
|
||||
signal_setup(SIG_DFL);
|
||||
|
||||
g_strfreev(enabled);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,6 @@ static gchar *option_plugin = NULL;
|
||||
static gchar *option_noplugin = NULL;
|
||||
static gboolean option_detach = TRUE;
|
||||
static gboolean option_version = FALSE;
|
||||
static gboolean option_backtrace = TRUE;
|
||||
|
||||
static gboolean parse_debug(const char *key, const char *value,
|
||||
gpointer user_data, GError **error)
|
||||
@@ -159,9 +158,6 @@ static GOptionEntry options[] = {
|
||||
"Don't run as daemon in background" },
|
||||
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
|
||||
"Show version information and exit" },
|
||||
{ "nobacktrace", 0, G_OPTION_FLAG_REVERSE,
|
||||
G_OPTION_ARG_NONE, &option_backtrace,
|
||||
"Don't print out backtrace information" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@@ -217,8 +213,7 @@ int main(int argc, char **argv)
|
||||
|
||||
signal = setup_signalfd();
|
||||
|
||||
__ofono_log_init(argv[0], option_debug, option_detach,
|
||||
option_backtrace);
|
||||
__ofono_log_init(argv[0], option_debug, option_detach);
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
@@ -244,11 +239,7 @@ int main(int argc, char **argv)
|
||||
|
||||
__ofono_manager_init();
|
||||
|
||||
/*
|
||||
* BT HFP SCO socket creation moved to Bluez5 plugin.
|
||||
* Bluez4 handles the SCO socket, it will conflict with oFono.
|
||||
*/
|
||||
//__ofono_handsfree_audio_manager_init();
|
||||
__ofono_handsfree_audio_manager_init();
|
||||
|
||||
__ofono_plugin_init(option_plugin, option_noplugin);
|
||||
|
||||
@@ -259,7 +250,7 @@ int main(int argc, char **argv)
|
||||
|
||||
__ofono_plugin_cleanup();
|
||||
|
||||
//__ofono_handsfree_audio_manager_cleanup(); See comment above
|
||||
__ofono_handsfree_audio_manager_cleanup();
|
||||
|
||||
__ofono_manager_cleanup();
|
||||
|
||||
@@ -273,7 +264,7 @@ cleanup:
|
||||
|
||||
g_main_loop_unref(event_loop);
|
||||
|
||||
__ofono_log_cleanup(option_backtrace);
|
||||
__ofono_log_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -414,9 +414,7 @@ static void flush_atoms(struct ofono_modem *modem, enum modem_state new_state)
|
||||
while (cur) {
|
||||
struct ofono_atom *atom = cur->data;
|
||||
|
||||
/* in case we are powering off the modem, flush everything */
|
||||
if (atom->modem_state <= new_state &&
|
||||
new_state > MODEM_STATE_POWER_OFF) {
|
||||
if (atom->modem_state <= new_state) {
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
continue;
|
||||
|
||||
@@ -934,40 +934,6 @@ static void append_operator_struct_list(struct ofono_netreg *netreg,
|
||||
dbus_free_string_array(children);
|
||||
}
|
||||
|
||||
static void network_signal_operators_changed(struct ofono_netreg *netreg)
|
||||
{
|
||||
const char *path = __ofono_atom_get_path(netreg->atom);
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
DBusMessage *signal;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter array;
|
||||
|
||||
signal = dbus_message_new_signal(path,
|
||||
OFONO_NETWORK_REGISTRATION_INTERFACE, "OperatorsChanged");
|
||||
if (signal == NULL) {
|
||||
ofono_error("Unable to allocate new "
|
||||
OFONO_NETWORK_REGISTRATION_INTERFACE
|
||||
".OperatorsChanged signal");
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_iter_init_append(signal, &iter);
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_STRUCT_BEGIN_CHAR_AS_STRING
|
||||
DBUS_TYPE_OBJECT_PATH_AS_STRING
|
||||
DBUS_TYPE_ARRAY_AS_STRING
|
||||
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
|
||||
DBUS_TYPE_STRING_AS_STRING
|
||||
DBUS_TYPE_VARIANT_AS_STRING
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
|
||||
DBUS_STRUCT_END_CHAR_AS_STRING,
|
||||
&array);
|
||||
append_operator_struct_list(netreg, &array);
|
||||
dbus_message_iter_close_container(&iter, &array);
|
||||
|
||||
g_dbus_send_message(conn, signal);
|
||||
}
|
||||
|
||||
static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
const struct ofono_network_operator *list,
|
||||
void *data)
|
||||
@@ -976,7 +942,6 @@ static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter array;
|
||||
gboolean changed;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
DBG("Error occurred during operator list");
|
||||
@@ -985,7 +950,7 @@ static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
return;
|
||||
}
|
||||
|
||||
changed = update_operator_list(netreg, total, list);
|
||||
update_operator_list(netreg, total, list);
|
||||
|
||||
reply = dbus_message_new_method_return(netreg->pending);
|
||||
|
||||
@@ -1005,11 +970,6 @@ static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
dbus_message_iter_close_container(&iter, &array);
|
||||
|
||||
__ofono_dbus_pending_reply(&netreg->pending, reply);
|
||||
|
||||
DBG("operator list %schanged", changed ? "" : "not ");
|
||||
|
||||
if (changed)
|
||||
network_signal_operators_changed(netreg);
|
||||
}
|
||||
|
||||
static DBusMessage *network_scan(DBusConnection *conn,
|
||||
@@ -1081,8 +1041,6 @@ static const GDBusMethodTable network_registration_methods[] = {
|
||||
static const GDBusSignalTable network_registration_signals[] = {
|
||||
{ GDBUS_SIGNAL("PropertyChanged",
|
||||
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
|
||||
{ GDBUS_SIGNAL("OperatorsChanged",
|
||||
GDBUS_ARGS({ "operators", "a(oa{sv})"})) },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -2148,14 +2106,18 @@ void ofono_netreg_register(struct ofono_netreg *netreg)
|
||||
ofono_sim_add_spn_watch(netreg->sim, &netreg->spn_watch,
|
||||
spn_read_cb, netreg, NULL);
|
||||
|
||||
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
|
||||
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
|
||||
sim_spdi_read_cb, netreg);
|
||||
if (__ofono_sim_service_available(netreg->sim,
|
||||
SIM_UST_SERVICE_PROVIDER_DISPLAY_INFO,
|
||||
SIM_SST_SERVICE_PROVIDER_DISPLAY_INFO)) {
|
||||
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
|
||||
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
|
||||
sim_spdi_read_cb, netreg);
|
||||
|
||||
ofono_sim_add_file_watch(netreg->sim_context,
|
||||
SIM_EFSPDI_FILEID,
|
||||
sim_spdi_changed,
|
||||
netreg, NULL);
|
||||
ofono_sim_add_file_watch(netreg->sim_context,
|
||||
SIM_EFSPDI_FILEID,
|
||||
sim_spdi_changed,
|
||||
netreg, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
__ofono_atom_register(netreg->atom, netreg_unregister);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<allow send_interface="org.ofono.SmartMessagingAgent"/>
|
||||
<allow send_interface="org.ofono.PositioningRequestAgent"/>
|
||||
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
|
||||
<allow send_interface="org.ofono.VoiceCallAgent"/>
|
||||
</policy>
|
||||
|
||||
<policy user="radio">
|
||||
@@ -26,7 +25,6 @@
|
||||
<allow send_interface="org.ofono.SmartMessagingAgent"/>
|
||||
<allow send_interface="org.ofono.PositioningRequestAgent"/>
|
||||
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
|
||||
<allow send_interface="org.ofono.VoiceCallAgent"/>
|
||||
</policy>
|
||||
|
||||
<policy at_console="true">
|
||||
|
||||
@@ -38,9 +38,8 @@ void __ofono_modem_shutdown(void);
|
||||
#include <ofono/log.h>
|
||||
|
||||
int __ofono_log_init(const char *program, const char *debug,
|
||||
ofono_bool_t detach,
|
||||
ofono_bool_t backtrace);
|
||||
void __ofono_log_cleanup(ofono_bool_t backtrace);
|
||||
ofono_bool_t detach);
|
||||
void __ofono_log_cleanup(void);
|
||||
void __ofono_log_enable(struct ofono_debug_desc *start,
|
||||
struct ofono_debug_desc *stop);
|
||||
|
||||
@@ -507,17 +506,8 @@ void __ofono_gprs_provision_free_settings(
|
||||
int count);
|
||||
|
||||
#include <ofono/emulator.h>
|
||||
|
||||
enum ofono_emulator_slc_condition {
|
||||
OFONO_EMULATOR_SLC_CONDITION_CMER,
|
||||
OFONO_EMULATOR_SLC_CONDITION_CHLD,
|
||||
OFONO_EMULATOR_SLC_CONDITION_BIND,
|
||||
};
|
||||
|
||||
void __ofono_emulator_set_indicator_forced(struct ofono_emulator *em,
|
||||
const char *name, int value);
|
||||
void __ofono_emulator_slc_condition(struct ofono_emulator *em,
|
||||
enum ofono_emulator_slc_condition cond);
|
||||
|
||||
#include <ofono/gnss.h>
|
||||
#include <ofono/cdma-sms.h>
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
[Unit]
|
||||
Description=Telephony service
|
||||
Requires=dbus.service
|
||||
After=dbus.service
|
||||
After=syslog.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=org.ofono
|
||||
User=root
|
||||
EnvironmentFile=-/var/lib/environment/ofono/*.conf
|
||||
ExecStart=@prefix@/sbin/ofonod -n --nobacktrace $OFONO_ARGS
|
||||
ExecStart=@prefix@/sbin/ofonod -n $OFONO_ARGS
|
||||
StandardError=null
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user