Compare commits

...

87 Commits

Author SHA1 Message Date
Tommi Kenakkala
133d92f265 Merge pull request #236 from special/master
[ofono] Encode SMS as UTF-16 instead of UCS-2
2014-06-26 08:56:29 +03:00
Tommi Kenakkala
ad6fd49dbc Merge pull request #237 from martinjones/cfu_change
[ofono] Fix call forwarding unconditional change signal emission.
Wrong property names signalled for conditional call forwarding types when status of unconditional type changed.
2014-06-24 14:01:06 +03:00
Martin Jones
888e857779 [ofono] Fix call forwarding unconditional change signal emission.
When toggling cfu the change signals for the other types didn't have the
prefix applied.
2014-06-20 02:01:37 +00:00
Tommi Kenakkala
e189cd138b Merge pull request #235 from jpoutiai/sms-on-sim
[RILMODEM] initial support to read and delete sms from sim (class2, voicemail mwi)
2014-06-18 16:21:14 +03:00
John Brooks
6b8b5d29a1 [ofono] Encode SMS as UTF-16 instead of UCS-2
UCS-2 is an older 16-bit encoding compatible with the unicode BMP.
UTF-16 extends UCS-2 to add support for surrogate pairs and the rest of
the unicode set. All valid UCS-2 text is also valid UTF-16 text, and all
UTF-16 text not containing surrogate pairs is valid UCS-2.

We decode incoming SMS as UTF-16 instead of UCS-2 to add support for
these extended characters. We should do the same for encoding outgoing
SMS messages.
2014-06-18 06:04:38 -06:00
Jarko Poutiainen
960ef29014 [RILMODEM] removing unnecessary empty lines and null check
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-06-17 15:14:10 +03:00
Jarko Poutiainen
30f3dd2c53 [RILMODEM] change cb_data_new2 to abort in failure
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-06-17 15:13:49 +03:00
Jarko Poutiainen
feb1126123 [RILMODEM] initial support to read and delete sms from sim
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-06-17 11:57:44 +03:00
Tommi Kenakkala
420651829a Merge pull request #234 from mkuukkane/remove-dundee
Remove dundee from ofono compilation.
2014-06-16 12:32:05 +03:00
Jarko Poutiainen
0835875b65 Merge pull request #233 from tkenakka/netregfix
[rilmodem] Null netreg pointer on netreg remove
2014-06-13 15:00:28 +03:00
Tommi Kenakkala
153599eb70 [rilmodem] Null netreg pointer on netreg remove
Netreg driver has a static copy of the netreg pointer.
Missing NULLing may cause problems on corner cases after
netreg is freed (when core atom is flushed).

Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-06-13 10:52:24 +03:00
Marko Kuukkanen
fafef8bfd3 [ofono] Remove dundee (service) 2014-06-12 10:40:27 +03:00
Jarko Poutiainen
3bce306f6e Merge pull request #231 from jpoutiai/gprs
[RILMODEM] gprs set detach notified only for callback
2014-06-09 10:14:00 +03:00
Tommi Kenakkala
68767f6ea2 Merge pull request #232 from mkuukkane/ussd
[rilmodem] Don't send <CR> with USSD string
2014-06-06 15:05:58 +03:00
Marko Kuukkanen
a3cd7b0898 [rilmodem] Don't send <CR> with USSD string 2014-06-06 15:00:04 +03:00
Jarko Poutiainen
d0364f89cd [RILMODEM] gprs set detach notified only for callback
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-06-05 15:05:58 +03:00
Jarko Poutiainen
9aa8375233 Merge pull request #230 from martinjones/master
[voicecall] Cancel pending DTMF tones before hanging up call.
2014-06-04 12:57:54 +03:00
Martin Jones
77b3adfd60 [voicecall] Cancel pending DTMF tones before hanging up call. 2014-06-04 09:27:43 +00:00
Marko Kuukkanen
b4bb7e72d8 Merge pull request #229 from mkuukkane/transfer
Explicit call transfer rilmodem implementation
2014-06-02 14:23:45 +03:00
Marko Kuukkanen
8e20975660 [rilmodem] Explicit call transfer driver implementation 2014-06-02 08:39:55 +03:00
Marko Kuukkanen
0e8a53bdf0 [test] Add test script for explicit call transfer 2014-06-02 08:38:31 +03:00
Jarko Poutiainen
9a29fdde06 Merge pull request #228 from jpoutiai/master
Refactoring rilmodem gprs implementation
2014-05-30 14:09:37 +03:00
Jarko Poutiainen
269fa3db0e [RILMODEM] fake also roaming
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-27 12:42:56 +03:00
Jarko Poutiainen
64dab08751 [RILMODEM] code review and checkpatch cleaning
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-27 12:39:50 +03:00
Jarko Poutiainen
7a72726d9a [RILMODEM] code review and checkpatch cleaning
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-27 12:39:39 +03:00
Jarko Poutiainen
b6fb89c3a0 [RILMODEM] refactor gprs-context driver
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-26 11:17:34 +03:00
Jarko Poutiainen
d51d858cd6 [RILMODEM] refactor gprs driver
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-26 11:17:15 +03:00
Tommi Kenakkala
24d1be80c5 Merge pull request #227 from tkenakka/logging
[rilmodem] Improve ril.c logging
2014-05-26 09:23:03 +03:00
Tommi Kenakkala
19c2a6fc64 [rilmodem] Improve ril.c logging
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-05-23 23:58:41 +03:00
Martti Piirainen
6e3236b739 Merge pull request #226 from jpoutiai/master
more default logging
2014-05-20 14:21:43 +03:00
Jarko Poutiainen
e5223ac8af [RILMODEM] add more logging
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-19 10:28:18 +03:00
Jarko Poutiainen
9505b6baf3 [RILMODEM] add more logging
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-19 10:28:04 +03:00
Jarko Poutiainen
4c268731b9 [RILMODEM] add more logging
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-19 10:27:50 +03:00
Martti Piirainen
5b158c3a28 Merge pull request #224 from jpoutiai/master
[RILMODEM] prevent ofono crash when sim removed while reading
2014-05-19 09:51:34 +03:00
Tommi Kenakkala
9745d202d3 Merge pull request #225 from marttipiirainen/nettime
Fix crash in network time plugin
2014-05-15 14:15:10 +03:00
Martti Piirainen
2329468e25 [nettime] Prevent crash if MNC or MCC is missing 2014-05-15 07:36:07 +03:00
Martti Piirainen
2b352aedb4 [nettime] Export test script to .rpm 2014-05-15 07:21:07 +03:00
Jarko Poutiainen
b319c77bcc [RILMODEM] prevent ofono crash when sim removed while reading
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-14 14:08:21 +03:00
Martti Piirainen
4b95656d72 Merge pull request #223 from jpoutiai/master
[RILMODEM] hardening phonebook driver implementation
2014-05-14 13:57:51 +03:00
Jarko Poutiainen
b3dc0d0146 [RILMODEM] hardening phonebook driver implementation
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-05-12 15:08:28 +03:00
Martti Piirainen
319866c450 Merge pull request #222 from marttipiirainen/mbpi_primary
Use "primary provider" information from MBPI
2014-05-12 09:21:26 +03:00
Martti Piirainen
2847cfcd03 [provision] Prioritize "primary" providers (MNOs) over MVNOs 2014-05-11 11:04:58 +03:00
Martti Piirainen
65501536d3 [mbpi] Parse provider's "primary" property 2014-05-11 11:01:56 +03:00
Martti Piirainen
eef58998c0 [gprs-provision] Add field to distinguish primary MNO from MVNO 2014-05-11 10:32:05 +03:00
Tommi Kenakkala
571d440c14 Merge pull request #220 from jpoutiai/master
[SRC] fix incorrect CF state after CFU erasure
2014-05-05 08:17:19 +03:00
Jarko Poutiainen
25fc82a073 [SRC] fix incorrect CF state after CFU erasure
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-30 14:41:45 +03:00
Tommi Kenakkala
e50518effa Merge pull request #219 from tkenakka/conffix
[rilmodem] Fix ratmode bad conf file handling
2014-04-30 09:44:16 +03:00
Tommi Kenakkala
84e1386978 [rilmodem] Fix ratmode bad conf file handling
g_key_file_load_from_file loads also dirs, if a bad file/dir was
picked up first then logic deduced wrong the need for ratmode reconfig.

Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-04-30 09:35:52 +03:00
Slava Monich
0cdd483894 Merge pull request #218 from monich/leaks
[rilmodem] Plugged a few memory leaks
2014-04-29 16:14:44 +03:00
Slava Monich
7dbeba0e83 Merge pull request #217 from monich/simsms
[push-forwarder] Fixed sim/sms watch id mixup
2014-04-29 16:14:01 +03:00
Slava Monich
d7cf952a16 [rilmodem] Plugged a few memory leaks 2014-04-29 15:37:14 +03:00
Slava Monich
e8379285b3 [push-forwarder] Fixed sim/sms watch id mixup 2014-04-29 14:55:01 +03:00
Tommi Kenakkala
f9a91c8453 Merge pull request #216 from jpoutiai/master
Disable stack trace from command line
2014-04-28 15:54:20 +03:00
Jarko Poutiainen
882f75b500 [SRC] Disable stack trace from command line ofono.service.in
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 15:32:33 +03:00
Jarko Poutiainen
5b6ddee098 [SRC] Disable stack trace from command line ofono.h
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 12:57:05 +03:00
Jarko Poutiainen
5cbf0de041 [SRC] Disable stack trace from command line main.c
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 12:56:45 +03:00
Jarko Poutiainen
8ce12b2232 [SRC] Disable stack trace from command line log.c
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 12:56:21 +03:00
Jarko Poutiainen
62d42e0407 Merge pull request #215 from lpotter/master
[rilmodem] Fix gprs state after offline mode.
2014-04-28 11:09:52 +03:00
Lorn Potter
5053a342e7 [rilmodem] Fix gprs state after offline mode. 2014-04-23 10:54:57 +10:00
Martti Piirainen
5c53260938 Merge pull request #213 from marttipiirainen/mbpi3
Take Service Provider Name into account in MBPI provisioning
2014-04-22 15:11:36 +03:00
Martti Piirainen
e3e691fb48 Merge pull request #214 from marttipiirainen/ringback
[voicecall] Inform client when local ringback tone is needed
2014-04-22 13:54:13 +03:00
Martti Piirainen
8fa99a07e8 [provision] Take SPN into account when finding APNs 2014-04-17 08:14:08 +03:00
Slava Monich
23f92a5b3e [mbpi] Parse gsm provider name 2014-04-17 07:32:36 +03:00
Slava Monich
94494f3a63 [provision] Fixed memory leak 2014-04-16 16:07:40 +03:00
Martti Piirainen
098b3d4a64 [unit] Add provisioning tests 2014-04-16 16:07:29 +03:00
Martti Piirainen
cfeb58f2a8 [provision] Expose provision_get_settings() in header (for testability) 2014-04-16 16:07:21 +03:00
Martti Piirainen
5f821b4a9a [voicecall] Inform client when local ringback tone is needed
In some networks, MO calls do not get the "alerting" tone in-band, so the device needs to play one locally.

