mirror of
https://github.com/sailfishos/ofono
synced 2025-11-26 20:31:06 +08:00
Compare commits
151 Commits
mer/1.14+g
...
mer/1.14+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
420651829a | ||
|
|
0835875b65 | ||
|
|
153599eb70 | ||
|
|
fafef8bfd3 | ||
|
|
3bce306f6e | ||
|
|
68767f6ea2 | ||
|
|
a3cd7b0898 | ||
|
|
d0364f89cd | ||
|
|
9aa8375233 | ||
|
|
77b3adfd60 | ||
|
|
b4bb7e72d8 | ||
|
|
8e20975660 | ||
|
|
0e8a53bdf0 | ||
|
|
9a29fdde06 | ||
|
|
269fa3db0e | ||
|
|
64dab08751 | ||
|
|
7a72726d9a | ||
|
|
b6fb89c3a0 | ||
|
|
d51d858cd6 | ||
|
|
24d1be80c5 | ||
|
|
19c2a6fc64 | ||
|
|
6e3236b739 | ||
|
|
e5223ac8af | ||
|
|
9505b6baf3 | ||
|
|
4c268731b9 | ||
|
|
5b158c3a28 | ||
|
|
9745d202d3 | ||
|
|
2329468e25 | ||
|
|
2b352aedb4 | ||
|
|
b319c77bcc | ||
|
|
4b95656d72 | ||
|
|
b3dc0d0146 | ||
|
|
319866c450 | ||
|
|
2847cfcd03 | ||
|
|
65501536d3 | ||
|
|
eef58998c0 | ||
|
|
571d440c14 | ||
|
|
25fc82a073 | ||
|
|
e50518effa | ||
|
|
84e1386978 | ||
|
|
0cdd483894 | ||
|
|
7dbeba0e83 | ||
|
|
d7cf952a16 | ||
|
|
e8379285b3 | ||
|
|
f9a91c8453 | ||
|
|
882f75b500 | ||
|
|
5b6ddee098 | ||
|
|
5cbf0de041 | ||
|
|
8ce12b2232 | ||
|
|
62d42e0407 | ||
|
|
5053a342e7 | ||
|
|
5c53260938 | ||
|
|
e3e691fb48 | ||
|
|
8fa99a07e8 | ||
|
|
23f92a5b3e | ||
|
|
94494f3a63 | ||
|
|
098b3d4a64 | ||
|
|
cfeb58f2a8 | ||
|
|
5f821b4a9a | ||
|
|
533d248288 | ||
|
|
4f512b6e56 | ||
|
|
ce3a5e5a0b | ||
|
|
c97ef76c93 | ||
|
|
95659d7c49 | ||
|
|
eb986f49e4 | ||
|
|
4691d385c0 | ||
|
|
0ddebfea70 | ||
|
|
2d1f2b0650 | ||
|
|
0ca5c87999 | ||
|
|
e3dcd67a1b | ||
|
|
99b9099082 | ||
|
|
ec74da107d | ||
|
|
50f146939f | ||
|
|
e7a07b4694 | ||
|
|
461d18f4a3 | ||
|
|
16ea57247d | ||
|
|
837fa1f8f1 | ||
|
|
1469b52db9 | ||
|
|
c156bbf14b | ||
|
|
a724d6bc9d | ||
|
|
21b7c9bc97 | ||
|
|
fc04b4cef2 | ||
|
|
88f42f44c1 | ||
|
|
2aed3c3f66 | ||
|
|
9c9028b164 | ||
|
|
6d35002f11 | ||
|
|
803dda81ea | ||
|
|
31f8abf851 | ||
|
|
8f4aefa945 | ||
|
|
58e133cbf5 | ||
|
|
6c3992aa86 | ||
|
|
c3352608c6 | ||
|
|
5da34324ca | ||
|
|
b64a5c2655 | ||
|
|
e11c1afdd3 | ||
|
|
9834debe92 | ||
|
|
2d75463ae2 | ||
|
|
95b95f9af9 | ||
|
|
d43ec9e0ed | ||
|
|
8bc1e0a300 | ||
|
|
b489dc995b | ||
|
|
d25fd17f09 | ||
|
|
73a794e9f6 | ||
|
|
df0e72c780 | ||
|
|
7cdaa7cd13 | ||
|
|
558a6639d6 | ||
|
|
5f2e8e24f0 | ||
|
|
31f85495dc | ||
|
|
689d7358ba | ||
|
|
b3ca644f1d | ||
|
|
1e811dd49a | ||
|
|
9a520a7825 | ||
|
|
2f51bc9e62 | ||
|
|
d8dd65b579 | ||
|
|
1e139cb4c6 | ||
|
|
68c0a9f164 | ||
|
|
dfe0f280de | ||
|
|
5a54a71fd8 | ||
|
|
0f39bdc9c3 | ||
|
|
24e8514c55 | ||
|
|
f1b689ed3c | ||
|
|
e5df37be4b | ||
|
|
a61a8cc183 | ||
|
|
e25b5b13f9 | ||
|
|
3f3375442d | ||
|
|
782669b412 | ||
|
|
5a401c8b50 | ||
|
|
3ac41bc759 | ||
|
|
5af079bd03 | ||
|
|
cf6278f5cc | ||
|
|
dd3b0c5aca | ||
|
|
988a759e4c | ||
|
|
555585c17f | ||
|
|
4b99034c3f | ||
|
|
03e35b6757 | ||
|
|
b36fdce803 | ||
|
|
34251bdba7 | ||
|
|
530c66393a | ||
|
|
10c823d732 | ||
|
|
db6d4d1e8e | ||
|
|
5bcbc64e60 | ||
|
|
48cec5cc58 | ||
|
|
6e40473ce9 | ||
|
|
90cae692df | ||
|
|
d8270409d0 | ||
|
|
e644196aa3 | ||
|
|
fed4a94862 | ||
|
|
ccc8d1afd4 | ||
|
|
417f20c662 | ||
|
|
304f7cc197 | ||
|
|
354285a438 |
@@ -142,7 +142,9 @@ builtin_sources += drivers/rilmodem/rilmodem.h \
|
|||||||
drivers/rilmodem/call-settings.c \
|
drivers/rilmodem/call-settings.c \
|
||||||
drivers/rilmodem/call-forwarding.c \
|
drivers/rilmodem/call-forwarding.c \
|
||||||
drivers/rilmodem/cbs.c \
|
drivers/rilmodem/cbs.c \
|
||||||
drivers/rilmodem/oemraw-messages.c
|
drivers/rilmodem/oemraw-messages.c \
|
||||||
|
drivers/rilmodem/call-barring.c \
|
||||||
|
drivers/rilmodem/stk.c
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -512,7 +514,7 @@ if PROVISION
|
|||||||
builtin_sources += plugins/mbpi.h plugins/mbpi.c
|
builtin_sources += plugins/mbpi.h plugins/mbpi.c
|
||||||
|
|
||||||
builtin_modules += provision
|
builtin_modules += provision
|
||||||
builtin_sources += plugins/provision.c
|
builtin_sources += plugins/provision.h plugins/provision.c
|
||||||
|
|
||||||
builtin_modules += cdma_provision
|
builtin_modules += cdma_provision
|
||||||
builtin_sources += plugins/cdma-provision.c
|
builtin_sources += plugins/cdma-provision.c
|
||||||
@@ -547,6 +549,13 @@ builtin_sources += plugins/smart-messaging.c
|
|||||||
builtin_modules += push_notification
|
builtin_modules += push_notification
|
||||||
builtin_sources += plugins/push-notification.c
|
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_modules += sms_history
|
||||||
builtin_sources += plugins/smshistory.c
|
builtin_sources += plugins/smshistory.c
|
||||||
|
|
||||||
@@ -578,7 +587,7 @@ src_ofonod_SOURCES = $(builtin_sources) src/ofono.ver \
|
|||||||
src/cdma-provision.c src/handsfree.c \
|
src/cdma-provision.c src/handsfree.c \
|
||||||
src/handsfree-audio.c src/bluetooth.h \
|
src/handsfree-audio.c src/bluetooth.h \
|
||||||
src/hfp.h src/sim-mnclength.c src/oemraw.c \
|
src/hfp.h src/sim-mnclength.c src/oemraw.c \
|
||||||
src/siri.c
|
src/siri.c src/voicecallagent.c
|
||||||
|
|
||||||
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
||||||
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
|
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
|
||||||
@@ -711,13 +720,16 @@ test_scripts = test/backtrace \
|
|||||||
test/set-context-property \
|
test/set-context-property \
|
||||||
test/test-gnss \
|
test/test-gnss \
|
||||||
test/swap-calls \
|
test/swap-calls \
|
||||||
|
test/transfer-call \
|
||||||
test/release-and-answer \
|
test/release-and-answer \
|
||||||
test/release-and-swap \
|
test/release-and-swap \
|
||||||
test/hold-and-answer \
|
test/hold-and-answer \
|
||||||
test/hangup-multiparty \
|
test/hangup-multiparty \
|
||||||
test/hangup-call \
|
test/hangup-call \
|
||||||
test/display-icon \
|
test/display-icon \
|
||||||
test/set-msisdn
|
test/set-msisdn \
|
||||||
|
test/test-voicecallagent \
|
||||||
|
test/get-network-time
|
||||||
|
|
||||||
if TEST
|
if TEST
|
||||||
testdir = $(pkglibdir)/test
|
testdir = $(pkglibdir)/test
|
||||||
@@ -738,7 +750,8 @@ unit_tests = unit/test-common unit/test-util unit/test-idmap \
|
|||||||
unit/test-grilrequest \
|
unit/test-grilrequest \
|
||||||
unit/test-grilreply \
|
unit/test-grilreply \
|
||||||
unit/test-grilunsol \
|
unit/test-grilunsol \
|
||||||
unit/test-sms unit/test-cdmasms
|
unit/test-sms unit/test-cdmasms \
|
||||||
|
unit/test-provision
|
||||||
|
|
||||||
noinst_PROGRAMS = $(unit_tests) \
|
noinst_PROGRAMS = $(unit_tests) \
|
||||||
unit/test-sms-root unit/test-mux unit/test-caif
|
unit/test-sms-root unit/test-mux unit/test-caif
|
||||||
@@ -805,6 +818,13 @@ unit_test_grilunsol_SOURCES = unit/test-grilunsol.c $(gril_sources) \
|
|||||||
unit_test_grilunsol_LDADD = @GLIB_LIBS@ -ldl
|
unit_test_grilunsol_LDADD = @GLIB_LIBS@ -ldl
|
||||||
unit_objects += $(unit_test_grilunsol_OBJECTS)
|
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)
|
TESTS = $(unit_tests)
|
||||||
|
|
||||||
if TOOLS
|
if TOOLS
|
||||||
|
|||||||
@@ -192,7 +192,10 @@ AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
|
|||||||
AC_ARG_ENABLE(nettime, AC_HELP_STRING([--disable-nettime],
|
AC_ARG_ENABLE(nettime, AC_HELP_STRING([--disable-nettime],
|
||||||
[disable Nettime plugin]),
|
[disable Nettime plugin]),
|
||||||
[enable_nettime=${enableval}])
|
[enable_nettime=${enableval}])
|
||||||
AM_CONDITIONAL(NETTIME, test "${enable_netttime}" != "no")
|
if (test "${enable_nettime}" != "no"); then
|
||||||
|
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(NETTIME, test "${enable_nettime}" != "no")
|
||||||
|
|
||||||
AC_ARG_WITH([provisiondb], AC_HELP_STRING([--with-provisiondb=FILE],
|
AC_ARG_WITH([provisiondb], AC_HELP_STRING([--with-provisiondb=FILE],
|
||||||
[location of provision database]), [path_provisiondb=${withval}])
|
[location of provision database]), [path_provisiondb=${withval}])
|
||||||
@@ -223,6 +226,17 @@ AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
|
|||||||
[enable_datafiles=${enableval}])
|
[enable_datafiles=${enableval}])
|
||||||
AM_CONDITIONAL(DATAFILES, test "${enable_datafiles}" != "no")
|
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
|
if (test "${prefix}" = "NONE"); then
|
||||||
dnl no prefix and no localstatedir, so default to /var
|
dnl no prefix and no localstatedir, so default to /var
|
||||||
if (test "$localstatedir" = '${prefix}/var'); then
|
if (test "$localstatedir" = '${prefix}/var'); then
|
||||||
|
|||||||
@@ -198,6 +198,25 @@ Methods dict GetProperties()
|
|||||||
[service].Error.InvalidFormat
|
[service].Error.InvalidFormat
|
||||||
[service].Error.Failed
|
[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)
|
Signals CallAdded(object path, dict properties)
|
||||||
|
|
||||||
Signal that is sent when a new call is added. It
|
Signal that is sent when a new call is added. It
|
||||||
@@ -257,3 +276,26 @@ Properties array{string} EmergencyNumbers [readonly]
|
|||||||
of numbers provided by the specification and any
|
of numbers provided by the specification and any
|
||||||
extra numbers provisioned by the carrier on the
|
extra numbers provisioned by the carrier on the
|
||||||
SIM.
|
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.
|
||||||
|
|
||||||
|
|||||||
310
ofono/drivers/rilmodem/call-barring.c
Normal file
310
ofono/drivers/rilmodem/call-barring.c
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* oFono - Open Source Telephony
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Jolla Ltd
|
||||||
|
* Contact: Miia Leinonen
|
||||||
|
*
|
||||||
|
* 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 <glib.h>
|
||||||
|
|
||||||
|
#include <ofono/log.h>
|
||||||
|
#include <ofono/modem.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "gril.h"
|
||||||
|
#include "call-barring.h"
|
||||||
|
#include "rilmodem.h"
|
||||||
|
#include "ril_constants.h"
|
||||||
|
|
||||||
|
/* See 3GPP 27.007 7.4 for possible values */
|
||||||
|
#define RIL_MAX_SERVICE_LENGTH 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ril.h does not state that string count must be given, but that is
|
||||||
|
* still expected by the modem
|
||||||
|
*/
|
||||||
|
#define RIL_QUERY_STRING_COUNT 4
|
||||||
|
#define RIL_SET_STRING_COUNT 5
|
||||||
|
#define RIL_SET_PW_STRING_COUNT 3
|
||||||
|
|
||||||
|
#define RIL_LENGTH_ZERO 0
|
||||||
|
|
||||||
|
struct barring_data {
|
||||||
|
GRil *ril;
|
||||||
|
guint timer_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ril_call_barring_query_cb(struct ril_msg *message,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
struct parcel rilp;
|
||||||
|
struct ofono_error error;
|
||||||
|
ofono_call_barring_query_cb_t cb = cbd->cb;
|
||||||
|
int bearer_class = 0;
|
||||||
|
|
||||||
|
if (message->error != RIL_E_SUCCESS) {
|
||||||
|
ofono_error("Call Barring query failed, err: %i",
|
||||||
|
message->error);
|
||||||
|
decode_ril_error(&error, "FAIL");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ril_util_init_parcel(message, &rilp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Services for which the specified barring facility is active.
|
||||||
|
* "0" means "disabled for all, -1 if unknown"
|
||||||
|
*/
|
||||||
|
parcel_r_int32(&rilp); /* count - we know there is only 1 */
|
||||||
|
bearer_class = parcel_r_int32(&rilp);
|
||||||
|
DBG("Active services: %i", bearer_class);
|
||||||
|
|
||||||
|
decode_ril_error(&error, "OK");
|
||||||
|
|
||||||
|
out:
|
||||||
|
cb(&error, bearer_class, cbd->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_call_barring_query(struct ofono_call_barring *cb,
|
||||||
|
const char *lock, int cls,
|
||||||
|
ofono_call_barring_query_cb_t callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct barring_data *bd = ofono_call_barring_get_data(cb);
|
||||||
|
struct cb_data *cbd = cb_data_new(callback, data);
|
||||||
|
struct parcel rilp;
|
||||||
|
int ret = 0;
|
||||||
|
char cls_textual[RIL_MAX_SERVICE_LENGTH];
|
||||||
|
|
||||||
|
DBG("lock: %s, services to query: %i", lock, cls);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RIL modems do not support 7 as default bearer class. According to
|
||||||
|
* the 22.030 Annex C: When service code is not given it corresponds to
|
||||||
|
* "All tele and bearer services"
|
||||||
|
*/
|
||||||
|
if (cls == BEARER_CLASS_DEFAULT)
|
||||||
|
cls = SERVICE_CLASS_NONE;
|
||||||
|
|
||||||
|
sprintf(cls_textual, "%d", cls);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See 3GPP 27.007 7.4 for parameter descriptions.
|
||||||
|
* According to ril.h password should be empty string "" when not
|
||||||
|
* needed, but in reality we only need to give string length as 0
|
||||||
|
*/
|
||||||
|
parcel_init(&rilp);
|
||||||
|
parcel_w_int32(&rilp, RIL_QUERY_STRING_COUNT); /* Nbr of strings */
|
||||||
|
parcel_w_string(&rilp, (char *) lock); /* Facility code */
|
||||||
|
parcel_w_int32(&rilp, RIL_LENGTH_ZERO); /* Password length */
|
||||||
|
parcel_w_string(&rilp, (char *) cls_textual);
|
||||||
|
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
|
||||||
|
|
||||||
|
ret = g_ril_send(bd->ril, RIL_REQUEST_QUERY_FACILITY_LOCK,
|
||||||
|
rilp.data, rilp.size, ril_call_barring_query_cb,
|
||||||
|
cbd, g_free);
|
||||||
|
|
||||||
|
parcel_free(&rilp);
|
||||||
|
|
||||||
|
if (ret <= 0) {
|
||||||
|
ofono_error("Sending Call Barring query failed, err: %i", ret);
|
||||||
|
g_free(cbd);
|
||||||
|
CALLBACK_WITH_FAILURE(callback, -1, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_call_barring_set_cb(struct ril_msg *message, gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
struct ofono_error error;
|
||||||
|
ofono_call_barring_set_cb_t cb = cbd->cb;
|
||||||
|
|
||||||
|
if (message->error != RIL_E_SUCCESS) {
|
||||||
|
ofono_error("Call Barring Set request failed, err: %i",
|
||||||
|
message->error);
|
||||||
|
decode_ril_error(&error, "FAIL");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
decode_ril_error(&error, "OK");
|
||||||
|
|
||||||
|
out:
|
||||||
|
cb(&error, cbd->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_call_barring_set(struct ofono_call_barring *cb,
|
||||||
|
const char *lock, int enable,
|
||||||
|
const char *passwd, int cls,
|
||||||
|
ofono_call_barring_set_cb_t callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct barring_data *bd = ofono_call_barring_get_data(cb);
|
||||||
|
struct cb_data *cbd = cb_data_new(callback, data);
|
||||||
|
struct parcel rilp;
|
||||||
|
int ret = 0;
|
||||||
|
char cls_textual[RIL_MAX_SERVICE_LENGTH];
|
||||||
|
|
||||||
|
DBG("lock: %s, enable: %i, bearer class: %i", lock, enable, cls);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RIL modem does not support 7 as default bearer class. According to
|
||||||
|
* the 22.030 Annex C: When service code is not given it corresponds to
|
||||||
|
* "All tele and bearer services"
|
||||||
|
*/
|
||||||
|
if (cls == BEARER_CLASS_DEFAULT)
|
||||||
|
cls = SERVICE_CLASS_NONE;
|
||||||
|
|
||||||
|
sprintf(cls_textual, "%d", cls);
|
||||||
|
|
||||||
|
/* See 3GPP 27.007 7.4 for parameter descriptions */
|
||||||
|
parcel_init(&rilp);
|
||||||
|
parcel_w_int32(&rilp, RIL_SET_STRING_COUNT); /* Nbr of strings */
|
||||||
|
parcel_w_string(&rilp, (char *) lock); /* Facility code */
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
parcel_w_string(&rilp, RIL_FACILITY_LOCK);
|
||||||
|
else
|
||||||
|
parcel_w_string(&rilp, RIL_FACILITY_UNLOCK);
|
||||||
|
|
||||||
|
parcel_w_string(&rilp, (char *) passwd);
|
||||||
|
parcel_w_string(&rilp, (char *) cls_textual);
|
||||||
|
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
|
||||||
|
|
||||||
|
ret = g_ril_send(bd->ril, RIL_REQUEST_SET_FACILITY_LOCK,
|
||||||
|
rilp.data, rilp.size, ril_call_barring_set_cb,
|
||||||
|
cbd, g_free);
|
||||||
|
|
||||||
|
parcel_free(&rilp);
|
||||||
|
|
||||||
|
if (ret <= 0) {
|
||||||
|
ofono_error("Sending Call Barring Set request failed, err: %i",
|
||||||
|
ret);
|
||||||
|
g_free(cbd);
|
||||||
|
CALLBACK_WITH_FAILURE(callback, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_call_barring_set_passwd_cb(struct ril_msg *message,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
struct ofono_error error;
|
||||||
|
ofono_call_barring_set_cb_t cb = cbd->cb;
|
||||||
|
|
||||||
|
if (message->error != RIL_E_SUCCESS) {
|
||||||
|
ofono_error("Call Barring Set PW req failed, err: %i",
|
||||||
|
message->error);
|
||||||
|
decode_ril_error(&error, "FAIL");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
decode_ril_error(&error, "OK");
|
||||||
|
|
||||||
|
out:
|
||||||
|
cb(&error, cbd->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_call_barring_set_passwd(struct ofono_call_barring *barr,
|
||||||
|
const char *lock,
|
||||||
|
const char *old_passwd,
|
||||||
|
const char *new_passwd,
|
||||||
|
ofono_call_barring_set_cb_t cb,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct barring_data *bd = ofono_call_barring_get_data(barr);
|
||||||
|
struct cb_data *cbd = cb_data_new(cb, data);
|
||||||
|
struct parcel rilp;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
DBG("");
|
||||||
|
|
||||||
|
parcel_init(&rilp);
|
||||||
|
parcel_w_int32(&rilp, RIL_SET_PW_STRING_COUNT); /* Nbr of strings */
|
||||||
|
parcel_w_string(&rilp, (char *) lock); /* Facility code */
|
||||||
|
parcel_w_string(&rilp, (char *) old_passwd);
|
||||||
|
parcel_w_string(&rilp, (char *) new_passwd);
|
||||||
|
|
||||||
|
ret = g_ril_send(bd->ril, RIL_REQUEST_CHANGE_BARRING_PASSWORD,
|
||||||
|
rilp.data, rilp.size, ril_call_barring_set_passwd_cb,
|
||||||
|
cbd, g_free);
|
||||||
|
|
||||||
|
parcel_free(&rilp);
|
||||||
|
|
||||||
|
if (ret <= 0) {
|
||||||
|
ofono_error("Sending Call Barring Set PW req failed, err: %i",
|
||||||
|
ret);
|
||||||
|
g_free(cbd);
|
||||||
|
CALLBACK_WITH_FAILURE(cb, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean ril_delayed_register(gpointer user_data)
|
||||||
|
{
|
||||||
|
struct ofono_call_barring *cb = user_data;
|
||||||
|
struct barring_data *bd = ofono_call_barring_get_data(cb);
|
||||||
|
|
||||||
|
bd->timer_id = 0;
|
||||||
|
|
||||||
|
ofono_call_barring_register(cb);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ril_call_barring_probe(struct ofono_call_barring *cb,
|
||||||
|
unsigned int vendor, void *user)
|
||||||
|
{
|
||||||
|
GRil *ril = user;
|
||||||
|
struct barring_data *bd = g_try_new0(struct barring_data, 1);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_call_barring_remove(struct ofono_call_barring *cb)
|
||||||
|
{
|
||||||
|
struct barring_data *data = ofono_call_barring_get_data(cb);
|
||||||
|
ofono_call_barring_set_data(cb, NULL);
|
||||||
|
|
||||||
|
if (data->timer_id > 0)
|
||||||
|
g_source_remove(data->timer_id);
|
||||||
|
|
||||||
|
g_ril_unref(data->ril);
|
||||||
|
g_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ofono_call_barring_driver driver = {
|
||||||
|
.name = "rilmodem",
|
||||||
|
.probe = ril_call_barring_probe,
|
||||||
|
.remove = ril_call_barring_remove,
|
||||||
|
.query = ril_call_barring_query,
|
||||||
|
.set = ril_call_barring_set,
|
||||||
|
.set_passwd = ril_call_barring_set_passwd
|
||||||
|
};
|
||||||
|
|
||||||
|
void ril_call_barring_init(void)
|
||||||
|
{
|
||||||
|
ofono_call_barring_driver_register(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ril_call_barring_exit(void)
|
||||||
|
{
|
||||||
|
ofono_call_barring_driver_unregister(&driver);
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
* Copyright (C) 2013 Jolla Ltd
|
* Copyright (C) 2013-2014 Jolla Ltd
|
||||||
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
|
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -89,16 +89,13 @@ static void ril_registration(struct ofono_call_forwarding *cf, int type,
|
|||||||
|
|
||||||
parcel_w_int32(&rilp, type);
|
parcel_w_int32(&rilp, type);
|
||||||
|
|
||||||
/* Modem seems to respond with error to all queries
|
/*
|
||||||
|
* Modem seems to respond with error to all queries
|
||||||
* or settings made with bearer class
|
* or settings made with bearer class
|
||||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||||
* SERVICE_CLASS_VOICE effectively making it the
|
* BEARER_CLASS_VOICE as per RIL design.
|
||||||
* default bearer. This in line with API which is
|
|
||||||
* contains only voice anyways. TODO: Checkout
|
|
||||||
* the behaviour with final modem
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (cls == BEARER_CLASS_DEFAULT)
|
if (cls == BEARER_CLASS_DEFAULT)
|
||||||
cls = BEARER_CLASS_VOICE;
|
cls = BEARER_CLASS_VOICE;
|
||||||
|
|
||||||
@@ -137,16 +134,13 @@ static void ril_send_forward_cmd(struct ofono_call_forwarding *cf,
|
|||||||
|
|
||||||
parcel_w_int32(&rilp, type);
|
parcel_w_int32(&rilp, type);
|
||||||
|
|
||||||
/* Modem seems to respond with error to all queries
|
/*
|
||||||
|
* Modem seems to respond with error to all queries
|
||||||
* or settings made with bearer class
|
* or settings made with bearer class
|
||||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||||
* SERVICE_CLASS_VOICE effectively making it the
|
* BEARER_CLASS_VOICE as per RIL design.
|
||||||
* default bearer. This in line with API which is
|
|
||||||
* contains only voice anyways. TODO: Checkout
|
|
||||||
* the behaviour with final modem
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (cls == BEARER_CLASS_DEFAULT)
|
if (cls == BEARER_CLASS_DEFAULT)
|
||||||
cls = BEARER_CLASS_VOICE;
|
cls = BEARER_CLASS_VOICE;
|
||||||
|
|
||||||
@@ -241,12 +235,11 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
list[i].phone_number.number[
|
list[i].phone_number.number[
|
||||||
OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
|
OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
|
||||||
|
|
||||||
list[i].time = parcel_r_int32(&rilp);
|
|
||||||
}
|
}
|
||||||
|
list[i].time = parcel_r_int32(&rilp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CALLBACK_WITH_SUCCESS(cb, 1, list, cbd->data);
|
CALLBACK_WITH_SUCCESS(cb, nmbr_of_resps, list, cbd->data);
|
||||||
|
|
||||||
g_free(list);
|
g_free(list);
|
||||||
} else {
|
} else {
|
||||||
@@ -272,18 +265,15 @@ static void ril_query(struct ofono_call_forwarding *cf, int type, int cls,
|
|||||||
|
|
||||||
parcel_w_int32(&rilp, type);
|
parcel_w_int32(&rilp, type);
|
||||||
|
|
||||||
/* Modem seems to respond with error to all queries
|
/*
|
||||||
|
* Modem seems to respond with error to all queries
|
||||||
* or settings made with bearer class
|
* or settings made with bearer class
|
||||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||||
* SERVICE_CLASS_VOICE effectively making it the
|
* SERVICE_CLASS_NONE as per RIL design.
|
||||||
* default bearer. This in line with API which is
|
|
||||||
* contains only voice anyways. TODO: Checkout
|
|
||||||
* the behaviour with final modem
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (cls == BEARER_CLASS_DEFAULT)
|
if (cls == BEARER_CLASS_DEFAULT)
|
||||||
cls = BEARER_CLASS_VOICE;
|
cls = SERVICE_CLASS_NONE;
|
||||||
|
|
||||||
parcel_w_int32(&rilp, cls);
|
parcel_w_int32(&rilp, cls);
|
||||||
|
|
||||||
@@ -351,10 +341,10 @@ static struct ofono_call_forwarding_driver driver = {
|
|||||||
.probe = ril_call_forwarding_probe,
|
.probe = ril_call_forwarding_probe,
|
||||||
.remove = ril_call_forwarding_remove,
|
.remove = ril_call_forwarding_remove,
|
||||||
.erasure = ril_erasure,
|
.erasure = ril_erasure,
|
||||||
.deactivation = ril_deactivate,
|
.deactivation = ril_deactivate,
|
||||||
.query = ril_query,
|
.query = ril_query,
|
||||||
.registration = ril_registration,
|
.registration = ril_registration,
|
||||||
.activation = ril_activate
|
.activation = ril_activate
|
||||||
};
|
};
|
||||||
|
|
||||||
void ril_call_forwarding_init(void)
|
void ril_call_forwarding_init(void)
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ static void query_revision_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
revision = parcel_r_string(&rilp);
|
revision = parcel_r_string(&rilp);
|
||||||
|
|
||||||
cb(&error, revision, cbd->data);
|
cb(&error, revision, cbd->data);
|
||||||
|
g_free(revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_query_revision(struct ofono_devinfo *info,
|
static void ril_query_revision(struct ofono_devinfo *info,
|
||||||
@@ -137,10 +138,10 @@ static void query_serial_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ril_util_init_parcel(message, &rilp);
|
ril_util_init_parcel(message, &rilp);
|
||||||
|
|
||||||
imei = parcel_r_string(&rilp);
|
imei = parcel_r_string(&rilp);
|
||||||
|
|
||||||
cb(&error, imei, cbd->data);
|
cb(&error, imei, cbd->data);
|
||||||
|
g_free(imei);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_query_serial(struct ofono_devinfo *info,
|
static void ril_query_serial(struct ofono_devinfo *info,
|
||||||
|
|||||||
@@ -45,6 +45,12 @@
|
|||||||
|
|
||||||
#include "rilmodem.h"
|
#include "rilmodem.h"
|
||||||
|
|
||||||
|
enum data_call_state {
|
||||||
|
DATA_CALL_INACTIVE,
|
||||||
|
DATA_CALL_LINK_DOWN,
|
||||||
|
DATA_CALL_ACTIVE,
|
||||||
|
};
|
||||||
|
|
||||||
enum state {
|
enum state {
|
||||||
STATE_IDLE,
|
STATE_IDLE,
|
||||||
STATE_ENABLING,
|
STATE_ENABLING,
|
||||||
@@ -62,22 +68,16 @@ struct gprs_context_data {
|
|||||||
|
|
||||||
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
|
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
|
||||||
unsigned int id,
|
unsigned int id,
|
||||||
ofono_gprs_context_cb_t cb, void *data);
|
ofono_gprs_context_cb_t cb,
|
||||||
|
void *data);
|
||||||
|
|
||||||
static void set_context_disconnected(struct gprs_context_data *gcd)
|
static void set_context_disconnected(struct gprs_context_data *gcd)
|
||||||
{
|
{
|
||||||
DBG("");
|
|
||||||
|
|
||||||
gcd->active_ctx_cid = -1;
|
gcd->active_ctx_cid = -1;
|
||||||
gcd->active_rild_cid = -1;
|
gcd->active_rild_cid = -1;
|
||||||
gcd->state = STATE_IDLE;
|
gcd->state = STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconnect_context(struct ofono_gprs_context *gc)
|
|
||||||
{
|
|
||||||
ril_gprs_context_deactivate_primary(gc, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -85,7 +85,6 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
|||||||
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
||||||
struct data_call *call = NULL;
|
struct data_call *call = NULL;
|
||||||
struct unsol_data_call_list *unsol;
|
struct unsol_data_call_list *unsol;
|
||||||
gboolean active_cid_found = FALSE;
|
|
||||||
gboolean disconnect = FALSE;
|
gboolean disconnect = FALSE;
|
||||||
GSList *iterator = NULL;
|
GSList *iterator = NULL;
|
||||||
struct ofono_error error;
|
struct ofono_error error;
|
||||||
@@ -100,19 +99,55 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
|||||||
for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
|
for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
|
||||||
call = (struct data_call *) iterator->data;
|
call = (struct data_call *) iterator->data;
|
||||||
|
|
||||||
if (call->cid == gcd->active_rild_cid) {
|
if (call->status != 0)
|
||||||
active_cid_found = TRUE;
|
ofono_info("data call status:%d", call->status);
|
||||||
|
|
||||||
if (call->active == 0) {
|
if (call->active == DATA_CALL_INACTIVE) {
|
||||||
disconnect = TRUE;
|
disconnect = TRUE;
|
||||||
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
|
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (call->active == DATA_CALL_ACTIVE) {
|
||||||
|
char **split_ip_addr = NULL;
|
||||||
|
const char **dns_addresses;
|
||||||
|
|
||||||
|
if (call->ifname) {
|
||||||
|
ofono_gprs_context_set_interface(gc,
|
||||||
|
call->ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (call->addresses) {
|
||||||
|
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||||
|
ril_util_get_netmask(call->addresses));
|
||||||
|
|
||||||
|
split_ip_addr = g_strsplit(call->addresses,
|
||||||
|
"/", 2);
|
||||||
|
ofono_gprs_context_set_ipv4_address(gc,
|
||||||
|
split_ip_addr[0], TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (call->gateways) {
|
||||||
|
ofono_gprs_context_set_ipv4_gateway(gc,
|
||||||
|
call->gateways);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (call->dnses)
|
||||||
|
DBG("dnses:%s", call->dnses);
|
||||||
|
|
||||||
|
dns_addresses =
|
||||||
|
(const char **)(call->dnses ?
|
||||||
|
g_strsplit((const gchar*)call->dnses, " ", 3)
|
||||||
|
: NULL);
|
||||||
|
|
||||||
|
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
||||||
|
dns_addresses);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disconnect || active_cid_found == FALSE) {
|
if (disconnect) {
|
||||||
ofono_error("Clearing active context");
|
ofono_error("Clearing active context");
|
||||||
set_context_disconnected(gcd);
|
set_context_disconnected(gcd);
|
||||||
}
|
}
|
||||||
@@ -149,10 +184,7 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
gcd->active_rild_cid = reply->cid;
|
gcd->active_rild_cid = reply->cid;
|
||||||
|
|
||||||
if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
|
if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||||
if (gcd->active_rild_cid != -1) {
|
ofono_error("no active context. disconnect");
|
||||||
ofono_error("no active context. disconnect");
|
|
||||||
disconnect_context(gc);
|
|
||||||
}
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +196,6 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
error.type = OFONO_ERROR_TYPE_FAILURE;
|
error.type = OFONO_ERROR_TYPE_FAILURE;
|
||||||
error.error = reply->status;
|
error.error = reply->status;
|
||||||
|
|
||||||
set_context_disconnected(gcd);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +203,7 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
* TODO: consier moving this into parse_data_reply
|
* TODO: consier moving this into parse_data_reply
|
||||||
*
|
*
|
||||||
* Note - the address may optionally include a prefix size
|
* Note - the address may optionally include a prefix size
|
||||||
* ( Eg. "/30" ). As this confuses NetworkManager, we
|
* ( Eg. "/30" ). As this may confuse client, we
|
||||||
* explicitly strip any prefix after calculating the netmask.
|
* explicitly strip any prefix after calculating the netmask.
|
||||||
*/
|
*/
|
||||||
split_ip_addr = g_strsplit(reply->ip_addrs[0], "/", 2);
|
split_ip_addr = g_strsplit(reply->ip_addrs[0], "/", 2);
|
||||||
@@ -209,7 +240,7 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
ofono_gprs_context_set_ipv4_gateway(gc, reply->gateways[0]);
|
ofono_gprs_context_set_ipv4_gateway(gc, reply->gateways[0]);
|
||||||
|
|
||||||
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
||||||
(const char **) reply->dns_addresses);
|
(const char **) reply->dns_addresses);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
g_ril_reply_free_setup_data_call(reply);
|
g_ril_reply_free_setup_data_call(reply);
|
||||||
@@ -219,8 +250,8 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
|
static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
|
||||||
const struct ofono_gprs_primary_context *ctx,
|
const struct ofono_gprs_primary_context *ctx,
|
||||||
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 gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
struct cb_data *cbd = cb_data_new(cb, data);
|
||||||
@@ -284,7 +315,8 @@ error:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
struct cb_data *cbd = user_data;
|
||||||
ofono_gprs_context_cb_t cb = cbd->cb;
|
ofono_gprs_context_cb_t cb = cbd->cb;
|
||||||
@@ -322,7 +354,8 @@ static void ril_deactivate_data_call_cb(struct ril_msg *message, gpointer user_d
|
|||||||
|
|
||||||
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
|
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
|
||||||
unsigned int id,
|
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 gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
|
||||||
struct cb_data *cbd = NULL;
|
struct cb_data *cbd = NULL;
|
||||||
@@ -375,6 +408,7 @@ error:
|
|||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");
|
ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");
|
||||||
g_free(cbd);
|
g_free(cbd);
|
||||||
|
|
||||||
if (cb)
|
if (cb)
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
CALLBACK_WITH_FAILURE(cb, data);
|
||||||
}
|
}
|
||||||
@@ -415,14 +449,13 @@ static void ril_gprs_context_remove(struct ofono_gprs_context *gc)
|
|||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
if (gcd->state != STATE_IDLE) {
|
if (gcd->state != STATE_IDLE)
|
||||||
ril_gprs_context_detach_shutdown(gc, 0);
|
ril_gprs_context_detach_shutdown(gc, 0);
|
||||||
}
|
|
||||||
|
|
||||||
ofono_gprs_context_set_data(gc, NULL);
|
ofono_gprs_context_set_data(gc, NULL);
|
||||||
|
|
||||||
if (gcd->regid != -1)
|
if (gcd->regid != -1)
|
||||||
g_ril_unregister(gcd->ril,gcd->regid);
|
g_ril_unregister(gcd->ril, gcd->regid);
|
||||||
|
|
||||||
g_ril_unref(gcd->ril);
|
g_ril_unref(gcd->ril);
|
||||||
g_free(gcd);
|
g_free(gcd);
|
||||||
@@ -432,9 +465,9 @@ static struct ofono_gprs_context_driver driver = {
|
|||||||
.name = RILMODEM,
|
.name = RILMODEM,
|
||||||
.probe = ril_gprs_context_probe,
|
.probe = ril_gprs_context_probe,
|
||||||
.remove = ril_gprs_context_remove,
|
.remove = ril_gprs_context_remove,
|
||||||
.activate_primary = ril_gprs_context_activate_primary,
|
.activate_primary = ril_gprs_context_activate_primary,
|
||||||
.deactivate_primary = ril_gprs_context_deactivate_primary,
|
.deactivate_primary = ril_gprs_context_deactivate_primary,
|
||||||
.detach_shutdown = ril_gprs_context_detach_shutdown,
|
.detach_shutdown = ril_gprs_context_detach_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ril_gprs_context_init(void)
|
void ril_gprs_context_init(void)
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
#include "rilmodem.h"
|
#include "rilmodem.h"
|
||||||
|
|
||||||
#include <ofono/netreg.h>
|
#include <ofono/netreg.h>
|
||||||
|
#include <ofono/sim.h>
|
||||||
|
#include "storage.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This module is the ofono_gprs_driver implementation for rilmodem.
|
* This module is the ofono_gprs_driver implementation for rilmodem.
|
||||||
@@ -63,16 +65,23 @@
|
|||||||
* +CREG ( see 27.003 7.2 ).
|
* +CREG ( see 27.003 7.2 ).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FAKE_STATE_TIMER 5
|
||||||
|
|
||||||
struct gprs_data {
|
struct gprs_data {
|
||||||
GRil *ril;
|
GRil *ril;
|
||||||
gboolean ofono_attached;
|
gboolean ofono_attached;
|
||||||
int max_cids;
|
int max_cids;
|
||||||
int rild_status;
|
int rild_status;
|
||||||
|
int true_status;
|
||||||
gboolean notified;
|
gboolean notified;
|
||||||
guint registerid;
|
guint registerid;
|
||||||
guint timer_id;
|
guint timer_id;
|
||||||
|
guint fake_timer_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*if we have called ofono_gprs_register or not*/
|
||||||
|
static gboolean registered;
|
||||||
|
|
||||||
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
||||||
ofono_gprs_status_cb_t cb,
|
ofono_gprs_status_cb_t cb,
|
||||||
void *data);
|
void *data);
|
||||||
@@ -81,7 +90,10 @@ static void ril_gprs_state_change(struct ril_msg *message, gpointer user_data)
|
|||||||
{
|
{
|
||||||
struct ofono_gprs *gprs = user_data;
|
struct ofono_gprs *gprs = user_data;
|
||||||
|
|
||||||
g_assert(message->req == RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
|
g_assert(message->req ==
|
||||||
|
RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
|
||||||
|
|
||||||
|
DBG("");
|
||||||
|
|
||||||
/* We need to notify core always to cover situations when
|
/* We need to notify core always to cover situations when
|
||||||
* connection drops temporarily for example when user is
|
* connection drops temporarily for example when user is
|
||||||
@@ -97,6 +109,7 @@ static gboolean ril_gprs_set_attached_callback(gpointer user_data)
|
|||||||
ofono_gprs_cb_t cb = cbd->cb;
|
ofono_gprs_cb_t cb = cbd->cb;
|
||||||
struct ofono_gprs *gprs = cbd->user;
|
struct ofono_gprs *gprs = cbd->user;
|
||||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
gd->timer_id = 0;
|
gd->timer_id = 0;
|
||||||
@@ -129,11 +142,12 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
|
|||||||
* are met.
|
* are met.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
gd->notified = (gd->ofono_attached == attached) ? TRUE : FALSE;
|
||||||
|
|
||||||
gd->ofono_attached = attached;
|
gd->ofono_attached = attached;
|
||||||
|
|
||||||
cbd->user = gprs;
|
cbd->user = gprs;
|
||||||
|
|
||||||
ril_gprs_registration_status(gprs, NULL, NULL);
|
|
||||||
/*
|
/*
|
||||||
* However we cannot respond immediately, since core sets the
|
* However we cannot respond immediately, since core sets the
|
||||||
* value of driver_attached after calling set_attached and that
|
* value of driver_attached after calling set_attached and that
|
||||||
@@ -144,6 +158,42 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
|
|||||||
cbd);
|
cbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean ril_fake_response(gpointer user_data)
|
||||||
|
{
|
||||||
|
struct cb_data *cbd = user_data;
|
||||||
|
struct ofono_gprs *gprs = cbd->user;
|
||||||
|
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
||||||
|
|
||||||
|
DBG("");
|
||||||
|
|
||||||
|
ofono_gprs_status_notify(gprs, gd->true_status);
|
||||||
|
g_free(cbd);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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);
|
||||||
|
|
||||||
|
return roaming_allowed;
|
||||||
|
}
|
||||||
|
|
||||||
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct cb_data *cbd = user_data;
|
struct cb_data *cbd = user_data;
|
||||||
@@ -153,7 +203,8 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
struct ofono_error error;
|
struct ofono_error error;
|
||||||
int status, lac, ci, tech;
|
int status, lac, ci, tech;
|
||||||
int max_cids = 1;
|
int max_cids = 1;
|
||||||
int id = RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED;
|
|
||||||
|
DBG("");
|
||||||
|
|
||||||
if (gd && message->error == RIL_E_SUCCESS) {
|
if (gd && message->error == RIL_E_SUCCESS) {
|
||||||
decode_ril_error(&error, "OK");
|
decode_ril_error(&error, "OK");
|
||||||
@@ -174,12 +225,20 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gd->rild_status == -1) {
|
if ((gd->fake_timer_id > 0) &&
|
||||||
ofono_gprs_register(gprs);
|
((status == (NETWORK_REGISTRATION_STATUS_REGISTERED
|
||||||
|
|| NETWORK_REGISTRATION_STATUS_ROAMING)) ||
|
||||||
|
!(gd->ofono_attached))) {
|
||||||
|
g_source_remove(gd->fake_timer_id);
|
||||||
|
gd->true_status = -1;
|
||||||
|
}
|
||||||
|
|
||||||
DBG("Starting to listen network status");
|
if (status > 10)
|
||||||
gd->registerid = g_ril_register(gd->ril,
|
status = status - 10;
|
||||||
id, ril_gprs_state_change, gprs);
|
|
||||||
|
if (!registered) {
|
||||||
|
ofono_gprs_register(gprs);
|
||||||
|
registered = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_cids > gd->max_cids) {
|
if (max_cids > gd->max_cids) {
|
||||||
@@ -193,63 +252,130 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||||
status = check_if_really_roaming(status);
|
status = check_if_really_roaming(status);
|
||||||
|
|
||||||
if (gd->ofono_attached && !gd->notified) {
|
DBG(" attached:%d, status:%d", gd->ofono_attached, status);
|
||||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
|
|
||||||
status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
|
if (!gd->ofono_attached) {
|
||||||
DBG("connection becomes available");
|
if (status == NETWORK_REGISTRATION_STATUS_ROAMING) {
|
||||||
gd->ofono_attached = TRUE;
|
if (!gd->notified && cb) {
|
||||||
|
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 (status == NETWORK_REGISTRATION_STATUS_SEARCHING &&
|
||||||
|
!gd->notified &&
|
||||||
|
cb)
|
||||||
|
/*
|
||||||
|
* This is a hack that prevents core ending
|
||||||
|
* into eternal loop with driver
|
||||||
|
*/
|
||||||
|
decode_ril_error(&error, "FAIL");
|
||||||
|
|
||||||
ofono_gprs_status_notify(gprs, status);
|
ofono_gprs_status_notify(gprs, status);
|
||||||
gd->notified = TRUE;
|
|
||||||
gd->rild_status = status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cb)
|
||||||
|
gd->notified = TRUE;
|
||||||
|
|
||||||
|
gd->rild_status = status;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gd->ofono_attached &&
|
if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
|
||||||
status != NETWORK_REGISTRATION_STATUS_SEARCHING) {
|
status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
|
||||||
DBG("ofono attached, start faking responses");
|
|
||||||
if (status != NETWORK_REGISTRATION_STATUS_ROAMING) {
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (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);
|
ofono_gprs_status_notify(gprs, status);
|
||||||
gd->ofono_attached = TRUE;
|
gd->rild_status = status;
|
||||||
|
} else {
|
||||||
|
if (gd->fake_timer_id <= 0) {
|
||||||
|
struct cb_data *fake_cbd = cb_data_new(NULL, NULL);
|
||||||
|
|
||||||
|
fake_cbd->user = gprs;
|
||||||
|
gd->fake_timer_id = g_timeout_add_seconds(
|
||||||
|
FAKE_STATE_TIMER,
|
||||||
|
ril_fake_response, fake_cbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gd->true_status = status;
|
||||||
|
|
||||||
|
if (gd->rild_status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||||
|
status = NETWORK_REGISTRATION_STATUS_ROAMING;
|
||||||
|
else
|
||||||
|
status = NETWORK_REGISTRATION_STATUS_REGISTERED;
|
||||||
|
|
||||||
|
gd->rild_status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
ofono_info("data registration status is %d", status);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofono_gprs_register(gprs);
|
||||||
|
|
||||||
|
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 == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||||
|
status = check_if_really_roaming(status);
|
||||||
|
|
||||||
|
out:
|
||||||
|
ofono_info("data registration status is %d", status);
|
||||||
|
|
||||||
|
DBG("Starting to listen network status");
|
||||||
|
gd->registerid = g_ril_register(gd->ril,
|
||||||
|
id, ril_gprs_state_change, gprs);
|
||||||
|
|
||||||
gd->rild_status = status;
|
gd->rild_status = status;
|
||||||
|
|
||||||
error:
|
|
||||||
if (cb)
|
|
||||||
cb(&error, status, cbd->data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
||||||
@@ -261,20 +387,27 @@ static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
|||||||
int request = RIL_REQUEST_DATA_REGISTRATION_STATE;
|
int request = RIL_REQUEST_DATA_REGISTRATION_STATE;
|
||||||
guint ret;
|
guint ret;
|
||||||
|
|
||||||
|
DBG("");
|
||||||
|
|
||||||
if (gd == NULL || cbd == NULL)
|
if (gd == NULL || cbd == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cbd->user = gprs;
|
cbd->user = gprs;
|
||||||
|
|
||||||
ret = g_ril_send(gd->ril, request,
|
ret = g_ril_send(gd->ril, request,
|
||||||
NULL, 0, ril_data_reg_cb, cbd, g_free);
|
NULL, 0,
|
||||||
|
((gd->rild_status == -1)
|
||||||
|
? ril_data_probe_reg_cb
|
||||||
|
: ril_data_reg_cb), cbd, g_free);
|
||||||
|
|
||||||
g_ril_print_request_no_args(gd->ril, ret, request);
|
g_ril_print_request_no_args(gd->ril, ret, request);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE failed.");
|
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE fail.");
|
||||||
g_free(cbd);
|
g_free(cbd);
|
||||||
CALLBACK_WITH_FAILURE(cb, -1, data);
|
|
||||||
|
if (cb)
|
||||||
|
CALLBACK_WITH_FAILURE(cb, -1, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,9 +425,13 @@ static int ril_gprs_probe(struct ofono_gprs *gprs,
|
|||||||
gd->ofono_attached = FALSE;
|
gd->ofono_attached = FALSE;
|
||||||
gd->max_cids = 0;
|
gd->max_cids = 0;
|
||||||
gd->rild_status = -1;
|
gd->rild_status = -1;
|
||||||
|
gd->true_status = -1;
|
||||||
gd->notified = FALSE;
|
gd->notified = FALSE;
|
||||||
gd->registerid = -1;
|
gd->registerid = -1;
|
||||||
gd->timer_id = 0;
|
gd->timer_id = 0;
|
||||||
|
|
||||||
|
registered = FALSE;
|
||||||
|
|
||||||
ofono_gprs_set_data(gprs, gd);
|
ofono_gprs_set_data(gprs, gd);
|
||||||
|
|
||||||
ril_gprs_registration_status(gprs, NULL, NULL);
|
ril_gprs_registration_status(gprs, NULL, NULL);
|
||||||
@@ -316,6 +453,9 @@ static void ril_gprs_remove(struct ofono_gprs *gprs)
|
|||||||
if (gd->timer_id > 0)
|
if (gd->timer_id > 0)
|
||||||
g_source_remove(gd->timer_id);
|
g_source_remove(gd->timer_id);
|
||||||
|
|
||||||
|
if (gd->fake_timer_id > 0)
|
||||||
|
g_source_remove(gd->fake_timer_id);
|
||||||
|
|
||||||
g_ril_unref(gd->ril);
|
g_ril_unref(gd->ril);
|
||||||
g_free(gd);
|
g_free(gd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -573,6 +573,17 @@ error:
|
|||||||
ofono_error("Unable to notify ofono about nitz");
|
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)
|
gint check_if_really_roaming(gint status)
|
||||||
{
|
{
|
||||||
const char *net_mcc = ofono_netreg_get_mcc(current_netreg);
|
const char *net_mcc = ofono_netreg_get_mcc(current_netreg);
|
||||||
@@ -658,6 +669,7 @@ static void ril_netreg_remove(struct ofono_netreg *netreg)
|
|||||||
g_source_remove(nd->nitz_timeout);
|
g_source_remove(nd->nitz_timeout);
|
||||||
|
|
||||||
ofono_netreg_set_data(netreg, NULL);
|
ofono_netreg_set_data(netreg, NULL);
|
||||||
|
current_netreg = NULL;
|
||||||
|
|
||||||
if (nd->timer_id > 0)
|
if (nd->timer_id > 0)
|
||||||
g_source_remove(nd->timer_id);
|
g_source_remove(nd->timer_id);
|
||||||
|
|||||||
@@ -38,14 +38,18 @@
|
|||||||
struct oem_raw_data {
|
struct oem_raw_data {
|
||||||
GRil *ril;
|
GRil *ril;
|
||||||
unsigned int vendor;
|
unsigned int vendor;
|
||||||
|
guint timer_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean ril_oemraw_delayed_register(gpointer user_data)
|
static gboolean ril_oemraw_delayed_register(gpointer user_data)
|
||||||
{
|
{
|
||||||
struct ofono_oem_raw *raw = user_data;
|
struct ofono_oem_raw *raw = user_data;
|
||||||
|
struct oem_raw_data *od = ofono_oem_raw_get_data(raw);
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
|
od->timer_id = 0;
|
||||||
|
|
||||||
ofono_oem_raw_dbus_register(raw);
|
ofono_oem_raw_dbus_register(raw);
|
||||||
return FALSE; /* This makes the timeout a single-shot */
|
return FALSE; /* This makes the timeout a single-shot */
|
||||||
}
|
}
|
||||||
@@ -64,7 +68,8 @@ static int ril_oemraw_probe(struct ofono_oem_raw *raw, unsigned int vendor,
|
|||||||
od->vendor = vendor;
|
od->vendor = vendor;
|
||||||
ofono_oem_raw_set_data(raw, od);
|
ofono_oem_raw_set_data(raw, od);
|
||||||
|
|
||||||
g_timeout_add_seconds(1, ril_oemraw_delayed_register, raw);
|
od->timer_id = g_timeout_add_seconds(1, ril_oemraw_delayed_register,
|
||||||
|
raw);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -79,6 +84,9 @@ static void ril_oemraw_remove(struct ofono_oem_raw *raw)
|
|||||||
|
|
||||||
ofono_oem_raw_set_data(raw, NULL);
|
ofono_oem_raw_set_data(raw, NULL);
|
||||||
|
|
||||||
|
if (od->timer_id)
|
||||||
|
g_source_remove(od->timer_id);
|
||||||
|
|
||||||
g_ril_unref(od->ril);
|
g_ril_unref(od->ril);
|
||||||
g_free(od);
|
g_free(od);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,11 +162,18 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
|
|||||||
char *number, struct pb_file_info *next_file,
|
char *number, struct pb_file_info *next_file,
|
||||||
struct pb_data *pbd)
|
struct pb_data *pbd)
|
||||||
{
|
{
|
||||||
const uint8_t name_length = len - 14;
|
uint8_t name_length;
|
||||||
const uint8_t number_start = name_length;
|
uint8_t number_start;
|
||||||
uint8_t number_length = 0;
|
uint8_t number_length = 0;
|
||||||
uint8_t extension_record = UNUSED;
|
uint8_t extension_record = UNUSED;
|
||||||
uint8_t i, prefix;
|
uint8_t i, prefix;
|
||||||
|
|
||||||
|
if (len < 14)
|
||||||
|
return;
|
||||||
|
|
||||||
|
name_length = len - 14;
|
||||||
|
number_start = name_length;
|
||||||
|
|
||||||
name = sim_string_to_utf8(msg, name_length);
|
name = sim_string_to_utf8(msg, name_length);
|
||||||
/* Length contains also TON&NPI */
|
/* Length contains also TON&NPI */
|
||||||
number_length = msg[number_start];
|
number_length = msg[number_start];
|
||||||
@@ -256,15 +263,19 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_sne(size_t len,
|
void handle_sne(size_t len, const unsigned char *msg, char *sne)
|
||||||
const unsigned char *msg,
|
|
||||||
char *sne)
|
|
||||||
{
|
{
|
||||||
const uint8_t sne_length = len - 2;
|
uint8_t sne_length;
|
||||||
uint8_t phonebook_entry_nbr = msg[len - 1];
|
uint8_t phonebook_entry_nbr;
|
||||||
|
|
||||||
DBG("SNE");
|
DBG("SNE");
|
||||||
|
|
||||||
|
if (len < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sne_length = len - 2;
|
||||||
|
phonebook_entry_nbr = msg[len - 1];
|
||||||
|
|
||||||
sne = sim_string_to_utf8(msg, sne_length);
|
sne = sim_string_to_utf8(msg, sne_length);
|
||||||
|
|
||||||
if (sne) {
|
if (sne) {
|
||||||
@@ -299,20 +310,26 @@ void handle_sne(size_t len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_anr(size_t len,
|
void handle_anr(size_t len,const unsigned char *msg,char *anr,
|
||||||
const unsigned char *msg,
|
struct pb_file_info *next_file, struct pb_data *pbd)
|
||||||
char *anr,
|
|
||||||
struct pb_file_info *next_file,
|
|
||||||
struct pb_data *pbd)
|
|
||||||
{
|
{
|
||||||
uint8_t number_length = 0;
|
uint8_t number_length = 0;
|
||||||
uint8_t extension_record = UNUSED;
|
uint8_t extension_record = UNUSED;
|
||||||
uint8_t aas_record = UNUSED;
|
uint8_t aas_record = UNUSED;
|
||||||
uint8_t i, prefix;
|
uint8_t i, prefix;
|
||||||
uint8_t phonebook_entry_nbr = msg[len - 1];
|
uint8_t phonebook_entry_nbr;
|
||||||
GSList *list_entry;
|
GSList *list_entry;
|
||||||
|
|
||||||
DBG("ANR");
|
DBG("ANR");
|
||||||
|
|
||||||
|
if (!msg)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
phonebook_entry_nbr = msg[len - 1];
|
||||||
|
|
||||||
if (msg[0] == UNUSED)
|
if (msg[0] == UNUSED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -398,11 +415,18 @@ void handle_anr(size_t len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_email(size_t len,
|
void handle_email(size_t len, const unsigned char *msg, char *email)
|
||||||
const unsigned char *msg,
|
|
||||||
char *email)
|
|
||||||
{
|
{
|
||||||
uint8_t phonebook_entry_nbr = msg[len - 1];
|
uint8_t phonebook_entry_nbr;
|
||||||
|
|
||||||
|
if (!msg)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
phonebook_entry_nbr = msg[len - 1];
|
||||||
|
|
||||||
email = sim_string_to_utf8(msg, len - 2);
|
email = sim_string_to_utf8(msg, len - 2);
|
||||||
|
|
||||||
/* GSlist nth counts from 0, PB entries from 1 */
|
/* GSlist nth counts from 0, PB entries from 1 */
|
||||||
@@ -434,13 +458,13 @@ void handle_email(size_t len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_ext1(struct pb_data *pbd,
|
void handle_ext1(struct pb_data *pbd, const unsigned char *msg,
|
||||||
const unsigned char *msg,
|
char *ext_number, struct pb_file_info *next_file)
|
||||||
char *ext_number,
|
|
||||||
struct pb_file_info *next_file)
|
|
||||||
{
|
{
|
||||||
uint8_t number_length, i, next_extension_record;
|
uint8_t number_length, i, next_extension_record;
|
||||||
|
|
||||||
|
if (!msg)
|
||||||
|
return;
|
||||||
|
|
||||||
number_length = msg[1];
|
number_length = msg[1];
|
||||||
|
|
||||||
@@ -818,7 +842,7 @@ static void pb_content_data_cb(const struct ofono_error *error,
|
|||||||
file_info = pb_next->data;
|
file_info = pb_next->data;
|
||||||
|
|
||||||
if (((file_info->structure ==
|
if (((file_info->structure ==
|
||||||
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
|
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
|
||||||
(file_info->structure ==
|
(file_info->structure ==
|
||||||
OFONO_SIM_FILE_STRUCTURE_CYCLIC))
|
OFONO_SIM_FILE_STRUCTURE_CYCLIC))
|
||||||
&& (file_info->record <
|
&& (file_info->record <
|
||||||
@@ -1107,15 +1131,27 @@ static void pb_reference_data_cb(const struct ofono_error *error,
|
|||||||
pbd->pb_reference_file_info.record_length)) {
|
pbd->pb_reference_file_info.record_length)) {
|
||||||
pbd->pb_reference_file_info.record++;
|
pbd->pb_reference_file_info.record++;
|
||||||
DBG("Next EFpbr record %d", pbd->pb_reference_file_info.record);
|
DBG("Next EFpbr record %d", pbd->pb_reference_file_info.record);
|
||||||
pbd->sim_driver->read_file_linear(get_sim(),
|
if (RIL_APPTYPE_SIM == ril_get_app_type()) {
|
||||||
pbd->pb_reference_file_info.
|
pbd->sim_driver->read_file_linear(get_sim(),
|
||||||
file_id,
|
pbd->pb_reference_file_info.
|
||||||
pbd->pb_reference_file_info.
|
file_id,
|
||||||
record,
|
pbd->pb_reference_file_info.
|
||||||
pbd->pb_reference_file_info.
|
record,
|
||||||
record_length,
|
pbd->pb_reference_file_info.
|
||||||
NULL, 0,
|
record_length,
|
||||||
pb_reference_data_cb, cbd);
|
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);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
struct pb_file_info *file_info;
|
struct pb_file_info *file_info;
|
||||||
DBG("All EFpbr records read");
|
DBG("All EFpbr records read");
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <ofono/log.h>
|
#include <ofono/log.h>
|
||||||
#include <ofono/modem.h>
|
#include <ofono/modem.h>
|
||||||
#include <ofono/radio-settings.h>
|
#include <ofono/radio-settings.h>
|
||||||
|
#include <ofono/sim.h>
|
||||||
|
|
||||||
#include "gril.h"
|
#include "gril.h"
|
||||||
#include "grilutil.h"
|
#include "grilutil.h"
|
||||||
@@ -74,7 +75,7 @@ static void ril_set_rat_mode(struct ofono_radio_settings *rs,
|
|||||||
int pref = rd->ratmode;
|
int pref = rd->ratmode;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ofono_info("setting rat mode");
|
ofono_info("setting rat mode:%d", mode);
|
||||||
|
|
||||||
parcel_init(&rilp);
|
parcel_init(&rilp);
|
||||||
|
|
||||||
@@ -200,11 +201,17 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
|||||||
{
|
{
|
||||||
GKeyFile *keyfile;
|
GKeyFile *keyfile;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
char *path = RIL_CONFIG;
|
char *config_path = RIL_CONFIG_DIR;
|
||||||
char **alreadyset = NULL;
|
char **alreadyset = NULL;
|
||||||
gboolean needsconfig = FALSE;
|
gboolean needsconfig = FALSE;
|
||||||
gboolean value = FALSE;
|
gboolean value = FALSE;
|
||||||
|
gboolean found = FALSE;
|
||||||
rsd->ratmode = PREF_NET_TYPE_GSM_WCDMA_AUTO;
|
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
|
* First we need to check should the LTE be on
|
||||||
@@ -215,15 +222,45 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
|||||||
|
|
||||||
g_key_file_set_list_separator(keyfile, ',');
|
g_key_file_set_list_separator(keyfile, ',');
|
||||||
|
|
||||||
if (g_key_file_load_from_file(keyfile, path, 0, &err)) {
|
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_has_group(keyfile, LTE_FLAG))
|
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;
|
rsd->ratmode = PREF_NET_TYPE_LTE_GSM_WCDMA;
|
||||||
} else {
|
break;
|
||||||
g_error_free(err);
|
}
|
||||||
needsconfig = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_key_file_free(keyfile);
|
g_key_file_free(keyfile);
|
||||||
|
g_dir_close(config_dir);
|
||||||
|
|
||||||
/* Then we need to check if it already set */
|
/* Then we need to check if it already set */
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,10 @@ static int rilmodem_init(void)
|
|||||||
ril_ussd_init();
|
ril_ussd_init();
|
||||||
ril_call_settings_init();
|
ril_call_settings_init();
|
||||||
ril_call_forwarding_init();
|
ril_call_forwarding_init();
|
||||||
|
ril_call_barring_init();
|
||||||
ril_cbs_init();
|
ril_cbs_init();
|
||||||
ril_oemraw_init();
|
ril_oemraw_init();
|
||||||
|
ril_stk_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -76,8 +78,10 @@ static void rilmodem_exit(void)
|
|||||||
ril_ussd_exit();
|
ril_ussd_exit();
|
||||||
ril_call_settings_exit();
|
ril_call_settings_exit();
|
||||||
ril_call_forwarding_exit();
|
ril_call_forwarding_exit();
|
||||||
|
ril_call_barring_exit();
|
||||||
ril_cbs_exit();
|
ril_cbs_exit();
|
||||||
ril_oemraw_exit();
|
ril_oemraw_exit();
|
||||||
|
ril_stk_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
OFONO_PLUGIN_DEFINE(rilmodem, "RIL modem driver", VERSION,
|
OFONO_PLUGIN_DEFINE(rilmodem, "RIL modem driver", VERSION,
|
||||||
|
|||||||
@@ -28,9 +28,14 @@
|
|||||||
/* Shared constants */
|
/* Shared constants */
|
||||||
#define EF_STATUS_INVALIDATED 0
|
#define EF_STATUS_INVALIDATED 0
|
||||||
#define EF_STATUS_VALID 1
|
#define EF_STATUS_VALID 1
|
||||||
#define RIL_CONFIG "/etc/ofono/ril_subscription.conf"
|
#define RIL_HW_CONFIG "/etc/ofono/ril_subscription.conf"
|
||||||
|
#define RIL_CONFIG_DIR "/etc/ofono/"
|
||||||
#define RIL_STORE "rilmodem"
|
#define RIL_STORE "rilmodem"
|
||||||
#define LTE_FLAG "4gOn"
|
#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_init(void);
|
||||||
extern void ril_devinfo_exit(void);
|
extern void ril_devinfo_exit(void);
|
||||||
@@ -68,6 +73,9 @@ extern void ril_call_settings_exit(void);
|
|||||||
extern void ril_call_forwarding_init(void);
|
extern void ril_call_forwarding_init(void);
|
||||||
extern void ril_call_forwarding_exit(void);
|
extern void ril_call_forwarding_exit(void);
|
||||||
|
|
||||||
|
extern void ril_call_barring_init(void);
|
||||||
|
extern void ril_call_barring_exit(void);
|
||||||
|
|
||||||
extern void ril_cbs_init(void);
|
extern void ril_cbs_init(void);
|
||||||
extern void ril_cbs_exit(void);
|
extern void ril_cbs_exit(void);
|
||||||
|
|
||||||
@@ -76,3 +84,7 @@ extern void ril_phonebook_exit(void);
|
|||||||
|
|
||||||
extern void ril_oemraw_init(void);
|
extern void ril_oemraw_init(void);
|
||||||
extern void ril_oemraw_exit(void);
|
extern void ril_oemraw_exit(void);
|
||||||
|
|
||||||
|
extern void ril_stk_init(void);
|
||||||
|
extern void ril_stk_exit(void);
|
||||||
|
|
||||||
|
|||||||
@@ -402,13 +402,25 @@ gboolean ril_util_parse_sim_status(GRil *gril,
|
|||||||
|
|
||||||
apps[i]->app_type = parcel_r_int32(&rilp);
|
apps[i]->app_type = parcel_r_int32(&rilp);
|
||||||
apps[i]->app_state = 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);
|
apps[i]->perso_substate = parcel_r_int32(&rilp);
|
||||||
|
|
||||||
/* TODO: we need a way to instruct parcel to skip
|
/* TODO: we need a way to instruct parcel to skip
|
||||||
* a string, without allocating memory...
|
* a string, without allocating memory...
|
||||||
*/
|
*/
|
||||||
apps[i]->aid_str = parcel_r_string(&rilp); /* application ID (AID) */
|
apps[i]->aid_str = parcel_r_string(&rilp); /* app ID (AID) */
|
||||||
apps[i]->app_str = parcel_r_string(&rilp); /* application label */
|
apps[i]->app_str = parcel_r_string(&rilp); /* app label */
|
||||||
|
|
||||||
apps[i]->pin_replaced = parcel_r_int32(&rilp);
|
apps[i]->pin_replaced = parcel_r_int32(&rilp);
|
||||||
apps[i]->pin1_state = parcel_r_int32(&rilp);
|
apps[i]->pin1_state = parcel_r_int32(&rilp);
|
||||||
@@ -459,7 +471,8 @@ gboolean ril_util_parse_reg(GRil *gril,
|
|||||||
* >= 4 for VOICE_REG reply
|
* >= 4 for VOICE_REG reply
|
||||||
* >= 5 for DATA_REG reply
|
* >= 5 for DATA_REG reply
|
||||||
*/
|
*/
|
||||||
if ((tmp = parcel_r_int32(&rilp)) < 4) {
|
tmp = parcel_r_int32(&rilp);
|
||||||
|
if (tmp < 4) {
|
||||||
DBG("Size of response array is too small: %d", tmp);
|
DBG("Size of response array is too small: %d", tmp);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -482,10 +495,12 @@ gboolean ril_util_parse_reg(GRil *gril,
|
|||||||
* voice & data response.
|
* voice & data response.
|
||||||
*/
|
*/
|
||||||
if (tmp--) {
|
if (tmp--) {
|
||||||
sreason = parcel_r_string(&rilp); /* TODO: different use for CDMA */
|
/* TODO: different use for CDMA */
|
||||||
|
sreason = parcel_r_string(&rilp);
|
||||||
|
|
||||||
if (tmp--) {
|
if (tmp--) {
|
||||||
smax = parcel_r_string(&rilp); /* TODO: different use for CDMA */
|
/* TODO: different use for CDMA */
|
||||||
|
smax = parcel_r_string(&rilp);
|
||||||
|
|
||||||
if (smax && max_calls)
|
if (smax && max_calls)
|
||||||
*max_calls = atoi(smax);
|
*max_calls = atoi(smax);
|
||||||
@@ -518,7 +533,7 @@ gboolean ril_util_parse_reg(GRil *gril,
|
|||||||
|
|
||||||
if (tech) {
|
if (tech) {
|
||||||
if (stech) {
|
if (stech) {
|
||||||
switch(atoi(stech)) {
|
switch (atoi(stech)) {
|
||||||
case RADIO_TECH_UNKNOWN:
|
case RADIO_TECH_UNKNOWN:
|
||||||
*tech = -1;
|
*tech = -1;
|
||||||
break;
|
break;
|
||||||
@@ -659,7 +674,8 @@ gint ril_util_get_signal(GRil *gril, struct ril_msg *message)
|
|||||||
return -1;
|
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;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < num_apps; i++) {
|
for (i = 0; i < num_apps; i++) {
|
||||||
|
|||||||
@@ -62,29 +62,6 @@ enum at_util_charset {
|
|||||||
RIL_UTIL_CHARSET_8859_H = 0x10000,
|
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
|
#define MAX_UICC_APPS 16
|
||||||
|
|
||||||
struct sim_status {
|
struct sim_status {
|
||||||
@@ -146,6 +123,8 @@ struct ofono_sim *get_sim();
|
|||||||
|
|
||||||
gint check_if_really_roaming(gint status);
|
gint check_if_really_roaming(gint status);
|
||||||
|
|
||||||
|
gboolean check_if_ok_to_attach();
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
struct cb_data {
|
struct cb_data {
|
||||||
@@ -193,7 +172,7 @@ static inline int ril_util_convert_signal_strength(int strength)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_FAILURE(e) \
|
#define DECLARE_FAILURE(e) \
|
||||||
struct ofono_error e; \
|
struct ofono_error e; \
|
||||||
e.type = OFONO_ERROR_TYPE_FAILURE; \
|
e.type = OFONO_ERROR_TYPE_FAILURE; \
|
||||||
e.error = 0 \
|
e.error = 0 \
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
* Copyright (C) 2013 Canonical, Ltd. 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
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -74,10 +75,6 @@
|
|||||||
#define ENTER_SIM_PUK_PARAMS 3
|
#define ENTER_SIM_PUK_PARAMS 3
|
||||||
#define CHANGE_SIM_PIN_PARAMS 3
|
#define CHANGE_SIM_PIN_PARAMS 3
|
||||||
|
|
||||||
/* RIL_FACILITY_LOCK parameters */
|
|
||||||
#define RIL_FACILITY_UNLOCK "0"
|
|
||||||
#define RIL_FACILITY_LOCK "1"
|
|
||||||
|
|
||||||
/* Current SIM */
|
/* Current SIM */
|
||||||
static struct ofono_sim *current_sim;
|
static struct ofono_sim *current_sim;
|
||||||
/* Current active app */
|
/* Current active app */
|
||||||
@@ -106,6 +103,7 @@ struct sim_data {
|
|||||||
enum ofono_sim_password_type passwd_state;
|
enum ofono_sim_password_type passwd_state;
|
||||||
guint card_state;
|
guint card_state;
|
||||||
guint idle_id;
|
guint idle_id;
|
||||||
|
gboolean removed;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ril_pin_change_state_cb(struct ril_msg *message,
|
static void ril_pin_change_state_cb(struct ril_msg *message,
|
||||||
@@ -183,6 +181,15 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
|
|
||||||
DBG("");
|
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) {
|
if (message->error == RIL_E_SUCCESS) {
|
||||||
decode_ril_error(&error, "OK");
|
decode_ril_error(&error, "OK");
|
||||||
} else {
|
} else {
|
||||||
@@ -217,11 +224,13 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
|
|
||||||
if (response_len) {
|
if (response_len) {
|
||||||
if (response[0] == 0x62) {
|
if (response[0] == 0x62) {
|
||||||
ok = sim_parse_3g_get_response(response, response_len,
|
ok = sim_parse_3g_get_response(
|
||||||
&flen, &rlen, &str, access, NULL);
|
response, response_len,
|
||||||
|
&flen, &rlen, &str, access, NULL);
|
||||||
} else
|
} else
|
||||||
ok = sim_parse_2g_get_response(response, response_len,
|
ok = sim_parse_2g_get_response(
|
||||||
&flen, &rlen, &str, access, &file_status);
|
response, response_len,
|
||||||
|
&flen, &rlen, &str, access, &file_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
@@ -240,7 +249,8 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ril_sim_read_info(struct ofono_sim *sim, int fileid,
|
static void ril_sim_read_info(struct ofono_sim *sim, int fileid,
|
||||||
const unsigned char *path, unsigned int path_len,
|
const unsigned char *path,
|
||||||
|
unsigned int path_len,
|
||||||
ofono_sim_file_info_cb_t cb,
|
ofono_sim_file_info_cb_t cb,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
@@ -340,7 +350,8 @@ error:
|
|||||||
|
|
||||||
static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
|
static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
|
||||||
int start, int length,
|
int start, int length,
|
||||||
const unsigned char *path, unsigned int path_len,
|
const unsigned char *path,
|
||||||
|
unsigned int path_len,
|
||||||
ofono_sim_read_cb_t cb, void *data)
|
ofono_sim_read_cb_t cb, void *data)
|
||||||
{
|
{
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||||
@@ -393,7 +404,8 @@ static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
|
|||||||
|
|
||||||
static void ril_sim_read_record(struct ofono_sim *sim, int fileid,
|
static void ril_sim_read_record(struct ofono_sim *sim, int fileid,
|
||||||
int record, int length,
|
int record, int length,
|
||||||
const unsigned char *path, unsigned int path_len,
|
const unsigned char *path,
|
||||||
|
unsigned int path_len,
|
||||||
ofono_sim_read_cb_t cb, void *data)
|
ofono_sim_read_cb_t cb, void *data)
|
||||||
{
|
{
|
||||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||||
@@ -506,10 +518,10 @@ static void ril_read_imsi(struct ofono_sim *sim, ofono_sim_imsi_cb_t cb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
|
void set_pin_lock_state(struct ofono_sim *sim, struct sim_app *app)
|
||||||
{
|
{
|
||||||
DBG("pin1:%u,pin2:%u",app->pin1_state,app->pin2_state);
|
DBG("pin1:%u,pin2:%u", app->pin1_state, app->pin2_state);
|
||||||
/*
|
/*
|
||||||
* Updates only pin and pin2 state. Other locks are not dealt here. For
|
* Updates only pin and pin2 state. Other locks are not dealt here. For
|
||||||
* that a RIL_REQUEST_QUERY_FACILITY_LOCK request should be used.
|
* that a RIL_REQUEST_QUERY_FACILITY_LOCK request should be used.
|
||||||
*/
|
*/
|
||||||
@@ -518,10 +530,11 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
|
|||||||
case RIL_PINSTATE_ENABLED_VERIFIED:
|
case RIL_PINSTATE_ENABLED_VERIFIED:
|
||||||
case RIL_PINSTATE_ENABLED_BLOCKED:
|
case RIL_PINSTATE_ENABLED_BLOCKED:
|
||||||
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
|
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
|
||||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,TRUE);
|
ofono_set_pin_lock_state(sim, OFONO_SIM_PASSWORD_SIM_PIN, TRUE);
|
||||||
break;
|
break;
|
||||||
case RIL_PINSTATE_DISABLED:
|
case RIL_PINSTATE_DISABLED:
|
||||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,FALSE);
|
ofono_set_pin_lock_state(
|
||||||
|
sim, OFONO_SIM_PASSWORD_SIM_PIN, FALSE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -531,10 +544,12 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
|
|||||||
case RIL_PINSTATE_ENABLED_VERIFIED:
|
case RIL_PINSTATE_ENABLED_VERIFIED:
|
||||||
case RIL_PINSTATE_ENABLED_BLOCKED:
|
case RIL_PINSTATE_ENABLED_BLOCKED:
|
||||||
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
|
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
|
||||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,TRUE);
|
ofono_set_pin_lock_state(
|
||||||
|
sim, OFONO_SIM_PASSWORD_SIM_PIN2, TRUE);
|
||||||
break;
|
break;
|
||||||
case RIL_PINSTATE_DISABLED:
|
case RIL_PINSTATE_DISABLED:
|
||||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,FALSE);
|
ofono_set_pin_lock_state(
|
||||||
|
sim, OFONO_SIM_PASSWORD_SIM_PIN2, FALSE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -552,42 +567,42 @@ static void configure_active_app(struct sim_data *sd,
|
|||||||
|
|
||||||
DBG("setting aid_str (AID) to: %s", sd->aid_str);
|
DBG("setting aid_str (AID) to: %s", sd->aid_str);
|
||||||
switch (app->app_state) {
|
switch (app->app_state) {
|
||||||
case APPSTATE_PIN:
|
case RIL_APPSTATE_PIN:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
|
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
|
||||||
break;
|
break;
|
||||||
case APPSTATE_PUK:
|
case RIL_APPSTATE_PUK:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
|
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
|
||||||
break;
|
break;
|
||||||
case APPSTATE_SUBSCRIPTION_PERSO:
|
case RIL_APPSTATE_SUBSCRIPTION_PERSO:
|
||||||
switch (app->perso_substate) {
|
switch (app->perso_substate) {
|
||||||
case PERSOSUBSTATE_SIM_NETWORK:
|
case RIL_PERSOSUBSTATE_SIM_NETWORK:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PIN;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PIN;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
|
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PIN;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PIN;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_CORPORATE:
|
case RIL_PERSOSUBSTATE_SIM_CORPORATE:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PIN;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PIN;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
|
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PIN;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PIN;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_SIM:
|
case RIL_PERSOSUBSTATE_SIM_SIM:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSIM_PIN;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHSIM_PIN;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_NETWORK_PUK:
|
case RIL_PERSOSUBSTATE_SIM_NETWORK_PUK:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PUK;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PUK;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
|
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PUK;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PUK;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_CORPORATE_PUK:
|
case RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PUK;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PUK;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
|
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PUK;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PUK;
|
||||||
break;
|
break;
|
||||||
case PERSOSUBSTATE_SIM_SIM_PUK:
|
case RIL_PERSOSUBSTATE_SIM_SIM_PUK:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHFSIM_PUK;
|
sd->passwd_state = OFONO_SIM_PASSWORD_PHFSIM_PUK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -595,11 +610,11 @@ static void configure_active_app(struct sim_data *sd,
|
|||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case APPSTATE_READY:
|
case RIL_APPSTATE_READY:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
|
sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
|
||||||
break;
|
break;
|
||||||
case APPSTATE_UNKNOWN:
|
case RIL_APPSTATE_UNKNOWN:
|
||||||
case APPSTATE_DETECTED:
|
case RIL_APPSTATE_DETECTED:
|
||||||
default:
|
default:
|
||||||
sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
|
sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
|
||||||
break;
|
break;
|
||||||
@@ -642,7 +657,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
if (sd->sim_registered == FALSE) {
|
if (sd->sim_registered == FALSE) {
|
||||||
ofono_sim_register(sim);
|
ofono_sim_register(sim);
|
||||||
sd->sim_registered = TRUE;
|
sd->sim_registered = TRUE;
|
||||||
} else
|
} else {
|
||||||
/* TODO: There doesn't seem to be any other
|
/* TODO: There doesn't seem to be any other
|
||||||
* way to force the core SIM code to
|
* way to force the core SIM code to
|
||||||
* recheck the PIN.
|
* recheck the PIN.
|
||||||
@@ -650,15 +665,17 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
* more appropriate call here??
|
* more appropriate call here??
|
||||||
* __ofono_sim_refresh(sim, NULL, TRUE, TRUE);
|
* __ofono_sim_refresh(sim, NULL, TRUE, TRUE);
|
||||||
*/
|
*/
|
||||||
DBG("sd->card_state:%u",sd->card_state);
|
DBG("sd->card_state:%u", sd->card_state);
|
||||||
if (sd->card_state != RIL_CARDSTATE_PRESENT) {
|
if (sd->card_state != RIL_CARDSTATE_PRESENT) {
|
||||||
ofono_sim_inserted_notify(sim, TRUE);
|
ofono_sim_inserted_notify(sim, TRUE);
|
||||||
sd->card_state = RIL_CARDSTATE_PRESENT;
|
sd->card_state = RIL_CARDSTATE_PRESENT;
|
||||||
|
sd->removed = FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (current_passwd) {
|
if (current_passwd) {
|
||||||
if (!strcmp(current_passwd, defaultpasswd)) {
|
if (!strcmp(current_passwd, defaultpasswd)) {
|
||||||
__ofono_sim_recheck_pin(sim);
|
__ofono_sim_recheck_pin(sim);
|
||||||
} else if (sd->passwd_state !=
|
} else if (sd->passwd_state !=
|
||||||
OFONO_SIM_PASSWORD_SIM_PIN) {
|
OFONO_SIM_PASSWORD_SIM_PIN) {
|
||||||
__ofono_sim_recheck_pin(sim);
|
__ofono_sim_recheck_pin(sim);
|
||||||
@@ -690,6 +707,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
parcel_w_int32(&rilp, 1);
|
parcel_w_int32(&rilp, 1);
|
||||||
parcel_w_int32(&rilp, 1);
|
parcel_w_int32(&rilp, 1);
|
||||||
|
|
||||||
|
ofono_info("RIL_REQUEST_RADIO_POWER ON");
|
||||||
g_ril_send(sd->ril,
|
g_ril_send(sd->ril,
|
||||||
RIL_REQUEST_RADIO_POWER,
|
RIL_REQUEST_RADIO_POWER,
|
||||||
rilp.data,
|
rilp.data,
|
||||||
@@ -709,7 +727,10 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
if (status.card_state == RIL_CARDSTATE_ABSENT) {
|
if (status.card_state == RIL_CARDSTATE_ABSENT) {
|
||||||
DBG("sd->card_state:%u,status.card_state:%u,",
|
DBG("sd->card_state:%u,status.card_state:%u,",
|
||||||
sd->card_state, status.card_state);
|
sd->card_state, status.card_state);
|
||||||
|
ofono_info("RIL_CARDSTATE_ABSENT");
|
||||||
ofono_sim_inserted_notify(sim, FALSE);
|
ofono_sim_inserted_notify(sim, FALSE);
|
||||||
|
if (sd->card_state == RIL_CARDSTATE_PRESENT)
|
||||||
|
sd->removed = TRUE;
|
||||||
sd->card_state = RIL_CARDSTATE_ABSENT;
|
sd->card_state = RIL_CARDSTATE_ABSENT;
|
||||||
|
|
||||||
if (current_passwd)
|
if (current_passwd)
|
||||||
@@ -787,8 +808,8 @@ static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
retries[passwd_type] = retry_count;
|
retries[passwd_type] = retry_count;
|
||||||
sd->retries[passwd_type] = retries[passwd_type];
|
sd->retries[passwd_type] = retries[passwd_type];
|
||||||
|
|
||||||
/* TODO: re-bfactor to not use macro for FAILURE; doesn't return error! */
|
DBG("result=%d passwd_type=%d retry_count=%d",
|
||||||
|
message->error, passwd_type, retry_count);
|
||||||
if (message->error == RIL_E_SUCCESS) {
|
if (message->error == RIL_E_SUCCESS) {
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||||
g_ril_print_response_no_args(sd->ril, message);
|
g_ril_print_response_no_args(sd->ril, message);
|
||||||
@@ -837,11 +858,53 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_pin_change_state(struct ofono_sim *sim,
|
static int ril_perso_change_state(struct ofono_sim *sim,
|
||||||
enum ofono_sim_password_type passwd_type,
|
enum ofono_sim_password_type passwd_type,
|
||||||
int enable, const char *passwd,
|
int enable, const char *passwd,
|
||||||
ofono_sim_lock_unlock_cb_t cb, void *data)
|
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 sim_data *sd = ofono_sim_get_data(sim);
|
||||||
struct cb_data *cbd = cb_data_new(cb, data);
|
struct cb_data *cbd = cb_data_new(cb, data);
|
||||||
struct parcel rilp;
|
struct parcel rilp;
|
||||||
@@ -879,9 +942,9 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
|||||||
parcel_w_string(&rilp, "P2");
|
parcel_w_string(&rilp, "P2");
|
||||||
break;
|
break;
|
||||||
case OFONO_SIM_PASSWORD_PHNET_PIN:
|
case OFONO_SIM_PASSWORD_PHNET_PIN:
|
||||||
g_ril_append_print_buf(sd->ril, "(PN,");
|
ret = ril_perso_change_state(sim, passwd_type, enable, passwd,
|
||||||
parcel_w_string(&rilp, "PN");
|
cb, data);
|
||||||
break;
|
goto end;
|
||||||
case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
|
case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
|
||||||
g_ril_append_print_buf(sd->ril, "(PU,");
|
g_ril_append_print_buf(sd->ril, "(PU,");
|
||||||
parcel_w_string(&rilp, "PU");
|
parcel_w_string(&rilp, "PU");
|
||||||
@@ -895,8 +958,7 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
|||||||
parcel_w_string(&rilp, "PC");
|
parcel_w_string(&rilp, "PC");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CALLBACK_WITH_FAILURE(cb, data);
|
goto end;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
@@ -923,6 +985,7 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
|||||||
|
|
||||||
g_ril_print_request(sd->ril, ret, request);
|
g_ril_print_request(sd->ril, ret, request);
|
||||||
|
|
||||||
|
end:
|
||||||
parcel_free(&rilp);
|
parcel_free(&rilp);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
@@ -1052,6 +1115,7 @@ static int ril_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
|||||||
sd->passwd_type = OFONO_SIM_PASSWORD_NONE;
|
sd->passwd_type = OFONO_SIM_PASSWORD_NONE;
|
||||||
sd->sim_registered = FALSE;
|
sd->sim_registered = FALSE;
|
||||||
sd->card_state = RIL_CARDSTATE_ABSENT;
|
sd->card_state = RIL_CARDSTATE_ABSENT;
|
||||||
|
sd->removed = FALSE;
|
||||||
|
|
||||||
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
|
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
|
||||||
sd->retries[i] = -1;
|
sd->retries[i] = -1;
|
||||||
@@ -1085,6 +1149,8 @@ static void ril_sim_remove(struct ofono_sim *sim)
|
|||||||
if (sd->idle_id > 0)
|
if (sd->idle_id > 0)
|
||||||
g_source_remove(sd->idle_id);
|
g_source_remove(sd->idle_id);
|
||||||
|
|
||||||
|
g_free(sd->aid_str);
|
||||||
|
g_free(sd->app_str);
|
||||||
g_ril_unref(sd->ril);
|
g_ril_unref(sd->ril);
|
||||||
g_free(sd);
|
g_free(sd);
|
||||||
}
|
}
|
||||||
@@ -1105,17 +1171,6 @@ static struct ofono_sim_driver driver = {
|
|||||||
.change_passwd = ril_change_passwd,
|
.change_passwd = ril_change_passwd,
|
||||||
.query_pin_retries = ril_query_pin_retries,
|
.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
|
* TODO: Implementing SIM write file IO support requires
|
||||||
* the following functions to be defined.
|
* the following functions to be defined.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -168,10 +168,14 @@ static void submit_sms_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
int mr;
|
int mr;
|
||||||
|
|
||||||
if (message->error == RIL_E_SUCCESS) {
|
if (message->error == RIL_E_SUCCESS) {
|
||||||
ofono_info("sms sending succesful");
|
ofono_info("sms sending successful");
|
||||||
decode_ril_error(&error, "OK");
|
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 {
|
} else {
|
||||||
ofono_error("sms sending failed");
|
ofono_error("sms sending failed, retry");
|
||||||
decode_ril_error(&error, "FAIL");
|
decode_ril_error(&error, "FAIL");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,19 +252,21 @@ static void ril_ack_delivery_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
"SMS acknowledgement failed: Further SMS reception is not guaranteed");
|
"SMS acknowledgement failed: Further SMS reception is not guaranteed");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_ack_delivery(struct ofono_sms *sms)
|
static void ril_ack_delivery(struct ofono_sms *sms, int error)
|
||||||
{
|
{
|
||||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
struct sms_data *sd = ofono_sms_get_data(sms);
|
||||||
struct parcel rilp;
|
struct parcel rilp;
|
||||||
int ret;
|
int ret;
|
||||||
int request = RIL_REQUEST_SMS_ACKNOWLEDGE;
|
int request = RIL_REQUEST_SMS_ACKNOWLEDGE;
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
code = 0xFF;
|
||||||
|
|
||||||
parcel_init(&rilp);
|
parcel_init(&rilp);
|
||||||
parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
|
parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
|
||||||
parcel_w_int32(&rilp, 1); /* Successful receipt */
|
parcel_w_int32(&rilp, error); /* Successful (1)/Failed (0) receipt */
|
||||||
parcel_w_int32(&rilp, 0); /* error code */
|
parcel_w_int32(&rilp, code); /* error code */
|
||||||
|
|
||||||
/* TODO: should ACK be sent for either of the error cases? */
|
|
||||||
|
|
||||||
/* ACK the incoming NEW_SMS */
|
/* ACK the incoming NEW_SMS */
|
||||||
ret = g_ril_send(sd->ril, request,
|
ret = g_ril_send(sd->ril, request,
|
||||||
@@ -329,11 +335,13 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
|
|||||||
ril_buf_len - smsc_len);
|
ril_buf_len - smsc_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
ril_ack_delivery(sms);
|
ril_ack_delivery(sms, TRUE);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
ril_ack_delivery(sms, FALSE);
|
||||||
|
|
||||||
ofono_error("Unable to parse NEW_SMS notification");
|
ofono_error("Unable to parse NEW_SMS notification");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
337
ofono/drivers/rilmodem/stk.c
Normal file
337
ofono/drivers/rilmodem/stk.c
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
ofono_stk_proactive_command_notify(stk, len, (const guchar *)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);
|
||||||
|
|
||||||
|
ofono_stk_proactive_command_handled_notify(stk, len,
|
||||||
|
(const guchar *)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);
|
||||||
|
}
|
||||||
@@ -75,12 +75,30 @@ static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
|
|||||||
if (charset == SMS_CHARSET_7BIT) {
|
if (charset == SMS_CHARSET_7BIT) {
|
||||||
unsigned char unpacked_buf[182] = "";
|
unsigned char unpacked_buf[182] = "";
|
||||||
long written;
|
long written;
|
||||||
|
int length;
|
||||||
|
|
||||||
unpack_7bit_own_buf(pdu, len, 0, TRUE,
|
unpack_7bit_own_buf(pdu, len, 0, TRUE,
|
||||||
sizeof(unpacked_buf), &written, 0,
|
sizeof(unpacked_buf), &written, 0,
|
||||||
unpacked_buf);
|
unpacked_buf);
|
||||||
|
|
||||||
if (written >= 1) {
|
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;
|
struct parcel rilp;
|
||||||
parcel_init(&rilp);
|
parcel_init(&rilp);
|
||||||
parcel_w_string(&rilp, (char *)unpacked_buf);
|
parcel_w_string(&rilp, (char *)unpacked_buf);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
* Copyright (C) 2012 Canonical Ltd.
|
* Copyright (C) 2012 Canonical Ltd.
|
||||||
* Copyright (C) 2013 Jolla Ltd.
|
* Copyright (C) 2014 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -86,6 +86,21 @@ struct lastcause_req {
|
|||||||
static void send_one_dtmf(struct voicecall_data *vd);
|
static void send_one_dtmf(struct voicecall_data *vd);
|
||||||
static void clear_dtmf_queue(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)
|
static void lastcause_cb(struct ril_msg *message, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct lastcause_req *reqdata = user_data;
|
struct lastcause_req *reqdata = user_data;
|
||||||
@@ -99,11 +114,38 @@ static void lastcause_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
if (parcel_r_int32(&rilp) > 0)
|
if (parcel_r_int32(&rilp) > 0)
|
||||||
last_cause = parcel_r_int32(&rilp);
|
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);
|
ofono_info("Call %d ended with RIL cause %d", id, last_cause);
|
||||||
if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) {
|
if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) {
|
||||||
reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
|
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);
|
ofono_voicecall_disconnected(vc, id, reason, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +278,8 @@ static void generic_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
int request = RIL_REQUEST_GET_CURRENT_CALLS;
|
int request = RIL_REQUEST_GET_CURRENT_CALLS;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ofono_info("request:%d",message->req);
|
||||||
|
|
||||||
if (message->error == RIL_E_SUCCESS) {
|
if (message->error == RIL_E_SUCCESS) {
|
||||||
decode_ril_error(&error, "OK");
|
decode_ril_error(&error, "OK");
|
||||||
} else {
|
} else {
|
||||||
@@ -634,6 +678,13 @@ static void ril_create_multiparty(struct ofono_voicecall *vc,
|
|||||||
cb(&error, data);
|
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)
|
static void private_chat_cb(struct ril_msg *message, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct ofono_error error;
|
struct ofono_error error;
|
||||||
@@ -727,6 +778,23 @@ static gboolean enable_supp_svc(gpointer user_data)
|
|||||||
return FALSE;
|
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)
|
static gboolean ril_delayed_register(gpointer user_data)
|
||||||
{
|
{
|
||||||
struct ofono_voicecall *vc = user_data;
|
struct ofono_voicecall *vc = user_data;
|
||||||
@@ -747,6 +815,10 @@ static gboolean ril_delayed_register(gpointer user_data)
|
|||||||
g_ril_register(vd->ril, RIL_UNSOL_SUPP_SVC_NOTIFICATION,
|
g_ril_register(vd->ril, RIL_UNSOL_SUPP_SVC_NOTIFICATION,
|
||||||
ril_ss_notify, vc);
|
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*/
|
/* request supplementary service notifications*/
|
||||||
enable_supp_svc(vc);
|
enable_supp_svc(vc);
|
||||||
|
|
||||||
@@ -803,6 +875,7 @@ static void ril_voicecall_remove(struct ofono_voicecall *vc)
|
|||||||
if (vd->timer_id > 0)
|
if (vd->timer_id > 0)
|
||||||
g_source_remove(vd->timer_id);
|
g_source_remove(vd->timer_id);
|
||||||
|
|
||||||
|
g_free(vd->tone_queue);
|
||||||
g_ril_unref(vd->ril);
|
g_ril_unref(vd->ril);
|
||||||
g_free(vd);
|
g_free(vd);
|
||||||
}
|
}
|
||||||
@@ -817,12 +890,13 @@ static struct ofono_voicecall_driver driver = {
|
|||||||
.release_specific = ril_hangup_specific,
|
.release_specific = ril_hangup_specific,
|
||||||
.send_tones = ril_send_dtmf,
|
.send_tones = ril_send_dtmf,
|
||||||
.create_multiparty = ril_create_multiparty,
|
.create_multiparty = ril_create_multiparty,
|
||||||
|
.transfer = ril_transfer,
|
||||||
.private_chat = ril_private_chat,
|
.private_chat = ril_private_chat,
|
||||||
.swap_without_accept = ril_swap_without_accept,
|
.swap_without_accept = ril_swap_without_accept,
|
||||||
.hold_all_active = ril_hold_all_active,
|
.hold_all_active = ril_hold_all_active,
|
||||||
.release_all_held = ril_release_all_held,
|
.release_all_held = ril_release_all_held,
|
||||||
.set_udub = ril_set_udub,
|
.set_udub = ril_set_udub,
|
||||||
.release_all_active = ril_release_all_active,
|
.release_all_active = ril_release_all_active,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ril_voicecall_init(void)
|
void ril_voicecall_init(void)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=DUN service
|
Description=DUN service
|
||||||
After=syslog.target
|
Requires=dbus.service
|
||||||
|
After=dbus.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=dbus
|
Type=dbus
|
||||||
|
|||||||
@@ -835,6 +835,9 @@ static gboolean can_write_data(gpointer data)
|
|||||||
gsize len;
|
gsize len;
|
||||||
char *cr;
|
char *cr;
|
||||||
gboolean wakeup_first = FALSE;
|
gboolean wakeup_first = FALSE;
|
||||||
|
#ifdef WRITE_SCHEDULER_DEBUG
|
||||||
|
int limiter;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Grab the first command off the queue and write as
|
/* Grab the first command off the queue and write as
|
||||||
* much of it as we can
|
* much of it as we can
|
||||||
@@ -886,13 +889,20 @@ static gboolean can_write_data(gpointer data)
|
|||||||
towrite = cr - (cmd->cmd + chat->cmd_bytes_written) + 1;
|
towrite = cr - (cmd->cmd + chat->cmd_bytes_written) + 1;
|
||||||
|
|
||||||
#ifdef WRITE_SCHEDULER_DEBUG
|
#ifdef WRITE_SCHEDULER_DEBUG
|
||||||
if (towrite > 5)
|
limiter = towrite;
|
||||||
towrite = 5;
|
|
||||||
|
if (limiter > 5)
|
||||||
|
limiter = 5;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bytes_written = g_at_io_write(chat->io,
|
bytes_written = g_at_io_write(chat->io,
|
||||||
cmd->cmd + chat->cmd_bytes_written,
|
cmd->cmd + chat->cmd_bytes_written,
|
||||||
towrite);
|
#ifdef WRITE_SCHEDULER_DEBUG
|
||||||
|
limiter
|
||||||
|
#else
|
||||||
|
towrite
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
if (bytes_written == 0)
|
if (bytes_written == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@@ -355,7 +355,8 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
|||||||
int i;
|
int i;
|
||||||
guint len, id;
|
guint len, id;
|
||||||
|
|
||||||
g_assert(count > 0);
|
if (!count)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
req = g_queue_peek_nth(p->command_queue, i);
|
req = g_queue_peek_nth(p->command_queue, i);
|
||||||
@@ -373,13 +374,13 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
|||||||
message->error));
|
message->error));
|
||||||
|
|
||||||
req = g_queue_pop_nth(p->command_queue, i);
|
req = g_queue_pop_nth(p->command_queue, i);
|
||||||
if (req->callback) {
|
if (req->callback)
|
||||||
req->callback(message, req->user_data);
|
req->callback(message, req->user_data);
|
||||||
}
|
|
||||||
|
|
||||||
len = g_queue_get_length(p->out_queue);
|
len = g_queue_get_length(p->out_queue);
|
||||||
for (i = 0; i < len; i++) {
|
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) {
|
if (id == req->id) {
|
||||||
g_queue_pop_nth(p->out_queue, i);
|
g_queue_pop_nth(p->out_queue, i);
|
||||||
break;
|
break;
|
||||||
@@ -403,14 +404,21 @@ 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)
|
static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
|
||||||
{
|
{
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
struct ril_notify *notify;
|
struct ril_notify *notify;
|
||||||
int req_key;
|
int req_key;
|
||||||
gpointer key, value;
|
gpointer key, value;
|
||||||
GList *list_item;
|
GSList *list_item;
|
||||||
struct ril_notify_node *node;
|
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
|
|
||||||
if (p->notify_list == NULL)
|
if (p->notify_list == NULL)
|
||||||
@@ -430,15 +438,12 @@ static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
|
|||||||
if (req_key != message->req)
|
if (req_key != message->req)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
list_item = (GList *) notify->nodes;
|
list_item = notify->nodes;
|
||||||
|
|
||||||
while (list_item != NULL) {
|
if (list_item)
|
||||||
node = list_item->data;
|
|
||||||
|
|
||||||
node->callback(message, node->user_data);
|
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
list_item = (GList *) g_slist_next(list_item);
|
|
||||||
}
|
g_slist_foreach(notify->nodes, notify_call_callback, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only log events not being listended for... */
|
/* Only log events not being listended for... */
|
||||||
@@ -582,9 +587,8 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
|
|||||||
while (p->suspended == FALSE && (p->read_so_far < len)) {
|
while (p->suspended == FALSE && (p->read_so_far < len)) {
|
||||||
gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
|
gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
|
||||||
|
|
||||||
if (rbytes < 4) {
|
if (rbytes < 4)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* this function attempts to read the next full length
|
/* this function attempts to read the next full length
|
||||||
* fixed message from the stream. if not all bytes are
|
* fixed message from the stream. if not all bytes are
|
||||||
@@ -595,9 +599,8 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
|
|||||||
message = read_fixed_record(p, buf, &rbytes);
|
message = read_fixed_record(p, buf, &rbytes);
|
||||||
|
|
||||||
/* wait for the rest of the record... */
|
/* wait for the rest of the record... */
|
||||||
if (message == NULL) {
|
if (message == NULL)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
buf += rbytes;
|
buf += rbytes;
|
||||||
p->read_so_far += rbytes;
|
p->read_so_far += rbytes;
|
||||||
@@ -642,7 +645,8 @@ static gboolean can_write_data(gpointer data)
|
|||||||
for (i = 0; i < qlen; i++) {
|
for (i = 0; i < qlen; i++) {
|
||||||
req = g_queue_peek_nth(ril->command_queue, i);
|
req = g_queue_peek_nth(ril->command_queue, i);
|
||||||
if (req) {
|
if (req) {
|
||||||
id = *(guint *) g_queue_peek_head(ril->out_queue);
|
id = *(guint *) g_queue_peek_head(
|
||||||
|
ril->out_queue);
|
||||||
if (req->id == id)
|
if (req->id == id)
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -191,6 +191,7 @@
|
|||||||
#define RIL_PERSOSUBSTATE_RUIM_RUIM_PUK 24
|
#define RIL_PERSOSUBSTATE_RUIM_RUIM_PUK 24
|
||||||
|
|
||||||
/* SIM - App states */
|
/* SIM - App states */
|
||||||
|
#define RIL_APPSTATE_ILLEGAL -1
|
||||||
#define RIL_APPSTATE_UNKNOWN 0
|
#define RIL_APPSTATE_UNKNOWN 0
|
||||||
#define RIL_APPSTATE_DETECTED 1
|
#define RIL_APPSTATE_DETECTED 1
|
||||||
#define RIL_APPSTATE_PIN 2
|
#define RIL_APPSTATE_PIN 2
|
||||||
@@ -384,4 +385,11 @@
|
|||||||
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1040
|
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1040
|
||||||
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1041
|
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1041
|
||||||
|
|
||||||
|
/* Suplementary services Service class*/
|
||||||
|
#define SERVICE_CLASS_NONE 0
|
||||||
|
|
||||||
|
/* RIL_FACILITY_LOCK parameters */
|
||||||
|
#define RIL_FACILITY_UNLOCK "0"
|
||||||
|
#define RIL_FACILITY_LOCK "1"
|
||||||
|
|
||||||
#endif /*__RIL_CONSTANTS_H*/
|
#endif /*__RIL_CONSTANTS_H*/
|
||||||
|
|||||||
@@ -80,29 +80,29 @@ extern "C" {
|
|||||||
DBusConnection *ofono_dbus_get_connection(void);
|
DBusConnection *ofono_dbus_get_connection(void);
|
||||||
|
|
||||||
void ofono_dbus_dict_append(DBusMessageIter *dict, const char *key, int type,
|
void ofono_dbus_dict_append(DBusMessageIter *dict, const char *key, int type,
|
||||||
void *value);
|
const void *value);
|
||||||
|
|
||||||
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||||
int type, void *val);
|
int type, const void *val);
|
||||||
|
|
||||||
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
||||||
int type, void *val);
|
int type, const void *val);
|
||||||
|
|
||||||
int ofono_dbus_signal_property_changed(DBusConnection *conn, const char *path,
|
int ofono_dbus_signal_property_changed(DBusConnection *conn, const char *path,
|
||||||
const char *interface, const char *name,
|
const char *interface, const char *name,
|
||||||
int type, void *value);
|
int type, const void *value);
|
||||||
|
|
||||||
int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
|
int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *name, int type,
|
const char *name, int type,
|
||||||
void *value);
|
const void *value);
|
||||||
|
|
||||||
int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *name, int type,
|
const char *name, int type,
|
||||||
void *value);
|
const void *value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ extern "C" {
|
|||||||
struct ofono_gprs_provision_data {
|
struct ofono_gprs_provision_data {
|
||||||
enum ofono_gprs_context_type type;
|
enum ofono_gprs_context_type type;
|
||||||
enum ofono_gprs_proto proto;
|
enum ofono_gprs_proto proto;
|
||||||
|
char *provider_name;
|
||||||
|
ofono_bool_t provider_primary;
|
||||||
char *name;
|
char *name;
|
||||||
char *apn;
|
char *apn;
|
||||||
char *username;
|
char *username;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ struct ofono_stk_driver {
|
|||||||
int length, const unsigned char *resp,
|
int length, const unsigned char *resp,
|
||||||
ofono_stk_generic_cb_t cb, void *data);
|
ofono_stk_generic_cb_t cb, void *data);
|
||||||
void (*user_confirmation)(struct ofono_stk *stk, ofono_bool_t confirm);
|
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);
|
int ofono_stk_driver_register(const struct ofono_stk_driver *d);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
|
* Copyright (C) 2014 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -171,6 +172,9 @@ void ofono_voicecall_ssn_mt_notify(struct ofono_voicecall *vc, unsigned int id,
|
|||||||
int code, int index,
|
int code, int index,
|
||||||
const struct ofono_phone_number *ph);
|
const struct ofono_phone_number *ph);
|
||||||
|
|
||||||
|
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
|
||||||
|
const ofono_bool_t playTone);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ enum MBPI_ERROR {
|
|||||||
struct gsm_data {
|
struct gsm_data {
|
||||||
const char *match_mcc;
|
const char *match_mcc;
|
||||||
const char *match_mnc;
|
const char *match_mnc;
|
||||||
|
char *provider_name;
|
||||||
|
gboolean provider_primary;
|
||||||
GSList *apns;
|
GSList *apns;
|
||||||
gboolean match_found;
|
gboolean match_found;
|
||||||
gboolean allow_duplicates;
|
gboolean allow_duplicates;
|
||||||
@@ -84,6 +86,7 @@ static GQuark mbpi_error_quark(void)
|
|||||||
|
|
||||||
void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
|
void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
|
||||||
{
|
{
|
||||||
|
g_free(ap->provider_name);
|
||||||
g_free(ap->name);
|
g_free(ap->name);
|
||||||
g_free(ap->apn);
|
g_free(ap->apn);
|
||||||
g_free(ap->username);
|
g_free(ap->username);
|
||||||
@@ -117,6 +120,7 @@ static void text_handler(GMarkupParseContext *context,
|
|||||||
{
|
{
|
||||||
char **string = userdata;
|
char **string = userdata;
|
||||||
|
|
||||||
|
g_free(*string);
|
||||||
*string = g_strndup(text, text_len);
|
*string = g_strndup(text, text_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +194,9 @@ static void apn_end(GMarkupParseContext *context, const gchar *element_name,
|
|||||||
{
|
{
|
||||||
if (g_str_equal(element_name, "name") ||
|
if (g_str_equal(element_name, "name") ||
|
||||||
g_str_equal(element_name, "username") ||
|
g_str_equal(element_name, "username") ||
|
||||||
g_str_equal(element_name, "password"))
|
g_str_equal(element_name, "password") ||
|
||||||
|
g_str_equal(element_name, "mmsc") ||
|
||||||
|
g_str_equal(element_name, "mmsproxy"))
|
||||||
g_markup_parse_context_pop(context);
|
g_markup_parse_context_pop(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,6 +292,9 @@ static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ap = g_new0(struct ofono_gprs_provision_data, 1);
|
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->apn = g_strdup(apn);
|
||||||
ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
|
ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
|
||||||
ap->proto = OFONO_GPRS_PROTO_IP;
|
ap->proto = OFONO_GPRS_PROTO_IP;
|
||||||
@@ -452,27 +461,68 @@ static const GMarkupParser provider_parser = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void toplevel_gsm_start(GMarkupParseContext *context,
|
static void gsm_provider_start(GMarkupParseContext *context,
|
||||||
const gchar *element_name,
|
const gchar *element_name,
|
||||||
const gchar **atribute_names,
|
const gchar **attribute_names,
|
||||||
const gchar **attribute_values,
|
const gchar **attribute_values,
|
||||||
gpointer userdata, GError **error)
|
gpointer userdata, GError **error)
|
||||||
{
|
{
|
||||||
struct gsm_data *gsm = userdata;
|
struct gsm_data *gsm = userdata;
|
||||||
|
|
||||||
if (g_str_equal(element_name, "gsm")) {
|
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")) {
|
||||||
gsm->match_found = FALSE;
|
gsm->match_found = FALSE;
|
||||||
g_markup_parse_context_push(context, &gsm_parser, gsm);
|
g_markup_parse_context_push(context, &gsm_parser, gsm);
|
||||||
} else if (g_str_equal(element_name, "cdma"))
|
} else if (g_str_equal(element_name, "cdma"))
|
||||||
g_markup_parse_context_push(context, &skip_parser, NULL);
|
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,
|
static void toplevel_gsm_end(GMarkupParseContext *context,
|
||||||
const gchar *element_name,
|
const gchar *element_name,
|
||||||
gpointer userdata, GError **error)
|
gpointer userdata, GError **error)
|
||||||
{
|
{
|
||||||
if (g_str_equal(element_name, "gsm") ||
|
if (g_str_equal(element_name, "provider"))
|
||||||
g_str_equal(element_name, "cdma"))
|
|
||||||
g_markup_parse_context_pop(context);
|
g_markup_parse_context_pop(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +536,7 @@ static const GMarkupParser toplevel_gsm_parser = {
|
|||||||
|
|
||||||
static void toplevel_cdma_start(GMarkupParseContext *context,
|
static void toplevel_cdma_start(GMarkupParseContext *context,
|
||||||
const gchar *element_name,
|
const gchar *element_name,
|
||||||
const gchar **atribute_names,
|
const gchar **attribute_names,
|
||||||
const gchar **attribute_values,
|
const gchar **attribute_values,
|
||||||
gpointer userdata, GError **error)
|
gpointer userdata, GError **error)
|
||||||
{
|
{
|
||||||
@@ -589,6 +639,7 @@ GSList *mbpi_lookup_apn(const char *mcc, const char *mnc,
|
|||||||
gsm.apns = NULL;
|
gsm.apns = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free(gsm.provider_name);
|
||||||
return gsm.apns;
|
return gsm.apns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,11 +188,11 @@ static int nettime_probe(struct ofono_nettime_context *context)
|
|||||||
NULL, // GDBusPropertyTable *properties
|
NULL, // GDBusPropertyTable *properties
|
||||||
NULL, // user data
|
NULL, // user data
|
||||||
NULL)) { // GDBusDestroyFunction destroy
|
NULL)) { // GDBusDestroyFunction destroy
|
||||||
ofono_error("Networkt time: Could not register interface %s, path %s",
|
ofono_error("Network time: Could not register interface %s, path %s",
|
||||||
OFONO_NETWORK_TIME_INTERFACE, path);
|
OFONO_NETWORK_TIME_INTERFACE, path);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
ofono_info("Network time: Registered inteface %s, path %s",
|
ofono_info("Network time: Registered interface %s, path %s",
|
||||||
OFONO_NETWORK_TIME_INTERFACE, path);
|
OFONO_NETWORK_TIME_INTERFACE, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +235,12 @@ static void nettime_info_received(struct ofono_nettime_context *context,
|
|||||||
|
|
||||||
netreg = __ofono_atom_get_data(__ofono_modem_find_atom(
|
netreg = __ofono_atom_get_data(__ofono_modem_find_atom(
|
||||||
context->modem, OFONO_ATOM_TYPE_NETREG));
|
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->path = ofono_modem_get_path(context->modem);
|
||||||
ntd->mcc = ofono_netreg_get_mcc(netreg);
|
ntd->mcc = ofono_netreg_get_mcc(netreg);
|
||||||
ntd->mnc = ofono_netreg_get_mnc(netreg);
|
ntd->mnc = ofono_netreg_get_mnc(netreg);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -36,9 +37,134 @@
|
|||||||
#include <ofono/modem.h>
|
#include <ofono/modem.h>
|
||||||
#include <ofono/gprs-provision.h>
|
#include <ofono/gprs-provision.h>
|
||||||
|
|
||||||
|
#include "provision.h"
|
||||||
#include "mbpi.h"
|
#include "mbpi.h"
|
||||||
|
|
||||||
static int provision_get_settings(const char *mcc, const char *mnc,
|
/* 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,
|
||||||
const char *spn,
|
const char *spn,
|
||||||
struct ofono_gprs_provision_data **settings,
|
struct ofono_gprs_provision_data **settings,
|
||||||
int *count)
|
int *count)
|
||||||
@@ -49,36 +175,26 @@ static int provision_get_settings(const char *mcc, const char *mnc,
|
|||||||
int ap_count;
|
int ap_count;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DBG("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
|
ofono_info("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: review with upstream. Default behavior was to
|
* Passing FALSE to mbpi_lookup_apn() would return
|
||||||
* disallow duplicate APN entries, which unfortunately exist
|
* an empty list if duplicates are found.
|
||||||
* in the mobile-broadband-provider-info db.
|
|
||||||
*/
|
*/
|
||||||
apns = mbpi_lookup_apn(mcc, mnc, TRUE, &error);
|
apns = mbpi_lookup_apn(mcc, mnc, TRUE, &error);
|
||||||
if (apns == NULL) {
|
if (error != NULL) {
|
||||||
if (error != NULL) {
|
ofono_error("%s", error->message);
|
||||||
ofono_error("%s", error->message);
|
g_error_free(error);
|
||||||
g_error_free(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
ap_count = g_slist_length(apns);
|
||||||
|
|
||||||
ofono_info("GPRS Provisioning found %d matching APNs for SPN: %s MCC: %s MNC: %s",
|
ofono_info("Provisioning %d APs", ap_count);
|
||||||
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);
|
*settings = g_try_new0(struct ofono_gprs_provision_data, ap_count);
|
||||||
if (*settings == NULL) {
|
if (*settings == NULL) {
|
||||||
@@ -97,25 +213,16 @@ static int provision_get_settings(const char *mcc, const char *mnc,
|
|||||||
for (l = apns, i = 0; l; l = l->next, i++) {
|
for (l = apns, i = 0; l; l = l->next, i++) {
|
||||||
struct ofono_gprs_provision_data *ap = l->data;
|
struct ofono_gprs_provision_data *ap = l->data;
|
||||||
|
|
||||||
/*
|
ofono_info("Name: '%s'", ap->name);
|
||||||
* Only create a data context for the first matching APN.
|
ofono_info("APN: '%s'", ap->apn);
|
||||||
* See comment above that restricts restricts apn_count.
|
ofono_info("Type: %s", mbpi_ap_type(ap->type));
|
||||||
*/
|
ofono_info("Username: '%s'", ap->username);
|
||||||
if (i == 0) {
|
ofono_info("Password: '%s'", ap->password);
|
||||||
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,
|
memcpy(*settings + i, ap,
|
||||||
sizeof(struct ofono_gprs_provision_data));
|
sizeof(struct ofono_gprs_provision_data));
|
||||||
|
|
||||||
g_free(ap);
|
|
||||||
} else {
|
|
||||||
mbpi_ap_free(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
g_free(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free(apns);
|
g_slist_free(apns);
|
||||||
|
|||||||
28
ofono/plugins/provision.h
Normal file
28
ofono/plugins/provision.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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);
|
||||||
|
|
||||||
541
ofono/plugins/push-forwarder.c
Normal file
541
ofono/plugins/push-forwarder.c
Normal file
@@ -0,0 +1,541 @@
|
|||||||
|
/*
|
||||||
|
* 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)
|
||||||
@@ -63,6 +63,7 @@
|
|||||||
#include <ofono/types.h>
|
#include <ofono/types.h>
|
||||||
#include <ofono/message-waiting.h>
|
#include <ofono/message-waiting.h>
|
||||||
#include <ofono/oemraw.h>
|
#include <ofono/oemraw.h>
|
||||||
|
#include <ofono/stk.h>
|
||||||
|
|
||||||
#include "drivers/rilmodem/rilmodem.h"
|
#include "drivers/rilmodem/rilmodem.h"
|
||||||
|
|
||||||
@@ -97,10 +98,10 @@ struct ril_data {
|
|||||||
static guint mce_daemon_watch;
|
static guint mce_daemon_watch;
|
||||||
static guint signal_watch;
|
static guint signal_watch;
|
||||||
static DBusConnection *connection;
|
static DBusConnection *connection;
|
||||||
|
gboolean reconnecting = FALSE;
|
||||||
|
|
||||||
static int ril_init(void);
|
static int ril_init(void);
|
||||||
guint reconnect_timer;
|
static void ril_exit(void);
|
||||||
|
|
||||||
static int send_get_sim_status(struct ofono_modem *modem);
|
static int send_get_sim_status(struct ofono_modem *modem);
|
||||||
|
|
||||||
static void ril_debug(const char *str, void *user_data)
|
static void ril_debug(const char *str, void *user_data)
|
||||||
@@ -112,13 +113,12 @@ static void ril_debug(const char *str, void *user_data)
|
|||||||
|
|
||||||
static void sim_status_cb(struct ril_msg *message, gpointer 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 ofono_modem *modem = user_data;
|
||||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||||
struct sim_status status;
|
struct sim_status status;
|
||||||
struct sim_app *apps[MAX_UICC_APPS];
|
struct sim_app *apps[MAX_UICC_APPS];
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ril.h claims this should NEVER fail!
|
* ril.h claims this should NEVER fail!
|
||||||
* However this isn't quite true. So,
|
* However this isn't quite true. So,
|
||||||
@@ -154,9 +154,12 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
|||||||
} else {
|
} else {
|
||||||
ofono_warn("No SIM card present.");
|
ofono_warn("No SIM card present.");
|
||||||
}
|
}
|
||||||
// We cannot power on modem, but we need to get
|
|
||||||
// certain interfaces up to be able to make emergency calls
|
/*
|
||||||
// in offline mode and without SIM
|
* We cannot power on modem, but we need to get
|
||||||
|
* certain interfaces up to be able to make emergency calls
|
||||||
|
* in offline mode and without SIM
|
||||||
|
*/
|
||||||
ofono_modem_set_powered(modem, TRUE);
|
ofono_modem_set_powered(modem, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,6 +188,7 @@ static int send_get_sim_status(struct ofono_modem *modem)
|
|||||||
|
|
||||||
static int ril_probe(struct ofono_modem *modem)
|
static int ril_probe(struct ofono_modem *modem)
|
||||||
{
|
{
|
||||||
|
DBG("");
|
||||||
struct ril_data *ril = NULL;
|
struct ril_data *ril = NULL;
|
||||||
|
|
||||||
ril = g_try_new0(struct ril_data, 1);
|
ril = g_try_new0(struct ril_data, 1);
|
||||||
@@ -207,9 +211,9 @@ error:
|
|||||||
|
|
||||||
static void ril_remove(struct ofono_modem *modem)
|
static void ril_remove(struct ofono_modem *modem)
|
||||||
{
|
{
|
||||||
|
DBG("");
|
||||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||||
|
|
||||||
|
|
||||||
ofono_modem_set_data(modem, NULL);
|
ofono_modem_set_data(modem, NULL);
|
||||||
|
|
||||||
if (!ril)
|
if (!ril)
|
||||||
@@ -218,9 +222,6 @@ static void ril_remove(struct ofono_modem *modem)
|
|||||||
if (ril->timer_id > 0)
|
if (ril->timer_id > 0)
|
||||||
g_source_remove(ril->timer_id);
|
g_source_remove(ril->timer_id);
|
||||||
|
|
||||||
if (reconnect_timer > 0)
|
|
||||||
g_source_remove(ril->timer_id);
|
|
||||||
|
|
||||||
g_ril_unref(ril->modem);
|
g_ril_unref(ril->modem);
|
||||||
|
|
||||||
g_free(ril);
|
g_free(ril);
|
||||||
@@ -228,7 +229,7 @@ static void ril_remove(struct ofono_modem *modem)
|
|||||||
|
|
||||||
static void ril_pre_sim(struct ofono_modem *modem)
|
static void ril_pre_sim(struct ofono_modem *modem)
|
||||||
{
|
{
|
||||||
DBG("enter");
|
DBG("");
|
||||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||||
struct ofono_sim *sim;
|
struct ofono_sim *sim;
|
||||||
|
|
||||||
@@ -241,6 +242,7 @@ static void ril_pre_sim(struct ofono_modem *modem)
|
|||||||
|
|
||||||
static void ril_post_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 ril_data *ril = ofono_modem_get_data(modem);
|
||||||
struct ofono_gprs *gprs;
|
struct ofono_gprs *gprs;
|
||||||
struct ofono_gprs_context *gc;
|
struct ofono_gprs_context *gc;
|
||||||
@@ -258,7 +260,7 @@ static void ril_post_sim(struct ofono_modem *modem)
|
|||||||
ril->modem);
|
ril->modem);
|
||||||
if (gc == NULL)
|
if (gc == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ofono_gprs_add_context(gprs, gc);
|
ofono_gprs_add_context(gprs, gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,6 +268,8 @@ static void ril_post_sim(struct ofono_modem *modem)
|
|||||||
ofono_radio_settings_create(modem, 0, "rilmodem", ril->modem);
|
ofono_radio_settings_create(modem, 0, "rilmodem", ril->modem);
|
||||||
ofono_phonebook_create(modem, 0, "rilmodem", ril->modem);
|
ofono_phonebook_create(modem, 0, "rilmodem", ril->modem);
|
||||||
ofono_call_forwarding_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);
|
mw = ofono_message_waiting_create(modem);
|
||||||
if (mw)
|
if (mw)
|
||||||
@@ -274,7 +278,7 @@ static void ril_post_sim(struct ofono_modem *modem)
|
|||||||
|
|
||||||
static void ril_post_online(struct ofono_modem *modem)
|
static void ril_post_online(struct ofono_modem *modem)
|
||||||
{
|
{
|
||||||
DBG("enter");
|
DBG("");
|
||||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||||
|
|
||||||
ofono_call_volume_create(modem, 0, "rilmodem", ril->modem);
|
ofono_call_volume_create(modem, 0, "rilmodem", ril->modem);
|
||||||
@@ -282,19 +286,17 @@ static void ril_post_online(struct ofono_modem *modem)
|
|||||||
ofono_netreg_create(modem, 0, "rilmodem", ril->modem);
|
ofono_netreg_create(modem, 0, "rilmodem", ril->modem);
|
||||||
ofono_ussd_create(modem, 0, "rilmodem", ril->modem);
|
ofono_ussd_create(modem, 0, "rilmodem", ril->modem);
|
||||||
ofono_call_settings_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);
|
ofono_oem_raw_create(modem, 0, "rilmodem", ril->modem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_set_online_cb(struct ril_msg *message, gpointer user_data)
|
static void ril_set_online_cb(struct ril_msg *message, gpointer user_data)
|
||||||
{
|
{
|
||||||
DBG("enter");
|
DBG("");
|
||||||
struct cb_data *cbd = user_data;
|
struct cb_data *cbd = user_data;
|
||||||
ofono_modem_online_cb_t cb = cbd->cb;
|
ofono_modem_online_cb_t cb = cbd->cb;
|
||||||
|
|
||||||
if (message->error == RIL_E_SUCCESS) {
|
if (message->error == RIL_E_SUCCESS)
|
||||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||||
}
|
}
|
||||||
@@ -311,12 +313,13 @@ static void ril_set_online(struct ofono_modem *modem, ofono_bool_t online,
|
|||||||
parcel_init(&rilp);
|
parcel_init(&rilp);
|
||||||
parcel_w_int32(&rilp, 1); /* Number of params */
|
parcel_w_int32(&rilp, 1); /* Number of params */
|
||||||
parcel_w_int32(&rilp, online); /* Radio ON = 1, Radio OFF = 0 */
|
parcel_w_int32(&rilp, online); /* Radio ON = 1, Radio OFF = 0 */
|
||||||
DBG("1");
|
|
||||||
|
ofono_info("RIL_REQUEST_RADIO_POWER %d", online);
|
||||||
ret = g_ril_send(ril->modem, RIL_REQUEST_RADIO_POWER, rilp.data,
|
ret = g_ril_send(ril->modem, RIL_REQUEST_RADIO_POWER, rilp.data,
|
||||||
rilp.size, ril_set_online_cb, cbd, g_free);
|
rilp.size, ril_set_online_cb, cbd, g_free);
|
||||||
|
|
||||||
parcel_free(&rilp);
|
parcel_free(&rilp);
|
||||||
DBG("2");
|
DBG("RIL_REQUEST_RADIO_POWER done");
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
g_free(cbd);
|
g_free(cbd);
|
||||||
CALLBACK_WITH_FAILURE(callback, data);
|
CALLBACK_WITH_FAILURE(callback, data);
|
||||||
@@ -354,6 +357,7 @@ static int ril_screen_state(struct ofono_modem *modem, ofono_bool_t state)
|
|||||||
static gboolean display_changed(DBusConnection *conn,
|
static gboolean display_changed(DBusConnection *conn,
|
||||||
DBusMessage *message, void *user_data)
|
DBusMessage *message, void *user_data)
|
||||||
{
|
{
|
||||||
|
DBG("");
|
||||||
struct ofono_modem *modem = user_data;
|
struct ofono_modem *modem = user_data;
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
const char *value;
|
const char *value;
|
||||||
@@ -376,6 +380,7 @@ static gboolean display_changed(DBusConnection *conn,
|
|||||||
|
|
||||||
static void mce_connect(DBusConnection *conn, void *user_data)
|
static void mce_connect(DBusConnection *conn, void *user_data)
|
||||||
{
|
{
|
||||||
|
DBG("");
|
||||||
signal_watch = g_dbus_add_signal_watch(conn,
|
signal_watch = g_dbus_add_signal_watch(conn,
|
||||||
MCE_SERVICE, NULL,
|
MCE_SERVICE, NULL,
|
||||||
MCE_SIGNAL_IF,
|
MCE_SIGNAL_IF,
|
||||||
@@ -386,12 +391,15 @@ static void mce_connect(DBusConnection *conn, void *user_data)
|
|||||||
|
|
||||||
static void mce_disconnect(DBusConnection *conn, void *user_data)
|
static void mce_disconnect(DBusConnection *conn, void *user_data)
|
||||||
{
|
{
|
||||||
|
DBG("");
|
||||||
g_dbus_remove_watch(conn, signal_watch);
|
g_dbus_remove_watch(conn, signal_watch);
|
||||||
signal_watch = 0;
|
signal_watch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_connected(struct ril_msg *message, gpointer user_data)
|
static void ril_connected(struct ril_msg *message, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
DBG("");
|
||||||
|
|
||||||
struct ofono_modem *modem = (struct ofono_modem *) user_data;
|
struct ofono_modem *modem = (struct ofono_modem *) user_data;
|
||||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||||
|
|
||||||
@@ -406,25 +414,35 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
|
|||||||
|
|
||||||
connection = ofono_dbus_get_connection();
|
connection = ofono_dbus_get_connection();
|
||||||
mce_daemon_watch = g_dbus_add_service_watch(connection, MCE_SERVICE,
|
mce_daemon_watch = g_dbus_add_service_watch(connection, MCE_SERVICE,
|
||||||
mce_connect, mce_disconnect, modem, NULL);
|
mce_connect, mce_disconnect, modem, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean ril_re_init(gpointer user_data)
|
static gboolean ril_re_init(gpointer user_data)
|
||||||
{
|
{
|
||||||
ril_init();
|
DBG("");
|
||||||
return FALSE;
|
if (reconnecting) {
|
||||||
|
ril_init();
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gril_disconnected(gpointer user_data)
|
static void gril_disconnected(gpointer user_data)
|
||||||
{
|
{
|
||||||
/* Signal clients modem going down */
|
/* Signal clients modem going down
|
||||||
|
*/
|
||||||
struct ofono_modem *modem = user_data;
|
struct ofono_modem *modem = user_data;
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
|
||||||
if (modem) {
|
if (ofono_modem_is_registered(modem)) {
|
||||||
ofono_modem_remove(modem);
|
ofono_modem_remove(modem);
|
||||||
mce_disconnect(conn, user_data);
|
mce_disconnect(conn, user_data);
|
||||||
reconnect_timer = g_timeout_add_seconds(2, ril_re_init, NULL);
|
}
|
||||||
|
|
||||||
|
if (!reconnecting) {
|
||||||
|
reconnecting = TRUE;
|
||||||
|
g_timeout_add_seconds(2, ril_re_init, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,10 +452,10 @@ void ril_switchUser()
|
|||||||
ofono_error("prctl(PR_SET_KEEPCAPS) failed:%s,%d",
|
ofono_error("prctl(PR_SET_KEEPCAPS) failed:%s,%d",
|
||||||
strerror(errno), errno);
|
strerror(errno), errno);
|
||||||
|
|
||||||
if (setgid(RADIO_ID) < 0 )
|
if (setgid(RADIO_ID) < 0)
|
||||||
ofono_error("setgid(%d) failed:%s,%d",
|
ofono_error("setgid(%d) failed:%s,%d",
|
||||||
RADIO_ID, strerror(errno), errno);
|
RADIO_ID, strerror(errno), errno);
|
||||||
if (setuid(RADIO_ID) < 0 )
|
if (setuid(RADIO_ID) < 0)
|
||||||
ofono_error("setuid(%d) failed:%s,%d",
|
ofono_error("setuid(%d) failed:%s,%d",
|
||||||
RADIO_ID, strerror(errno), errno);
|
RADIO_ID, strerror(errno), errno);
|
||||||
|
|
||||||
@@ -457,7 +475,7 @@ void ril_switchUser()
|
|||||||
|
|
||||||
static int ril_enable(struct ofono_modem *modem)
|
static int ril_enable(struct ofono_modem *modem)
|
||||||
{
|
{
|
||||||
DBG("enter");
|
DBG("%p", modem);
|
||||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||||
|
|
||||||
ril->have_sim = FALSE;
|
ril->have_sim = FALSE;
|
||||||
@@ -482,6 +500,8 @@ static int ril_enable(struct ofono_modem *modem)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reconnecting = FALSE;
|
||||||
|
|
||||||
if (getenv("OFONO_RIL_TRACE"))
|
if (getenv("OFONO_RIL_TRACE"))
|
||||||
g_ril_set_trace(ril->modem, TRUE);
|
g_ril_set_trace(ril->modem, TRUE);
|
||||||
|
|
||||||
@@ -498,17 +518,18 @@ static int ril_enable(struct ofono_modem *modem)
|
|||||||
|
|
||||||
static int ril_disable(struct ofono_modem *modem)
|
static int ril_disable(struct ofono_modem *modem)
|
||||||
{
|
{
|
||||||
|
DBG("%p", modem);
|
||||||
|
|
||||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||||
struct parcel rilp;
|
struct parcel rilp;
|
||||||
int request = RIL_REQUEST_RADIO_POWER;
|
int request = RIL_REQUEST_RADIO_POWER;
|
||||||
guint ret;
|
guint ret;
|
||||||
|
|
||||||
DBG("%p", modem);
|
|
||||||
|
|
||||||
parcel_init(&rilp);
|
parcel_init(&rilp);
|
||||||
parcel_w_int32(&rilp, 1); /* size of array */
|
parcel_w_int32(&rilp, 1); /* size of array */
|
||||||
parcel_w_int32(&rilp, 0); /* POWER=OFF */
|
parcel_w_int32(&rilp, 0); /* POWER=OFF */
|
||||||
|
|
||||||
|
ofono_info("RIL_REQUEST_RADIO_POWER OFF");
|
||||||
/* fire and forget i.e. not waiting for the callback*/
|
/* fire and forget i.e. not waiting for the callback*/
|
||||||
ret = g_ril_send(ril->modem, request, rilp.data,
|
ret = g_ril_send(ril->modem, request, rilp.data,
|
||||||
rilp.size, NULL, NULL, NULL);
|
rilp.size, NULL, NULL, NULL);
|
||||||
@@ -552,7 +573,7 @@ static struct ofono_modem_driver ril_driver = {
|
|||||||
*/
|
*/
|
||||||
static int ril_init(void)
|
static int ril_init(void)
|
||||||
{
|
{
|
||||||
DBG("enter");
|
DBG("");
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
struct ofono_modem *modem;
|
struct ofono_modem *modem;
|
||||||
|
|
||||||
@@ -577,23 +598,6 @@ static int ril_init(void)
|
|||||||
retval = ofono_modem_register(modem);
|
retval = ofono_modem_register(modem);
|
||||||
DBG("ofono_modem_register returned: %d", retval);
|
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;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -713,8 +713,12 @@ static DBusMessage *set_property_request(struct ofono_call_forwarding *cf,
|
|||||||
if (ph->number[0] != '\0')
|
if (ph->number[0] != '\0')
|
||||||
cf->driver->registration(cf, type, cls, ph, timeout,
|
cf->driver->registration(cf, type, cls, ph, timeout,
|
||||||
set_property_callback, cf);
|
set_property_callback, cf);
|
||||||
else
|
else {
|
||||||
|
if (cf->query_next == CALL_FORWARDING_TYPE_UNCONDITIONAL)
|
||||||
|
cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
|
||||||
|
|
||||||
cf->driver->erasure(cf, type, cls, set_property_callback, cf);
|
cf->driver->erasure(cf, type, cls, set_property_callback, cf);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ struct error_mapping_entry cme_errors_mapping[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void append_variant(DBusMessageIter *iter,
|
static void append_variant(DBusMessageIter *iter,
|
||||||
int type, void *value)
|
int type, const void *value)
|
||||||
{
|
{
|
||||||
char sig[2];
|
char sig[2];
|
||||||
DBusMessageIter valueiter;
|
DBusMessageIter valueiter;
|
||||||
@@ -65,7 +65,7 @@ static void append_variant(DBusMessageIter *iter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ofono_dbus_dict_append(DBusMessageIter *dict,
|
void ofono_dbus_dict_append(DBusMessageIter *dict,
|
||||||
const char *key, int type, void *value)
|
const char *key, int type, const void *value)
|
||||||
{
|
{
|
||||||
DBusMessageIter keyiter;
|
DBusMessageIter keyiter;
|
||||||
|
|
||||||
@@ -85,7 +85,8 @@ void ofono_dbus_dict_append(DBusMessageIter *dict,
|
|||||||
dbus_message_iter_close_container(dict, &keyiter);
|
dbus_message_iter_close_container(dict, &keyiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_array_variant(DBusMessageIter *iter, int type, void *val)
|
static void append_array_variant(DBusMessageIter *iter, int type,
|
||||||
|
const void *val)
|
||||||
{
|
{
|
||||||
DBusMessageIter variant, array;
|
DBusMessageIter variant, array;
|
||||||
char typesig[2];
|
char typesig[2];
|
||||||
@@ -113,7 +114,7 @@ static void append_array_variant(DBusMessageIter *iter, int type, void *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||||
int type, void *val)
|
int type, const void *val)
|
||||||
{
|
{
|
||||||
DBusMessageIter entry;
|
DBusMessageIter entry;
|
||||||
|
|
||||||
@@ -127,7 +128,8 @@ void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
|||||||
dbus_message_iter_close_container(dict, &entry);
|
dbus_message_iter_close_container(dict, &entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
|
static void append_dict_variant(DBusMessageIter *iter, int type,
|
||||||
|
const void *val)
|
||||||
{
|
{
|
||||||
DBusMessageIter variant, array, entry;
|
DBusMessageIter variant, array, entry;
|
||||||
char typesig[5];
|
char typesig[5];
|
||||||
@@ -182,7 +184,7 @@ static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
||||||
int type, void *val)
|
int type, const void *val)
|
||||||
{
|
{
|
||||||
DBusMessageIter entry;
|
DBusMessageIter entry;
|
||||||
|
|
||||||
@@ -200,7 +202,7 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
|||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *name,
|
const char *name,
|
||||||
int type, void *value)
|
int type, const void *value)
|
||||||
{
|
{
|
||||||
DBusMessage *signal;
|
DBusMessage *signal;
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
@@ -225,7 +227,7 @@ int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
|
|||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *name,
|
const char *name,
|
||||||
int type, void *value)
|
int type, const void *value)
|
||||||
|
|
||||||
{
|
{
|
||||||
DBusMessage *signal;
|
DBusMessage *signal;
|
||||||
@@ -251,7 +253,7 @@ int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
|||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *name,
|
const char *name,
|
||||||
int type, void *value)
|
int type, const void *value)
|
||||||
|
|
||||||
{
|
{
|
||||||
DBusMessage *signal;
|
DBusMessage *signal;
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
#define MAX_MESSAGE_CENTER_LENGTH 255
|
#define MAX_MESSAGE_CENTER_LENGTH 255
|
||||||
#define MAX_CONTEXTS 256
|
#define MAX_CONTEXTS 256
|
||||||
#define SUSPEND_TIMEOUT 8
|
#define SUSPEND_TIMEOUT 8
|
||||||
|
#define MAX_MMS_MTU 1280
|
||||||
|
|
||||||
/* 27.007 Section 7.29 */
|
/* 27.007 Section 7.29 */
|
||||||
enum packet_bearer {
|
enum packet_bearer {
|
||||||
@@ -758,6 +759,31 @@ static void pri_reset_context_settings(struct pri_context *ctx)
|
|||||||
g_free(interface);
|
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)
|
static void pri_update_mms_context_settings(struct pri_context *ctx)
|
||||||
{
|
{
|
||||||
struct ofono_gprs_context *gc = ctx->context_driver;
|
struct ofono_gprs_context *gc = ctx->context_driver;
|
||||||
@@ -774,6 +800,8 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
|
|||||||
|
|
||||||
if (ctx->proxy_host)
|
if (ctx->proxy_host)
|
||||||
pri_setproxy(settings->interface, ctx->proxy_host);
|
pri_setproxy(settings->interface, ctx->proxy_host);
|
||||||
|
|
||||||
|
pri_limit_mtu(settings->interface, MAX_MMS_MTU);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_context_properties(struct pri_context *ctx,
|
static void append_context_properties(struct pri_context *ctx,
|
||||||
@@ -3016,14 +3044,56 @@ static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
|
|||||||
__ofono_atom_register(gprs->atom, gprs_unregister);
|
__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)
|
static void spn_read_cb(const char *spn, const char *dc, void *data)
|
||||||
{
|
{
|
||||||
struct ofono_gprs *gprs = data;
|
struct ofono_gprs *gprs = data;
|
||||||
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
|
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
|
||||||
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
|
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
|
||||||
|
|
||||||
provision_contexts(gprs, ofono_sim_get_mcc(sim),
|
if (gprs->contexts == NULL) {
|
||||||
|
provision_contexts(gprs, ofono_sim_get_mcc(sim),
|
||||||
ofono_sim_get_mnc(sim), spn);
|
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);
|
ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
|
||||||
|
|
||||||
@@ -3040,7 +3110,7 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
|
|||||||
|
|
||||||
gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
|
gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
|
||||||
|
|
||||||
if (gprs->contexts)
|
if (mms_context_configured(gprs))
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
|
ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
|
||||||
|
|||||||
@@ -289,7 +289,8 @@ void __ofono_log_enable(struct ofono_debug_desc *start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int __ofono_log_init(const char *program, const char *debug,
|
int __ofono_log_init(const char *program, const char *debug,
|
||||||
ofono_bool_t detach)
|
ofono_bool_t detach,
|
||||||
|
ofono_bool_t backtrace)
|
||||||
{
|
{
|
||||||
static char path[PATH_MAX];
|
static char path[PATH_MAX];
|
||||||
int option = LOG_NDELAY | LOG_PID;
|
int option = LOG_NDELAY | LOG_PID;
|
||||||
@@ -305,7 +306,8 @@ int __ofono_log_init(const char *program, const char *debug,
|
|||||||
if (detach == FALSE)
|
if (detach == FALSE)
|
||||||
option |= LOG_PERROR;
|
option |= LOG_PERROR;
|
||||||
|
|
||||||
signal_setup(signal_handler);
|
if (backtrace == TRUE)
|
||||||
|
signal_setup(signal_handler);
|
||||||
|
|
||||||
openlog(basename(program), option, LOG_DAEMON);
|
openlog(basename(program), option, LOG_DAEMON);
|
||||||
|
|
||||||
@@ -314,13 +316,14 @@ int __ofono_log_init(const char *program, const char *debug,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __ofono_log_cleanup(void)
|
void __ofono_log_cleanup(ofono_bool_t backtrace)
|
||||||
{
|
{
|
||||||
syslog(LOG_INFO, "Exit");
|
syslog(LOG_INFO, "Exit");
|
||||||
|
|
||||||
closelog();
|
closelog();
|
||||||
|
|
||||||
signal_setup(SIG_DFL);
|
if (backtrace == TRUE)
|
||||||
|
signal_setup(SIG_DFL);
|
||||||
|
|
||||||
g_strfreev(enabled);
|
g_strfreev(enabled);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ static gchar *option_plugin = NULL;
|
|||||||
static gchar *option_noplugin = NULL;
|
static gchar *option_noplugin = NULL;
|
||||||
static gboolean option_detach = TRUE;
|
static gboolean option_detach = TRUE;
|
||||||
static gboolean option_version = FALSE;
|
static gboolean option_version = FALSE;
|
||||||
|
static gboolean option_backtrace = TRUE;
|
||||||
|
|
||||||
static gboolean parse_debug(const char *key, const char *value,
|
static gboolean parse_debug(const char *key, const char *value,
|
||||||
gpointer user_data, GError **error)
|
gpointer user_data, GError **error)
|
||||||
@@ -158,6 +159,9 @@ static GOptionEntry options[] = {
|
|||||||
"Don't run as daemon in background" },
|
"Don't run as daemon in background" },
|
||||||
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
|
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
|
||||||
"Show version information and exit" },
|
"Show version information and exit" },
|
||||||
|
{ "nobacktrace", 0, G_OPTION_FLAG_REVERSE,
|
||||||
|
G_OPTION_ARG_NONE, &option_backtrace,
|
||||||
|
"Don't print out backtrace information" },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -213,7 +217,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
signal = setup_signalfd();
|
signal = setup_signalfd();
|
||||||
|
|
||||||
__ofono_log_init(argv[0], option_debug, option_detach);
|
__ofono_log_init(argv[0], option_debug, option_detach,
|
||||||
|
option_backtrace);
|
||||||
|
|
||||||
dbus_error_init(&error);
|
dbus_error_init(&error);
|
||||||
|
|
||||||
@@ -264,7 +269,7 @@ cleanup:
|
|||||||
|
|
||||||
g_main_loop_unref(event_loop);
|
g_main_loop_unref(event_loop);
|
||||||
|
|
||||||
__ofono_log_cleanup();
|
__ofono_log_cleanup(option_backtrace);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2106,18 +2106,14 @@ void ofono_netreg_register(struct ofono_netreg *netreg)
|
|||||||
ofono_sim_add_spn_watch(netreg->sim, &netreg->spn_watch,
|
ofono_sim_add_spn_watch(netreg->sim, &netreg->spn_watch,
|
||||||
spn_read_cb, netreg, NULL);
|
spn_read_cb, netreg, NULL);
|
||||||
|
|
||||||
if (__ofono_sim_service_available(netreg->sim,
|
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
|
||||||
SIM_UST_SERVICE_PROVIDER_DISPLAY_INFO,
|
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
|
||||||
SIM_SST_SERVICE_PROVIDER_DISPLAY_INFO)) {
|
sim_spdi_read_cb, netreg);
|
||||||
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,
|
ofono_sim_add_file_watch(netreg->sim_context,
|
||||||
SIM_EFSPDI_FILEID,
|
SIM_EFSPDI_FILEID,
|
||||||
sim_spdi_changed,
|
sim_spdi_changed,
|
||||||
netreg, NULL);
|
netreg, NULL);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__ofono_atom_register(netreg->atom, netreg_unregister);
|
__ofono_atom_register(netreg->atom, netreg_unregister);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<allow send_interface="org.ofono.SmartMessagingAgent"/>
|
<allow send_interface="org.ofono.SmartMessagingAgent"/>
|
||||||
<allow send_interface="org.ofono.PositioningRequestAgent"/>
|
<allow send_interface="org.ofono.PositioningRequestAgent"/>
|
||||||
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
|
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
|
||||||
|
<allow send_interface="org.ofono.VoiceCallAgent"/>
|
||||||
</policy>
|
</policy>
|
||||||
|
|
||||||
<policy user="radio">
|
<policy user="radio">
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
<allow send_interface="org.ofono.SmartMessagingAgent"/>
|
<allow send_interface="org.ofono.SmartMessagingAgent"/>
|
||||||
<allow send_interface="org.ofono.PositioningRequestAgent"/>
|
<allow send_interface="org.ofono.PositioningRequestAgent"/>
|
||||||
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
|
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
|
||||||
|
<allow send_interface="org.ofono.VoiceCallAgent"/>
|
||||||
</policy>
|
</policy>
|
||||||
|
|
||||||
<policy at_console="true">
|
<policy at_console="true">
|
||||||
|
|||||||
@@ -38,8 +38,9 @@ void __ofono_modem_shutdown(void);
|
|||||||
#include <ofono/log.h>
|
#include <ofono/log.h>
|
||||||
|
|
||||||
int __ofono_log_init(const char *program, const char *debug,
|
int __ofono_log_init(const char *program, const char *debug,
|
||||||
ofono_bool_t detach);
|
ofono_bool_t detach,
|
||||||
void __ofono_log_cleanup(void);
|
ofono_bool_t backtrace);
|
||||||
|
void __ofono_log_cleanup(ofono_bool_t backtrace);
|
||||||
void __ofono_log_enable(struct ofono_debug_desc *start,
|
void __ofono_log_enable(struct ofono_debug_desc *start,
|
||||||
struct ofono_debug_desc *stop);
|
struct ofono_debug_desc *stop);
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Telephony service
|
Description=Telephony service
|
||||||
After=syslog.target
|
Requires=dbus.service
|
||||||
|
After=dbus.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=dbus
|
Type=dbus
|
||||||
BusName=org.ofono
|
BusName=org.ofono
|
||||||
User=root
|
User=root
|
||||||
EnvironmentFile=-/var/lib/environment/ofono/*.conf
|
EnvironmentFile=-/var/lib/environment/ofono/*.conf
|
||||||
ExecStart=@prefix@/sbin/ofonod -n $OFONO_ARGS
|
ExecStart=@prefix@/sbin/ofonod -n --nobacktrace $OFONO_ARGS
|
||||||
StandardError=null
|
StandardError=null
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=3
|
RestartSec=3
|
||||||
|
|||||||
@@ -767,12 +767,14 @@ static char *sim_network_name_parse(const unsigned char *buffer, int length,
|
|||||||
gboolean *add_ci)
|
gboolean *add_ci)
|
||||||
{
|
{
|
||||||
char *ret = NULL;
|
char *ret = NULL;
|
||||||
unsigned char *endp;
|
|
||||||
unsigned char dcs;
|
unsigned char dcs;
|
||||||
int i;
|
int i;
|
||||||
gboolean ci = FALSE;
|
gboolean ci = FALSE;
|
||||||
|
unsigned char *unpacked_buf;
|
||||||
|
long num_char, written;
|
||||||
|
int spare_bits;
|
||||||
|
|
||||||
if (length < 1)
|
if (length < 2)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dcs = *buffer++;
|
dcs = *buffer++;
|
||||||
@@ -787,11 +789,18 @@ static char *sim_network_name_parse(const unsigned char *buffer, int length,
|
|||||||
|
|
||||||
switch (dcs & (7 << 4)) {
|
switch (dcs & (7 << 4)) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
endp = memchr(buffer, 0xff, length);
|
spare_bits = dcs & 0x07;
|
||||||
if (endp)
|
num_char = (length * 8 - spare_bits) / 7;
|
||||||
length = endp - buffer;
|
|
||||||
ret = convert_gsm_to_utf8(buffer, length,
|
unpacked_buf = unpack_7bit(buffer, length, 0, FALSE,
|
||||||
NULL, NULL, 0xff);
|
num_char, &written, 0);
|
||||||
|
if (unpacked_buf == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = convert_gsm_to_utf8(unpacked_buf, written, NULL, NULL, 0);
|
||||||
|
|
||||||
|
g_free(unpacked_buf);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
if ((length % 2) == 1) {
|
if ((length % 2) == 1) {
|
||||||
|
|||||||
@@ -737,6 +737,11 @@ static DBusMessage *stk_register_agent(DBusConnection *conn,
|
|||||||
if (stk->session_agent == NULL)
|
if (stk->session_agent == NULL)
|
||||||
stk->current_agent = stk->default_agent;
|
stk->current_agent = stk->default_agent;
|
||||||
|
|
||||||
|
if (stk->driver && stk->driver->ready) {
|
||||||
|
DBG("Report driver agent is ready");
|
||||||
|
stk->driver->ready(stk);
|
||||||
|
}
|
||||||
|
|
||||||
return dbus_message_new_method_return(msg);
|
return dbus_message_new_method_return(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
|
* Copyright (C) 2014 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
#include "simutil.h"
|
#include "simutil.h"
|
||||||
#include "smsutil.h"
|
#include "smsutil.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
#include "voicecallagent.h"
|
||||||
|
|
||||||
#define MAX_VOICE_CALLS 16
|
#define MAX_VOICE_CALLS 16
|
||||||
|
|
||||||
@@ -75,6 +77,7 @@ struct ofono_voicecall {
|
|||||||
ofono_voicecall_cb_t release_queue_done_cb;
|
ofono_voicecall_cb_t release_queue_done_cb;
|
||||||
struct ofono_emulator *pending_em;
|
struct ofono_emulator *pending_em;
|
||||||
unsigned int pending_id;
|
unsigned int pending_id;
|
||||||
|
struct voicecall_agent *vc_agent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct voicecall {
|
struct voicecall {
|
||||||
@@ -555,6 +558,11 @@ static DBusMessage *voicecall_hangup(DBusConnection *conn,
|
|||||||
struct ofono_voicecall *vc = v->vc;
|
struct ofono_voicecall *vc = v->vc;
|
||||||
struct ofono_call *call = v->call;
|
struct ofono_call *call = v->call;
|
||||||
gboolean single_call = vc->call_list->next == 0;
|
gboolean single_call = vc->call_list->next == 0;
|
||||||
|
struct tone_queue_entry *tone_entry = NULL;
|
||||||
|
|
||||||
|
/* clear any remaining tones */
|
||||||
|
while ((tone_entry = g_queue_peek_head(vc->toneq)))
|
||||||
|
tone_request_finish(vc, tone_entry, ENOENT, TRUE);
|
||||||
|
|
||||||
if (vc->pending || vc->pending_em)
|
if (vc->pending || vc->pending_em)
|
||||||
return __ofono_error_busy(msg);
|
return __ofono_error_busy(msg);
|
||||||
@@ -2140,6 +2148,72 @@ static DBusMessage *manager_get_calls(DBusConnection *conn,
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void voicecall_agent_notify(gpointer user_data)
|
||||||
|
{
|
||||||
|
struct ofono_voicecall *vc = user_data;
|
||||||
|
vc->vc_agent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusMessage *voicecall_register_agent(DBusConnection *conn,
|
||||||
|
DBusMessage *msg, void *data)
|
||||||
|
{
|
||||||
|
struct ofono_voicecall *vc = data;
|
||||||
|
const char *agent_path;
|
||||||
|
|
||||||
|
if (vc->vc_agent)
|
||||||
|
return __ofono_error_busy(msg);
|
||||||
|
|
||||||
|
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH,
|
||||||
|
&agent_path, DBUS_TYPE_INVALID) == FALSE)
|
||||||
|
return __ofono_error_invalid_args(msg);
|
||||||
|
|
||||||
|
if (!__ofono_dbus_valid_object_path(agent_path))
|
||||||
|
return __ofono_error_invalid_format(msg);
|
||||||
|
|
||||||
|
vc->vc_agent = voicecall_agent_new(agent_path,
|
||||||
|
dbus_message_get_sender(msg));
|
||||||
|
|
||||||
|
if (vc->vc_agent == NULL)
|
||||||
|
return __ofono_error_failed(msg);
|
||||||
|
|
||||||
|
voicecall_agent_set_removed_notify(vc->vc_agent,
|
||||||
|
voicecall_agent_notify, vc);
|
||||||
|
|
||||||
|
return dbus_message_new_method_return(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusMessage *voicecall_unregister_agent(DBusConnection *conn,
|
||||||
|
DBusMessage *msg, void *data)
|
||||||
|
{
|
||||||
|
struct ofono_voicecall *vc = data;
|
||||||
|
const char *agent_path;
|
||||||
|
const char *agent_bus = dbus_message_get_sender(msg);
|
||||||
|
|
||||||
|
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &agent_path,
|
||||||
|
DBUS_TYPE_INVALID) == FALSE)
|
||||||
|
return __ofono_error_invalid_args(msg);
|
||||||
|
|
||||||
|
if (vc->vc_agent == NULL)
|
||||||
|
return __ofono_error_failed(msg);
|
||||||
|
|
||||||
|
if (!voicecall_agent_matches(vc->vc_agent, agent_path, agent_bus))
|
||||||
|
return __ofono_error_access_denied(msg);
|
||||||
|
|
||||||
|
if (vc->vc_agent) {
|
||||||
|
voicecall_agent_free(vc->vc_agent);
|
||||||
|
vc->vc_agent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbus_message_new_method_return(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
|
||||||
|
const ofono_bool_t playTone)
|
||||||
|
{
|
||||||
|
if (vc->vc_agent)
|
||||||
|
voicecall_agent_ringback_tone(vc->vc_agent, playTone);
|
||||||
|
}
|
||||||
|
|
||||||
static const GDBusMethodTable manager_methods[] = {
|
static const GDBusMethodTable manager_methods[] = {
|
||||||
{ GDBUS_METHOD("GetProperties",
|
{ GDBUS_METHOD("GetProperties",
|
||||||
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
|
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
|
||||||
@@ -2172,6 +2246,12 @@ static const GDBusMethodTable manager_methods[] = {
|
|||||||
{ GDBUS_METHOD("GetCalls",
|
{ GDBUS_METHOD("GetCalls",
|
||||||
NULL, GDBUS_ARGS({ "calls_with_properties", "a(oa{sv})" }),
|
NULL, GDBUS_ARGS({ "calls_with_properties", "a(oa{sv})" }),
|
||||||
manager_get_calls) },
|
manager_get_calls) },
|
||||||
|
{ GDBUS_ASYNC_METHOD("RegisterVoicecallAgent",
|
||||||
|
GDBUS_ARGS({ "path", "o" }), NULL,
|
||||||
|
voicecall_register_agent) },
|
||||||
|
{ GDBUS_ASYNC_METHOD("UnregisterVoicecallAgent",
|
||||||
|
GDBUS_ARGS({ "path", "o" }), NULL,
|
||||||
|
voicecall_unregister_agent) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2744,6 +2824,11 @@ static void voicecall_unregister(struct ofono_atom *atom)
|
|||||||
|
|
||||||
voicecall_close_settings(vc);
|
voicecall_close_settings(vc);
|
||||||
|
|
||||||
|
if (vc->vc_agent) {
|
||||||
|
voicecall_agent_free(vc->vc_agent);
|
||||||
|
vc->vc_agent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (vc->sim_state_watch) {
|
if (vc->sim_state_watch) {
|
||||||
ofono_sim_remove_state_watch(vc->sim, vc->sim_state_watch);
|
ofono_sim_remove_state_watch(vc->sim, vc->sim_state_watch);
|
||||||
vc->sim_state_watch = 0;
|
vc->sim_state_watch = 0;
|
||||||
@@ -2859,19 +2944,24 @@ static void read_sim_ecc_numbers(int id, void *userdata)
|
|||||||
ecc_g3_read_cb, vc);
|
ecc_g3_read_cb, vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_ecc_numbers(struct ofono_voicecall *vc)
|
||||||
|
{
|
||||||
|
if (vc->sim_context == NULL) {
|
||||||
|
vc->sim_context = ofono_sim_context_create(vc->sim);
|
||||||
|
ofono_sim_add_file_watch(vc->sim_context, SIM_EFECC_FILEID,
|
||||||
|
read_sim_ecc_numbers, vc, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
read_sim_ecc_numbers(SIM_EFECC_FILEID, vc);
|
||||||
|
}
|
||||||
|
|
||||||
static void sim_state_watch(enum ofono_sim_state new_state, void *user)
|
static void sim_state_watch(enum ofono_sim_state new_state, void *user)
|
||||||
{
|
{
|
||||||
struct ofono_voicecall *vc = user;
|
struct ofono_voicecall *vc = user;
|
||||||
|
|
||||||
switch (new_state) {
|
switch (new_state) {
|
||||||
case OFONO_SIM_STATE_INSERTED:
|
case OFONO_SIM_STATE_INSERTED:
|
||||||
if (vc->sim_context == NULL)
|
get_ecc_numbers(vc);
|
||||||
vc->sim_context = ofono_sim_context_create(vc->sim);
|
|
||||||
|
|
||||||
read_sim_ecc_numbers(SIM_EFECC_FILEID, vc);
|
|
||||||
|
|
||||||
ofono_sim_add_file_watch(vc->sim_context, SIM_EFECC_FILEID,
|
|
||||||
read_sim_ecc_numbers, vc, NULL);
|
|
||||||
break;
|
break;
|
||||||
case OFONO_SIM_STATE_NOT_PRESENT:
|
case OFONO_SIM_STATE_NOT_PRESENT:
|
||||||
case OFONO_SIM_STATE_RESETTING:
|
case OFONO_SIM_STATE_RESETTING:
|
||||||
@@ -2888,6 +2978,8 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *user)
|
|||||||
voicecall_close_settings(vc);
|
voicecall_close_settings(vc);
|
||||||
break;
|
break;
|
||||||
case OFONO_SIM_STATE_READY:
|
case OFONO_SIM_STATE_READY:
|
||||||
|
get_ecc_numbers(vc);
|
||||||
|
|
||||||
voicecall_load_settings(vc);
|
voicecall_load_settings(vc);
|
||||||
break;
|
break;
|
||||||
case OFONO_SIM_STATE_LOCKED_OUT:
|
case OFONO_SIM_STATE_LOCKED_OUT:
|
||||||
|
|||||||
131
ofono/src/voicecallagent.c
Normal file
131
ofono/src/voicecallagent.c
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* oFono - Open Source Telephony
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gdbus.h>
|
||||||
|
|
||||||
|
#include "ofono.h"
|
||||||
|
#include "voicecallagent.h"
|
||||||
|
|
||||||
|
#define OFONO_VOICECALL_AGENT_INTERFACE "org.ofono.VoiceCallAgent"
|
||||||
|
|
||||||
|
struct voicecall_agent {
|
||||||
|
char *path; /* Agent Path */
|
||||||
|
char *bus; /* Agent bus */
|
||||||
|
guint disconnect_watch; /* DBus disconnect watch */
|
||||||
|
ofono_destroy_func removed_cb;
|
||||||
|
void *removed_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void voicecall_agent_ringback_tone(struct voicecall_agent *agent,
|
||||||
|
const ofono_bool_t playTone)
|
||||||
|
{
|
||||||
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
DBusMessage *message = dbus_message_new_method_call(
|
||||||
|
agent->bus, agent->path,
|
||||||
|
OFONO_VOICECALL_AGENT_INTERFACE,
|
||||||
|
"RingbackTone");
|
||||||
|
|
||||||
|
if (message == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &playTone,
|
||||||
|
DBUS_TYPE_INVALID))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbus_message_set_no_reply(message, TRUE);
|
||||||
|
g_dbus_send_message(conn, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void voicecall_agent_send_release(struct voicecall_agent *agent)
|
||||||
|
{
|
||||||
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
DBusMessage *message = dbus_message_new_method_call(
|
||||||
|
agent->bus, agent->path,
|
||||||
|
OFONO_VOICECALL_AGENT_INTERFACE,
|
||||||
|
"Release");
|
||||||
|
|
||||||
|
if (message == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbus_message_set_no_reply(message, TRUE);
|
||||||
|
g_dbus_send_message(conn, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void voicecall_agent_set_removed_notify(struct voicecall_agent *agent,
|
||||||
|
ofono_destroy_func destroy,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
agent->removed_cb = destroy;
|
||||||
|
agent->removed_data = user_data; /* voicecall atom (not owned) */
|
||||||
|
}
|
||||||
|
|
||||||
|
void voicecall_agent_free(struct voicecall_agent *agent)
|
||||||
|
{
|
||||||
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
|
||||||
|
if (agent->disconnect_watch) {
|
||||||
|
voicecall_agent_send_release(agent);
|
||||||
|
g_dbus_remove_watch(conn, agent->disconnect_watch);
|
||||||
|
agent->disconnect_watch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agent->removed_cb)
|
||||||
|
agent->removed_cb(agent->removed_data);
|
||||||
|
|
||||||
|
g_free(agent->path);
|
||||||
|
g_free(agent->bus);
|
||||||
|
g_free(agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ofono_bool_t voicecall_agent_matches(struct voicecall_agent *agent,
|
||||||
|
const char *path, const char *sender)
|
||||||
|
{
|
||||||
|
return g_str_equal(agent->path, path) &&
|
||||||
|
g_str_equal(agent->bus, sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
void voicecall_agent_disconnect_cb(DBusConnection *conn, void *user_data)
|
||||||
|
{
|
||||||
|
struct voicecall_agent *agent = user_data;
|
||||||
|
|
||||||
|
agent->disconnect_watch = 0;
|
||||||
|
voicecall_agent_free(agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct voicecall_agent *voicecall_agent_new(const char *path,
|
||||||
|
const char *sender)
|
||||||
|
{
|
||||||
|
struct voicecall_agent *agent = g_try_new0(struct voicecall_agent, 1);
|
||||||
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
|
||||||
|
if (agent == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
agent->path = g_strdup(path);
|
||||||
|
agent->bus = g_strdup(sender);
|
||||||
|
|
||||||
|
agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
|
||||||
|
voicecall_agent_disconnect_cb,
|
||||||
|
agent, NULL);
|
||||||
|
|
||||||
|
return agent;
|
||||||
|
}
|
||||||
40
ofono/src/voicecallagent.h
Normal file
40
ofono/src/voicecallagent.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* oFono - Open Source Telephony
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct voicecall_agent;
|
||||||
|
|
||||||
|
void voicecall_agent_ringback_tone(struct voicecall_agent *agent,
|
||||||
|
const ofono_bool_t playTone);
|
||||||
|
|
||||||
|
void voicecall_agent_set_removed_notify(struct voicecall_agent *agent,
|
||||||
|
ofono_destroy_func removed_cb,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
void voicecall_agent_free(struct voicecall_agent *agent);
|
||||||
|
|
||||||
|
ofono_bool_t voicecall_agent_matches(struct voicecall_agent *agent,
|
||||||
|
const char *path, const char *sender);
|
||||||
|
|
||||||
|
struct voicecall_agent *voicecall_agent_new(const char *path,
|
||||||
|
const char *sender);
|
||||||
|
|
||||||
|
void voicecall_agent_disconnect_cb(DBusConnection *conn,
|
||||||
|
void *user_data);
|
||||||
@@ -63,6 +63,8 @@ if __name__ == "__main__":
|
|||||||
except dbus.DBusException, e:
|
except dbus.DBusException, e:
|
||||||
print "Unable to Disable All barrings: ", e
|
print "Unable to Disable All barrings: ", e
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
print "Disabled all call barrings"
|
||||||
|
sys.exit(0)
|
||||||
elif (sys.argv[1] == 'passwd'):
|
elif (sys.argv[1] == 'passwd'):
|
||||||
try:
|
try:
|
||||||
cb.ChangePassword(old_password, new_password)
|
cb.ChangePassword(old_password, new_password)
|
||||||
@@ -77,6 +79,8 @@ if __name__ == "__main__":
|
|||||||
except dbus.DBusException, e:
|
except dbus.DBusException, e:
|
||||||
print "Unable to set property: ", e
|
print "Unable to set property: ", e
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
print "Property set completed", property
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
canexit = True
|
canexit = True
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
import gobject
|
import gobject
|
||||||
|
import sys
|
||||||
|
|
||||||
import dbus
|
import dbus
|
||||||
import dbus.mainloop.glib
|
import dbus.mainloop.glib
|
||||||
|
|
||||||
|
def print_usage():
|
||||||
|
print "Usage: test-ss-control-cb <password>"
|
||||||
|
sys.exit(1);
|
||||||
|
|
||||||
def property_changed(property, value):
|
def property_changed(property, value):
|
||||||
print "CallBarring property %s changed to %s" % (property, value)
|
print "CallBarring property %s changed to %s" % (property, value)
|
||||||
|
|
||||||
@@ -15,6 +20,11 @@ def print_properties(cb):
|
|||||||
print "property %s, value: %s" % (p, properties[p])
|
print "property %s, value: %s" % (p, properties[p])
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
if (len(sys.argv) != 2):
|
||||||
|
print_usage()
|
||||||
|
|
||||||
|
password = sys.argv[1]
|
||||||
|
|
||||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||||
|
|
||||||
bus = dbus.SystemBus()
|
bus = dbus.SystemBus()
|
||||||
@@ -29,7 +39,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
cb.connect_to_signal("PropertyChanged", property_changed)
|
cb.connect_to_signal("PropertyChanged", property_changed)
|
||||||
|
|
||||||
ss = dbus.Interface(bus.get_object('org.ofono', modems[0]),
|
ss = dbus.Interface(bus.get_object('org.ofono', modems[0][0]),
|
||||||
'org.ofono.SupplementaryServices')
|
'org.ofono.SupplementaryServices')
|
||||||
|
|
||||||
print_properties(cb)
|
print_properties(cb)
|
||||||
@@ -82,13 +92,19 @@ if __name__ == "__main__":
|
|||||||
print "Query All"
|
print "Query All"
|
||||||
print ss.Initiate("*#330#")
|
print ss.Initiate("*#330#")
|
||||||
|
|
||||||
|
ss_string = "*33*" + password + "*11#"
|
||||||
|
|
||||||
print "Enable Barring for Outgoing International calls for Voice"
|
print "Enable Barring for Outgoing International calls for Voice"
|
||||||
print ss.Initiate("*33*3579*11#")
|
print ss.Initiate(ss_string)
|
||||||
|
|
||||||
print_properties(cb)
|
print_properties(cb)
|
||||||
|
|
||||||
|
ss_string = "#330*" + password + "#"
|
||||||
|
|
||||||
print "Disable All Barrings"
|
print "Disable All Barrings"
|
||||||
print ss.Initiate("#330*3579#")
|
print ss.Initiate(ss_string)
|
||||||
|
|
||||||
|
sys.exit(1);
|
||||||
|
|
||||||
mainloop = gobject.MainLoop()
|
mainloop = gobject.MainLoop()
|
||||||
mainloop.run()
|
mainloop.run()
|
||||||
|
|||||||
48
ofono/test/test-voicecallagent
Executable file
48
ofono/test/test-voicecallagent
Executable file
@@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import gobject
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import dbus
|
||||||
|
import dbus.service
|
||||||
|
import dbus.mainloop.glib
|
||||||
|
|
||||||
|
class VoiceCallAgent(dbus.service.Object):
|
||||||
|
@dbus.service.method("org.ofono.VoiceCallAgent",
|
||||||
|
in_signature="", out_signature="")
|
||||||
|
def Release(self):
|
||||||
|
print "Agent got Release"
|
||||||
|
mainloop.quit()
|
||||||
|
|
||||||
|
@dbus.service.method("org.ofono.VoiceCallAgent",
|
||||||
|
in_signature="b", out_signature="")
|
||||||
|
def RingbackTone(self, playTone):
|
||||||
|
print "Agent got playTone notification: %d" % playTone
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||||
|
|
||||||
|
bus = dbus.SystemBus()
|
||||||
|
manager = dbus.Interface(bus.get_object("org.ofono", "/"),
|
||||||
|
"org.ofono.Manager")
|
||||||
|
|
||||||
|
modems = manager.GetModems()
|
||||||
|
|
||||||
|
for path, properties in modems:
|
||||||
|
if "org.ofono.VoiceCallManager" not in properties["Interfaces"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
vcm = dbus.Interface(bus.get_object('org.ofono', path),
|
||||||
|
'org.ofono.VoiceCallManager')
|
||||||
|
|
||||||
|
path = "/test/agent"
|
||||||
|
agent = VoiceCallAgent(bus, path)
|
||||||
|
vcm.RegisterVoicecallAgent(agent)
|
||||||
|
print "Agent registered"
|
||||||
|
mainloop = gobject.MainLoop()
|
||||||
|
|
||||||
|
try:
|
||||||
|
mainloop.run()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
vcm.UnregisterVoicecallAgent(path)
|
||||||
|
print "Agent unregistered (interrupt)"
|
||||||
20
ofono/test/transfer-call
Executable file
20
ofono/test/transfer-call
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import dbus
|
||||||
|
|
||||||
|
bus = dbus.SystemBus()
|
||||||
|
|
||||||
|
manager = dbus.Interface(bus.get_object('org.ofono', '/'),
|
||||||
|
'org.ofono.Manager')
|
||||||
|
|
||||||
|
modems = manager.GetModems()
|
||||||
|
modem = modems[0][0]
|
||||||
|
|
||||||
|
if (len(sys.argv) == 2):
|
||||||
|
modem = sys.argv[1]
|
||||||
|
|
||||||
|
manager = dbus.Interface(bus.get_object('org.ofono', modem),
|
||||||
|
'org.ofono.VoiceCallManager')
|
||||||
|
|
||||||
|
manager.Transfer(timeout=100)
|
||||||
99
ofono/unit/test-provision.c
Normal file
99
ofono/unit/test-provision.c
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
struct ofono_modem;
|
||||||
|
#include <gprs-provision.h>
|
||||||
|
#include "plugins/mbpi.h"
|
||||||
|
#include "plugins/provision.h"
|
||||||
|
|
||||||
|
|
||||||
|
void get_and_print_settings(const char *mcc, const char *mnc,
|
||||||
|
const char *spn)
|
||||||
|
{
|
||||||
|
struct ofono_gprs_provision_data *settings;
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
|
provision_get_settings(mcc, mnc, spn, &settings, &count);
|
||||||
|
g_print("Found %d contexts for (%s/%s/%s):\n", count, mcc, mnc, spn);
|
||||||
|
for (i = 0; i < count; i++){
|
||||||
|
struct ofono_gprs_provision_data ap = settings[i];
|
||||||
|
g_print(" Name: %s\n", ap.name);
|
||||||
|
g_print(" APN: %s\n", ap.apn);
|
||||||
|
g_print(" Type: %s\n", mbpi_ap_type(ap.type));
|
||||||
|
if (ap.username)
|
||||||
|
g_print(" Username: %s\n", ap.username);
|
||||||
|
if (ap.password)
|
||||||
|
g_print(" Password: %s\n", ap.password);
|
||||||
|
if (ap.message_proxy)
|
||||||
|
g_print(" MMS proxy: %s\n", ap.message_proxy);
|
||||||
|
if (ap.message_center)
|
||||||
|
g_print(" MMS center: %s\n", ap.message_center);
|
||||||
|
g_print("----------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_get_settings(void)
|
||||||
|
{
|
||||||
|
/* not in database */
|
||||||
|
get_and_print_settings("999", "999", NULL);
|
||||||
|
|
||||||
|
/* partial and case-insensitive matching */
|
||||||
|
get_and_print_settings("244", "91", "sonera");
|
||||||
|
get_and_print_settings("244", "91", "sONErA");
|
||||||
|
get_and_print_settings("244", "91", "sone");
|
||||||
|
get_and_print_settings("244", "91", "nera");
|
||||||
|
|
||||||
|
/* related to Sonera/Finland network */
|
||||||
|
get_and_print_settings("244", "91", NULL);
|
||||||
|
get_and_print_settings("244", "91", "sonera");
|
||||||
|
get_and_print_settings("244", "91", "aina");
|
||||||
|
|
||||||
|
/* related to DNA/Finland network */
|
||||||
|
get_and_print_settings("244", "03", NULL);
|
||||||
|
get_and_print_settings("244", "03", "dna");
|
||||||
|
get_and_print_settings("244", "03", "aina");
|
||||||
|
get_and_print_settings("244", "04", NULL);
|
||||||
|
get_and_print_settings("244", "04", "dna");
|
||||||
|
get_and_print_settings("244", "04", "aina");
|
||||||
|
|
||||||
|
/* related to O2/UK network */
|
||||||
|
get_and_print_settings("234", "10", NULL);
|
||||||
|
get_and_print_settings("234", "10", "o2");
|
||||||
|
get_and_print_settings("234", "10", "tesco");
|
||||||
|
get_and_print_settings("234", "10", "giffgaff");
|
||||||
|
|
||||||
|
/* related to E-Plus/Germany network */
|
||||||
|
get_and_print_settings("262", "03", NULL);
|
||||||
|
get_and_print_settings("262", "03", "E-Plus");
|
||||||
|
get_and_print_settings("262", "03", "simyo");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
g_test_init(&argc, &argv, NULL);
|
||||||
|
g_test_add_func("/testprovision/get_settings", test_get_settings);
|
||||||
|
return g_test_run();
|
||||||
|
}
|
||||||
@@ -345,12 +345,21 @@ const unsigned char valid_efopl[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const unsigned char valid_efpnn[][28] = {
|
const unsigned char valid_efpnn[][28] = {
|
||||||
{ 0x43, 0x0a, 0x00, 0x54, 0x75, 0x78, 0x20, 0x43, 0x6f, 0x6d,
|
{ 0x43, 0x08, 0x00, 0xD4, 0x3A, 0x1E, 0x34, 0x7C, 0xB7, 0xDB,
|
||||||
0x6d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, },
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, },
|
||||||
{ 0x43, 0x05, 0x00, 0x4C, 0x6F, 0x6E, 0x67, 0x45, 0x06, 0x00,
|
{ 0x43, 0x05, 0x00, 0x4C, 0x6F, 0x6E, 0x67, 0x45, 0x06, 0x00,
|
||||||
0x53, 0x68, 0x6F, 0x72, 0x74, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
|
0x53, 0x68, 0x6F, 0x72, 0x74, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unsigned char valid_efpnn_2[][28] = {
|
||||||
|
/* Solavei */
|
||||||
|
{ 0x43, 0x08, 0x87, 0xD3, 0x37, 0x3B, 0x6C, 0x2F, 0xA7, 0x01 },
|
||||||
|
/* T-Mobile / T-Mobile */
|
||||||
|
{ 0x43, 0x08, 0x80, 0xD4, 0x56, 0xF3, 0x2D, 0x4E, 0xB3, 0xCB,
|
||||||
|
0x45, 0x08, 0x80, 0xD4, 0x56, 0xF3, 0x2D, 0x4E, 0xB3, 0xCB,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||||
|
};
|
||||||
|
|
||||||
static void test_eons(void)
|
static void test_eons(void)
|
||||||
{
|
{
|
||||||
const struct sim_eons_operator_info *op_info;
|
const struct sim_eons_operator_info *op_info;
|
||||||
@@ -360,6 +369,7 @@ static void test_eons(void)
|
|||||||
|
|
||||||
g_assert(sim_eons_pnn_is_empty(eons_info));
|
g_assert(sim_eons_pnn_is_empty(eons_info));
|
||||||
|
|
||||||
|
/* 1. a fictious operator */
|
||||||
sim_eons_add_pnn_record(eons_info, 1,
|
sim_eons_add_pnn_record(eons_info, 1,
|
||||||
valid_efpnn[0], sizeof(valid_efpnn[0]));
|
valid_efpnn[0], sizeof(valid_efpnn[0]));
|
||||||
g_assert(!sim_eons_pnn_is_empty(eons_info));
|
g_assert(!sim_eons_pnn_is_empty(eons_info));
|
||||||
@@ -380,6 +390,27 @@ static void test_eons(void)
|
|||||||
g_assert(!op_info->shortname);
|
g_assert(!op_info->shortname);
|
||||||
g_assert(!op_info->info);
|
g_assert(!op_info->info);
|
||||||
|
|
||||||
|
/* 2. a real-world MVNO */
|
||||||
|
sim_eons_add_pnn_record(eons_info, 1,
|
||||||
|
valid_efpnn_2[0], sizeof(valid_efpnn_2[0]));
|
||||||
|
g_assert(!sim_eons_pnn_is_empty(eons_info));
|
||||||
|
|
||||||
|
sim_eons_add_pnn_record(eons_info, 2,
|
||||||
|
valid_efpnn_2[1], sizeof(valid_efpnn_2[1]));
|
||||||
|
g_assert(!sim_eons_pnn_is_empty(eons_info));
|
||||||
|
|
||||||
|
sim_eons_add_opl_record(eons_info, valid_efopl, sizeof(valid_efopl));
|
||||||
|
sim_eons_optimize(eons_info);
|
||||||
|
|
||||||
|
op_info = sim_eons_lookup(eons_info, "246", "82");
|
||||||
|
g_assert(op_info == NULL);
|
||||||
|
op_info = sim_eons_lookup(eons_info, "246", "81");
|
||||||
|
g_assert(op_info);
|
||||||
|
|
||||||
|
g_assert(!strcmp(op_info->longname, "Solavei"));
|
||||||
|
g_assert(!op_info->shortname);
|
||||||
|
g_assert(!op_info->info);
|
||||||
|
|
||||||
sim_eons_free(eons_info);
|
sim_eons_free(eons_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1769,6 +1769,63 @@ static void test_wap_push(gconstpointer data)
|
|||||||
g_slist_free(list);
|
g_slist_free(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *simple_deliver_unicode = "0791534850020290"
|
||||||
|
"040c915348608475840008412060610141800e0054006500730074002062116211";
|
||||||
|
|
||||||
|
static const char *simple_deliver_unicode_surrogate = "0791534850020290"
|
||||||
|
"040c915348608475840008412060610141800e00540065007300740020D83DDE3B";
|
||||||
|
|
||||||
|
static void test_decode_unicode(void)
|
||||||
|
{
|
||||||
|
struct sms sms;
|
||||||
|
unsigned char *pdu;
|
||||||
|
long pdu_len;
|
||||||
|
gboolean ret;
|
||||||
|
struct sms_assembly *assembly;
|
||||||
|
GSList *l;
|
||||||
|
char *decoded;
|
||||||
|
|
||||||
|
/* contains UCS-2 (Chinese characters) */
|
||||||
|
pdu = decode_hex(simple_deliver_unicode, -1, &pdu_len, 0);
|
||||||
|
g_assert(pdu);
|
||||||
|
g_assert(pdu_len == (long)strlen(simple_deliver_unicode) / 2);
|
||||||
|
ret = sms_decode(pdu, pdu_len, FALSE, 33, &sms);
|
||||||
|
g_free(pdu);
|
||||||
|
|
||||||
|
g_assert(ret);
|
||||||
|
g_assert(sms.type == SMS_TYPE_DELIVER);
|
||||||
|
g_assert(sms.deliver.udl == 14);
|
||||||
|
|
||||||
|
assembly = sms_assembly_new(NULL);
|
||||||
|
l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
|
||||||
|
&sms.deliver.oaddr, 0, 1, 0);
|
||||||
|
g_assert(l);
|
||||||
|
g_assert(g_slist_length(l) == 1);
|
||||||
|
decoded = sms_decode_text(l);
|
||||||
|
sms_assembly_free(assembly);
|
||||||
|
g_assert(strcmp(decoded, "Test 我我") == 0);
|
||||||
|
|
||||||
|
/* contains UTF-16 (a Unicode surrogate pair representing an emoticon) */
|
||||||
|
pdu = decode_hex(simple_deliver_unicode_surrogate, -1, &pdu_len, 0);
|
||||||
|
g_assert(pdu);
|
||||||
|
g_assert(pdu_len == (long)strlen(simple_deliver_unicode_surrogate) / 2);
|
||||||
|
ret = sms_decode(pdu, pdu_len, FALSE, 33, &sms);
|
||||||
|
g_free(pdu);
|
||||||
|
|
||||||
|
g_assert(ret);
|
||||||
|
g_assert(sms.type == SMS_TYPE_DELIVER);
|
||||||
|
g_assert(sms.deliver.udl == 14);
|
||||||
|
|
||||||
|
assembly = sms_assembly_new(NULL);
|
||||||
|
l = sms_assembly_add_fragment(assembly, &sms, time(NULL),
|
||||||
|
&sms.deliver.oaddr, 0, 1, 0);
|
||||||
|
g_assert(l);
|
||||||
|
g_assert(g_slist_length(l) == 1);
|
||||||
|
decoded = sms_decode_text(l);
|
||||||
|
sms_assembly_free(assembly);
|
||||||
|
g_assert(strcmp(decoded, "Test 😻") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char long_string[152*33 + 1];
|
char long_string[152*33 + 1];
|
||||||
@@ -1850,5 +1907,7 @@ int main(int argc, char **argv)
|
|||||||
g_test_add_data_func("/testsms/Test WAP Push 1", &wap_push_1,
|
g_test_add_data_func("/testsms/Test WAP Push 1", &wap_push_1,
|
||||||
test_wap_push);
|
test_wap_push);
|
||||||
|
|
||||||
|
g_test_add_func("/testsms/Test Decode Unicode", test_decode_unicode);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
#
|
|
||||||
# Do NOT Edit the Auto-generated Part!
|
|
||||||
# Generated by: spectacle version 0.26
|
|
||||||
#
|
|
||||||
|
|
||||||
Name: ofono
|
Name: ofono
|
||||||
|
|
||||||
# >> macros
|
|
||||||
# << macros
|
|
||||||
|
|
||||||
Summary: Open Source Telephony
|
Summary: Open Source Telephony
|
||||||
Version: 1.14
|
Version: 1.14
|
||||||
Release: 1
|
Release: 1
|
||||||
@@ -15,7 +7,6 @@ Group: Communications/Connectivity Adaptation
|
|||||||
License: GPLv2
|
License: GPLv2
|
||||||
URL: http://ofono.org
|
URL: http://ofono.org
|
||||||
Source0: http://www.kernel.org/pub/linux/network/ofono/ofono-%{version}.tar.xz
|
Source0: http://www.kernel.org/pub/linux/network/ofono/ofono-%{version}.tar.xz
|
||||||
Source100: ofono.yaml
|
|
||||||
Requires: dbus
|
Requires: dbus
|
||||||
Requires: systemd
|
Requires: systemd
|
||||||
Requires: ofono-configs
|
Requires: ofono-configs
|
||||||
@@ -27,6 +18,7 @@ BuildRequires: pkgconfig(dbus-1)
|
|||||||
BuildRequires: pkgconfig(libudev) >= 145
|
BuildRequires: pkgconfig(libudev) >= 145
|
||||||
BuildRequires: pkgconfig(bluez) >= 4.85
|
BuildRequires: pkgconfig(bluez) >= 4.85
|
||||||
BuildRequires: pkgconfig(mobile-broadband-provider-info)
|
BuildRequires: pkgconfig(mobile-broadband-provider-info)
|
||||||
|
BuildRequires: pkgconfig(libwspcodec) >= 2.0
|
||||||
BuildRequires: libtool
|
BuildRequires: libtool
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
@@ -66,79 +58,68 @@ This package provides default configs for ofono
|
|||||||
%prep
|
%prep
|
||||||
%setup -q -n %{name}-%{version}/%{name}
|
%setup -q -n %{name}-%{version}/%{name}
|
||||||
|
|
||||||
# >> setup
|
|
||||||
./bootstrap
|
./bootstrap
|
||||||
# << setup
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# >> build pre
|
|
||||||
autoreconf --force --install
|
autoreconf --force --install
|
||||||
# << build pre
|
|
||||||
|
|
||||||
%configure --disable-static \
|
%configure --disable-static \
|
||||||
--enable-dundee \
|
|
||||||
--enable-test \
|
--enable-test \
|
||||||
--with-systemdunitdir="/%{_lib}/systemd/system"
|
--with-systemdunitdir="/%{_lib}/systemd/system"
|
||||||
|
|
||||||
make %{?jobs:-j%jobs}
|
make %{?jobs:-j%jobs}
|
||||||
|
|
||||||
# >> build post
|
|
||||||
# << build post
|
%check
|
||||||
|
# run unit tests
|
||||||
|
make check
|
||||||
|
|
||||||
%install
|
%install
|
||||||
rm -rf %{buildroot}
|
rm -rf %{buildroot}
|
||||||
# >> install pre
|
|
||||||
# << install pre
|
|
||||||
%make_install
|
%make_install
|
||||||
|
|
||||||
# >> install post
|
mkdir -p %{buildroot}/%{_sysconfdir}/ofono/push_forwarder.d
|
||||||
mkdir -p %{buildroot}/%{_lib}/systemd/system/network.target.wants
|
mkdir -p %{buildroot}/%{_lib}/systemd/system/network.target.wants
|
||||||
ln -s ../ofono.service %{buildroot}/%{_lib}/systemd/system/network.target.wants/ofono.service
|
ln -s ../ofono.service %{buildroot}/%{_lib}/systemd/system/network.target.wants/ofono.service
|
||||||
# << install post
|
|
||||||
|
|
||||||
%preun
|
%preun
|
||||||
if [ "$1" -eq 0 ]; then
|
if [ "$1" -eq 0 ]; then
|
||||||
systemctl stop ofono.service
|
systemctl stop ofono.service ||:
|
||||||
fi
|
fi
|
||||||
|
|
||||||
%post
|
%post
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload ||:
|
||||||
systemctl reload-or-try-restart ofono.service
|
# Do not restart during update
|
||||||
|
# We don't want to break anything during update
|
||||||
|
# New daemon is taken in use after reboot
|
||||||
|
# systemctl reload-or-try-restart ofono.service ||:
|
||||||
|
|
||||||
%postun
|
%postun
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload ||:
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
# >> files
|
|
||||||
%doc COPYING ChangeLog AUTHORS README
|
%doc COPYING ChangeLog AUTHORS README
|
||||||
%config(noreplace) %{_sysconfdir}/dbus-1/system.d/*.conf
|
%config %{_sysconfdir}/dbus-1/system.d/*.conf
|
||||||
%{_sbindir}/*
|
%{_sbindir}/*
|
||||||
/%{_lib}/systemd/system/network.target.wants/ofono.service
|
/%{_lib}/systemd/system/network.target.wants/ofono.service
|
||||||
/%{_lib}/systemd/system/ofono.service
|
/%{_lib}/systemd/system/ofono.service
|
||||||
/%{_lib}/systemd/system/dundee.service
|
|
||||||
%dir %{_sysconfdir}/ofono/
|
%dir %{_sysconfdir}/ofono/
|
||||||
|
%dir %{_sysconfdir}/ofono/push_forwarder.d
|
||||||
# This file is part of phonesim and not needed with ofono.
|
# This file is part of phonesim and not needed with ofono.
|
||||||
%exclude %{_sysconfdir}/ofono/phonesim.conf
|
%exclude %{_sysconfdir}/ofono/phonesim.conf
|
||||||
%doc /usr/share/man/man8/ofonod.8.gz
|
%doc /usr/share/man/man8/ofonod.8.gz
|
||||||
%dir %attr(775,radio,radio) /var/lib/ofono
|
%dir %attr(775,radio,radio) /var/lib/ofono
|
||||||
# << files
|
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
%{_includedir}/ofono/
|
%{_includedir}/ofono/
|
||||||
%{_libdir}/pkgconfig/ofono.pc
|
%{_libdir}/pkgconfig/ofono.pc
|
||||||
# >> files devel
|
|
||||||
# << files devel
|
|
||||||
|
|
||||||
%files tests
|
%files tests
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
%{_libdir}/%{name}/test/*
|
%{_libdir}/%{name}/test/*
|
||||||
# >> files tests
|
|
||||||
# << files tests
|
|
||||||
|
|
||||||
%files configs-mer
|
%files configs-mer
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
%config /etc/ofono/ril_subscription.conf
|
%config /etc/ofono/ril_subscription.conf
|
||||||
# >> files ofono-configs-mer
|
|
||||||
# << files ofono-configs-mer
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
Name: ofono
|
|
||||||
Summary: Open Source Telephony
|
|
||||||
Description: Telephony stack
|
|
||||||
Version: 1.14
|
|
||||||
Release: 1
|
|
||||||
Group: Communications/Connectivity Adaptation
|
|
||||||
License: GPLv2
|
|
||||||
URL: http://ofono.org
|
|
||||||
Sources:
|
|
||||||
- http://www.kernel.org/pub/linux/network/ofono/ofono-%{version}.tar.xz
|
|
||||||
Requires:
|
|
||||||
- dbus
|
|
||||||
PkgBR:
|
|
||||||
- libtool
|
|
||||||
- automake
|
|
||||||
- autoconf
|
|
||||||
PkgConfigBR:
|
|
||||||
- glib-2.0
|
|
||||||
- dbus-1
|
|
||||||
- libudev >= 145
|
|
||||||
- bluez >= 4.85
|
|
||||||
- mobile-broadband-provider-info
|
|
||||||
SetupOptions: -q -n %{name}-%{version}/%{name}
|
|
||||||
ConfigOptions:
|
|
||||||
- --enable-dundee
|
|
||||||
- --enable-test
|
|
||||||
- --with-systemdunitdir="/%{_lib}/systemd/system"
|
|
||||||
SubPackages:
|
|
||||||
- Name: devel
|
|
||||||
Summary: Headers for oFono
|
|
||||||
Group: Development/Libraries
|
|
||||||
Description: Development headers and libraries for oFono
|
|
||||||
Files:
|
|
||||||
- "%{_includedir}/ofono/"
|
|
||||||
- "%{_libdir}/pkgconfig/ofono.pc"
|
|
||||||
|
|
||||||
- Name: tests
|
|
||||||
Summary: Test Scripts for oFono
|
|
||||||
Group: Development/Libraries
|
|
||||||
Description: Scripts for testing oFono and its functionality
|
|
||||||
Obsoletes:
|
|
||||||
- "ofono-test < 1.0"
|
|
||||||
Provides:
|
|
||||||
- "ofono-test >= 1.0"
|
|
||||||
Requires:
|
|
||||||
- dbus-python
|
|
||||||
- pygobject2
|
|
||||||
Files:
|
|
||||||
- "%{_libdir}/%{name}/test/*"
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user