Compare commits

..

3 Commits

Author SHA1 Message Date
Miia Leinonen
72395683a1 [rilmodem] Fix for Call Barring commit
Signed-off-by: Miia Leinonen <miia.leinonen@oss.tieto.com>
2014-01-16 09:52:30 +02:00
Miia Leinonen
f595d0fae0 [rilmodem] Add Call Barring support
Signed-off-by: Miia Leinonen <miia.leinonen@oss.tieto.com>
2014-01-16 09:52:30 +02:00
Jarko Poutiainen
a170c3a01e [rilmodem] add missing brace characters
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-01-16 09:52:30 +02:00
217 changed files with 1864 additions and 8243 deletions

View File

@@ -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>

View File

@@ -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.

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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'.

View File

@@ -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.

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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
};

View File

@@ -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)

View File

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

View File

@@ -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);

View File

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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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,

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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);

View File

@@ -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++) {

View File

@@ -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 \

View File

@@ -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.
*

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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, &current_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);
}

View File

@@ -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)

View File

@@ -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();

View File

@@ -1,7 +1,6 @@
[Unit]
Description=DUN service
Requires=dbus.service
After=dbus.service
After=syslog.target
[Service]
Type=dbus

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;
}

View File

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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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);

View File

@@ -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(

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

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

View File

@@ -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)

View File

@@ -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" },
{ }
};

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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,
};

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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">

View File

@@ -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>

View File

@@ -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