This commit adds a "voice call agent" API. It currently contains only the ringback tone notification, but can be extended later.
2014-04-16 15:31:45 +03:00
Martti Piirainen
533d248288 Merge pull request #210 from nemomobile-packages/next
Merge various improvements from 'next' to 'master'
2014-04-08 10:54:18 +03:00
Martti Piirainen
4f512b6e56 Merge pull request #209 from jpoutiai/next
[RILMODEM] fix cf query callback list handling
2014-04-07 10:18:48 +03:00
Martti Piirainen
ce3a5e5a0b Merge pull request #204 from monich/ril_delayed_register
[rilmodem] Actually remove delayed register timer
2014-04-07 10:13:28 +03:00
Martti Piirainen
c97ef76c93 Merge pull request #205 from monich/ril_oemraw_delayed_register
[rilmodem] Remove delayed register timer in ril_oemraw_remove
2014-04-07 10:13:11 +03:00
Jarko Poutiainen
95659d7c49 [RILMODEM] fix cf query callback list handling
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-04 15:03:08 +03:00
Tommi Kenakkala
eb986f49e4 Merge pull request #208 from tkenakka/next
[ofono][dundee] At startup order dundee after dbus instead of syslog.
2014-04-01 15:27:26 +03:00
Tommi Kenakkala
4691d385c0 [ofono][dundee] At startup order dundee after dbus instead of syslog.
According to systemd documentation
"Newer systemd versions (v35+) do not support non-socket-activated syslog
daemons anymore and we do no longer recommend people to order their units
after syslog.target."

Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-04-01 13:15:53 +03:00
Martti Piirainen
0ddebfea70 Merge pull request #207 from tkenakka/nwlock
[rilmodem] Network lock depersonalisation support
2014-03-31 07:12:49 +03:00
Tommi Kenakkala
2d1f2b0650 [rilmodem] Network lock depersonalisation support
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-03-28 13:52:56 +02:00
Martti Piirainen
0ca5c87999 Merge pull request #206 from marttipiirainen/voice_busy
[rilmodem] Fine-tune disconnect reasons for MO calls
2014-03-28 12:33:58 +02:00
Martti Piirainen
e3dcd67a1b [rilmodem] Fine-tune disconnect reasons for MO calls 2014-03-28 08:04:23 +02:00
Slava Monich
99b9099082 [rilmodem] Remove delayed register timer in ril_oemraw_remove 2014-03-27 16:42:22 +02:00
Slava Monich
ec74da107d [rilmodem] Actually remove delayed register timer in ril_call_barring_remove 2014-03-27 16:33:47 +02:00
Jarko Poutiainen
50f146939f Merge pull request #203 from tkenakka/next
[rilmodem] Minor rilmodem/sim.c mem leak fix
2014-03-27 11:06:56 +02:00
Tommi Kenakkala
e7a07b4694 [rilmodem] Minor rilmodem/sim.c mem leak fix
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-03-27 10:58:32 +02:00
Martti Piirainen
461d18f4a3 Merge pull request #195 from marttipiirainen/unit
Unit test improvements
2014-03-26 13:07:47 +02:00
Jussi Kangas
16ea57247d [rilmodem] Check if really network registration status is really searching
If connection drops to searching and only voice call registration
status changes to roaming, with current implementation it is possible
to get through roaming allowed check in core. This prevents it.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-26 10:56:22 +02:00
Martti Piirainen
88f42f44c1 [unit] SMS decoding tests for Unicode 2014-03-14 09:05:22 +02:00
Martti Piirainen
2aed3c3f66 [unit] Fix EF_PNN unit test
Correct the encoding of the existing test case, and add a second test (the latter is based on Canonical rilmodem code).
2014-03-14 09:05:22 +02:00
Martti Piirainen
9c9028b164 [rpm] Run unit tests before creating .rpm 2014-03-14 09:05:22 +02:00
42 changed files with 1458 additions and 228 deletions

View File

@@ -514,7 +514,7 @@ if PROVISION
builtin_sources += plugins/mbpi.h plugins/mbpi.c
builtin_modules += provision
builtin_sources += plugins/provision.c
builtin_sources += plugins/provision.h plugins/provision.c
builtin_modules += cdma_provision
builtin_sources += plugins/cdma-provision.c
@@ -587,7 +587,7 @@ src_ofonod_SOURCES = $(builtin_sources) src/ofono.ver \
src/cdma-provision.c src/handsfree.c \
src/handsfree-audio.c src/bluetooth.h \
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) \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
@@ -720,13 +720,16 @@ test_scripts = test/backtrace \
test/set-context-property \
test/test-gnss \
test/swap-calls \
test/transfer-call \
test/release-and-answer \
test/release-and-swap \
test/hold-and-answer \
test/hangup-multiparty \
test/hangup-call \
test/display-icon \
test/set-msisdn
test/set-msisdn \
test/test-voicecallagent \
test/get-network-time
if TEST
testdir = $(pkglibdir)/test
@@ -747,7 +750,8 @@ unit_tests = unit/test-common unit/test-util unit/test-idmap \
unit/test-grilrequest \
unit/test-grilreply \
unit/test-grilunsol \
unit/test-sms unit/test-cdmasms
unit/test-sms unit/test-cdmasms \
unit/test-provision
noinst_PROGRAMS = $(unit_tests) \
unit/test-sms-root unit/test-mux unit/test-caif
@@ -814,6 +818,13 @@ unit_test_grilunsol_SOURCES = unit/test-grilunsol.c $(gril_sources) \
unit_test_grilunsol_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_grilunsol_OBJECTS)
unit_test_provision_SOURCES = unit/test-provision.c \
plugins/provision.h plugins/provision.c \
plugins/mbpi.c src/gprs-provision.c \
src/log.c
unit_test_provision_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_provision_OBJECTS)
TESTS = $(unit_tests)
if TOOLS

View File

@@ -198,6 +198,25 @@ Methods dict GetProperties()
[service].Error.InvalidFormat
[service].Error.Failed
void RegisterVoicecallAgent(object path)
Registers an agent which will be called whenever a
specific voice call related event requiring a client
action occurs. Currently, the only such action is
playing a ringback tone locally.
Possible Errors: [service].Error.InProgress
[service].Error.InvalidArguments
[service].Error.InvalidFormat
[service].Error.Failed
void UnregisterVoicecallAgent(object path)
Unregisters an agent.
Possible Errors: [service].Error.InvalidArguments
[service].Error.Failed
Signals CallAdded(object path, dict properties)
Signal that is sent when a new call is added. It
@@ -257,3 +276,26 @@ Properties array{string} EmergencyNumbers [readonly]
of numbers provided by the specification and any
extra numbers provisioned by the carrier on the
SIM.
VoiceCallAgent Hierarchy
========================
Service unique name
Interface org.ofono.VoiceCallAgent
Object path freely definable
Methods void RingbackTone(boolean playTone)
Requests the client to generate an alerting tone locally
(3GPP 24.008; 5.2.1.5). This can happen when an outgoing
voice call is made and network is not providing the
alerting tone. Value 0 stands for "stop playing ringback
tone" and 1 for "start playing ringback tone".
void Release() [noreply]
Agent is being released, possibly because of oFono
terminating, voicecall interface is being torn down or
modem is switched off. No UnregisterVoicecallAgent
call is needed.

View File

@@ -273,7 +273,7 @@ static int ril_call_barring_probe(struct ofono_call_barring *cb,
bd->ril = g_ril_clone(ril);
ofono_call_barring_set_data(cb, bd);
g_timeout_add_seconds(2, ril_delayed_register, cb);
bd->timer_id = g_timeout_add_seconds(2, ril_delayed_register, cb);
return 0;
}

View File

@@ -235,9 +235,8 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
list[i].phone_number.number[
OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
list[i].time = parcel_r_int32(&rilp);
}
list[i].time = parcel_r_int32(&rilp);
}
CALLBACK_WITH_SUCCESS(cb, nmbr_of_resps, list, cbd->data);

View File

@@ -98,6 +98,7 @@ static void query_revision_cb(struct ril_msg *message, gpointer user_data)
revision = parcel_r_string(&rilp);
cb(&error, revision, cbd->data);
g_free(revision);
}
static void ril_query_revision(struct ofono_devinfo *info,
@@ -137,10 +138,10 @@ static void query_serial_cb(struct ril_msg *message, gpointer user_data)
}
ril_util_init_parcel(message, &rilp);
imei = parcel_r_string(&rilp);
cb(&error, imei, cbd->data);
g_free(imei);
}
static void ril_query_serial(struct ofono_devinfo *info,

View File

@@ -45,6 +45,12 @@
#include "rilmodem.h"
enum data_call_state {
DATA_CALL_INACTIVE,
DATA_CALL_LINK_DOWN,
DATA_CALL_ACTIVE,
};
enum state {
STATE_IDLE,
STATE_ENABLING,
@@ -62,22 +68,16 @@ struct gprs_context_data {
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
unsigned int id,
ofono_gprs_context_cb_t cb, void *data);
ofono_gprs_context_cb_t cb,
void *data);
static void set_context_disconnected(struct gprs_context_data *gcd)
{
DBG("");
gcd->active_ctx_cid = -1;
gcd->active_rild_cid = -1;
gcd->state = STATE_IDLE;
}
static void 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,
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 data_call *call = NULL;
struct unsol_data_call_list *unsol;
gboolean active_cid_found = FALSE;
gboolean disconnect = FALSE;
GSList *iterator = NULL;
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) {
call = (struct data_call *) iterator->data;
if (call->cid == gcd->active_rild_cid) {
active_cid_found = TRUE;
if (call->status != 0)
ofono_info("data call status:%d", call->status);
if (call->active == 0) {
disconnect = TRUE;
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
if (call->active == DATA_CALL_INACTIVE) {
disconnect = TRUE;
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;
}
}
if (disconnect || active_cid_found == FALSE) {
if (disconnect) {
ofono_error("Clearing active context");
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;
if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
if (gcd->active_rild_cid != -1) {
ofono_error("no active context. disconnect");
disconnect_context(gc);
}
ofono_error("no active context. disconnect");
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.error = reply->status;
set_context_disconnected(gcd);
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
*
* 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.
*/
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_dns_servers(gc,
(const char **) reply->dns_addresses);
(const char **) reply->dns_addresses);
error:
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,
const struct ofono_gprs_primary_context *ctx,
ofono_gprs_context_cb_t cb, void *data)
const struct ofono_gprs_primary_context *ctx,
ofono_gprs_context_cb_t cb, void *data)
{
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
struct cb_data *cbd = cb_data_new(cb, data);
@@ -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;
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,
unsigned int id,
ofono_gprs_context_cb_t cb, void *data)
ofono_gprs_context_cb_t cb,
void *data)
{
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
struct cb_data *cbd = NULL;
@@ -375,6 +408,7 @@ error:
if (ret <= 0) {
ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");
g_free(cbd);
if (cb)
CALLBACK_WITH_FAILURE(cb, data);
}
@@ -415,14 +449,13 @@ static void ril_gprs_context_remove(struct ofono_gprs_context *gc)
DBG("");
if (gcd->state != STATE_IDLE) {
if (gcd->state != STATE_IDLE)
ril_gprs_context_detach_shutdown(gc, 0);
}
ofono_gprs_context_set_data(gc, NULL);
if (gcd->regid != -1)
g_ril_unregister(gcd->ril,gcd->regid);
g_ril_unregister(gcd->ril, gcd->regid);
g_ril_unref(gcd->ril);
g_free(gcd);
@@ -432,9 +465,9 @@ static struct ofono_gprs_context_driver driver = {
.name = RILMODEM,
.probe = ril_gprs_context_probe,
.remove = ril_gprs_context_remove,
.activate_primary = ril_gprs_context_activate_primary,
.deactivate_primary = ril_gprs_context_deactivate_primary,
.detach_shutdown = ril_gprs_context_detach_shutdown,
.activate_primary = ril_gprs_context_activate_primary,
.deactivate_primary = ril_gprs_context_deactivate_primary,
.detach_shutdown = ril_gprs_context_detach_shutdown,
};
void ril_gprs_context_init(void)

View File

@@ -45,6 +45,8 @@
#include "rilmodem.h"
#include <ofono/netreg.h>
#include <ofono/sim.h>
#include "storage.h"
/*
* This module is the ofono_gprs_driver implementation for rilmodem.
@@ -63,16 +65,23 @@
* +CREG ( see 27.003 7.2 ).
*/
#define FAKE_STATE_TIMER 5
struct gprs_data {
GRil *ril;
gboolean ofono_attached;
int max_cids;
int rild_status;
int true_status;
gboolean notified;
guint registerid;
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,
ofono_gprs_status_cb_t cb,
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;
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
* 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;
struct ofono_gprs *gprs = cbd->user;
struct gprs_data *gd = ofono_gprs_get_data(gprs);
DBG("");
gd->timer_id = 0;
@@ -129,11 +142,12 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
* are met.
*/
gd->notified = (gd->ofono_attached == attached) ? TRUE : FALSE;
gd->ofono_attached = attached;
cbd->user = gprs;
ril_gprs_registration_status(gprs, NULL, NULL);
/*
* However we cannot respond immediately, since core sets the
* value of driver_attached after calling set_attached and that
@@ -144,6 +158,42 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
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)
{
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;
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) {
decode_ril_error(&error, "OK");
@@ -174,12 +225,20 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
goto error;
}
if (gd->rild_status == -1) {
ofono_gprs_register(gprs);
if ((gd->fake_timer_id > 0) &&
((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");
gd->registerid = g_ril_register(gd->ril,
id, ril_gprs_state_change, gprs);
if (status > 10)
status = status - 10;
if (!registered) {
ofono_gprs_register(gprs);
registered = TRUE;
}
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)
status = check_if_really_roaming(status);
if (gd->ofono_attached && !gd->notified) {
if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
DBG("connection becomes available");
gd->ofono_attached = TRUE;
DBG(" attached:%d, status:%d", gd->ofono_attached, status);
if (!gd->ofono_attached) {
if (status == NETWORK_REGISTRATION_STATUS_ROAMING) {
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);
gd->notified = TRUE;
gd->rild_status = status;
}
if (cb)
gd->notified = TRUE;
gd->rild_status = status;
goto error;
}
if (gd->ofono_attached &&
status != NETWORK_REGISTRATION_STATUS_SEARCHING) {
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;
if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
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;
error:
if (cb)
cb(&error, status, cbd->data);
}
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;
guint ret;
DBG("");
if (gd == NULL || cbd == NULL)
return;
cbd->user = gprs;
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);
if (ret <= 0) {
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE failed.");
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE fail.");
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->max_cids = 0;
gd->rild_status = -1;
gd->true_status = -1;
gd->notified = FALSE;
gd->registerid = -1;
gd->timer_id = 0;
registered = FALSE;
ofono_gprs_set_data(gprs, gd);
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)
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_free(gd);
}

View File

@@ -573,6 +573,17 @@ error:
ofono_error("Unable to notify ofono about nitz");
}
gboolean check_if_ok_to_attach()
{
int status = NETWORK_REGISTRATION_STATUS_SEARCHING;
status = ofono_netreg_get_status(current_netreg);
if (status == NETWORK_REGISTRATION_STATUS_SEARCHING
|| status == NETWORK_REGISTRATION_STATUS_ROAMING
|| status == NETWORK_REGISTRATION_STATUS_REGISTERED)
return TRUE;
return FALSE;
}
gint check_if_really_roaming(gint status)
{
const char *net_mcc = ofono_netreg_get_mcc(current_netreg);
@@ -658,6 +669,7 @@ static void ril_netreg_remove(struct ofono_netreg *netreg)
g_source_remove(nd->nitz_timeout);
ofono_netreg_set_data(netreg, NULL);
current_netreg = NULL;
if (nd->timer_id > 0)
g_source_remove(nd->timer_id);

View File

@@ -38,14 +38,18 @@
struct oem_raw_data {
GRil *ril;
unsigned int vendor;
guint timer_id;
};
static gboolean ril_oemraw_delayed_register(gpointer user_data)
{
struct ofono_oem_raw *raw = user_data;
struct oem_raw_data *od = ofono_oem_raw_get_data(raw);
DBG("");
od->timer_id = 0;
ofono_oem_raw_dbus_register(raw);
return FALSE; /* This makes the timeout a single-shot */
}
@@ -64,7 +68,8 @@ static int ril_oemraw_probe(struct ofono_oem_raw *raw, unsigned int vendor,
od->vendor = vendor;
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;
}
@@ -79,6 +84,9 @@ static void ril_oemraw_remove(struct ofono_oem_raw *raw)
ofono_oem_raw_set_data(raw, NULL);
if (od->timer_id)
g_source_remove(od->timer_id);
g_ril_unref(od->ril);
g_free(od);
}

View File

@@ -162,11 +162,18 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
char *number, struct pb_file_info *next_file,
struct pb_data *pbd)
{
const uint8_t name_length = len - 14;
const uint8_t number_start = name_length;
uint8_t name_length;
uint8_t number_start;
uint8_t number_length = 0;
uint8_t extension_record = UNUSED;
uint8_t i, prefix;
if (len < 14)
return;
name_length = len - 14;
number_start = name_length;
name = sim_string_to_utf8(msg, name_length);
/* Length contains also TON&NPI */
number_length = msg[number_start];
@@ -256,15 +263,19 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
}
}
void handle_sne(size_t len,
const unsigned char *msg,
char *sne)
void handle_sne(size_t len, const unsigned char *msg, char *sne)
{
const uint8_t sne_length = len - 2;
uint8_t phonebook_entry_nbr = msg[len - 1];
uint8_t sne_length;
uint8_t phonebook_entry_nbr;
DBG("SNE");
if (len < 2)
return;
sne_length = len - 2;
phonebook_entry_nbr = msg[len - 1];
sne = sim_string_to_utf8(msg, sne_length);
if (sne) {
@@ -299,20 +310,26 @@ void handle_sne(size_t len,
}
}
void handle_anr(size_t len,
const unsigned char *msg,
char *anr,
struct pb_file_info *next_file,
struct pb_data *pbd)
void handle_anr(size_t len,const unsigned char *msg,char *anr,
struct pb_file_info *next_file, struct pb_data *pbd)
{
uint8_t number_length = 0;
uint8_t extension_record = UNUSED;
uint8_t aas_record = UNUSED;
uint8_t i, prefix;
uint8_t phonebook_entry_nbr = msg[len - 1];
uint8_t phonebook_entry_nbr;
GSList *list_entry;
DBG("ANR");
if (!msg)
return;
if (len < 1)
return;
phonebook_entry_nbr = msg[len - 1];
if (msg[0] == UNUSED)
return;
@@ -398,11 +415,18 @@ void handle_anr(size_t len,
}
}
void handle_email(size_t len,
const unsigned char *msg,
char *email)
void handle_email(size_t len, const unsigned char *msg, char *email)
{
uint8_t phonebook_entry_nbr = 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);
/* 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,
const unsigned char *msg,
char *ext_number,
struct pb_file_info *next_file)
void handle_ext1(struct pb_data *pbd, const unsigned char *msg,
char *ext_number, struct pb_file_info *next_file)
{
uint8_t number_length, i, next_extension_record;
if (!msg)
return;
number_length = msg[1];
@@ -818,7 +842,7 @@ static void pb_content_data_cb(const struct ofono_error *error,
file_info = pb_next->data;
if (((file_info->structure ==
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
(file_info->structure ==
OFONO_SIM_FILE_STRUCTURE_CYCLIC))
&& (file_info->record <

View File

@@ -75,7 +75,7 @@ static void ril_set_rat_mode(struct ofono_radio_settings *rs,
int pref = rd->ratmode;
int ret = 0;
ofono_info("setting rat mode");
ofono_info("setting rat mode:%d", mode);
parcel_init(&rilp);
@@ -209,7 +209,6 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
rsd->ratmode = PREF_NET_TYPE_GSM_WCDMA_AUTO;
GDir *config_dir;
const gchar *config_file;
char *path;
gsize length;
gchar **codes = NULL;
int i;
@@ -225,11 +224,14 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
config_dir = g_dir_open(config_path, 0, NULL);
while ((config_file = g_dir_read_name(config_dir)) != NULL) {
path = g_strconcat(RIL_CONFIG_DIR "/", config_file, 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);
if (!g_key_file_load_from_file(keyfile, path, 0, &err)) {
g_free(path);
if (!ok) {
g_error_free(err);
needsconfig = TRUE;
DBG("Rilconfig file skipped");
continue;
}
@@ -258,6 +260,7 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
}
g_key_file_free(keyfile);
g_dir_close(config_dir);
/* Then we need to check if it already set */

View File

@@ -123,6 +123,8 @@ struct ofono_sim *get_sim();
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);
struct cb_data {
@@ -147,7 +149,7 @@ static inline struct cb_data *cb_data_new2(void *user, void *cb,
{
struct cb_data *ret;
ret = g_try_new0(struct cb_data, 1);
ret = g_new0(struct cb_data, 1);
if (ret) {
ret->cb = cb;

View File

@@ -4,6 +4,7 @@
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013 Canonical, Ltd. All rights reserved.
* Copyright (C) 2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -102,6 +103,7 @@ struct sim_data {
enum ofono_sim_password_type passwd_state;
guint card_state;
guint idle_id;
gboolean removed;
};
static void ril_pin_change_state_cb(struct ril_msg *message,
@@ -179,6 +181,15 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
DBG("");
/* In case sim card has been removed prior to this callback has been
* called we must not call the core call back method as otherwise the
* core will crash.
*/
if (sd->removed == TRUE) {
ofono_error("RIL_CARDSTATE_ABSENT");
return;
}
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
@@ -658,6 +669,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
if (sd->card_state != RIL_CARDSTATE_PRESENT) {
ofono_sim_inserted_notify(sim, TRUE);
sd->card_state = RIL_CARDSTATE_PRESENT;
sd->removed = FALSE;
}
}
@@ -695,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);
ofono_info("RIL_REQUEST_RADIO_POWER ON");
g_ril_send(sd->ril,
RIL_REQUEST_RADIO_POWER,
rilp.data,
@@ -714,7 +727,10 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
if (status.card_state == RIL_CARDSTATE_ABSENT) {
DBG("sd->card_state:%u,status.card_state:%u,",
sd->card_state, status.card_state);
ofono_info("RIL_CARDSTATE_ABSENT");
ofono_sim_inserted_notify(sim, FALSE);
if (sd->card_state == RIL_CARDSTATE_PRESENT)
sd->removed = TRUE;
sd->card_state = RIL_CARDSTATE_ABSENT;
if (current_passwd)
@@ -792,10 +808,8 @@ static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
retries[passwd_type] = retry_count;
sd->retries[passwd_type] = retries[passwd_type];
/*
* 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) {
CALLBACK_WITH_SUCCESS(cb, cbd->data);
g_ril_print_response_no_args(sd->ril, message);
@@ -844,11 +858,53 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
}
}
static int ril_perso_change_state(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
int request = 0;
int ret = 0;
sd->passwd_type = passwd_type;
cbd->user = sd;
parcel_init(&rilp);
switch (passwd_type) {
case OFONO_SIM_PASSWORD_PHNET_PIN:
if (enable) {
DBG("Not supported, enable=%d", enable);
goto end;
}
request = RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION;
parcel_w_int32(&rilp, RIL_PERSOSUBSTATE_SIM_NETWORK);
parcel_w_string(&rilp, (char *) passwd);
break;
default:
DBG("Not supported, type=%d", passwd_type);
goto end;
}
ret = g_ril_send(sd->ril, request,
rilp.data, rilp.size, ril_pin_change_state_cb,
cbd, g_free);
g_ril_print_request(sd->ril, ret, request);
end:
parcel_free(&rilp);
return ret;
}
static void ril_pin_change_state(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data)
{
DBG("passwd_type=%d", passwd_type);
struct sim_data *sd = ofono_sim_get_data(sim);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
@@ -886,9 +942,9 @@ static void ril_pin_change_state(struct ofono_sim *sim,
parcel_w_string(&rilp, "P2");
break;
case OFONO_SIM_PASSWORD_PHNET_PIN:
g_ril_append_print_buf(sd->ril, "(PN,");
parcel_w_string(&rilp, "PN");
break;
ret = ril_perso_change_state(sim, passwd_type, enable, passwd,
cb, data);
goto end;
case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
g_ril_append_print_buf(sd->ril, "(PU,");
parcel_w_string(&rilp, "PU");
@@ -902,8 +958,7 @@ static void ril_pin_change_state(struct ofono_sim *sim,
parcel_w_string(&rilp, "PC");
break;
default:
CALLBACK_WITH_FAILURE(cb, data);
return;
goto end;
}
if (enable)
@@ -930,6 +985,7 @@ static void ril_pin_change_state(struct ofono_sim *sim,
g_ril_print_request(sd->ril, ret, request);
end:
parcel_free(&rilp);
if (ret <= 0) {
@@ -1059,6 +1115,7 @@ static int ril_sim_probe(struct ofono_sim *sim, unsigned int vendor,
sd->passwd_type = OFONO_SIM_PASSWORD_NONE;
sd->sim_registered = FALSE;
sd->card_state = RIL_CARDSTATE_ABSENT;
sd->removed = FALSE;
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
sd->retries[i] = -1;
@@ -1092,6 +1149,8 @@ static void ril_sim_remove(struct ofono_sim *sim)
if (sd->idle_id > 0)
g_source_remove(sd->idle_id);
g_free(sd->aid_str);
g_free(sd->app_str);
g_ril_unref(sd->ril);
g_free(sd);
}
@@ -1112,17 +1171,6 @@ static struct ofono_sim_driver driver = {
.change_passwd = ril_change_passwd,
.query_pin_retries = ril_query_pin_retries,
/*
* TODO: Implmenting PIN/PUK support requires defining
* the following driver methods.
*
* In the meanwhile, as long as the SIM card is present,
* and unlocked, the core SIM code will check for the
* presence of query_passwd_state, and if null, then the
* function sim_initialize_after_pin() is called.
*
* .query_pin_retries = ril_pin_retries_query,
* .query_locked = ril_pin_query_enabled,
*
* TODO: Implementing SIM write file IO support requires
* the following functions to be defined.
*

View File

@@ -38,10 +38,18 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/sms.h>
#include <ofono/types.h>
#include <ofono/sim.h>
#include "smsutil.h"
#include "util.h"
#include "rilmodem.h"
#include "simutil.h"
#define SIM_EFSMS_FILEID 0x6F3C
#define EFSMS_LENGTH 176
unsigned char path[4] = {0x3F, 0x00, 0x7F, 0x10};
struct sms_data {
GRil *ril;
@@ -345,6 +353,99 @@ error:
ofono_error("Unable to parse NEW_SMS notification");
}
static void ril_new_sms_on_sim_cb(struct ril_msg *message, gpointer user_data)
{
DBG("");
if (message->error == RIL_E_SUCCESS)
ofono_info("sms deleted from sim");
else
ofono_error("deleting sms from sim failed");
}
static void ril_request_delete_sms_om_sim(struct ofono_sms *sms,int record)
{
struct sms_data *data = ofono_sms_get_data(sms);
struct parcel rilp;
int request = RIL_REQUEST_DELETE_SMS_ON_SIM;
int ret;
DBG("Deleting record: %d", record);
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* Number of int32 values in array */
parcel_w_int32(&rilp, record);
ret = g_ril_send(data->ril, request, rilp.data,
rilp.size, ril_new_sms_on_sim_cb, NULL, NULL);
parcel_free(&rilp);
if (ret <= 0)
ofono_error("cannot delete sms from sim");
}
static void ril_read_sms_on_sim_cb(const struct ofono_error *error,
const unsigned char *sdata,
int length, void *data)
{
struct cb_data *cbd = data;
struct ofono_sms *sms = cbd->user;
int sms_len,i,record;
unsigned int smsc_len;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_error("cannot read sms from sim");
goto exit;
}
sms_len = strlen(sdata);
/*
* It seems when reading EFsms RIL returns the whole record including
* the first status byte therefore we ignore that as we are only
* interested of the following pdu
*/
/* The first octect in the pdu contains the SMSC address length
* which is the X following octects it reads. We add 1 octet to
* the read length to take into account this read octet in order
* to calculate the proper tpdu length.
*/
smsc_len = sdata[1] + 1;
ofono_sms_deliver_notify(sms, sdata + 1, length - 1,
length - smsc_len - 1);
record = (int)cbd->data;
ril_request_delete_sms_om_sim(sms,record);
exit:
g_free(cbd);
}
static void ril_new_sms_on_sim(struct ril_msg *message, gpointer user_data)
{
struct ofono_sms *sms = user_data;
struct parcel rilp;
int record;
ofono_info("new sms on sim");
ril_util_init_parcel(message, &rilp);
/* data length of the response */
record = parcel_r_int32(&rilp);
if (record > 0) {
record = parcel_r_int32(&rilp);
struct cb_data *cbd = cb_data_new2(sms, NULL, record);
DBG(":%d", record);
get_sim_driver()->read_file_linear(get_sim(), SIM_EFSMS_FILEID,
record, EFSMS_LENGTH, path,
sizeof(path),
ril_read_sms_on_sim_cb, cbd);
}
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_sms *sms = user_data;
@@ -360,6 +461,8 @@ static gboolean ril_delayed_register(gpointer user_data)
ril_sms_notify, sms);
g_ril_register(data->ril, RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
ril_sms_notify, sms);
g_ril_register(data->ril, RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM,
ril_new_sms_on_sim, sms);
/* This makes the timeout a single-shot */
return FALSE;

View File

@@ -275,6 +275,7 @@ void ril_stk_set_lang()
setenv("LANG", pch + strlen(CFG_LANG), 1);
DBG("LANG %s", getenv("LANG"));
}
g_free(contents);
}
}

View File

@@ -75,12 +75,30 @@ static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
if (charset == SMS_CHARSET_7BIT) {
unsigned char unpacked_buf[182] = "";
long written;
int length;
unpack_7bit_own_buf(pdu, len, 0, TRUE,
sizeof(unpacked_buf), &written, 0,
unpacked_buf);
if (written >= 1) {
/*
* When USSD was packed, additional CR
might have been added (according to
23.038 6.1.2.3.1). So if the last
character is CR, it should be removed
here. And in addition written doesn't
contain correct length...
Over 2 characters long USSD string must
end with # (checked in
valid_ussd_string() ), so it should be
safe to remove extra CR.
*/
length = strlen((char *)unpacked_buf);
if (length > 2 &&
unpacked_buf[length-1] == '\r')
unpacked_buf[length-1] = 0;
struct parcel rilp;
parcel_init(&rilp);
parcel_w_string(&rilp, (char *)unpacked_buf);

View File

@@ -4,7 +4,7 @@
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* 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
* 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 clear_dtmf_queue(struct voicecall_data *vd);
/*
* structs ofono_voicecall and voicecall are fully defined
* in src/voicecall.c; we need (read) access to the
* call objects, so partially redefine them here.
*/
struct ofono_voicecall {
GSList *call_list;
/* ... */
};
struct voicecall {
struct ofono_call *call;
/* ... */
};
static void lastcause_cb(struct ril_msg *message, gpointer user_data)
{
struct lastcause_req *reqdata = user_data;
@@ -99,11 +114,38 @@ static void lastcause_cb(struct ril_msg *message, gpointer user_data)
if (parcel_r_int32(&rilp) > 0)
last_cause = parcel_r_int32(&rilp);
/*
* Not all call control cause values specified in 3GPP TS 24.008
* "Mobile radio interface Layer 3 specification; Core network protocols",
* Annex H, are properly reflected in the RIL API. For example, cause
* #21 "call rejected" is mapped to CALL_FAIL_ERROR_UNSPECIFIED, and
* thus indistinguishable from a network failure.
* We signal disconnect reason "remote" for cause values
* - #16 "normal call clearing"
* - #17 "user busy"
* - UNSPECIFIED for MO calls that are not yet connected
* , and disconnect reason "network" otherwise.
*/
ofono_info("Call %d ended with RIL cause %d", id, last_cause);
if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) {
reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
}
if (last_cause == CALL_FAIL_ERROR_UNSPECIFIED) {
GSList *l;
struct voicecall *v;
for (l = vc->call_list; l; l = l->next) {
v = l->data;
if (v->call->id == id) {
if (v->call->status == CALL_STATUS_DIALING
|| v->call->status == CALL_STATUS_ALERTING) {
reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
}
break;
}
}
}
ofono_voicecall_disconnected(vc, id, reason, NULL);
}
@@ -236,6 +278,8 @@ static void generic_cb(struct ril_msg *message, gpointer user_data)
int request = RIL_REQUEST_GET_CURRENT_CALLS;
int ret;
ofono_info("request:%d",message->req);
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
@@ -634,6 +678,13 @@ static void ril_create_multiparty(struct ofono_voicecall *vc,
cb(&error, data);
}
static void ril_transfer(struct ofono_voicecall *vc,
ofono_voicecall_cb_t cb, void *data)
{
ril_template(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, vc, generic_cb, 0,
NULL, 0, cb, data);
}
static void private_chat_cb(struct ril_msg *message, gpointer user_data)
{
struct ofono_error error;
@@ -727,6 +778,23 @@ static gboolean enable_supp_svc(gpointer user_data)
return FALSE;
}
static void ril_ringback_tone_notify(struct ril_msg *message,
gpointer user_data)
{
struct parcel rilp;
struct ofono_voicecall *vc = user_data;
gboolean playTone = FALSE;
ril_util_init_parcel(message, &rilp);
if (message->req == RIL_UNSOL_RINGBACK_TONE) {
if (parcel_r_int32(&rilp) > 0)
playTone = parcel_r_int32(&rilp);
DBG("play ringback tone: %d", playTone);
ofono_voicecall_ringback_tone_notify(vc, playTone);
}
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_voicecall *vc = user_data;
@@ -747,6 +815,10 @@ static gboolean ril_delayed_register(gpointer user_data)
g_ril_register(vd->ril, RIL_UNSOL_SUPP_SVC_NOTIFICATION,
ril_ss_notify, vc);
/* Register for ringback tone notifications */
g_ril_register(vd->ril, RIL_UNSOL_RINGBACK_TONE,
ril_ringback_tone_notify, vc);
/* request supplementary service notifications*/
enable_supp_svc(vc);
@@ -803,6 +875,7 @@ static void ril_voicecall_remove(struct ofono_voicecall *vc)
if (vd->timer_id > 0)
g_source_remove(vd->timer_id);
g_free(vd->tone_queue);
g_ril_unref(vd->ril);
g_free(vd);
}
@@ -817,12 +890,13 @@ static struct ofono_voicecall_driver driver = {
.release_specific = ril_hangup_specific,
.send_tones = ril_send_dtmf,
.create_multiparty = ril_create_multiparty,
.transfer = ril_transfer,
.private_chat = ril_private_chat,
.swap_without_accept = ril_swap_without_accept,
.hold_all_active = ril_hold_all_active,
.release_all_held = ril_release_all_held,
.set_udub = ril_set_udub,
.release_all_active = ril_release_all_active,
.release_all_active = ril_release_all_active,
};
void ril_voicecall_init(void)

View File

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

View File

@@ -31,6 +31,8 @@ extern "C" {
struct ofono_gprs_provision_data {
enum ofono_gprs_context_type type;
enum ofono_gprs_proto proto;
char *provider_name;
ofono_bool_t provider_primary;
char *name;
char *apn;
char *username;

View File

@@ -3,6 +3,7 @@
* 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
@@ -171,6 +172,9 @@ void ofono_voicecall_ssn_mt_notify(struct ofono_voicecall *vc, unsigned int id,
int code, int index,
const struct ofono_phone_number *ph);
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
const ofono_bool_t playTone);
#ifdef __cplusplus
}
#endif

View File

@@ -53,6 +53,8 @@ enum MBPI_ERROR {
struct gsm_data {
const char *match_mcc;
const char *match_mnc;
char *provider_name;
gboolean provider_primary;
GSList *apns;
gboolean match_found;
gboolean allow_duplicates;
@@ -84,6 +86,7 @@ static GQuark mbpi_error_quark(void)
void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
{
g_free(ap->provider_name);
g_free(ap->name);
g_free(ap->apn);
g_free(ap->username);
@@ -117,6 +120,7 @@ static void text_handler(GMarkupParseContext *context,
{
char **string = userdata;
g_free(*string);
*string = g_strndup(text, text_len);
}
@@ -288,6 +292,9 @@ static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
}
ap = g_new0(struct ofono_gprs_provision_data, 1);
ap->provider_name = g_strdup(gsm->provider_name);
ap->provider_primary = gsm->provider_primary;
ap->apn = g_strdup(apn);
ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
ap->proto = OFONO_GPRS_PROTO_IP;
@@ -454,27 +461,68 @@ static const GMarkupParser provider_parser = {
NULL,
};
static void toplevel_gsm_start(GMarkupParseContext *context,
static void gsm_provider_start(GMarkupParseContext *context,
const gchar *element_name,
const gchar **atribute_names,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer userdata, GError **error)
{
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;
g_markup_parse_context_push(context, &gsm_parser, gsm);
} else if (g_str_equal(element_name, "cdma"))
g_markup_parse_context_push(context, &skip_parser, NULL);
}
static void gsm_provider_end(GMarkupParseContext *context,
const gchar *element_name,
gpointer userdata, GError **error)
{
if (g_str_equal(element_name, "name") ||
g_str_equal(element_name, "gsm") ||
g_str_equal(element_name, "cdma"))
g_markup_parse_context_pop(context);
}
static const GMarkupParser gsm_provider_parser = {
gsm_provider_start,
gsm_provider_end,
NULL,
NULL,
NULL,
};
static void toplevel_gsm_start(GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer userdata, GError **error)
{
struct gsm_data *gsm = userdata;
if (g_str_equal(element_name, "provider")) {
g_markup_collect_attributes(element_name, attribute_names,
attribute_values, error,
G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL,
"primary", &gsm->provider_primary,
G_MARKUP_COLLECT_INVALID);
g_markup_parse_context_push(context, &gsm_provider_parser, gsm);
}
}
static void toplevel_gsm_end(GMarkupParseContext *context,
const gchar *element_name,
gpointer userdata, GError **error)
{
if (g_str_equal(element_name, "gsm") ||
g_str_equal(element_name, "cdma"))
if (g_str_equal(element_name, "provider"))
g_markup_parse_context_pop(context);
}
@@ -488,7 +536,7 @@ static const GMarkupParser toplevel_gsm_parser = {
static void toplevel_cdma_start(GMarkupParseContext *context,
const gchar *element_name,
const gchar **atribute_names,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer userdata, GError **error)
{
@@ -591,6 +639,7 @@ GSList *mbpi_lookup_apn(const char *mcc, const char *mnc,
gsm.apns = NULL;
}
g_free(gsm.provider_name);
return gsm.apns;
}

View File

@@ -188,11 +188,11 @@ static int nettime_probe(struct ofono_nettime_context *context)
NULL, // GDBusPropertyTable *properties
NULL, // user data
NULL)) { // GDBusDestroyFunction destroy
ofono_error("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);
return 1;
} else {
ofono_info("Network time: Registered inteface %s, path %s",
ofono_info("Network time: Registered interface %s, path %s",
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(
context->modem, OFONO_ATOM_TYPE_NETREG));
if (!(ofono_netreg_get_mcc(netreg) && ofono_netreg_get_mnc(netreg))) {
DBG("Incomplete network time received, ignoring");
return;
}
ntd->path = ofono_modem_get_path(context->modem);
ntd->mcc = ofono_netreg_get_mcc(netreg);
ntd->mnc = ofono_netreg_get_mnc(netreg);

View File

@@ -24,6 +24,7 @@
#include <config.h>
#endif
#define _GNU_SOURCE
#include <errno.h>
#include <string.h>
@@ -36,57 +37,134 @@
#include <ofono/modem.h>
#include <ofono/gprs-provision.h>
#include "provision.h"
#include "mbpi.h"
/* Returns the list containing exactly one INTERNET and one MMS access point */
static GSList *provision_normalize_apn_list(GSList *apns)
static GSList *provision_normalize_apn_list(GSList *apns, const char* spn)
{
struct ofono_gprs_provision_data *internet = NULL;
struct ofono_gprs_provision_data *mms = NULL;
GSList *l = apns;
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 && !internet) {
internet = ap;
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS && !mms) {
mms = ap;
} else {
/* Remove duplicate and unnecessary access points */
DBG("Discarding APN: '%s' Name: '%s' Type: %s",
ap->apn, ap->name, mbpi_ap_type(ap->type));
mbpi_ap_free(ap);
apns = g_slist_remove_link(apns, l);
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;
}
if (!internet) {
internet = g_try_new0(struct ofono_gprs_provision_data, 1);
if (internet) {
internet->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
internet->name = g_strdup("Internet");
internet->apn = g_strdup("internet");
apns = g_slist_append(apns, internet);
/*
* 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 (!mms) {
mms = g_try_new0(struct ofono_gprs_provision_data, 1);
if (mms) {
mms->type = OFONO_GPRS_CONTEXT_TYPE_MMS;
mms->name = g_strdup("MMS");
mms->apn = g_strdup("mms");
apns = g_slist_append(apns, mms);
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");
}
}
return apns;
best_apns = g_slist_append(best_apns, best_internet);
best_apns = g_slist_append(best_apns, best_mms);
return best_apns;
}
static int provision_get_settings(const char *mcc, const char *mnc,
int provision_get_settings(const char *mcc, const char *mnc,
const char *spn,
struct ofono_gprs_provision_data **settings,
int *count)
@@ -97,7 +175,7 @@ static int provision_get_settings(const char *mcc, const char *mnc,
int ap_count;
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);
/*
* Passing FALSE to mbpi_lookup_apn() would return
@@ -109,13 +187,14 @@ static int provision_get_settings(const char *mcc, const char *mnc,
g_error_free(error);
}
apns = provision_normalize_apn_list(apns);
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);
DBG("Found %d APs", ap_count);
ofono_info("Provisioning %d APs", ap_count);
*settings = g_try_new0(struct ofono_gprs_provision_data, ap_count);
if (*settings == NULL) {
@@ -134,11 +213,11 @@ static int provision_get_settings(const char *mcc, const char *mnc,
for (l = apns, i = 0; l; l = l->next, i++) {
struct ofono_gprs_provision_data *ap = l->data;
DBG("Name: '%s'", ap->name);
DBG("APN: '%s'", ap->apn);
DBG("Type: %s", mbpi_ap_type(ap->type));
DBG("Username: '%s'", ap->username);
DBG("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,
sizeof(struct ofono_gprs_provision_data));

28
ofono/plugins/provision.h Normal file
View 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);

View File

@@ -282,10 +282,10 @@ static void pf_modem_watch(struct ofono_modem *modem,
return;
pm->modem = modem;
pm->sim_watch_id = __ofono_modem_add_atom_watch(modem,
pm->sms_watch_id = __ofono_modem_add_atom_watch(modem,
OFONO_ATOM_TYPE_SMS, pf_sms_watch, pm,
pf_sms_watch_done);
pm->sms_watch_id = __ofono_modem_add_atom_watch(modem,
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);

View File

@@ -113,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)
{
DBG("error=%d", message->error);
struct ofono_modem *modem = user_data;
struct ril_data *ril = ofono_modem_get_data(modem);
struct sim_status status;
struct sim_app *apps[MAX_UICC_APPS];
DBG("");
/*
* ril.h claims this should NEVER fail!
* However this isn't quite true. So,
@@ -189,6 +188,7 @@ static int send_get_sim_status(struct ofono_modem *modem)
static int ril_probe(struct ofono_modem *modem)
{
DBG("");
struct ril_data *ril = NULL;
ril = g_try_new0(struct ril_data, 1);
@@ -211,9 +211,9 @@ error:
static void ril_remove(struct ofono_modem *modem)
{
DBG("");
struct ril_data *ril = ofono_modem_get_data(modem);
ofono_modem_set_data(modem, NULL);
if (!ril)
@@ -229,7 +229,7 @@ static void ril_remove(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 ofono_sim *sim;
@@ -242,6 +242,7 @@ static void ril_pre_sim(struct ofono_modem *modem)
static void ril_post_sim(struct ofono_modem *modem)
{
DBG("");
struct ril_data *ril = ofono_modem_get_data(modem);
struct ofono_gprs *gprs;
struct ofono_gprs_context *gc;
@@ -277,7 +278,7 @@ static void ril_post_sim(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);
ofono_call_volume_create(modem, 0, "rilmodem", ril->modem);
@@ -290,7 +291,7 @@ static void ril_post_online(struct ofono_modem *modem)
static void ril_set_online_cb(struct ril_msg *message, gpointer user_data)
{
DBG("enter");
DBG("");
struct cb_data *cbd = user_data;
ofono_modem_online_cb_t cb = cbd->cb;
@@ -312,12 +313,13 @@ static void ril_set_online(struct ofono_modem *modem, ofono_bool_t online,
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* Number of params */
parcel_w_int32(&rilp, online); /* Radio ON = 1, Radio OFF = 0 */
DBG("1");
ofono_info("RIL_REQUEST_RADIO_POWER %d", online);
ret = g_ril_send(ril->modem, RIL_REQUEST_RADIO_POWER, rilp.data,
rilp.size, ril_set_online_cb, cbd, g_free);
parcel_free(&rilp);
DBG("2");
DBG("RIL_REQUEST_RADIO_POWER done");
if (ret <= 0) {
g_free(cbd);
CALLBACK_WITH_FAILURE(callback, data);
@@ -355,6 +357,7 @@ static int ril_screen_state(struct ofono_modem *modem, ofono_bool_t state)
static gboolean display_changed(DBusConnection *conn,
DBusMessage *message, void *user_data)
{
DBG("");
struct ofono_modem *modem = user_data;
DBusMessageIter iter;
const char *value;
@@ -377,6 +380,7 @@ static gboolean display_changed(DBusConnection *conn,
static void mce_connect(DBusConnection *conn, void *user_data)
{
DBG("");
signal_watch = g_dbus_add_signal_watch(conn,
MCE_SERVICE, NULL,
MCE_SIGNAL_IF,
@@ -387,12 +391,15 @@ static void mce_connect(DBusConnection *conn, void *user_data)
static void mce_disconnect(DBusConnection *conn, void *user_data)
{
DBG("");
g_dbus_remove_watch(conn, signal_watch);
signal_watch = 0;
}
static void ril_connected(struct ril_msg *message, gpointer user_data)
{
DBG("");
struct ofono_modem *modem = (struct ofono_modem *) user_data;
struct ril_data *ril = ofono_modem_get_data(modem);
@@ -412,6 +419,7 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
static gboolean ril_re_init(gpointer user_data)
{
DBG("");
if (reconnecting) {
ril_init();
return TRUE;
@@ -467,7 +475,7 @@ void ril_switchUser()
static int ril_enable(struct ofono_modem *modem)
{
DBG("enter");
DBG("%p", modem);
struct ril_data *ril = ofono_modem_get_data(modem);
ril->have_sim = FALSE;
@@ -510,17 +518,18 @@ static int ril_enable(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 parcel rilp;
int request = RIL_REQUEST_RADIO_POWER;
guint ret;
DBG("%p", modem);
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* size of array */
parcel_w_int32(&rilp, 0); /* POWER=OFF */
ofono_info("RIL_REQUEST_RADIO_POWER OFF");
/* fire and forget i.e. not waiting for the callback*/
ret = g_ril_send(ril->modem, request, rilp.data,
rilp.size, NULL, NULL, NULL);
@@ -564,7 +573,7 @@ static struct ofono_modem_driver ril_driver = {
*/
static int ril_init(void)
{
DBG("enter");
DBG("");
int retval = 0;
struct ofono_modem *modem;

View File

@@ -411,9 +411,12 @@ static void set_new_cond_list(struct ofono_call_forwarding *cf,
number = phone_number_to_string(
&lc->phone_number);
snprintf(attr, sizeof(attr), "%s%s",
bearer_class_to_string(lc->cls), cf_type_lut[i]);
ofono_dbus_signal_property_changed(conn, path,
OFONO_CALL_FORWARDING_INTERFACE,
cf_type_lut[i],
attr,
DBUS_TYPE_STRING, &number);
}
@@ -713,8 +716,12 @@ static DBusMessage *set_property_request(struct ofono_call_forwarding *cf,
if (ph->number[0] != '\0')
cf->driver->registration(cf, type, cls, ph, timeout,
set_property_callback, cf);
else
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);
}
return NULL;
}

View File

@@ -289,7 +289,8 @@ void __ofono_log_enable(struct ofono_debug_desc *start,
}
int __ofono_log_init(const char *program, const char *debug,
ofono_bool_t detach)
ofono_bool_t detach,
ofono_bool_t backtrace)
{
static char path[PATH_MAX];
int option = LOG_NDELAY | LOG_PID;
@@ -305,7 +306,8 @@ int __ofono_log_init(const char *program, const char *debug,
if (detach == FALSE)
option |= LOG_PERROR;
signal_setup(signal_handler);
if (backtrace == TRUE)
signal_setup(signal_handler);
openlog(basename(program), option, LOG_DAEMON);
@@ -314,13 +316,14 @@ int __ofono_log_init(const char *program, const char *debug,
return 0;
}
void __ofono_log_cleanup(void)
void __ofono_log_cleanup(ofono_bool_t backtrace)
{
syslog(LOG_INFO, "Exit");
closelog();
signal_setup(SIG_DFL);
if (backtrace == TRUE)
signal_setup(SIG_DFL);
g_strfreev(enabled);
}

View File

@@ -133,6 +133,7 @@ static gchar *option_plugin = NULL;
static gchar *option_noplugin = NULL;
static gboolean option_detach = TRUE;
static gboolean option_version = FALSE;
static gboolean option_backtrace = TRUE;
static gboolean parse_debug(const char *key, const char *value,
gpointer user_data, GError **error)
@@ -158,6 +159,9 @@ static GOptionEntry options[] = {
"Don't run as daemon in background" },
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
"Show version information and exit" },
{ "nobacktrace", 0, G_OPTION_FLAG_REVERSE,
G_OPTION_ARG_NONE, &option_backtrace,
"Don't print out backtrace information" },
{ NULL },
};
@@ -213,7 +217,8 @@ int main(int argc, char **argv)
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);
@@ -264,7 +269,7 @@ cleanup:
g_main_loop_unref(event_loop);
__ofono_log_cleanup();
__ofono_log_cleanup(option_backtrace);
return 0;
}

View File

@@ -15,6 +15,7 @@
<allow send_interface="org.ofono.SmartMessagingAgent"/>
<allow send_interface="org.ofono.PositioningRequestAgent"/>
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
<allow send_interface="org.ofono.VoiceCallAgent"/>
</policy>
<policy user="radio">
@@ -25,6 +26,7 @@
<allow send_interface="org.ofono.SmartMessagingAgent"/>
<allow send_interface="org.ofono.PositioningRequestAgent"/>
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
<allow send_interface="org.ofono.VoiceCallAgent"/>
</policy>
<policy at_console="true">

View File

@@ -38,8 +38,9 @@ void __ofono_modem_shutdown(void);
#include <ofono/log.h>
int __ofono_log_init(const char *program, const char *debug,
ofono_bool_t detach);
void __ofono_log_cleanup(void);
ofono_bool_t detach,
ofono_bool_t backtrace);
void __ofono_log_cleanup(ofono_bool_t backtrace);
void __ofono_log_enable(struct ofono_debug_desc *start,
struct ofono_debug_desc *stop);

View File

@@ -8,7 +8,7 @@ Type=dbus
BusName=org.ofono
User=root
EnvironmentFile=-/var/lib/environment/ofono/*.conf
ExecStart=@prefix@/sbin/ofonod -n $OFONO_ARGS
ExecStart=@prefix@/sbin/ofonod -n --nobacktrace $OFONO_ARGS
StandardError=null
Restart=always
RestartSec=3

View File

@@ -3561,7 +3561,7 @@ GSList *sms_text_prepare_with_alphabet(const char *to, const char *utf8,
if (gsm_encoded == NULL) {
gsize converted;
ucs2_encoded = g_convert(utf8, -1, "UCS-2BE//TRANSLIT", "UTF-8",
ucs2_encoded = g_convert(utf8, -1, "UTF-16BE//TRANSLIT", "UTF-8",
NULL, &converted, NULL);
written = converted;
}

View File

@@ -3,6 +3,7 @@
* 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
@@ -38,6 +39,7 @@
#include "simutil.h"
#include "smsutil.h"
#include "storage.h"
#include "voicecallagent.h"
#define MAX_VOICE_CALLS 16
@@ -75,6 +77,7 @@ struct ofono_voicecall {
ofono_voicecall_cb_t release_queue_done_cb;
struct ofono_emulator *pending_em;
unsigned int pending_id;
struct voicecall_agent *vc_agent;
};
struct voicecall {
@@ -555,6 +558,11 @@ static DBusMessage *voicecall_hangup(DBusConnection *conn,
struct ofono_voicecall *vc = v->vc;
struct ofono_call *call = v->call;
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)
return __ofono_error_busy(msg);
@@ -2140,6 +2148,72 @@ static DBusMessage *manager_get_calls(DBusConnection *conn,
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[] = {
{ GDBUS_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
@@ -2172,6 +2246,12 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetCalls",
NULL, GDBUS_ARGS({ "calls_with_properties", "a(oa{sv})" }),
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);
if (vc->vc_agent) {
voicecall_agent_free(vc->vc_agent);
vc->vc_agent = 0;
}
if (vc->sim_state_watch) {
ofono_sim_remove_state_watch(vc->sim, vc->sim_state_watch);
vc->sim_state_watch = 0;

131
ofono/src/voicecallagent.c Normal file
View 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;
}

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

48
ofono/test/test-voicecallagent Executable file
View 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
View 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)

View 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();
}

View File

@@ -345,12 +345,21 @@ const unsigned char valid_efopl[] = {
};
const unsigned char valid_efpnn[][28] = {
{ 0x43, 0x0a, 0x00, 0x54, 0x75, 0x78, 0x20, 0x43, 0x6f, 0x6d,
0x6d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, },
{ 0x43, 0x08, 0x00, 0xD4, 0x3A, 0x1E, 0x34, 0x7C, 0xB7, 0xDB,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, },
{ 0x43, 0x05, 0x00, 0x4C, 0x6F, 0x6E, 0x67, 0x45, 0x06, 0x00,
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)
{
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));
/* 1. a fictious operator */
sim_eons_add_pnn_record(eons_info, 1,
valid_efpnn[0], sizeof(valid_efpnn[0]));
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->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);
}

View File

@@ -1769,6 +1769,63 @@ static void test_wap_push(gconstpointer data)
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)
{
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,
test_wap_push);
g_test_add_func("/testsms/Test Decode Unicode", test_decode_unicode);
return g_test_run();
}

View File

@@ -64,13 +64,16 @@ This package provides default configs for ofono
autoreconf --force --install
%configure --disable-static \
--enable-dundee \
--enable-test \
--with-systemdunitdir="/%{_lib}/systemd/system"
make %{?jobs:-j%jobs}
%check
# run unit tests
make check
%install
rm -rf %{buildroot}
%make_install
@@ -97,11 +100,10 @@ systemctl daemon-reload ||:
%files
%defattr(-,root,root,-)
%doc COPYING ChangeLog AUTHORS README
%config(noreplace) %{_sysconfdir}/dbus-1/system.d/*.conf
%config %{_sysconfdir}/dbus-1/system.d/*.conf
%{_sbindir}/*
/%{_lib}/systemd/system/network.target.wants/ofono.service
/%{_lib}/systemd/system/ofono.service
/%{_lib}/systemd/system/dundee.service
%dir %{_sysconfdir}/ofono/
%dir %{_sysconfdir}/ofono/push_forwarder.d
# This file is part of phonesim and not needed with ofono.