Compare commits

...

65 Commits

Author SHA1 Message Date
Slava Monich
9bf4c9cda7 gprs: Check GPRS_FLAG_ATTACHED_UPDATE
... in pri_deactivate_callback

This prevents attached state from getting stuck at 0 like this:

1. Context deactivation is initiated over D-Bus, ctx->pending is set
2. Attached becomes FALSE, context is still marked as active
3. Attached becomes TRUE, gprs_attached_update sets GPRS_FLAG_ATTACHED_UPDATE
4. Deactivation completes, attached is 0, driver_attached is 1

Futher network status updates don't call gprs_attached_update because
driver_attached is still 1, so attached is staying 0 until we lose the
data registration again which may not happen for quite a long time.
2016-11-08 14:12:23 +03:00
Slava Monich
3b4ce1f47b Merge branch 'cached_spn' into 'master'
Don't update SPN while slot is being enabled or disabled

To avoid bothering clients with inconsistent states that make
little sense.

See merge request !82
2016-09-29 10:42:46 +00:00
Slava Monich
d8aefd40c4 [ril] Don't update SPN while slot is being enabled or disabled. Fixes JB#36420
It's better to hold it off until we arrive at a consistent state.
2016-09-28 00:18:15 +03:00
Slava Monich
e79055354c Merge branch 'master' into 'master'
Remove bluez build requirement

There doesn't seem to be any reason for requiring bluez at build time.
Besides since bluez (5) is renamed as bluez5 this won't be compatible
with it.

See merge request !81
2016-09-21 21:45:12 +00:00
Slava Monich
5e75f650c3 Merge branch 'ussd' into 'master'
Don't fail USSD cancel requests

See merge request !80
2016-09-21 21:44:25 +00:00
Jarko Poutiainen
ae782ca6f2 [packaging] remove bluez build requirement.Contributes to JB#36046 2016-09-21 16:10:59 +03:00
Slava Monich
b929a8e8c8 [ril] Don't fail USSD cancel requests from the core. Contributest to JB#36348
If we pass RIL_REQUEST_CANCEL_USSD error to the core, ofono will stay in
its current state and reject the subsequent USSD requests.
2016-09-21 13:41:47 +03:00
Slava Monich
530c3bc812 [ril] Improved parsing of RIL_UNSOL_ON_USSD packets
Particularly, prevent the crash if the USSD type string is missing.
2016-09-21 13:34:15 +03:00
martinjones
0e1a58781f Merge branch 'conf_proto' into 'master'
[ril] Fix creating multiparty and splitting multiparty. Contributes to JB#4743



See merge request !79
2016-08-11 09:41:40 +00:00
Martin Jones
77a26177e5 [ril] Fix creating multiparty and splitting multiparty. Contributes to JB#4743 2016-08-11 09:39:40 +00:00
Slava Monich
f6ea7e4c36 Merge branch 'cf_get_prop' into 'master'
Allow multiple pending org.ofono.CallForwarding.GetProperties

See merge request !77
2016-08-11 08:13:22 +00:00
Slava Monich
babea14604 Merge branch 'jb35840' into 'master'
See merge request !78
2016-07-27 13:24:16 +00:00
Slava Monich
e13ae6d5b3 [ril] Fixed default single-SIM config. Fixes JB#35840
It has to be Jolla1 compatible.
2016-07-27 16:00:54 +03:00
Slava Monich
40ce8f7185 Merge branch 'sim_write' into 'master'
SIM write support

If it's done right, quite a few things (those that have to do with
writing stuff to SIM card) should start working.

See merge request !76
2016-07-25 09:19:54 +00:00
Slava Monich
f68585a784 [ril] Implemented SIM write I/O support. Fixes MER#1199 2016-07-25 12:15:06 +03:00
Slava Monich
16105b8ace [ril] Cleaned up call forwarding code. JB#20921 2016-07-25 12:13:22 +03:00
Slava Monich
91245de799 [ofono] call-forwarding: allow multiple pending GetProperties
The very first call that that every org.ofono.CallForwarding
client makes is GetProperties. With multiple clients, only the
first one was waiting for the completion of the initial query,
all other calls were rejected with org.ofono.Error.InProgress.
In theory, the clients could retry the call later, but in
reality very few clients actually do that.
2016-07-20 22:57:49 +03:00
Slava Monich
c52471132a Merge branch 'pin_retries' into 'master'
Query number of retries left with empty pin

This works with some Qualcomm RILs. Those RILs that don't support
it will fail this request with no harm done. In case if it turns
out to be harmful with some RILs, it can be turned off with
emptyPinQuery=false in ril_subscription.conf

See merge request !75
2016-07-15 14:07:17 +00:00
Slava Monich
a8e7b86733 Merge branch 'band-mode' into 'master'
Query available band modes at startup

With some RIL implementations, RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE
causes some magic Android properties to appear. Otherwise it's
harmless and fairly useless.

See merge request !72
2016-07-15 14:07:00 +00:00
Slava Monich
8829682fad [ril] Query number of retries left with empty pin. MER#1089
This works with some Qualcomm RILs. Those RILs that don't support it
will fail this request with no harm done.

In case if turns out to be harmful with some RILs, it can be turned off
with emptyPinQuery=false in ril_subscription.conf
2016-07-07 11:37:54 +03:00
Slava Monich
246e30d1a5 Merge branch 'locked_pins' into 'master'
Implement SC facility lock query

Otherwise `org.ofono.SimManager` `LockedPins` state gets lost after
ofono is restarted. A few cherry-picks from upstream were required.

See merge request !73
2016-07-07 08:34:25 +00:00
Slava Monich
83267e1fa5 Merge branch 'ril_phonebook' into 'master'
Free phonebook state if export hasn't finished

Fixes memory leaks like these:

==21616== 56 (8 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 437 of 520
==21616==    at 0x483F380: malloc (vg_replace_malloc.c:296)
==21616==    by 0x4AEB26F: g_malloc (gmem.c:94)
==21616==    by 0x4B010D9: g_slice_alloc (gslice.c:1025)
==21616==    by 0x4B01FC7: g_slist_append (gslist.c:213)
==21616==    by 0x32553: start_sim_app_read (ril_phonebook.c:860)
==21616==    by 0x3276B: pb_reference_data_cb (ril_phonebook.c:903)
==21616==    by 0x153EB3: sim_fs_op_error (simfs.c:271)
==21616==    by 0x1552BB: sim_fs_op_info_cb (simfs.c:682)
==21616==    by 0x3BBA3: ril_sim_file_info_cb (ril_sim.c:358)
==21616==    by 0x489F679: grilio_channel_handle_packet (grilio_channel.c:711)
==21616==    by 0x489F679: grilio_channel_read (grilio_channel.c:811)
==21616==    by 0x489F679: grilio_channel_read_callback (grilio_channel.c:824)
==21616==    by 0x4AE621B: g_main_dispatch (gmain.c:3154)
==21616==    by 0x4AE621B: g_main_context_dispatch (gmain.c:3769)
==21616==    by 0x4AE64C9: g_main_context_iterate.isra.4 (gmain.c:3840)
==21616== 
==21616== 366 (28 direct, 338 indirect) bytes in 1 blocks are definitely lost in loss record 503 of 520
==21616==    at 0x483F380: malloc (vg_replace_malloc.c:296)
==21616==    by 0x4AEB26F: g_malloc (gmem.c:94)
==21616==    by 0x4B010D9: g_slice_alloc (gslice.c:1025)
==21616==    by 0x4B1076B: g_tree_new_full (gtree.c:217)
==21616==    by 0x324CF: start_sim_app_read (ril_phonebook.c:846)
==21616==    by 0x3276B: pb_reference_data_cb (ril_phonebook.c:903)
==21616==    by 0x153EB3: sim_fs_op_error (simfs.c:271)
==21616==    by 0x1552BB: sim_fs_op_info_cb (simfs.c:682)
==21616==    by 0x3BBA3: ril_sim_file_info_cb (ril_sim.c:358)
==21616==    by 0x489F679: grilio_channel_handle_packet (grilio_channel.c:711)
==21616==    by 0x489F679: grilio_channel_read (grilio_channel.c:811)
==21616==    by 0x489F679: grilio_channel_read_callback (grilio_channel.c:824)
==21616==    by 0x4AE621B: g_main_dispatch (gmain.c:3154)
==21616==    by 0x4AE621B: g_main_context_dispatch (gmain.c:3769)
==21616==    by 0x4AE64C9: g_main_context_iterate.isra.4 (gmain.c:3840)

Those occur if SIM card is removed before phonebook export is finished

See merge request !74
2016-07-07 08:33:47 +00:00
Slava Monich
e1ab11ad25 Merge branch 'configs-mer' into 'master'
configs-mer doesn't need to require ofono

The dependency goes the other way around.

See merge request !71
2016-07-07 08:32:36 +00:00
Slava Monich
a9193282d5 [ril] Fixed another memory leak in RIL phonebook. Fixes to MER#1615 2016-07-07 00:11:27 +03:00
Slava Monich
f80bb5c5bb [ril] Implement facility lock query. Fixes MER#1614 2016-07-06 19:27:34 +03:00
Slava Monich
66eb87777f sim: Query the status of SC facility lock 2016-07-06 19:27:00 +03:00
Denis Kenzior
e5291006fd include: Remove unused query_locked method 2016-07-06 19:27:00 +03:00
Denis Kenzior
c609d7cc07 isi: Change query_locked to query_facility_lock 2016-07-06 19:27:00 +03:00
Denis Kenzior
0de562b019 isimodem: Remove unimplemented query_locked method 2016-07-06 19:27:00 +03:00
Denis Kenzior
60b11f712c atmodem: Change query_locked to query_facility_lock 2016-07-06 19:27:00 +03:00
Samrat Guha Niyogi
80d347b964 sim: Query the status of PS and PN facility locks 2016-07-06 19:27:00 +03:00
Samrat Guha Niyogi
97abd10984 include: Add query_facility_lock method 2016-07-06 19:27:00 +03:00
Slava Monich
5201fc0183 [ril] Free phonebook state if export hasn't finished. Contributes to MER#1615 2016-07-06 12:37:21 +03:00
Slava Monich
14e4ef8e07 [ril] Query available band modes at startup. Contributes to JB#35461 2016-07-04 23:21:23 +03:00
Slava Monich
22bc6d526e [rpm] configs-mer doesn't need to require ofono
The dependency goes the other way around.
2016-07-04 21:20:28 +03:00
Slava Monich
baa4fe30e5 Merge branch 'master' into 'master'
Ensure /var/lib/ofono exists on package.

Directory wasn't being created with new automake.

Makefile.am includes:

statedir = $(localstatedir)/lib/ofono
state_DATA =

Suspect newer just skips it as empty. mkdir should be a safe workaround.

See merge request !69
2016-07-04 16:58:03 +00:00
Slava Monich
d0d0793ccb Merge branch 'allow-data' into 'master'
Add allowDataReq ril_subscription.conf option

That fixes Nexus 5 port. Tested by community.

See merge request !70
2016-07-04 16:56:21 +00:00
Slava Monich
55dd461ce7 [ril] Allow to specify default values in Settings section of ril_subscription.conf
Those will become default for all modems but still can be overwritten in
per-modem config sections.
2016-07-03 16:18:48 +03:00
Slava Monich
4da1a30290 [ril] Added allowDataReq ril_subscription.conf option. Fixes MER#1613
Set to true if your RIL doesn't support RIL_REQUEST_ALLOW_DATA
2016-07-02 14:17:06 +03:00
Slava Monich
303f527d79 [ofono] Deleted obsolete debuglog-api.txt 2016-06-28 14:13:05 +03:00
Pekka Vuorela
27e8621c0b [ofono] Ensure /var/lib/ofono exists on package. Contributes to JB#35132 2016-06-16 15:47:44 +03:00
Slava Monich
200237372a Merge branch 'jb35406' into 'master'
Retry data call on PDP_FAIL_ERROR_UNSPECIFIED

According to comment in android's ril.h, if data call setup fails
with status PDP_FAIL_ERROR_UNSPECIFIED, then we need to silently
retry the call. Let's do that.

See merge request !68
2016-06-07 11:27:31 +00:00
Slava Monich
9cae262c80 [ril] Retry data call on PDP_FAIL_ERROR_UNSPECIFIED. Fixes JB#35406
According to comment in android's ril.h, if data call setup fails
with status PDP_FAIL_ERROR_UNSPECIFIED, then we need to silently
retry the call.
2016-06-07 11:23:49 +03:00
Slava Monich
5e23459b67 Merge branch 'debuglog' into 'master'
Control ofono logging over D-Bus

The previous solution only allowed switching logs on/off, this one
allows to pipe the log to another process.

See merge request !67
2016-05-30 20:29:56 +00:00
Slava Monich
a88d7af6c8 Merge branch 'dtmf' into 'master'
Fix memory trashing after sending DTMF tone

After a DTMF tone was sent,tone_queue buffer was becoming just
a few bytes long but the code kept on assuming that it's still
pointing to at least MAX_DTMF_BUFFER bytes of memory. Under
valgrind it looked like this:

==3914== Invalid write of size 1
==3914==    at 0x4B01AEE: g_strlcat (gstrfuncs.c:1488)
==3914==    by 0x33645: ril_voicecall_send_dtmf (ril_voicecall.c:639)
==3914==    by 0x7EE4B: tone_request_run (voicecall.c:4001)
==3914==    by 0x4AE5B57: g_timeout_dispatch (gmain.c:4577)
==3914==    by 0x4AE521B: g_main_dispatch (gmain.c:3154)
==3914==    by 0x4AE521B: g_main_context_dispatch (gmain.c:3769)
==3914==    by 0x4AE54C9: g_main_context_iterate.isra.4 (gmain.c:3840)
==3914==    by 0x4AE573B: g_main_loop_run (gmain.c:4034)
==3914==    by 0x1F0AF: main (main.c:252)
==3914==  Address 0x591c361 is 0 bytes after a block of size 1 alloc'd
==3914==    at 0x483F380: malloc (vg_replace_malloc.c:296)
==3914==    by 0x4AEA26F: g_malloc (gmem.c:94)
==3914==    by 0x4B0130D: g_strdup (gstrfuncs.c:363)
==3914==    by 0x336AB: ril_voicecall_send_dtmf_cb (ril_voicecall.c:600)
==3914==    by 0x489F679: grilio_channel_handle_packet (grilio_channel.c:711)
==3914==    by 0x489F679: grilio_channel_read (grilio_channel.c:811)
==3914==    by 0x489F679: grilio_channel_read_callback (grilio_channel.c:824)
==3914==    by 0x4AE521B: g_main_dispatch (gmain.c:3154)
==3914==    by 0x4AE521B: g_main_context_dispatch (gmain.c:3769)
==3914==    by 0x4AE54C9: g_main_context_iterate.isra.4 (gmain.c:3840)
==3914==    by 0x4AE573B: g_main_loop_run (gmain.c:4034)
==3914==    by 0x1F0AF: main (main.c:252)

This patch replaces tone_queue with a FIFO ring buffer.

See merge request !66
2016-05-30 19:56:28 +00:00
Slava Monich
290c3d2388 [ofono] Control ofono logging over D-Bus. Contributes to JB#34874
The previous solution only allowed switching logs on/off, this one
allows to pipe the log to another process.
2016-05-30 19:00:42 +03:00
Slava Monich
ee880398ad [ril] Fix memory trashing after sending DTMF tone. Fixes JB#35384 2016-05-30 16:18:23 +03:00
Slava Monich
d65bbc3236 Merge branch 'jb35249' into 'master'
Fix crash on exit if data call setup is pending

See merge request !65
2016-05-17 13:57:18 +00:00
Slava Monich
655544be45 [ril] Fix crash on exit if data call setup is pending. Fixes JB#35249
When context is being removed, the core has already completed its
pending D-Bus request, invoking the completion callback causes
libdbus to panic.
2016-05-16 18:04:34 +03:00
Slava Monich
50a544a191 Merge branch 'default-proto' into 'master'
Use the right data protocol for default context settings

Follow-up to mer-core/ofono!60

See merge request !64
2016-05-14 08:42:27 +00:00
Slava Monich
9e7a4a4d72 [ofono] Use the right data protocol for default context settings. Contributes to JB#32750 2016-05-14 11:40:38 +03:00
Slava Monich
c5b5e3109d Merge branch 'ackretry' into 'master'
Retry RIL_REQUEST_SMS_ACKNOWLEDGE

People report seeing `SMS acknowledgement failed: Further SMS
reception is not guaranteed` message in the log, when they have
some sort of trouble with SMS. Let's see if retry helps.

See merge request !63
2016-04-23 15:48:20 +00:00
Slava Monich
deb106343a [ril] Retry RIL_REQUEST_SMS_ACKNOWLEDGE. Contributes to JB#34851
People report seeing "SMS acknowledgement failed: Further SMS reception
is not guaranteed" message in the log, when they have some sort of trouble
with SMS. Let's see if retry helps.
2016-04-23 12:21:23 +03:00
Slava Monich
771e8becf2 Merge branch 'imei' into 'master'
Fix IMEI query at startup.

See merge request !62
2016-04-22 08:56:45 +00:00
Slava Monich
a0b69f974a [ril] Fixed IMEI query at startup. Fixes JB#34937
IMEI related queries were being completed too early.
2016-04-21 12:25:58 +03:00
Slava Monich
b3a4aaea95 [ofono] Silence "Interface xxx not found on the interface_list" messages
Attempt to remove a modem interface already removed (internally) by ofono
is not an error.
2016-04-20 12:22:33 +03:00
Slava Monich
137e504e10 Merge branch 'jb34928' into 'master'
Prevent crash in ril_delayed_register

See merge request !61
2016-04-19 12:18:32 +00:00
Slava Monich
2de3e445f0 Merge branch 'ipv4v6' into 'master'
Use IPV4V6 for internet contexts by default

Once the packet data protocol is configured, it's saved in the
config file and can be changed via UI. In other words, default
value only affects first-time configuration (i.e. provisioning)
and "Reset to default" function.

See merge request !60
2016-04-19 12:17:57 +00:00
Slava Monich
1cd0d60768 [ril] Prevent crash in ril_delayed_register. Fixes JB#34928
Delayed registration needs to be cancelled by ril_phonebook_remove
if it (registration) hasn't been done yet.
2016-04-19 00:41:33 +03:00
Slava Monich
d1f1f16355 [ofono] Use IPV4V6 (dual) for internet context by default. Fixes JB#32750 2016-04-18 18:59:09 +03:00
Slava Monich
4df72c9376 [ofono] mbpi: Make default packet data protocol configurable. Contributes to JB#32750
Note that according to TS 23.401, UE which is IPv6 and IPv4 capable
should request IPv4v6.
2016-04-18 18:53:50 +03:00
Slava Monich
a35ca2bbd9 [ofono] mbpi: Make MBPI database file configurable at runtime
Useful for provisioning unit tests, if nothing else.
2016-04-18 18:53:28 +03:00
Slava Monich
8376174c76 Merge branch 'oemraw' into 'master'
See merge request !59
2016-04-15 16:12:38 +00:00
Slava Monich
b6f5befcac [ril] Simplify OemRaw D-Bus interface implementation
Since support for this interface has never been merged upstream (and
most likely never will) there is no need to touch ofono core at all.
Moving everything into RIL plugin simplifies the implementation and
allows to delete a few hundred lines of unnecessary code.
2016-04-14 19:03:57 +03:00
Slava Monich
403f29320c [mbpi] Housekeeping 2016-04-13 17:51:32 +03:00
41 changed files with 1687 additions and 1385 deletions

View File

@@ -22,7 +22,7 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
include/private-network.h include/cdma-netreg.h \
include/cdma-provision.h include/handsfree.h \
include/handsfree-audio.h \
include/sim-mnclength.h include/oemraw.h \
include/sim-mnclength.h \
include/siri.h
nodist_pkginclude_HEADERS = include/version.h
@@ -127,6 +127,7 @@ builtin_sources += drivers/ril/ril_call_barring.c \
drivers/ril/ril_call_volume.c \
drivers/ril/ril_cell_info.c \
drivers/ril/ril_cell_info_dbus.c \
drivers/ril/ril_config.c \
drivers/ril/ril_cbs.c \
drivers/ril/ril_data.c \
drivers/ril/ril_devinfo.c \
@@ -618,7 +619,7 @@ builtin_cflags += @WSPCODEC_CFLAGS@
builtin_libadd += @WSPCODEC_LIBS@
endif
if LOGCONTROL
if DEBUGLOG
builtin_modules += debuglog
builtin_sources += plugins/debuglog.c
endif
@@ -653,7 +654,7 @@ src_ofonod_SOURCES = $(builtin_sources) src/ofono.ver \
src/cdma-sms.c src/private-network.c src/cdma-netreg.c \
src/cdma-provision.c src/handsfree.c \
src/handsfree-audio.c src/bluetooth.h \
src/sim-mnclength.c src/oemraw.c src/voicecallagent.c \
src/sim-mnclength.c src/voicecallagent.c \
src/hfp.h src/siri.c
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \

View File

@@ -252,10 +252,16 @@ if (test "${enable_pushforwarder}" != "no"); then
AC_SUBST(WSPCODEC_LIBS)
fi
AC_ARG_ENABLE(logcontrol,
AC_HELP_STRING([--enable-logcontrol], [enable log control plugin]),
[enable_logcontrol=${enableval}], [enable_logcontrol="no"])
AM_CONDITIONAL(LOGCONTROL, test "${enable_logcontrol}" != "no")
AC_ARG_ENABLE(debuglog,
AC_HELP_STRING([--enable-debuglog], [enable log control plugin]),
[enable_debuglog=${enableval}], [enable_debuglog="no"])
AM_CONDITIONAL(DEBUGLOG, test "${enable_debuglog}" != "no")
if (test "${enable_debuglog}" = "yes"); then
PKG_CHECK_MODULES(DBUSLOG, libdbuslogserver-dbus, dummy=yes,
AC_MSG_ERROR(libdbuslogserver-dbus is required))
CFLAGS="$CFLAGS $DBUSLOG_CFLAGS"
LIBS="$LIBS $DBUSLOG_LIBS"
fi
if (test "${prefix}" = "NONE"); then
dnl no prefix and no localstatedir, so default to /var

View File

@@ -1,28 +0,0 @@
Debug log control
=================
Service org.ofono
Interface org.ofono.DebugLog
Object path /
Methods void Enable(string pattern)
Enables all logs that match the pattern.
void Disable(string pattern)
Disables all logs that match the pattern.
array(string,boolean) List()
Returns all available log names and their current
states.
In order for Enable or Disable call to have any
effect, the pattern must match one or more of
these strings.
Signals Changed(string name, boolean enabled)
This signal indicates a changed log status of the
given log module.

View File

@@ -1516,7 +1516,7 @@ static void at_lock_status_cb(gboolean ok, GAtResult *result,
{
struct cb_data *cbd = user_data;
GAtResultIter iter;
ofono_sim_locked_cb_t cb = cbd->cb;
ofono_query_facility_lock_cb_t cb = cbd->cb;
struct ofono_error error;
int locked;
@@ -1541,9 +1541,9 @@ static void at_lock_status_cb(gboolean ok, GAtResult *result,
cb(&error, locked, cbd->data);
}
static void at_pin_query_enabled(struct ofono_sim *sim,
static void at_query_clck(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
ofono_sim_locked_cb_t cb, void *data)
ofono_query_facility_lock_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
struct cb_data *cbd = cb_data_new(cb, data);
@@ -1626,7 +1626,7 @@ static struct ofono_sim_driver driver = {
.reset_passwd = at_pin_send_puk,
.lock = at_pin_enable,
.change_passwd = at_change_passwd,
.query_locked = at_pin_query_enabled,
.query_facility_lock = at_query_clck,
};
static struct ofono_sim_driver driver_noef = {
@@ -1640,7 +1640,7 @@ static struct ofono_sim_driver driver_noef = {
.reset_passwd = at_pin_send_puk,
.lock = at_pin_enable,
.change_passwd = at_change_passwd,
.query_locked = at_pin_query_enabled,
.query_facility_lock = at_query_clck,
};
void at_sim_init(void)

View File

@@ -652,7 +652,7 @@ static void sec_code_state_resp_cb(const GIsiMessage *msg, void *opaque)
static void isi_query_locked(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
ofono_sim_locked_cb_t cb, void *data)
ofono_query_facility_lock_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
@@ -963,7 +963,7 @@ static struct ofono_sim_driver driver = {
.reset_passwd = isi_reset_passwd,
.lock = isi_lock,
.change_passwd = isi_change_passwd,
.query_locked = isi_query_locked,
.query_facility_lock = isi_query_locked,
};
void isi_sim_init(void)

View File

@@ -1032,14 +1032,6 @@ static void uicc_lock(struct ofono_sim *sim, enum ofono_sim_password_type type,
CALLBACK_WITH_FAILURE(cb, data);
}
static void uicc_query_locked(struct ofono_sim *sim,
enum ofono_sim_password_type type,
ofono_sim_locked_cb_t cb, void *data)
{
DBG("Not implemented");
CALLBACK_WITH_FAILURE(cb, -1, data);
}
static gboolean decode_fcp_pin_status(const GIsiSubBlockIter *iter, uint8_t read,
uint8_t *pin1, uint8_t *pin2)
{
@@ -1677,7 +1669,6 @@ static struct ofono_sim_driver driver = {
.reset_passwd = uicc_reset_passwd,
.change_passwd = uicc_change_passwd,
.lock = uicc_lock,
.query_locked = uicc_query_locked,
};
void isi_uicc_init(void)

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015 Jolla Ltd.
* Copyright (C) 2015-2016 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
@@ -25,14 +25,16 @@ struct ril_call_forward {
guint timer_id;
};
enum ril_call_forward_cmd {
enum ril_call_forward_action {
CF_ACTION_DISABLE,
CF_ACTION_ENABLE,
CF_ACTION_UNUSED,
CF_ACTION_INTERROGATE,
CF_ACTION_REGISTRATION,
CF_ACTION_ERASURE
};
#define CF_TIME_DEFAULT (0)
struct ril_call_forward_cbd {
struct ril_call_forward *fd;
union _ofono_call_forward_cb {
@@ -43,35 +45,57 @@ struct ril_call_forward_cbd {
gpointer data;
};
#define ril_call_forward_cbd_free g_free
static inline struct ril_call_forward *ril_call_forward_get_data(
struct ofono_call_forwarding *cf)
{
return ofono_call_forwarding_get_data(cf);
}
static void ril_call_forward_cbd_free(gpointer cbd)
{
g_slice_free(struct ril_call_forward_cbd, cbd);
}
static struct ril_call_forward_cbd *ril_call_forward_cbd_new(void *cb,
void *data)
{
struct ril_call_forward_cbd *cbd;
cbd = g_new0(struct ril_call_forward_cbd, 1);
cbd = g_slice_new0(struct ril_call_forward_cbd);
cbd->cb.ptr = cb;
cbd->data = data;
return cbd;
}
static inline void ril_call_forward_submit_request(struct ril_call_forward *fd,
GRilIoRequest* req, guint code, GRilIoChannelResponseFunc response,
void *cb, void *data)
static GRilIoRequest *ril_call_forward_req(enum ril_call_forward_action action,
int type, int cls, const struct ofono_phone_number *number, int time)
{
grilio_queue_send_request_full(fd->q, req, code, response,
ril_call_forward_cbd_free,
ril_call_forward_cbd_new(cb, data));
GRilIoRequest *req = grilio_request_new();
/*
* Modem seems to respond with error to all requests
* made with bearer class BEARER_CLASS_DEFAULT.
*/
if (cls == BEARER_CLASS_DEFAULT) {
cls = SERVICE_CLASS_NONE;
}
grilio_request_append_int32(req, action);
grilio_request_append_int32(req, type);
grilio_request_append_int32(req, cls); /* Service class */
if (number) {
grilio_request_append_int32(req, number->type);
grilio_request_append_utf8(req, number->number);
} else {
grilio_request_append_int32(req, 0x81); /* TOA unknown */
grilio_request_append_utf8(req, NULL); /* No number */
}
grilio_request_append_int32(req, time);
return req;
}
static void ril_forward_set_cb(GRilIoChannel *io, int status,
static void ril_call_forward_set_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
struct ofono_error error;
@@ -86,93 +110,51 @@ static void ril_forward_set_cb(GRilIoChannel *io, int status,
}
}
static void ril_call_forward_set(struct ofono_call_forwarding *cf,
enum ril_call_forward_action cmd, int type, int cls,
const struct ofono_phone_number *number, int time,
ofono_call_forwarding_set_cb_t cb, void *data)
{
struct ril_call_forward *fd = ril_call_forward_get_data(cf);
GRilIoRequest *req = ril_call_forward_req(cmd, type, cls, number, time);
grilio_queue_send_request_full(fd->q, req, RIL_REQUEST_SET_CALL_FORWARD,
ril_call_forward_set_cb, ril_call_forward_cbd_free,
ril_call_forward_cbd_new(cb, data));
grilio_request_unref(req);
}
static void ril_call_forward_registration(struct ofono_call_forwarding *cf,
int type, int cls, const struct ofono_phone_number *number,
int time, ofono_call_forwarding_set_cb_t cb, void *data)
{
struct ril_call_forward *fd = ril_call_forward_get_data(cf);
GRilIoRequest *req = grilio_request_new();
ofono_info("cf registration");
grilio_request_append_int32(req, CF_ACTION_REGISTRATION);
grilio_request_append_int32(req, type);
/*
* Modem seems to respond with error to all queries
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* BEARER_CLASS_VOICE as per RIL design.
*/
if (cls == BEARER_CLASS_DEFAULT) {
cls = BEARER_CLASS_VOICE;
}
grilio_request_append_int32(req, cls);
grilio_request_append_int32(req, number->type);
grilio_request_append_utf8(req, number->number);
grilio_request_append_int32(req, time);
ril_call_forward_submit_request(fd, req, RIL_REQUEST_SET_CALL_FORWARD,
ril_forward_set_cb, cb, data);
grilio_request_unref(req);
}
static void ril_call_forward_send_cmd(struct ofono_call_forwarding *cf,
int type, int cls, ofono_call_forwarding_set_cb_t cb,
void *data, int action)
{
struct ril_call_forward *fd = ril_call_forward_get_data(cf);
GRilIoRequest *req = grilio_request_new();
grilio_request_append_int32(req, action);
grilio_request_append_int32(req, type);
/*
* Modem seems to respond with error to all queries
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* BEARER_CLASS_VOICE as per RIL design.
*/
if (cls == BEARER_CLASS_DEFAULT) {
cls = BEARER_CLASS_VOICE;
}
grilio_request_append_int32(req, cls); /* Service class */
/* Following 3 values have no real meaning in erasure
* but apparently RIL expects them so fields need to
* be filled. Otherwise there is no response
*/
grilio_request_append_int32(req, 0x81); /* TOA unknown */
grilio_request_append_utf8(req, "1234567890");
grilio_request_append_int32(req, 60);
ril_call_forward_submit_request(fd, req, RIL_REQUEST_SET_CALL_FORWARD,
ril_forward_set_cb, cb, data);
grilio_request_unref(req);
ril_call_forward_set(cf, CF_ACTION_REGISTRATION, type, cls,
number, time, cb, data);
}
static void ril_call_forward_erasure(struct ofono_call_forwarding *cf,
int type, int cls, ofono_call_forwarding_set_cb_t cb, void *data)
{
ofono_info("CF_ACTION_ERASURE");
ril_call_forward_send_cmd(cf, type, cls, cb, data, CF_ACTION_ERASURE);
ofono_info("cf erasure");
ril_call_forward_set(cf, CF_ACTION_ERASURE, type, cls,
NULL, CF_TIME_DEFAULT, cb, data);
}
static void ril_call_forward_deactivate(struct ofono_call_forwarding *cf,
int type, int cls, ofono_call_forwarding_set_cb_t cb, void *data)
{
ofono_info("CF_ACTION_DISABLE");
ril_call_forward_send_cmd(cf, type, cls, cb, data, CF_ACTION_DISABLE);
ofono_info("cf disable");
ril_call_forward_set(cf, CF_ACTION_DISABLE, type, cls,
NULL, CF_TIME_DEFAULT, cb, data);
}
static void ril_call_forward_activate(struct ofono_call_forwarding *cf,
int type, int cls, ofono_call_forwarding_set_cb_t cb, void *data)
{
ofono_info("CF_ACTION_ENABLE");
ril_call_forward_send_cmd(cf, type, cls, cb, data, CF_ACTION_ENABLE);
ofono_info("cf enable");
ril_call_forward_set(cf, CF_ACTION_ENABLE, type, cls,
NULL, CF_TIME_DEFAULT, cb, data);
}
static void ril_call_forward_query_cb(GRilIoChannel *io, int status,
@@ -223,36 +205,14 @@ static void ril_call_forward_query(struct ofono_call_forwarding *cf, int type,
int cls, ofono_call_forwarding_query_cb_t cb, void *data)
{
struct ril_call_forward *fd = ril_call_forward_get_data(cf);
GRilIoRequest *req = grilio_request_new();
GRilIoRequest *req = ril_call_forward_req(CF_ACTION_INTERROGATE,
type, cls, NULL, CF_TIME_DEFAULT);
ofono_info("cf query");
grilio_request_append_int32(req, 2);
grilio_request_append_int32(req, type);
/*
* Modem seems to respond with error to all queries
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* SERVICE_CLASS_NONE as per RIL design.
*/
if (cls == BEARER_CLASS_DEFAULT) {
cls = SERVICE_CLASS_NONE;
}
grilio_request_append_int32(req, cls);
/* Following 3 values have no real meaning in query
* but apparently RIL expects them so fields need to
* be filled. Otherwise there is no response
*/
grilio_request_append_int32(req, 0x81); /* TOA unknown */
grilio_request_append_utf8(req, "1234567890");
grilio_request_append_int32(req, 0);
ril_call_forward_submit_request(fd, req,
RIL_REQUEST_QUERY_CALL_FORWARD_STATUS,
ril_call_forward_query_cb, cb, data);
grilio_queue_send_request_full(fd->q, req,
RIL_REQUEST_QUERY_CALL_FORWARD_STATUS,
ril_call_forward_query_cb, ril_call_forward_cbd_free,
ril_call_forward_cbd_new(cb, data));
grilio_request_unref(req);
}
@@ -286,7 +246,7 @@ static void ril_call_forward_remove(struct ofono_call_forwarding *cf)
DBG("");
ofono_call_forwarding_set_data(cf, NULL);
if (fd->timer_id > 0) {
if (fd->timer_id) {
g_source_remove(fd->timer_id);
}

View File

@@ -0,0 +1,115 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2016 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "ril_config.h"
/* Utilities for parsing ril_subscription.conf */
char* ril_config_get_string(GKeyFile *file, const char *group, const char *key)
{
char *val = g_key_file_get_string(file, group, key, NULL);
if (!val && strcmp(group, RILCONF_SETTINGS_GROUP)) {
/* Check the common section */
val = g_key_file_get_string(file, RILCONF_SETTINGS_GROUP, key,
NULL);
}
return val;
}
gboolean ril_config_get_integer(GKeyFile *file, const char *group,
const char *key, int *out_value)
{
GError *error = NULL;
int value = g_key_file_get_integer(file, group, key, &error);
if (!error) {
if (out_value) {
*out_value = value;
}
return TRUE;
} else {
g_error_free(error);
if (strcmp(group, RILCONF_SETTINGS_GROUP)) {
/* Check the common section */
error = NULL;
value = g_key_file_get_integer(file,
RILCONF_SETTINGS_GROUP, key, &error);
if (!error) {
if (out_value) {
*out_value = value;
}
return TRUE;
}
g_error_free(error);
}
return FALSE;
}
}
gboolean ril_config_get_boolean(GKeyFile *file, const char *group,
const char *key, gboolean *out_value)
{
GError *error = NULL;
gboolean value = g_key_file_get_boolean(file, group, key, &error);
if (!error) {
if (out_value) {
*out_value = value;
}
return TRUE;
} else {
g_error_free(error);
if (strcmp(group, RILCONF_SETTINGS_GROUP)) {
/* Check the common section */
error = NULL;
value = g_key_file_get_boolean(file,
RILCONF_SETTINGS_GROUP, key, &error);
if (!error) {
if (out_value) {
*out_value = value;
}
return TRUE;
}
g_error_free(error);
}
return FALSE;
}
}
gboolean ril_config_get_flag(GKeyFile *file, const char *group,
const char *key, int flag, int *flags)
{
gboolean value;
if (ril_config_get_boolean(file, group, key, &value)) {
if (value) {
*flags |= flag;
} else {
*flags &= ~flag;
}
return TRUE;
} else {
return FALSE;
}
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -0,0 +1,41 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2016 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef RIL_CONFIG_H
#define RIL_CONFIG_H
#include "ril_types.h"
/* Utilities for parsing ril_subscription.conf */
#define RILCONF_SETTINGS_GROUP "Settings"
char* ril_config_get_string(GKeyFile *file, const char *group, const char *key);
gboolean ril_config_get_integer(GKeyFile *file, const char *group,
const char *key, int *value);
gboolean ril_config_get_boolean(GKeyFile *file, const char *group,
const char *key, gboolean *value);
gboolean ril_config_get_flag(GKeyFile *file, const char *group,
const char *key, int flag, int *flags);
#endif /* RIL_CONFIG_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -99,6 +99,7 @@ struct ril_data_priv {
struct ril_data_request *req_queue;
struct ril_data_request *pending_req;
enum ril_data_allow_data_opt allow_data;
char *log_prefix;
guint query_id;
gulong io_event_id;
@@ -158,6 +159,7 @@ struct ril_data_request_setup {
char *password;
enum ofono_gprs_proto proto;
enum ofono_gprs_auth_method auth_method;
int retry_count;
};
struct ril_data_request_deact {
@@ -686,8 +688,6 @@ static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
struct ril_data_call_list *list = NULL;
struct ril_data_call *call = NULL;
ril_data_request_completed(req);
if (ril_status == RIL_E_SUCCESS) {
list = ril_data_call_list_parse(data, len);
}
@@ -701,6 +701,22 @@ static void ril_data_call_setup_cb(GRilIoChannel *io, int ril_status,
}
}
if (call && call->status == PDP_FAIL_ERROR_UNSPECIFIED &&
!setup->retry_count) {
/*
* Retry silently according to comment in ril.h
* (no more than once though)
*/
DBG("retrying silently");
setup->retry_count++;
req->pending_id = 0;
req->submit(req);
ril_data_call_list_free(list);
return;
}
ril_data_request_completed(req);
if (call && call->status == PDP_FAIL_NONE) {
if (ril_data_call_list_move_calls(self->data_calls, list) > 0) {
DBG("data call(s) added");
@@ -1004,7 +1020,7 @@ static void ril_data_settings_changed(struct ril_sim_settings *settings,
struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
struct ril_radio *radio, struct ril_network *network,
GRilIoChannel *io)
GRilIoChannel *io, enum ril_data_allow_data_opt opt)
{
GASSERT(dm);
if (G_LIKELY(dm)) {
@@ -1013,6 +1029,21 @@ struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
struct ril_sim_settings *settings = network->settings;
GRilIoRequest *req = grilio_request_new();
switch (opt) {
case RIL_ALLOW_DATA_ON:
case RIL_ALLOW_DATA_OFF:
priv->allow_data = opt;
break;
default:
/*
* When RIL_REQUEST_ALLOW_DATA first appeared in ril.h
* RIL_VERSION was 10
*/
priv->allow_data = (io->ril_version > 10) ?
RIL_ALLOW_DATA_ON : RIL_ALLOW_DATA_OFF;
break;
}
priv->log_prefix = (name && name[0]) ?
g_strconcat(name, " ", NULL) : g_strdup("");
@@ -1449,11 +1480,8 @@ static void ril_data_manager_switch_data_on(struct ril_data_manager *self,
OFONO_RADIO_ACCESS_MODE_ANY, TRUE);
}
/*
* RIL_VERSION in ril.h was 10 when RIL_REQUEST_ALLOW_DATA first
* appeared there.
*/
if (priv->io->ril_version >= 10) {
if (priv->allow_data == RIL_ALLOW_DATA_ON) {
ril_data_request_queue(ril_data_allow_new(data));
} else {
priv->flags |= RIL_DATA_FLAG_ON;

View File

@@ -54,6 +54,12 @@ enum ril_data_manager_flags {
RIL_DATA_MANAGER_3GLTE_HANDOVER = 0x01
};
enum ril_data_allow_data_opt {
RIL_ALLOW_DATA_AUTO,
RIL_ALLOW_DATA_ON,
RIL_ALLOW_DATA_OFF
};
enum ril_data_role {
RIL_DATA_ROLE_NONE, /* Data not allowed */
RIL_DATA_ROLE_MMS, /* Data is allowed at any speed */
@@ -74,7 +80,7 @@ typedef void (*ril_data_call_deactivate_cb_t)(struct ril_data *data,
struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
struct ril_radio *radio, struct ril_network *network,
GRilIoChannel *io);
GRilIoChannel *io, enum ril_data_allow_data_opt opt);
struct ril_data *ril_data_ref(struct ril_data *data);
void ril_data_unref(struct ril_data *data);
gboolean ril_data_allowed(struct ril_data *data);

View File

@@ -434,8 +434,6 @@ static void ril_gprs_context_activate_primary_cb(struct ril_data *data,
ofono_gprs_context_cb_t cb;
gpointer cb_data;
ofono_info("setting up data call");
ril_error_init_failure(&error);
if (ril_status != RIL_E_SUCCESS) {
ofono_error("GPRS context: Reply failure: %s",
@@ -456,6 +454,8 @@ static void ril_gprs_context_activate_primary_cb(struct ril_data *data,
goto done;
}
ofono_info("setting up data call");
/* Check the ip address */
ril_gprs_split_ip_by_protocol(call->addresses, &split_ip_addr,
&split_ipv6_addr);
@@ -636,7 +636,15 @@ static void ril_gprs_context_remove(struct ofono_gprs_context *gc)
DBG("");
ofono_gprs_context_set_data(gc, NULL);
ril_data_request_cancel(gcd->activate.req);
if (gcd->activate.req) {
/*
* The core has already completed its pending D-Bus
* request, invoking the completion callback will
* cause libdbus to panic.
*/
ril_data_request_detach(gcd->activate.req);
ril_data_request_cancel(gcd->activate.req);
}
if (gcd->deactivate.req) {
/* Let it complete but we won't be around to be notified. */

View File

@@ -300,7 +300,6 @@ static void ril_modem_post_online(struct ofono_modem *modem)
ofono_netreg_create(modem, 0, RILMODEM_DRIVER, md);
ofono_ussd_create(modem, 0, RILMODEM_DRIVER, md);
ofono_call_settings_create(modem, 0, RILMODEM_DRIVER, md);
ofono_oem_raw_create(modem, 0, RILMODEM_DRIVER, md);
}
static void ril_modem_set_online(struct ofono_modem *modem, ofono_bool_t online,
@@ -457,6 +456,15 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
ofono_modem_set_powered(modem->ofono, FALSE);
ofono_modem_set_powered(modem->ofono, TRUE);
md->power_state = POWERED_ON;
/*
* With some RIL implementations, querying available
* band modes causes some magic Android properties to
* appear. Otherwise this request is pretty harmless
* and useless.
*/
grilio_queue_send_request(md->q, NULL,
RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE);
return modem;
} else {
ofono_error("Error %d registering %s",

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015 Jolla Ltd.
* Copyright (C) 2015-2016 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
@@ -16,118 +16,147 @@
#include "ril_plugin.h"
#include "ril_util.h"
#include "ril_log.h"
#include "ril_constants.h"
#include "gdbus.h"
#include "ofono.h"
#define RIL_OEM_RAW_INTERFACE "org.ofono.OemRaw"
#define RIL_OEM_RAW_TIMEOUT (60*1000) /* 60 sec */
struct ril_oem_raw {
struct ril_modem *modem;
GRilIoQueue *q;
guint timer_id;
DBusConnection *conn;
char *path;
char *log_prefix;
};
struct ril_oem_raw_cbd {
ofono_oem_raw_query_cb_t cb;
gpointer data;
};
#define DBG_(oem,fmt,args...) DBG("%s" fmt, (oem)->log_prefix, ##args)
#define ril_oem_raw_cbd_free g_free
static inline struct ril_oem_raw *ril_oem_raw_get_data(
struct ofono_oem_raw *raw)
{
return ofono_oem_raw_get_data(raw);
}
static struct ril_oem_raw_cbd *ril_oem_raw_cbd_new(ofono_oem_raw_query_cb_t cb,
void *data)
{
struct ril_oem_raw_cbd *cbd = g_new0(struct ril_oem_raw_cbd, 1);
cbd->cb = cb;
cbd->data = data;
return cbd;
}
static void ril_oem_raw_request_cb(GRilIoChannel *io, int status,
static void ril_oem_raw_send_cb(GRilIoChannel *io, int ril_status,
const void *data, guint len, void *user_data)
{
struct ofono_error error;
struct ril_oem_raw_cbd *cbd = user_data;
DBusMessage *msg = user_data;
DBusMessage *reply;
if (status == RIL_E_SUCCESS) {
struct ofono_oem_raw_results result;
if (ril_status == RIL_E_SUCCESS) {
DBusMessageIter it, array;
const guchar* bytes = data;
guint i;
result.data = (void *)data;
result.length = len;
cbd->cb(ril_error_ok(&error), &result, cbd->data);
reply = dbus_message_new_method_return(msg);
dbus_message_iter_init_append(reply, &it);
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE_AS_STRING, &array);
for (i = 0; i < len; i++) {
guchar byte = bytes[i];
dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE,
&byte);
}
dbus_message_iter_close_container(&it, &array);
} else if (ril_status == GRILIO_STATUS_TIMEOUT) {
DBG("Timed out");
reply = __ofono_error_timed_out(msg);
} else {
DBG("error:%d len:%d ", status, len);
cbd->cb(ril_error_failure(&error), NULL, cbd->data);
DBG("Error %s", ril_error_to_string(ril_status));
reply = __ofono_error_failed(msg);
}
__ofono_dbus_pending_reply(&msg, reply);
}
static DBusMessage *ril_oem_raw_send(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
DBusMessageIter it;
struct ril_oem_raw *oem = user_data;
dbus_message_iter_init(msg, &it);
if (dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_ARRAY &&
dbus_message_iter_get_element_type(&it) == DBUS_TYPE_BYTE) {
char *data;
int data_len;
DBusMessageIter array;
GRilIoRequest *req;
/* Fetch the data */
dbus_message_iter_recurse(&it, &array);
dbus_message_iter_get_fixed_array(&array, &data, &data_len);
DBG_(oem, "%d bytes", data_len);
/*
* And forward it to rild. Set a timeout because rild may
* never respond to invalid requests.
*/
req = grilio_request_sized_new(data_len);
grilio_request_set_timeout(req, RIL_OEM_RAW_TIMEOUT);
grilio_request_append_bytes(req, data, data_len);
grilio_queue_send_request_full(oem->q, req,
RIL_REQUEST_OEM_HOOK_RAW, ril_oem_raw_send_cb,
NULL, dbus_message_ref(msg));
grilio_request_unref(req);
return NULL;
} else {
DBG_(oem, "Unexpected signature");
return __ofono_error_invalid_args(msg);
}
}
static void ril_oem_raw_request(struct ofono_oem_raw *raw,
const struct ofono_oem_raw_request *request,
ofono_oem_raw_query_cb_t cb, void *data)
{
struct ril_oem_raw *od = ril_oem_raw_get_data(raw);
GRilIoRequest *req = grilio_request_sized_new(request->length);
grilio_request_append_bytes(req, request->data, request->length);
grilio_queue_send_request_full(od->q, req, RIL_REQUEST_OEM_HOOK_RAW,
ril_oem_raw_request_cb, ril_oem_raw_cbd_free,
ril_oem_raw_cbd_new(cb, data));
grilio_request_unref(req);
}
static gboolean ril_oem_raw_register(gpointer user_data)
{
struct ofono_oem_raw *raw = user_data;
struct ril_oem_raw *od = ril_oem_raw_get_data(raw);
DBG("");
GASSERT(od->timer_id);
od->timer_id = 0;
ofono_oem_raw_dbus_register(raw);
/* Single-shot */
return FALSE;
}
static int ril_oem_raw_probe(struct ofono_oem_raw *raw, unsigned int vendor,
void *data)
{
struct ril_modem *modem = data;
struct ril_oem_raw *od = g_new0(struct ril_oem_raw, 1);
DBG("");
od->q = grilio_queue_new(ril_modem_io(modem));
od->timer_id = g_idle_add(ril_oem_raw_register, raw);
ofono_oem_raw_set_data(raw, od);
return 0;
}
static void ril_oem_raw_remove(struct ofono_oem_raw *raw)
{
struct ril_oem_raw *od = ril_oem_raw_get_data(raw);
DBG("");
grilio_queue_cancel_all(od->q, TRUE);
ofono_oem_raw_set_data(raw, NULL);
if (od->timer_id) {
g_source_remove(od->timer_id);
}
grilio_queue_unref(od->q);
g_free(od);
}
/* const */ struct ofono_oem_raw_driver ril_oem_raw_driver = {
.name = RILMODEM_DRIVER,
.probe = ril_oem_raw_probe,
.remove = ril_oem_raw_remove,
.request = ril_oem_raw_request,
static const GDBusMethodTable ril_oem_raw_methods[] = {
{ GDBUS_ASYNC_METHOD("Send",
GDBUS_ARGS({ "request", "ay" }),
GDBUS_ARGS({ "response", "ay" }),
ril_oem_raw_send) },
{ }
};
struct ril_oem_raw *ril_oem_raw_new(struct ril_modem *modem,
const char *log_prefix)
{
struct ril_oem_raw *oem = g_new0(struct ril_oem_raw, 1);
DBG("%s", ril_modem_get_path(modem));
oem->modem = modem;
oem->path = g_strdup(ril_modem_get_path(modem));
oem->conn = dbus_connection_ref(ofono_dbus_get_connection());
oem->q = grilio_queue_new(ril_modem_io(modem));
oem->log_prefix = (log_prefix && log_prefix[0]) ?
g_strconcat(log_prefix, " ", NULL) : g_strdup("");
/* Register D-Bus interface */
if (g_dbus_register_interface(oem->conn, oem->path,
RIL_OEM_RAW_INTERFACE, ril_oem_raw_methods,
NULL, NULL, oem, NULL)) {
ofono_modem_add_interface(modem->ofono, RIL_OEM_RAW_INTERFACE);
return oem;
} else {
ofono_error("OemRaw D-Bus register failed");
ril_oem_raw_free(oem);
return NULL;
}
}
void ril_oem_raw_free(struct ril_oem_raw *oem)
{
if (oem) {
DBG("%s", oem->path);
g_dbus_unregister_interface(oem->conn, oem->path,
RIL_OEM_RAW_INTERFACE);
ofono_modem_remove_interface(oem->modem->ofono,
RIL_OEM_RAW_INTERFACE);
dbus_connection_unref(oem->conn);
grilio_queue_cancel_all(oem->q, TRUE);
grilio_queue_unref(oem->q);
g_free(oem->log_prefix);
g_free(oem->path);
g_free(oem);
}
}
/*
* Local Variables:
* mode: C

View File

@@ -4,8 +4,8 @@
*
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) ST-Ericsson SA 2010.
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013 Jolla Ltd
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013-2016 Jolla Ltd
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
* Copyright (C) 2014 Canonical Ltd
*
@@ -17,11 +17,6 @@
* 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 "ril_plugin.h"
@@ -31,24 +26,6 @@
#include "simutil.h"
#include "util.h"
struct cb_data {
void *cb;
void *data;
void *user;
};
static inline struct cb_data *cb_data_new(void *cb, void *data, void *user)
{
struct cb_data *ret;
ret = g_new0(struct cb_data, 1);
ret->cb = cb;
ret->data = data;
ret->user = user;
return ret;
}
#define CALLBACK_WITH_FAILURE(cb, args...) \
do { \
struct ofono_error cb_e; \
@@ -153,7 +130,10 @@ struct pb_data {
struct ofono_sim *sim;
struct ofono_sim_context *sim_context;
const unsigned char *df_path;
guint register_id;
size_t df_size;
ofono_phonebook_cb_t cb;
void *cb_data;
};
static void read_info_cb(int ok, unsigned char file_status,
@@ -587,6 +567,20 @@ static void decode_read_response(const struct record_to_read *rec_data,
}
}
static gboolean free_entry(gpointer key, gpointer value, gpointer data)
{
struct phonebook_entry *entry = value;
g_free(entry->name);
g_free(entry->number);
g_free(entry->email);
g_free(entry->anr);
g_free(entry->sne);
g_free(entry);
return FALSE;
}
static gboolean export_entry(gpointer key, gpointer value, gpointer data)
{
struct ofono_phonebook *pb = data;
@@ -601,29 +595,18 @@ static gboolean export_entry(gpointer key, gpointer value, gpointer data)
entry->email,
NULL, NULL);
g_free(entry->name);
g_free(entry->number);
g_free(entry->email);
g_free(entry->anr);
g_free(entry->sne);
g_free(entry);
return FALSE;
return free_entry(key, value, NULL);
}
static void export_and_return(gboolean ok, struct cb_data *cbd)
static void free_pb_refs(struct pb_data *pbd, GTraverseFunc entry_func,
struct ofono_phonebook *pb)
{
struct ofono_phonebook *pb = cbd->user;
ofono_phonebook_cb_t cb = cbd->cb;
struct pb_data *pbd = ofono_phonebook_get_data(pb);
GSList *l;
DBG("phonebook fully read");
for (l = pbd->pb_refs; l != NULL; l = l->next) {
struct pb_ref_rec *ref = l->data;
g_tree_foreach(ref->phonebook, export_entry, pb);
g_tree_foreach(ref->phonebook, entry_func, pb);
g_tree_destroy(ref->phonebook);
g_slist_free_full(ref->pending_records, g_free);
g_slist_free_full(ref->pb_files, g_free);
@@ -631,28 +614,38 @@ static void export_and_return(gboolean ok, struct cb_data *cbd)
g_slist_free_full(pbd->pb_refs, g_free);
pbd->pb_refs = NULL;
}
if (ok)
CALLBACK_WITH_SUCCESS(cb, cbd->data);
else
CALLBACK_WITH_FAILURE(cb, cbd->data);
static void export_and_return(struct ofono_phonebook *pb, gboolean ok)
{
struct pb_data *pbd = ofono_phonebook_get_data(pb);
g_free(cbd);
DBG("phonebook fully read");
free_pb_refs(pbd, export_entry, pb);
if (pbd->cb) {
if (ok) {
CALLBACK_WITH_SUCCESS(pbd->cb, pbd->cb_data);
} else {
CALLBACK_WITH_FAILURE(pbd->cb, pbd->cb_data);
}
pbd->cb = NULL;
pbd->cb_data = NULL;
}
}
static void read_record_cb(int ok, int total_length, int record,
const unsigned char *data,
int record_length, void *userdata)
{
struct cb_data *cbd = userdata;
struct ofono_phonebook *pb = cbd->user;
struct ofono_phonebook *pb = userdata;
struct pb_data *pbd = ofono_phonebook_get_data(pb);
struct pb_ref_rec *ref = pbd->pb_ref_next->data;
struct record_to_read *rec;
if (!ok) {
ofono_error("%s: error %d", __func__, ok);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -678,13 +671,13 @@ static void read_record_cb(int ok, int total_length, int record,
rec->record,
rec->record_length,
pbd->df_path, pbd->df_size,
read_record_cb, cbd);
read_record_cb, pb);
} else {
/* Read files from next EF_PBR record, if any */
pbd->pb_ref_next = pbd->pb_ref_next->next;
if (pbd->pb_ref_next == NULL) {
export_and_return(TRUE, cbd);
export_and_return(pb, TRUE);
} else {
struct pb_ref_rec *ref;
@@ -693,7 +686,7 @@ static void read_record_cb(int ok, int total_length, int record,
ref = pbd->pb_ref_next->data;
if (!ref->pb_files) {
export_and_return(TRUE, cbd);
export_and_return(pb, TRUE);
} else {
struct pb_file_info *file_info;
@@ -704,7 +697,7 @@ static void read_record_cb(int ok, int total_length, int record,
file_info->file_id,
OFONO_SIM_FILE_STRUCTURE_FIXED,
pbd->df_path, pbd->df_size,
read_info_cb, cbd);
read_info_cb, pb);
}
}
}
@@ -714,15 +707,14 @@ static void pb_adn_cb(int ok, int total_length, int record,
const unsigned char *data,
int record_length, void *userdata)
{
struct cb_data *cbd = userdata;
struct ofono_phonebook *pb = cbd->user;
struct ofono_phonebook *pb = userdata;
struct pb_data *pbd = ofono_phonebook_get_data(pb);
struct pb_ref_rec *ref = pbd->pb_ref_next->data;
GSList *l;
if (!ok) {
ofono_error("%s: error %d", __func__, ok);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -768,9 +760,9 @@ static void pb_adn_cb(int ok, int total_length, int record,
rec->record,
rec->record_length,
pbd->df_path, pbd->df_size,
read_record_cb, cbd);
read_record_cb, pb);
} else {
export_and_return(TRUE, cbd);
export_and_return(pb, TRUE);
}
}
}
@@ -779,8 +771,7 @@ static void read_info_cb(int ok, unsigned char file_status,
int total_length, int record_length,
void *userdata)
{
struct cb_data *cbd = userdata;
struct ofono_phonebook *pb = cbd->user;
struct ofono_phonebook *pb = userdata;
struct pb_data *pbd = ofono_phonebook_get_data(pb);
struct pb_file_info *file_info;
struct pb_ref_rec *ref = pbd->pb_ref_next->data;
@@ -803,7 +794,7 @@ static void read_info_cb(int ok, unsigned char file_status,
if (ref->pb_next == NULL) {
if (ref->pb_files == NULL) {
ofono_warn("%s: no phonebook on SIM", __func__);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -813,20 +804,19 @@ static void read_info_cb(int ok, unsigned char file_status,
ofono_sim_read_path(pbd->sim_context, file_info->file_id,
OFONO_SIM_FILE_STRUCTURE_FIXED,
pbd->df_path, pbd->df_size,
pb_adn_cb, cbd);
pb_adn_cb, pb);
} else {
file_info = ref->pb_next->data;
ofono_sim_read_info(pbd->sim_context, file_info->file_id,
OFONO_SIM_FILE_STRUCTURE_FIXED,
pbd->df_path, pbd->df_size,
read_info_cb, cbd);
read_info_cb, pb);
}
}
static void start_sim_app_read(struct cb_data *cbd)
static void start_sim_app_read(struct ofono_phonebook *pb)
{
struct ofono_phonebook *pb = cbd->user;
struct pb_data *pbd = ofono_phonebook_get_data(pb);
struct pb_ref_rec *ref_rec;
struct pb_file_info *f_info;
@@ -838,7 +828,7 @@ static void start_sim_app_read(struct cb_data *cbd)
ref_rec = g_try_malloc0(sizeof(*ref_rec));
if (ref_rec == NULL) {
ofono_error("%s: OOM", __func__);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -849,7 +839,7 @@ static void start_sim_app_read(struct cb_data *cbd)
f_info = g_try_malloc0(sizeof(*f_info));
if (f_info == NULL) {
ofono_error("%s: OOM", __func__);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -861,7 +851,7 @@ static void start_sim_app_read(struct cb_data *cbd)
f_ext1 = g_try_malloc0(sizeof(*f_ext1));
if (f_ext1 == NULL) {
ofono_error("%s: OOM", __func__);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -879,15 +869,14 @@ static void start_sim_app_read(struct cb_data *cbd)
ofono_sim_read_info(pbd->sim_context, f_info->file_id,
OFONO_SIM_FILE_STRUCTURE_FIXED,
pbd->df_path, pbd->df_size,
read_info_cb, cbd);
read_info_cb, pb);
}
static void pb_reference_data_cb(int ok, int total_length, int record,
const unsigned char *sdata,
int record_length, void *userdata)
{
struct cb_data *cbd = userdata;
struct ofono_phonebook *pb = cbd->user;
struct ofono_phonebook *pb = userdata;
struct pb_data *pbd = ofono_phonebook_get_data(pb);
const unsigned char *ptr = sdata;
gboolean finished = FALSE;
@@ -899,14 +888,14 @@ static void pb_reference_data_cb(int ok, int total_length, int record,
if (!ok) {
/* We migh have a SIM instead of USIM application: try that */
DBG("%s: error %d, trying SIM files", __func__, ok);
start_sim_app_read(cbd);
start_sim_app_read(pb);
return;
}
ref_rec = g_try_malloc0(sizeof(*ref_rec));
if (ref_rec == NULL) {
ofono_error("%s: OOM", __func__);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -930,7 +919,7 @@ static void pb_reference_data_cb(int ok, int total_length, int record,
g_try_new0(struct pb_file_info, 1);
if (!file_info) {
ofono_error("%s: OOM", __func__);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -972,7 +961,7 @@ static void pb_reference_data_cb(int ok, int total_length, int record,
if (ref->pb_files == NULL) {
ofono_error("%s: no files to read", __func__);
export_and_return(FALSE, cbd);
export_and_return(pb, FALSE);
return;
}
@@ -984,7 +973,7 @@ static void pb_reference_data_cb(int ok, int total_length, int record,
ofono_sim_read_info(pbd->sim_context, file_info->file_id,
OFONO_SIM_FILE_STRUCTURE_FIXED,
pbd->df_path, pbd->df_size,
read_info_cb, cbd);
read_info_cb, pb);
}
}
@@ -993,7 +982,6 @@ static void ril_export_entries(struct ofono_phonebook *pb,
ofono_phonebook_cb_t cb, void *data)
{
struct pb_data *pbd = ofono_phonebook_get_data(pb);
struct cb_data *cbd;
DBG("Storage %s", storage);
@@ -1003,7 +991,8 @@ static void ril_export_entries(struct ofono_phonebook *pb,
return;
}
cbd = cb_data_new(cb, data, pb);
pbd->cb = cb;
pbd->cb_data = data;
/* Assume USIM, change in case EF_PBR is not present */
pbd->df_path = usim_path;
@@ -1011,13 +1000,15 @@ static void ril_export_entries(struct ofono_phonebook *pb,
ofono_sim_read(pbd->sim_context, SIM_EFPBR_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
pb_reference_data_cb, cbd);
pb_reference_data_cb, pb);
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_phonebook *pb = user_data;
struct pb_data *pbd = ofono_phonebook_get_data(pb);
pbd->register_id = 0;
ofono_phonebook_register(pb);
return FALSE;
}
@@ -1040,7 +1031,7 @@ static int ril_phonebook_probe(struct ofono_phonebook *pb,
ofono_phonebook_set_data(pb, pd);
g_idle_add(ril_delayed_register, pb);
pd->register_id = g_idle_add(ril_delayed_register, pb);
return 0;
}
@@ -1049,9 +1040,14 @@ static void ril_phonebook_remove(struct ofono_phonebook *pb)
{
struct pb_data *pbd = ofono_phonebook_get_data(pb);
if (pbd->register_id) {
g_source_remove(pbd->register_id);
}
ofono_phonebook_set_data(pb, NULL);
ofono_sim_context_free(pbd->sim_context);
free_pb_refs(pbd, free_entry, NULL);
g_free(pbd);
}

View File

@@ -14,6 +14,7 @@
*/
#include "ril_plugin.h"
#include "ril_config.h"
#include "ril_sim_card.h"
#include "ril_sim_info.h"
#include "ril_sim_settings.h"
@@ -49,10 +50,11 @@
#define RILMODEM_DEFAULT_SLOT 0xffffffff
#define RILMODEM_DEFAULT_TIMEOUT 0 /* No timeout */
#define RILMODEM_DEFAULT_SIM_FLAGS RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND
#define RILMODEM_DEFAULT_DATA_OPT RIL_ALLOW_DATA_AUTO
#define RILMODEM_DEFAULT_DM_FLAGS RIL_DATA_MANAGER_3GLTE_HANDOVER
#define RILMODEM_DEFAULT_EMPTY_PIN_QUERY TRUE /* optimistic */
#define RILMODEM_CONF_GROUP "Settings"
#define RILMODEM_CONF_3GHANDOVER "3GLTEHandover"
#define RILCONF_SETTINGS_3GHANDOVER "3GLTEHandover"
#define RILCONF_DEV_PREFIX "ril_"
#define RILCONF_PATH_PREFIX "/" RILCONF_DEV_PREFIX
@@ -64,6 +66,8 @@
#define RILCONF_4G "enable4G"
#define RILCONF_UICC_WORKAROUND "uiccWorkaround"
#define RILCONF_ECCLIST_FILE "ecclistFile"
#define RILCONF_ALLOW_DATA_REQ "allowDataReq"
#define RILCONF_EMPTY_PIN_QUERY "emptyPinQuery"
#define RIL_STORE "ril"
#define RIL_STORE_GROUP "Settings"
@@ -106,9 +110,10 @@ struct ril_slot {
char *sockpath;
char *sub;
char *ecclist_file;
gint timeout; /* RIL timeout, in milliseconds */
int timeout; /* RIL timeout, in milliseconds */
int index;
int sim_flags;
enum ril_data_allow_data_opt allow_data_opt;
struct ril_slot_config config;
struct ril_plugin_priv *plugin;
struct ril_modem *modem;
@@ -122,6 +127,7 @@ struct ril_slot {
struct ril_sim_settings *sim_settings;
struct ril_cell_info *cell_info;
struct ril_cell_info_dbus *cell_info_dbus;
struct ril_oem_raw *oem_raw;
struct ril_data *data;
GRilIoChannel *io;
gulong io_event_id[IO_EVENT_COUNT];
@@ -147,15 +153,24 @@ static void ril_plugin_retry_init_io(struct ril_slot *slot);
GLOG_MODULE_DEFINE("rilmodem");
static const char ril_debug_trace_name[] = "ril_trace";
static GLogModule ril_debug_trace_module = {
.name = ril_debug_trace_name,
.max_level = GLOG_LEVEL_VERBOSE,
.level = GLOG_LEVEL_VERBOSE,
.flags = GLOG_FLAG_HIDE_NAME
};
static struct ofono_debug_desc ril_debug_trace OFONO_DEBUG_ATTR = {
.name = "ril_trace",
.flags = OFONO_DEBUG_FLAG_DEFAULT,
.name = ril_debug_trace_name,
.flags = OFONO_DEBUG_FLAG_DEFAULT | OFONO_DEBUG_FLAG_HIDE_NAME,
.notify = ril_debug_trace_notify
};
static struct ofono_debug_desc ril_debug_dump OFONO_DEBUG_ATTR = {
.name = "ril_dump",
.flags = OFONO_DEBUG_FLAG_DEFAULT,
.flags = OFONO_DEBUG_FLAG_DEFAULT | OFONO_DEBUG_FLAG_HIDE_NAME,
.notify = ril_debug_dump_notify
};
@@ -518,8 +533,9 @@ static void ril_plugin_update_ready(struct ril_plugin_priv *plugin)
}
if (plugin->pub.ready != ready) {
DBG("%sready", ready ? "" : "not ");
plugin->pub.ready = ready;
ril_plugin_dbus_block_imei_requests(plugin->dbus, !ready);
DBG("%sready", ready ? "" : "not ");
ril_plugin_dbus_signal(plugin->dbus, RIL_PLUGIN_SIGNAL_READY);
}
}
@@ -673,6 +689,11 @@ static void ril_plugin_modem_removed(struct ril_modem *modem, void *data)
GASSERT(slot->modem);
GASSERT(slot->modem == modem);
if (slot->oem_raw) {
ril_oem_raw_free(slot->oem_raw);
slot->oem_raw = NULL;
}
if (slot->sim_info_dbus) {
ril_sim_info_dbus_free(slot->sim_info_dbus);
slot->sim_info_dbus = NULL;
@@ -692,12 +713,7 @@ static void ril_plugin_modem_removed(struct ril_modem *modem, void *data)
static void ril_plugin_trace(GRilIoChannel *io, GRILIO_PACKET_TYPE type,
guint id, guint code, const void *data, guint data_len, void *user_data)
{
/* Turn prefix off */
static GLogModule log_module = {
.max_level = GLOG_LEVEL_VERBOSE,
.level = GLOG_LEVEL_VERBOSE
};
static const GLogModule* log_module = &ril_debug_trace_module;
const char *prefix = io->name ? io->name : "";
const char dir = (type == GRILIO_PACKET_REQ) ? '<' : '>';
const char *scode;
@@ -710,21 +726,21 @@ static void ril_plugin_trace(GRilIoChannel *io, GRILIO_PACKET_TYPE type,
} else {
scode = ril_request_to_string(code);
}
gutil_log(&log_module, GLOG_LEVEL_VERBOSE, "%s%c [%08x] %s",
gutil_log(log_module, GLOG_LEVEL_VERBOSE, "%s%c [%08x] %s",
prefix, dir, id, scode);
break;
case GRILIO_PACKET_RESP:
gutil_log(&log_module, GLOG_LEVEL_VERBOSE, "%s%c [%08x] %s",
gutil_log(log_module, GLOG_LEVEL_VERBOSE, "%s%c [%08x] %s",
prefix, dir, id, ril_error_to_string(code));
break;
case GRILIO_PACKET_UNSOL:
gutil_log(&log_module, GLOG_LEVEL_VERBOSE, "%s%c %s",
gutil_log(log_module, GLOG_LEVEL_VERBOSE, "%s%c %s",
prefix, dir, ril_unsol_event_to_string(code));
break;
}
}
static void ril_debug_dump_update_slot(struct ril_slot *slot)
static void ril_debug_dump_update(struct ril_slot *slot)
{
if (slot->io) {
if (ril_debug_dump.flags & OFONO_DEBUG_FLAG_PRINT) {
@@ -740,7 +756,7 @@ static void ril_debug_dump_update_slot(struct ril_slot *slot)
}
}
static void ril_debug_trace_update_slot(struct ril_slot *slot)
static void ril_debug_trace_update(struct ril_slot *slot)
{
if (slot->io) {
if (ril_debug_trace.flags & OFONO_DEBUG_FLAG_PRINT) {
@@ -758,7 +774,7 @@ static void ril_debug_trace_update_slot(struct ril_slot *slot)
slot->dump_id);
slot->dump_id = 0;
}
ril_debug_dump_update_slot(slot);
ril_debug_dump_update(slot);
}
} else if (slot->trace_id) {
grilio_channel_remove_logger(slot->io, slot->trace_id);
@@ -804,6 +820,9 @@ static void ril_plugin_create_modem(struct ril_slot *slot)
slot->cell_info);
}
slot->oem_raw = ril_oem_raw_new(slot->modem,
ril_plugin_log_prefix(slot));
ril_modem_set_removed_cb(modem, ril_plugin_modem_removed, slot);
ril_modem_set_online_cb(modem, ril_plugin_modem_online, slot);
} else {
@@ -827,16 +846,13 @@ static void ril_plugin_imei_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
struct ril_slot *slot = user_data;
struct ril_plugin_priv *plugin = slot->plugin;
gboolean all_done = TRUE;
GSList *link;
char *imei = NULL;
GASSERT(slot->imei_req_id);
slot->imei_req_id = 0;
if (status == RIL_E_SUCCESS) {
GRilIoParser rilp;
char *imei;
grilio_parser_init(&rilp, data, len);
imei = grilio_parser_get_utf8(&rilp);
@@ -849,26 +865,16 @@ static void ril_plugin_imei_cb(GRilIoChannel *io, int status,
* IMEI (if rild crashed and we have reconnected)
*/
GASSERT(!slot->imei || !g_strcmp0(slot->imei, imei));
g_free(slot->imei);
slot->pub.imei = slot->imei = imei;
ril_plugin_check_modem(slot);
ril_plugin_update_ready(plugin);
} else {
ofono_error("Slot %u IMEI query error: %s", slot->config.slot,
ril_error_to_string(status));
}
for (link = plugin->slots; link && all_done; link = link->next) {
if (((struct ril_slot *)link->data)->imei_req_id) {
all_done = FALSE;
}
}
g_free(slot->imei);
slot->pub.imei = slot->imei = (imei ? imei : g_strdup("ERROR"));
if (all_done) {
DBG("all done");
ril_plugin_dbus_block_imei_requests(plugin->dbus, FALSE);
}
ril_plugin_check_modem(slot);
ril_plugin_update_ready(slot->plugin);
}
/*
@@ -941,7 +947,7 @@ static void ril_plugin_slot_connected(struct ril_slot *slot)
GASSERT(!slot->data);
slot->data = ril_data_new(slot->plugin->data_manager, log_prefix,
slot->radio, slot->network, slot->io);
slot->radio, slot->network, slot->io, slot->allow_data_opt);
GASSERT(!slot->cell_info);
if (slot->io->ril_version > 8) {
@@ -968,8 +974,8 @@ static void ril_plugin_init_io(struct ril_slot *slot)
DBG("%s %s", slot->sockpath, slot->sub);
slot->io = grilio_channel_new_socket(slot->sockpath, slot->sub);
if (slot->io) {
ril_debug_trace_update_slot(slot);
ril_debug_dump_update_slot(slot);
ril_debug_trace_update(slot);
ril_debug_dump_update(slot);
if (slot->name) {
grilio_channel_set_name(slot->io, slot->name);
@@ -1022,45 +1028,43 @@ static void ril_plugin_retry_init_io(struct ril_slot *slot)
ril_plugin_retry_init_io_cb, slot);
}
static struct ril_slot *ril_plugin_slot_new(const char *sockpath,
const char *path, const char *name, guint slot_index)
{
struct ril_slot *slot = g_new0(struct ril_slot, 1);
slot->sockpath = g_strdup(sockpath);
slot->path = g_strdup(path);
slot->name = g_strdup(name);
slot->config.slot = slot_index;
slot->config.enable_4g = RILMODEM_DEFAULT_4G;
slot->config.empty_pin_query = RILMODEM_DEFAULT_EMPTY_PIN_QUERY;
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
slot->allow_data_opt = RILMODEM_DEFAULT_DATA_OPT;
return slot;
}
static GSList *ril_plugin_create_default_config()
{
GSList *list = NULL;
if (g_file_test(RILMODEM_DEFAULT_SOCK, G_FILE_TEST_EXISTS)) {
struct ril_slot *slot;
if (g_file_test(RILMODEM_DEFAULT_SOCK2, G_FILE_TEST_EXISTS)) {
DBG("Falling back to default 2-SIM config");
slot = g_new0(struct ril_slot, 1);
slot->path = g_strdup(RILCONF_PATH_PREFIX "0");
slot->sockpath = g_strdup(RILMODEM_DEFAULT_SOCK);
slot->name = g_strdup("RIL1");
slot->config.enable_4g = RILMODEM_DEFAULT_4G;
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
list = g_slist_append(list, slot);
slot = g_new0(struct ril_slot, 1);
slot->path = g_strdup(RILCONF_PATH_PREFIX "1");
slot->sockpath = g_strdup(RILMODEM_DEFAULT_SOCK2);
slot->name = g_strdup("RIL2");
slot->config.enable_4g = RILMODEM_DEFAULT_4G;
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
slot->config.slot = 1;
list = g_slist_append(list, slot);
DBG("Falling back to default dual SIM config");
list = g_slist_append(list,
ril_plugin_slot_new(RILMODEM_DEFAULT_SOCK,
RILCONF_PATH_PREFIX "0", "RIL1", 0));
list = g_slist_append(list,
ril_plugin_slot_new(RILMODEM_DEFAULT_SOCK2,
RILCONF_PATH_PREFIX "1", "RIL2", 1));
} else {
DBG("Falling back to default Jolla1 config");
struct ril_slot * slot =
ril_plugin_slot_new(RILMODEM_DEFAULT_SOCK,
RILCONF_PATH_PREFIX "0", "RIL", 0);
slot = g_new0(struct ril_slot, 1);
slot->path = g_strdup(RILCONF_PATH_PREFIX "0");
slot->sockpath = g_strdup(RILMODEM_DEFAULT_SOCK);
DBG("Falling back to default single SIM config");
slot->sub = g_strdup(RILMODEM_DEFAULT_SUB);
slot->name = g_strdup("");
slot->config.enable_4g = RILMODEM_DEFAULT_4G;
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
list = g_slist_append(list, slot);
}
} else {
@@ -1070,20 +1074,6 @@ static GSList *ril_plugin_create_default_config()
return list;
}
static void ril_plugin_read_config_flag(GKeyFile *file, const char *group,
const char *key, int flag, int *flags)
{
GError *err = NULL;
if (g_key_file_get_boolean(file, group, key, &err)) {
*flags |= flag;
} else if (!err) {
*flags &= ~flag;
} else {
g_error_free(err);
}
}
static struct ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
const char *group)
{
@@ -1091,16 +1081,14 @@ static struct ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
char *sock = g_key_file_get_string(file, group, RILCONF_SOCKET, NULL);
if (sock) {
int value;
GError *err = NULL;
char *sub = g_key_file_get_string(file, group, RILCONF_SUB,
NULL);
char* strval;
char *sub = ril_config_get_string(file, group, RILCONF_SUB);
slot = g_new0(struct ril_slot, 1);
slot = ril_plugin_slot_new(NULL, NULL, NULL,
RILMODEM_DEFAULT_SLOT);
slot->sockpath = sock;
slot->path = g_strconcat("/", group, NULL);
slot->name = g_key_file_get_string(file, group, RILCONF_NAME,
NULL);
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
slot->name = ril_config_get_string(file, group, RILCONF_NAME);
if (sub && strlen(sub) == RIL_SUB_SIZE) {
DBG("%s: %s:%s", group, sock, sub);
@@ -1110,53 +1098,55 @@ static struct ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
g_free(sub);
}
value = g_key_file_get_integer(file, group, RILCONF_SLOT, &err);
if (!err && value >= 0) {
if (ril_config_get_integer(file, group, RILCONF_SLOT, &value) &&
value >= 0) {
slot->config.slot = value;
DBG("%s: slot %u", group, slot->config.slot);
} else {
slot->config.slot = RILMODEM_DEFAULT_SLOT;
if (err) {
g_error_free(err);
err = NULL;
}
}
value = g_key_file_get_integer(file, group, RILCONF_TIMEOUT,
&err);
if (!err) {
slot->timeout = value;
if (ril_config_get_integer(file, group, RILCONF_TIMEOUT,
&slot->timeout)) {
DBG("%s: timeout %d", group, slot->timeout);
} else {
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
if (err) {
g_error_free(err);
err = NULL;
}
}
slot->config.enable_4g = g_key_file_get_boolean(file, group,
RILCONF_4G, &err);
if (err) {
/* Set to default */
slot->config.enable_4g = RILMODEM_DEFAULT_4G;
g_error_free(err);
err = NULL;
}
ril_config_get_boolean(file, group, RILCONF_4G,
&slot->config.enable_4g);
DBG("%s: 4G %s", group, slot->config.enable_4g ? "on" : "off");
ril_plugin_read_config_flag(file, group,
RILCONF_UICC_WORKAROUND,
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND,
&slot->sim_flags);
DBG("%s: UICC workaround %s", group, (slot->sim_flags &
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND) ?
"on" : "off");
if (ril_config_get_boolean(file, group, RILCONF_EMPTY_PIN_QUERY,
&slot->config.empty_pin_query)) {
DBG("%s: %s %s", group, RILCONF_EMPTY_PIN_QUERY,
slot->config.empty_pin_query ? "on" : "off");
}
slot->ecclist_file = g_key_file_get_string(file, group,
RILCONF_ECCLIST_FILE, NULL);
if (ril_config_get_flag(file, group, RILCONF_UICC_WORKAROUND,
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND,
&slot->sim_flags)) {
DBG("%s: %s %s", group, RILCONF_UICC_WORKAROUND,
(slot->sim_flags &
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND) ?
"on" : "off");
}
strval = ril_config_get_string(file, group,
RILCONF_ALLOW_DATA_REQ);
if (strval) {
slot->allow_data_opt =
!strcasecmp(strval, "on") ? RIL_ALLOW_DATA_ON :
!strcasecmp(strval, "off")? RIL_ALLOW_DATA_OFF :
RIL_ALLOW_DATA_AUTO;
DBG("%s: %s %s", group, RILCONF_ALLOW_DATA_REQ,
slot->allow_data_opt==RIL_ALLOW_DATA_ON? "on":
slot->allow_data_opt==RIL_ALLOW_DATA_OFF? "off":
"auto");
g_free(strval);
}
slot->ecclist_file = ril_config_get_string(file, group,
RILCONF_ECCLIST_FILE);
if (slot->ecclist_file && slot->ecclist_file[0]) {
DBG("%s: ecclist file %s", group, slot->ecclist_file);
DBG("%s: %s %s", group, RILCONF_ECCLIST_FILE,
slot->ecclist_file);
slot->pub.ecclist_file = slot->ecclist_file;
} else {
g_free(slot->ecclist_file);
@@ -1239,10 +1229,10 @@ static GSList *ril_plugin_parse_config_file(GKeyFile *file,
if (slot) {
list = ril_plugin_add_slot(list, slot);
}
} else if (!strcmp(group, RILMODEM_CONF_GROUP)) {
} else if (!strcmp(group, RILCONF_SETTINGS_GROUP)) {
/* Plugin configuration */
ril_plugin_read_config_flag(file, group,
RILMODEM_CONF_3GHANDOVER,
ril_config_get_flag(file, group,
RILCONF_SETTINGS_3GHANDOVER,
RIL_DATA_MANAGER_3GLTE_HANDOVER,
&ps->dm_flags);
}
@@ -1525,19 +1515,19 @@ static void ril_plugin_enable_slot(struct ril_slot *slot)
slot->pub.enabled = TRUE;
}
struct ril_plugin_priv *ril_plugin = NULL;
static struct ril_plugin_priv *ril_plugin = NULL;
static void ril_debug_trace_notify(struct ofono_debug_desc *desc)
{
if (ril_plugin) {
ril_plugin_foreach_slot(ril_plugin, ril_debug_trace_update_slot);
ril_plugin_foreach_slot(ril_plugin, ril_debug_trace_update);
}
}
static void ril_debug_dump_notify(struct ofono_debug_desc *desc)
{
if (ril_plugin) {
ril_plugin_foreach_slot(ril_plugin, ril_debug_dump_update_slot);
ril_plugin_foreach_slot(ril_plugin, ril_debug_dump_update);
}
}
@@ -1564,7 +1554,22 @@ static int ril_plugin_init(void)
DBG("");
GASSERT(!ril_plugin);
/* ofono core calls openlog() */
/*
* Log categories (accessible via D-Bus) are generated from
* ofono_debug_desc structures, while libglibutil based log
* functions receive the log module name. Those should match
* otherwise the client receiving the log won't get the category
* information.
*/
grilio_hexdump_log.name = ril_debug_dump.name;
grilio_log.name = grilio_debug.name;
/*
* Debug log plugin hooks gutil_log_func2 while we replace
* gutil_log_func, they don't interfere with each other.
*
* Note that ofono core calls openlog(), so we don't need to.
*/
gutil_log_func = gutil_log_syslog;
ril_plugin_switch_user();
@@ -1633,7 +1638,6 @@ static int ril_plugin_init(void)
ofono_phonebook_driver_register(&ril_phonebook_driver);
ofono_ussd_driver_register(&ril_ussd_driver);
ofono_cbs_driver_register(&ril_cbs_driver);
ofono_oem_raw_driver_register(&ril_oem_raw_driver);
ofono_stk_driver_register(&ril_stk_driver);
/* This will create the modems (those that are enabled) */
@@ -1677,7 +1681,6 @@ static void ril_plugin_exit(void)
ofono_phonebook_driver_unregister(&ril_phonebook_driver);
ofono_ussd_driver_unregister(&ril_ussd_driver);
ofono_cbs_driver_unregister(&ril_cbs_driver);
ofono_oem_raw_driver_unregister(&ril_oem_raw_driver);
ofono_stk_driver_unregister(&ril_stk_driver);
if (ril_plugin) {

View File

@@ -28,7 +28,6 @@
#include <ofono/gprs-context.h>
#include <ofono/gprs.h>
#include <ofono/netreg.h>
#include <ofono/oemraw.h>
#include <ofono/phonebook.h>
#include <ofono/radio-settings.h>
#include <ofono/sim.h>
@@ -99,6 +98,11 @@ void ril_plugin_set_default_voice_imsi(struct ril_plugin *plugin,
void ril_plugin_set_default_data_imsi(struct ril_plugin *plugin,
const char *imsi);
struct ril_oem_raw;
struct ril_oem_raw *ril_oem_raw_new(struct ril_modem *md,
const char *log_prefix);
void ril_oem_raw_free(struct ril_oem_raw *raw);
struct ril_sim_info_dbus;
struct ril_sim_info_dbus *ril_sim_info_dbus_new(struct ril_modem *md,
struct ril_sim_info *info);
@@ -149,7 +153,6 @@ extern const struct ofono_gprs_context_driver ril_gprs_context_driver;
extern const struct ofono_gprs_driver ril_gprs_driver;
extern const struct ofono_modem_driver ril_modem_driver;
extern const struct ofono_netreg_driver ril_netreg_driver;
extern /* const */ struct ofono_oem_raw_driver ril_oem_raw_driver;
extern const struct ofono_phonebook_driver ril_phonebook_driver;
extern const struct ofono_radio_settings_driver ril_radio_settings_driver;
extern const struct ofono_sim_driver ril_sim_driver;

File diff suppressed because it is too large Load Diff

View File

@@ -57,6 +57,7 @@ struct ril_sim_info_priv {
char *sim_spn;
char *public_spn;
char default_spn[RIL_SIM_DEFAULT_SPN_BUFSIZE];
int public_spn_block;
struct ofono_sim *sim;
struct ril_sim_info_watch state_watch;
struct ril_sim_info_watch iccid_watch;
@@ -209,14 +210,18 @@ static void ril_sim_info_set_imsi(struct ril_sim_info *self, const char *imsi)
static void ril_sim_info_update_public_spn(struct ril_sim_info *self)
{
struct ril_sim_info_priv *priv = self->priv;
const char *spn = priv->sim_spn ? priv->sim_spn :
GASSERT(priv->public_spn_block >= 0);
if (!priv->public_spn_block) {
const char *spn = priv->sim_spn ? priv->sim_spn :
priv->cached_spn ? priv->cached_spn :
priv->default_spn;
if (g_strcmp0(priv->public_spn, spn)) {
g_free(priv->public_spn);
self->spn = priv->public_spn = g_strdup(spn);
ril_sim_info_signal_emit(self, SIGNAL_SPN_CHANGED);
if (g_strcmp0(priv->public_spn, spn)) {
g_free(priv->public_spn);
self->spn = priv->public_spn = g_strdup(spn);
ril_sim_info_signal_emit(self, SIGNAL_SPN_CHANGED);
}
}
}
@@ -226,11 +231,15 @@ static void ril_sim_info_set_cached_spn(struct ril_sim_info *self,
struct ril_sim_info_priv *priv = self->priv;
if (g_strcmp0(priv->cached_spn, spn)) {
DBG_(self, "cached spn \"%s\"", spn);
g_free(priv->cached_spn);
priv->cached_spn = g_strdup(spn);
priv->update_imsi_cache = TRUE;
ril_sim_info_update_imsi_cache(self);
if (spn) {
DBG_(self, "cached spn \"%s\"", spn);
priv->cached_spn = g_strdup(spn);
priv->update_imsi_cache = TRUE;
ril_sim_info_update_imsi_cache(self);
} else {
priv->cached_spn = NULL;
}
ril_sim_info_update_public_spn(self);
}
}
@@ -505,6 +514,7 @@ void ril_sim_info_set_ofono_sim(struct ril_sim_info *self,
struct ril_sim_info_priv *priv = self->priv;
if (priv->sim != sim) {
priv->public_spn_block++;
ril_sim_info_watch_remove(&priv->state_watch);
ril_sim_info_watch_remove(&priv->iccid_watch);
ril_sim_info_watch_remove(&priv->imsi_watch);
@@ -524,9 +534,14 @@ void ril_sim_info_set_ofono_sim(struct ril_sim_info *self,
DBG_(self, "attached to sim");
ril_sim_info_handle_sim_state(self,
ofono_sim_get_state(sim));
} else {
DBG_(self, "detached from sim");
ril_sim_info_update_default_spn(self);
ril_sim_info_network_check(self);
}
ril_sim_info_network_check(self);
priv->public_spn_block--;
ril_sim_info_update_public_spn(self);
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015 Jolla Ltd.
* Copyright (C) 2015-2016 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
@@ -22,6 +22,9 @@
#include "util.h"
#include "simutil.h"
#define RIL_SMS_ACK_RETRY_MS 1000
#define RIL_SMS_ACK_RETRY_COUNT 10
#define SIM_EFSMS_FILEID 0x6F3C
#define EFSMS_LENGTH 176
@@ -278,6 +281,8 @@ static void ril_ack_delivery(struct ril_sms *sd, gboolean error)
grilio_request_append_int32(req, code); /* error code */
/* ACK the incoming NEW_SMS */
grilio_request_set_retry(req, RIL_SMS_ACK_RETRY_MS,
RIL_SMS_ACK_RETRY_COUNT);
grilio_queue_send_request_full(sd->q, req,
RIL_REQUEST_SMS_ACKNOWLEDGE, ril_ack_delivery_cb, NULL, NULL);
grilio_request_unref(req);

View File

@@ -1,4 +1,4 @@
# This is a sample configuration file for the ril driver
# This is a sample configuration file for Jolla ril driver
#
# This file is expected to be installed in /etc/ofono
#
@@ -6,6 +6,10 @@
# common settings are in the [Settings] section, all other sections
# are ignored.
#
# If any value from [ril_x] section (except "socket") is defined
# in the [Settings] section, it becomes the default for all modems.
# Default values can still be redefined at [ril_x] level.
#
[Settings]
@@ -83,3 +87,21 @@ socket=/dev/socket/rild
# chmod 0644 /var/lib/ofono/ril.ecclist
#
#ecclistFile=/var/lib/ofono/ril.ecclist
# RIL_REQUEST_ALLOW_DATA may or may not be supported by your RIL.
# This option allows you to forcibly enable or disable use of this request.
# Possible values are auto, on and off
#
# Default is auto (usage based on the RIL version)
#
#allowDataReq=auto
# Since RIL interface doesn't provide the standard way of querying the
# number of pin retries left, some RIL implementation (namely Qualcomm)
# allow to query the retry count by sending the empty pin. If your RIL
# actually does check the empty pin (and decrements the retry count)
# then you should turn this feature off.
#
# Default is true
#
#emptyPinQuery=true

View File

@@ -52,6 +52,7 @@ struct ril_cell_info;
struct ril_slot_config {
guint slot;
gboolean enable_4g;
gboolean empty_pin_query;
};
#endif /* RIL_TYPES_H */

View File

@@ -50,17 +50,15 @@ static struct ril_ussd_cbd *ril_ussd_cbd_new(ofono_ussd_cb_t cb, void *data)
return cbd;
}
static void ril_ussd_cb(GRilIoChannel *io, int status,
static void ril_ussd_cancel_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
struct ofono_error error;
struct ril_ussd_cbd *cbd = user_data;
if (status == RIL_E_SUCCESS) {
cbd->cb(ril_error_ok(&error), cbd->data);
} else {
cbd->cb(ril_error_failure(&error), cbd->data);
}
/* Always report sucessful completion, otherwise ofono may get
* stuck in the USSD_STATE_ACTIVE state */
cbd->cb(ril_error_ok(&error), cbd->data);
}
static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
@@ -120,7 +118,8 @@ static void ril_ussd_cancel(struct ofono_ussd *ussd,
ofono_info("send ussd cancel");
grilio_queue_send_request_full(ud->q, NULL, RIL_REQUEST_CANCEL_USSD,
ril_ussd_cb, ril_ussd_cbd_free, ril_ussd_cbd_new(cb, data));
ril_ussd_cancel_cb, ril_ussd_cbd_free,
ril_ussd_cbd_new(cb, data));
}
static void ril_ussd_notify(GRilIoChannel *io, guint code,
@@ -128,32 +127,32 @@ static void ril_ussd_notify(GRilIoChannel *io, guint code,
{
struct ril_ussd *ud = user_data;
GRilIoParser rilp;
char *ussd_from_network = NULL;
char *type = NULL;
int ussdtype = 0;
char *type;
guint32 n = 0;
ofono_info("ussd_received");
ofono_info("ussd received");
GASSERT(code == RIL_UNSOL_ON_USSD);
grilio_parser_init(&rilp, data, len);
grilio_parser_get_uint32(&rilp, NULL);
grilio_parser_get_uint32(&rilp, &n);
type = grilio_parser_get_utf8(&rilp);
ussd_from_network = grilio_parser_get_utf8(&rilp);
ussdtype = g_ascii_xdigit_value(*type);
if (type) {
int ussdtype = g_ascii_xdigit_value(*type);
char *msg = (n > 1) ? grilio_parser_get_utf8(&rilp) : NULL;
if (ussd_from_network) {
const int data_len = strlen(ussd_from_network);
DBG("ussd_received, length %d", data_len);
ofono_ussd_notify(ud->ussd, ussdtype, 0xFF,
(const unsigned char *) ussd_from_network, data_len);
} else {
ofono_ussd_notify(ud->ussd, ussdtype, 0, NULL, 0);
if (msg) {
const int msglen = strlen(msg);
DBG("ussd length %d", msglen);
ofono_ussd_notify(ud->ussd, ussdtype, 0xFF,
(const unsigned char *)msg, msglen);
/* msg is freed by core if dcs is 0xFF */
} else {
ofono_ussd_notify(ud->ussd, ussdtype, 0, NULL, 0);
}
g_free(type);
}
/* ussd_from_network not freed because core does that if dcs is 0xFF */
g_free(type);
return;
}
static gboolean ril_ussd_register(gpointer user_data)
@@ -170,7 +169,7 @@ static gboolean ril_ussd_register(gpointer user_data)
ril_ussd_notify, RIL_UNSOL_ON_USSD, ud);
/* Single-shot */
return FALSE;
return G_SOURCE_REMOVE;
}
static int ril_ussd_probe(struct ofono_ussd *ussd, unsigned int vendor,

View File

@@ -32,9 +32,12 @@ gboolean ril_parse_mcc_mnc(const char *str, struct ofono_network_operator *op);
((err)->error = 0, (err)->type = OFONO_ERROR_TYPE_NO_ERROR)
#define ril_error_init_failure(err) \
((err)->error = 0, (err)->type = OFONO_ERROR_TYPE_FAILURE)
#define ril_error_init_sim_error(err,sw1,sw2) \
((err)->error = ((sw1) << 8)|(sw2), (err)->type = OFONO_ERROR_TYPE_SIM)
#define ril_error_ok(err) (ril_error_init_ok(err), err)
#define ril_error_failure(err) (ril_error_init_failure(err), err)
#define ril_error_sim(err,sw1,sw2) (ril_error_init_sim_error(err,sw1,sw2), err)
#endif /* RIL_UTIL_H */

View File

@@ -21,9 +21,9 @@
#include "common.h"
/* Amount of ms we wait between CLCC calls */
#include <gutil_ring.h>
#define FLAG_NEED_CLIP 1
#define MAX_DTMF_BUFFER 32
enum ril_voicecall_events {
VOICECALL_EVENT_CALL_STATE_CHANGED,
@@ -43,7 +43,7 @@ struct ril_voicecall {
ofono_voicecall_cb_t cb;
void *data;
guint timer_id;
gchar *tone_queue;
GUtilRing* dtmf_queue;
guint send_dtmf_id;
guint clcc_poll_id;
gulong event_id[VOICECALL_EVENT_COUNT];
@@ -596,11 +596,6 @@ static void ril_voicecall_send_dtmf_cb(GRilIoChannel *io, int status,
vd->send_dtmf_id = 0;
if (status == RIL_E_SUCCESS) {
/* Remove sent DTMF character from queue */
gchar *tmp = g_strdup(vd->tone_queue + 1);
g_free(vd->tone_queue);
vd->tone_queue = tmp;
/* Send the next one */
ril_voicecall_send_one_dtmf(vd);
} else {
@@ -611,12 +606,15 @@ static void ril_voicecall_send_dtmf_cb(GRilIoChannel *io, int status,
static void ril_voicecall_send_one_dtmf(struct ril_voicecall *vd)
{
if (!vd->send_dtmf_id && vd->tone_queue && vd->tone_queue[0]) {
if (!vd->send_dtmf_id && gutil_ring_size(vd->dtmf_queue) > 0) {
GRilIoRequest *req = grilio_request_sized_new(4);
const char dtmf_char = (char)
GPOINTER_TO_UINT(gutil_ring_get(vd->dtmf_queue));
/* RIL wants just one character */
DBG("%c", vd->tone_queue[0]);
grilio_request_append_utf8_chars(req, vd->tone_queue, 1);
GASSERT(dtmf_char);
DBG("%c", dtmf_char);
grilio_request_append_utf8_chars(req, &dtmf_char, 1);
vd->send_dtmf_id = grilio_queue_send_request_full(vd->q, req,
RIL_REQUEST_DTMF, ril_voicecall_send_dtmf_cb, NULL, vd);
grilio_request_unref(req);
@@ -629,43 +627,34 @@ static void ril_voicecall_send_dtmf(struct ofono_voicecall *vc,
struct ril_voicecall *vd = ril_voicecall_get_data(vc);
struct ofono_error error;
DBG("Queue '%s'",dtmf);
/*
* Queue any incoming DTMF (up to MAX_DTMF_BUFFER characters),
* send them to RIL one-by-one, immediately call back
* core with no error
* Queue any incoming DTMF, send them to RIL one-by-one,
* immediately call back core with no error
*/
g_strlcat(vd->tone_queue, dtmf, MAX_DTMF_BUFFER);
ril_voicecall_send_one_dtmf(vd);
DBG("Queue '%s'", dtmf);
while (*dtmf) {
gutil_ring_put(vd->dtmf_queue, GUINT_TO_POINTER(*dtmf));
dtmf++;
}
ril_voicecall_send_one_dtmf(vd);
cb(ril_error_ok(&error), data);
}
static void ril_voicecall_clear_dtmf_queue(struct ril_voicecall *vd)
{
g_free(vd->tone_queue);
vd->tone_queue = g_strnfill(MAX_DTMF_BUFFER + 1, '\0');
gutil_ring_clear(vd->dtmf_queue);
if (vd->send_dtmf_id) {
grilio_channel_cancel_request(vd->io, vd->send_dtmf_id, FALSE);
vd->send_dtmf_id = 0;
}
}
static void ril_voicecall_clcc_poll_on_success(GRilIoChannel *io,
int status, const void *data, guint len, void *user_data)
{
if (status == RIL_E_SUCCESS) {
ril_voicecall_clcc_poll((struct ril_voicecall *)user_data);
}
}
static void ril_voicecall_create_multiparty(struct ofono_voicecall *vc,
ofono_voicecall_cb_t cb, void *data)
{
struct ril_voicecall *vd = ril_voicecall_get_data(vc);
grilio_queue_send_request_full(vd->q, NULL, RIL_REQUEST_CONFERENCE,
ril_voicecall_clcc_poll_on_success, NULL, vd);
ril_voicecall_request(RIL_REQUEST_CONFERENCE,
vc, 0, NULL, cb, data);
}
static void ril_voicecall_transfer(struct ofono_voicecall *vc,
@@ -678,14 +667,17 @@ static void ril_voicecall_transfer(struct ofono_voicecall *vc,
static void ril_voicecall_private_chat(struct ofono_voicecall *vc, int id,
ofono_voicecall_cb_t cb, void *data)
{
struct ril_voicecall *vd = ril_voicecall_get_data(vc);
GRilIoRequest *req = grilio_request_sized_new(8);
struct ofono_error error;
DBG("Private chat with id %d", id);
grilio_request_append_int32(req, 1);
grilio_request_append_int32(req, id);
grilio_queue_send_request_full(vd->q, req,
RIL_REQUEST_SEPARATE_CONNECTION,
ril_voicecall_clcc_poll_on_success, NULL, vd);
ril_voicecall_request(RIL_REQUEST_SEPARATE_CONNECTION,
vc, 0, req, NULL, NULL);
grilio_request_unref(req);
cb(ril_error_ok(&error), data);
}
static void ril_voicecall_swap_without_accept(struct ofono_voicecall *vc,
@@ -817,6 +809,7 @@ static int ril_voicecall_probe(struct ofono_voicecall *vc, unsigned int vendor,
vd = g_new0(struct ril_voicecall, 1);
vd->io = grilio_channel_ref(ril_modem_io(modem));
vd->q = grilio_queue_new(vd->io);
vd->dtmf_queue = gutil_ring_new();
vd->vc = vc;
vd->timer_id = g_idle_add(ril_delayed_register, vd);
if (modem->ecclist_file) {
@@ -847,7 +840,7 @@ static void ril_voicecall_remove(struct ofono_voicecall *vc)
grilio_channel_unref(vd->io);
grilio_queue_cancel_all(vd->q, FALSE);
grilio_queue_unref(vd->q);
g_free(vd->tone_queue);
gutil_ring_unref(vd->dtmf_queue);
g_free(vd);
}

View File

@@ -3,7 +3,7 @@
* oFono - Open Telephony stack for Linux
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2013-2016 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
@@ -61,7 +61,6 @@ extern "C" {
#define OFONO_GNSS_POSR_AGENT_INTERFACE "org.ofono.PositioningRequestAgent"
#define OFONO_HANDSFREE_INTERFACE OFONO_SERVICE ".Handsfree"
#define OFONO_NETWORK_TIME_INTERFACE OFONO_SERVICE ".NetworkTime"
#define OFONO_OEM_RAW_INTERFACE "org.ofono.OemRaw"
#define OFONO_SIRI_INTERFACE OFONO_SERVICE ".Siri"
/* CDMA Interfaces */

View File

@@ -3,6 +3,7 @@
* oFono - Open Telephony stack for Linux
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013-2016 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
@@ -22,6 +23,8 @@
#ifndef __OFONO_LOG_H
#define __OFONO_LOG_H
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -50,6 +53,7 @@ struct ofono_debug_desc {
const char *file;
#define OFONO_DEBUG_FLAG_DEFAULT (0)
#define OFONO_DEBUG_FLAG_PRINT (1 << 0)
#define OFONO_DEBUG_FLAG_HIDE_NAME (1 << 1)
unsigned int flags;
void (*notify)(struct ofono_debug_desc* desc);
} __attribute__((aligned(OFONO_DEBUG_ALIGN)));
@@ -67,10 +71,20 @@ struct ofono_debug_desc {
.file = __FILE__, .flags = OFONO_DEBUG_FLAG_DEFAULT, \
}; \
if (__ofono_debug_desc.flags & OFONO_DEBUG_FLAG_PRINT) \
ofono_debug("%s:%s() " fmt, \
__FILE__, __FUNCTION__ , ## arg); \
__ofono_dbg(&__ofono_debug_desc, "%s() " fmt, \
__FUNCTION__ , ## arg); \
} while (0)
void __ofono_dbg(const struct ofono_debug_desc *desc, const char *format, ...)
__attribute__((format(printf, 2, 3)));
typedef void (*ofono_log_hook_cb_t)(const struct ofono_debug_desc *desc,
int priority, const char *format, va_list va);
extern ofono_log_hook_cb_t ofono_log_hook;
extern struct ofono_debug_desc __start___debug[];
extern struct ofono_debug_desc __stop___debug[];
#ifdef __cplusplus
}
#endif

View File

@@ -1,77 +0,0 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2013 Jolla Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __OFONO_OEM_RAW_H
#define __OFONO_OEM_RAW_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <dbus/dbus.h>
#include <ofono/types.h>
struct ofono_oem_raw;
/* Request response from driver to core */
struct ofono_oem_raw_results {
char *data;
int length;
};
/* Request details from core to driver */
struct ofono_oem_raw_request {
char *data;
int length; /* Number of bytes in data */
DBusMessage *pending;
};
typedef void (*ofono_oem_raw_query_cb_t)(const struct ofono_error *error,
const struct ofono_oem_raw_results *results, void *data);
struct ofono_oem_raw_driver {
const char *name;
int (*probe)(struct ofono_oem_raw *raw,
unsigned int vendor,
void *data);
void (*remove)(struct ofono_oem_raw *raw);
void (*request)(struct ofono_oem_raw *raw,
const struct ofono_oem_raw_request *request,
ofono_oem_raw_query_cb_t cb,
void *data);
};
struct ofono_oem_raw *ofono_oem_raw_create(struct ofono_modem *modem,
unsigned int vendor,
const char *driver,
void *data);
void ofono_oem_raw_dbus_register(struct ofono_oem_raw *raw);
void ofono_oem_raw_remove(struct ofono_oem_raw *raw);
int ofono_oem_raw_driver_register(struct ofono_oem_raw_driver *driver);
void ofono_oem_raw_driver_unregister(struct ofono_oem_raw_driver *driver);
void *ofono_oem_raw_get_data(struct ofono_oem_raw *raw);
void ofono_oem_raw_set_data(struct ofono_oem_raw *raw, void *cid);
#ifdef __cplusplus
}
#endif
#endif /* __OFONO_OEM_RAW_H */

View File

@@ -123,8 +123,8 @@ typedef void (*ofono_sim_pin_retries_cb_t)(const struct ofono_error *error,
typedef void (*ofono_sim_lock_unlock_cb_t)(const struct ofono_error *error,
void *data);
typedef void (*ofono_sim_locked_cb_t)(const struct ofono_error *error,
int locked, void *data);
typedef void (*ofono_query_facility_lock_cb_t)(const struct ofono_error *error,
ofono_bool_t status, void *data);
struct ofono_sim_driver {
const char *name;
@@ -175,9 +175,9 @@ struct ofono_sim_driver {
void (*lock)(struct ofono_sim *sim, enum ofono_sim_password_type type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data);
void (*query_locked)(struct ofono_sim *sim,
enum ofono_sim_password_type type,
ofono_sim_locked_cb_t cb, void *data);
void (*query_facility_lock)(struct ofono_sim *sim,
enum ofono_sim_password_type lock,
ofono_query_facility_lock_cb_t cb, void *data);
};
int ofono_sim_driver_register(const struct ofono_sim_driver *d);

View File

@@ -2,7 +2,7 @@
*
* oFono - Open Source Telephony
*
* Copyright (C) 2015 Jolla Ltd. All rights reserved.
* Copyright (C) 2015-2016 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -13,49 +13,148 @@
* 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 <gdbus.h>
#include <string.h>
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/plugin.h>
#include <ofono/dbus.h>
#include <ofono/log.h>
#include <ofono.h>
#define DEBUGLOG_INTERFACE OFONO_SERVICE ".DebugLog"
#define DEBUGLOG_PATH "/"
#define DEBUGLOG_CHANGED_SIGNAL "Changed"
#include <dbuslog_server_dbus.h>
#include <gutil_log.h>
static DBusConnection *connection = NULL;
#include <string.h>
#include <syslog.h>
extern struct ofono_debug_desc __start___debug[];
extern struct ofono_debug_desc __stop___debug[];
#define DEBUGLOG_PATH "/"
static void debuglog_signal(DBusConnection *conn, const char *name,
guint flags)
enum _debug_server_event {
DEBUG_EVENT_CATEGORY_ENABLED,
DEBUG_EVENT_CATEGORY_DISABLED,
DEBUG_EVENT_COUNT
};
static DBusLogServer *debuglog_server;
static GLogProc2 debuglog_default_log_proc;
static gulong debuglog_event_id[DEBUG_EVENT_COUNT];
static void debuglog_ofono_log_hook(const struct ofono_debug_desc *desc,
int priority, const char *format, va_list va)
{
DBusMessage *signal = dbus_message_new_signal(DEBUGLOG_PATH,
DEBUGLOG_INTERFACE, DEBUGLOG_CHANGED_SIGNAL);
DBUSLOG_LEVEL dbuslevel;
const char *category;
if (signal) {
DBusMessageIter iter;
const dbus_bool_t on = (flags & OFONO_DEBUG_FLAG_PRINT) != 0;
dbus_message_iter_init_append(signal, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &on);
g_dbus_send_message(conn, signal);
if (desc) {
category = desc->name ? desc->name : desc->file;
} else {
category = NULL;
}
/* ofono is only using these four priorities: */
switch (priority) {
case LOG_ERR:
dbuslevel = DBUSLOG_LEVEL_ERROR;
break;
case LOG_WARNING:
dbuslevel = DBUSLOG_LEVEL_WARNING;
break;
case LOG_INFO:
dbuslevel = DBUSLOG_LEVEL_INFO;
break;
case LOG_DEBUG:
dbuslevel = DBUSLOG_LEVEL_DEBUG;
break;
default:
dbuslevel = DBUSLOG_LEVEL_UNDEFINED;
break;
}
dbus_log_server_logv(debuglog_server, dbuslevel, category, format, va);
}
static void debuglog_gutil_log_func(const GLogModule* log, int level,
const char* format, va_list va)
{
DBUSLOG_LEVEL loglevel;
switch (level) {
case GLOG_LEVEL_ERR:
loglevel = DBUSLOG_LEVEL_ERROR;
break;
case GLOG_LEVEL_WARN:
loglevel = DBUSLOG_LEVEL_WARNING;
break;
case GLOG_LEVEL_INFO:
loglevel = DBUSLOG_LEVEL_INFO;
break;
case GLOG_LEVEL_DEBUG:
loglevel = DBUSLOG_LEVEL_DEBUG;
break;
case GLOG_LEVEL_VERBOSE:
loglevel = DBUSLOG_LEVEL_VERBOSE;
break;
default:
loglevel = DBUSLOG_LEVEL_UNDEFINED;
break;
}
dbus_log_server_logv(debuglog_server, loglevel, log->name, format, va);
if (debuglog_default_log_proc) {
debuglog_default_log_proc(log, level, format, va);
}
}
static gboolean debuglog_match(const char* s1, const char* s2)
{
return s1 && s2 && !strcmp(s1, s2);
}
static void debuglog_update_flags(const char* name, guint set, guint clear)
{
const guint flags = set | clear;
struct ofono_debug_desc *start = __start___debug;
struct ofono_debug_desc *stop = __stop___debug;
if (start && stop) {
struct ofono_debug_desc *desc;
for (desc = start; desc < stop; desc++) {
const char *matched = NULL;
if (debuglog_match(desc->file, name)) {
matched = desc->file;
} else if (debuglog_match(desc->name, name)) {
matched = desc->name;
}
if (matched) {
const guint old_flags = (desc->flags & flags);
desc->flags |= set;
desc->flags &= ~clear;
if ((desc->flags & flags) != old_flags &&
desc->notify) {
desc->notify(desc);
}
}
}
}
}
static void debuglog_category_enabled(DBusLogServer* server,
const char* category, gpointer user_data)
{
debuglog_update_flags(category, OFONO_DEBUG_FLAG_PRINT, 0);
}
static void debuglog_category_disabled(DBusLogServer* server,
const char* category, gpointer user_data)
{
debuglog_update_flags(category, 0, OFONO_DEBUG_FLAG_PRINT);
}
static GHashTable *debuglog_update_flags_hash(GHashTable *hash,
@@ -77,197 +176,80 @@ static GHashTable *debuglog_update_flags_hash(GHashTable *hash,
return hash;
}
static gboolean debuglog_match(const char* name, const char* pattern)
static guint debuglog_translate_flags(unsigned int ofono_flags)
{
return name && g_pattern_match_simple(pattern, name);
guint flags = 0;
if (ofono_flags & OFONO_DEBUG_FLAG_PRINT)
flags |= DBUSLOG_CATEGORY_FLAG_ENABLED;
if (ofono_flags & OFONO_DEBUG_FLAG_HIDE_NAME)
flags |= DBUSLOG_CATEGORY_FLAG_HIDE_NAME;
return flags;
}
static void debuglog_update(DBusConnection *conn, const char* pattern,
guint set_flags, guint clear_flags)
{
const guint flags = set_flags | clear_flags;
struct ofono_debug_desc *start = __start___debug;
struct ofono_debug_desc *stop = __stop___debug;
struct ofono_debug_desc *desc;
GHashTable *hash = NULL;
if (!start || !stop)
return;
for (desc = start; desc < stop; desc++) {
const char *matched = NULL;
if (debuglog_match(desc->file, pattern)) {
matched = desc->file;
} else if (debuglog_match(desc->name, pattern)) {
matched = desc->name;
}
if (matched) {
const guint old_flags = (desc->flags & flags);
desc->flags |= set_flags;
desc->flags &= ~clear_flags;
if ((desc->flags & flags) != old_flags) {
hash = debuglog_update_flags_hash(hash,
matched, desc->flags);
if (desc->notify) {
desc->notify(desc);
}
}
}
}
if (hash) {
GList *entry, *names = g_hash_table_get_keys(hash);
for (entry = names; entry; entry = entry->next) {
debuglog_signal(conn, entry->data,
GPOINTER_TO_INT(g_hash_table_lookup(
hash, entry->data)));
}
g_list_free(names);
g_hash_table_destroy(hash);
}
}
static DBusMessage *debuglog_handle(DBusConnection *conn, DBusMessage *msg,
guint set_flags, guint clear_flags)
{
const char *pattern;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
DBUS_TYPE_INVALID)) {
debuglog_update(conn, pattern, set_flags, clear_flags);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
} else {
return __ofono_error_invalid_args(msg);
}
}
static DBusMessage *debuglog_enable(DBusConnection *conn,
DBusMessage *msg, void *data)
{
return debuglog_handle(conn, msg, OFONO_DEBUG_FLAG_PRINT, 0);
}
static DBusMessage *debuglog_disable(DBusConnection *conn,
DBusMessage *msg, void *data)
{
return debuglog_handle(conn, msg, 0, OFONO_DEBUG_FLAG_PRINT);
}
static gint debuglog_list_compare(gconstpointer a, gconstpointer b)
{
return strcmp(a, b);
}
static void debuglog_list_append(DBusMessageIter *iter, const char *name,
guint flags)
{
DBusMessageIter entry;
dbus_bool_t enabled = (flags & OFONO_DEBUG_FLAG_PRINT) != 0;
dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &name);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_BOOLEAN, &enabled);
dbus_message_iter_close_container(iter, &entry);
}
static DBusMessage *debuglog_list(DBusConnection *conn,
DBusMessage *msg, void *data)
{
DBusMessage *reply = dbus_message_new_method_return(msg);
if (reply) {
struct ofono_debug_desc *start = __start___debug;
struct ofono_debug_desc *stop = __stop___debug;
DBusMessageIter iter, array;
dbus_message_iter_init_append(reply, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
"(sb)", &array);
if (start && stop) {
struct ofono_debug_desc *desc;
GList *names, *entry;
GHashTable *hash = g_hash_table_new_full(g_str_hash,
g_str_equal, NULL, NULL);
for (desc = start; desc < stop; desc++) {
debuglog_update_flags_hash(hash, desc->file,
desc->flags);
debuglog_update_flags_hash(hash, desc->name,
desc->flags);
}
names = g_list_sort(g_hash_table_get_keys(hash),
debuglog_list_compare);
for (entry = names; entry; entry = entry->next) {
const char *name = entry->data;
debuglog_list_append(&array, name,
GPOINTER_TO_INT(g_hash_table_lookup(
hash, name)));
}
g_list_free(names);
g_hash_table_destroy(hash);
}
dbus_message_iter_close_container(&iter, &array);
}
return reply;
}
static const GDBusMethodTable debuglog_methods[] = {
{ GDBUS_METHOD("Enable", GDBUS_ARGS({ "pattern", "s" }), NULL,
debuglog_enable) },
{ GDBUS_METHOD("Disable", GDBUS_ARGS({ "pattern", "s" }), NULL,
debuglog_disable) },
{ GDBUS_METHOD("List", NULL, GDBUS_ARGS({ "list", "a(sb)" }),
debuglog_list) },
{ },
};
static const GDBusSignalTable debuglog_signals[] = {
{ GDBUS_SIGNAL(DEBUGLOG_CHANGED_SIGNAL,
GDBUS_ARGS({ "name", "s" }, { "enabled", "b" })) },
{ }
};
static int debuglog_init(void)
{
DBG("");
const struct ofono_debug_desc *start = __start___debug;
const struct ofono_debug_desc *stop = __stop___debug;
connection = ofono_dbus_get_connection();
if (!connection)
return -1;
debuglog_server = dbus_log_server_new(ofono_dbus_get_connection(),
DEBUGLOG_PATH);
if (!g_dbus_register_interface(connection, DEBUGLOG_PATH,
DEBUGLOG_INTERFACE, debuglog_methods, debuglog_signals,
NULL, NULL, NULL)) {
ofono_error("debuglog: failed to register "
DEBUGLOG_INTERFACE);
return -1;
if (start && stop) {
const struct ofono_debug_desc *desc;
GHashTable *hash = NULL;
for (desc = start; desc < stop; desc++) {
const guint f = debuglog_translate_flags(desc->flags);
hash = debuglog_update_flags_hash(hash, desc->file, f);
hash = debuglog_update_flags_hash(hash, desc->name, f);
}
if (hash) {
gpointer key, value;
GHashTableIter it;
g_hash_table_iter_init(&it, hash);
while (g_hash_table_iter_next(&it, &key, &value)) {
dbus_log_server_add_category(debuglog_server,
key, DBUSLOG_LEVEL_UNDEFINED,
GPOINTER_TO_INT(value));
}
g_hash_table_destroy(hash);
}
debuglog_event_id[DEBUG_EVENT_CATEGORY_ENABLED] =
dbus_log_server_add_category_enabled_handler(
debuglog_server, debuglog_category_enabled,
NULL);
debuglog_event_id[DEBUG_EVENT_CATEGORY_DISABLED] =
dbus_log_server_add_category_disabled_handler(
debuglog_server, debuglog_category_disabled,
NULL);
}
debuglog_default_log_proc = gutil_log_func2;
gutil_log_func2 = debuglog_gutil_log_func;
ofono_log_hook = debuglog_ofono_log_hook;
dbus_log_server_set_default_level(debuglog_server, DBUSLOG_LEVEL_DEBUG);
dbus_log_server_start(debuglog_server);
return 0;
}
static void debuglog_exit(void)
{
DBG("");
if (connection) {
g_dbus_unregister_interface(connection, DEBUGLOG_PATH,
DEBUGLOG_INTERFACE);
dbus_connection_unref(connection);
connection = NULL;
}
gutil_log_func2 = debuglog_default_log_proc;
dbus_log_server_remove_handlers(debuglog_server, debuglog_event_id,
G_N_ELEMENTS(debuglog_event_id));
dbus_log_server_unref(debuglog_server);
debuglog_server = NULL;
}
OFONO_PLUGIN_DEFINE(debuglog, "Debug log control interface",
OFONO_PLUGIN_DEFINE(debuglog, "Debug log interface",
VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
debuglog_init, debuglog_exit)

View File

@@ -44,6 +44,16 @@
#include "mbpi.h"
const char *mbpi_database = MBPI_DATABASE;
/*
* Use IPv4 for MMS contexts because gprs.c assumes that MMS proxy
* address is IPv4.
*/
enum ofono_gprs_proto mbpi_default_internet_proto = OFONO_GPRS_PROTO_IPV4V6;
enum ofono_gprs_proto mbpi_default_mms_proto = OFONO_GPRS_PROTO_IP;
enum ofono_gprs_proto mbpi_default_proto = OFONO_GPRS_PROTO_IP;
#define _(x) case x: return (#x)
enum MBPI_ERROR {
@@ -111,7 +121,7 @@ static void mbpi_g_set_error(GMarkupParseContext *context, GError **error,
va_end(ap);
g_prefix_error(error, "%s:%d ", MBPI_DATABASE, line_number);
g_prefix_error(error, "%s:%d ", mbpi_database, line_number);
}
static void text_handler(GMarkupParseContext *context,
@@ -120,7 +130,7 @@ static void text_handler(GMarkupParseContext *context,
{
char **string = userdata;
g_free(*string);
g_free(*string);
*string = g_strndup(text, text_len);
}
@@ -166,7 +176,7 @@ static void authentication_start(GMarkupParseContext *context,
static void usage_start(GMarkupParseContext *context,
const gchar **attribute_names,
const gchar **attribute_values,
enum ofono_gprs_context_type *type, GError **error)
struct ofono_gprs_provision_data *apn, GError **error)
{
const char *text = NULL;
int i;
@@ -182,12 +192,14 @@ static void usage_start(GMarkupParseContext *context,
return;
}
if (strcmp(text, "internet") == 0)
*type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
else if (strcmp(text, "mms") == 0)
*type = OFONO_GPRS_CONTEXT_TYPE_MMS;
else if (strcmp(text, "wap") == 0)
*type = OFONO_GPRS_CONTEXT_TYPE_WAP;
if (strcmp(text, "internet") == 0) {
apn->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
apn->proto = mbpi_default_internet_proto;
} else if (strcmp(text, "mms") == 0) {
apn->type = OFONO_GPRS_CONTEXT_TYPE_MMS;
apn->proto = mbpi_default_mms_proto;
} else if (strcmp(text, "wap") == 0)
apn->type = OFONO_GPRS_CONTEXT_TYPE_WAP;
else
mbpi_g_set_error(context, error, G_MARKUP_ERROR,
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
@@ -220,7 +232,7 @@ static void apn_start(GMarkupParseContext *context, const gchar *element_name,
&apn->message_proxy);
else if (g_str_equal(element_name, "usage"))
usage_start(context, attribute_names, attribute_values,
&apn->type, error);
apn, error);
}
static void apn_end(GMarkupParseContext *context, const gchar *element_name,
@@ -331,7 +343,7 @@ static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
ap->apn = g_strdup(apn);
ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
ap->proto = OFONO_GPRS_PROTO_IP;
ap->proto = mbpi_default_proto;
ap->auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;
g_markup_parse_context_push(context, &apn_parser, ap);
@@ -611,11 +623,11 @@ static gboolean mbpi_parse(const GMarkupParser *parser, gpointer userdata,
GMarkupParseContext *context;
gboolean ret;
fd = open(MBPI_DATABASE, O_RDONLY);
fd = open(mbpi_database, O_RDONLY);
if (fd < 0) {
g_set_error(error, G_FILE_ERROR,
g_file_error_from_errno(errno),
"open(%s) failed: %s", MBPI_DATABASE,
"open(%s) failed: %s", mbpi_database,
g_strerror(errno));
return FALSE;
}
@@ -624,7 +636,7 @@ static gboolean mbpi_parse(const GMarkupParser *parser, gpointer userdata,
close(fd);
g_set_error(error, G_FILE_ERROR,
g_file_error_from_errno(errno),
"fstat(%s) failed: %s", MBPI_DATABASE,
"fstat(%s) failed: %s", mbpi_database,
g_strerror(errno));
return FALSE;
}
@@ -634,7 +646,7 @@ static gboolean mbpi_parse(const GMarkupParser *parser, gpointer userdata,
close(fd);
g_set_error(error, G_FILE_ERROR,
g_file_error_from_errno(errno),
"mmap(%s) failed: %s", MBPI_DATABASE,
"mmap(%s) failed: %s", mbpi_database,
g_strerror(errno));
return FALSE;
}

View File

@@ -19,6 +19,11 @@
*
*/
extern const char *mbpi_database;
extern enum ofono_gprs_proto mbpi_default_internet_proto;
extern enum ofono_gprs_proto mbpi_default_mms_proto;
extern enum ofono_gprs_proto mbpi_default_proto;
const char *mbpi_ap_type(enum ofono_gprs_context_type type);
void mbpi_ap_free(struct ofono_gprs_provision_data *data);

View File

@@ -3,7 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2013-2016 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,7 @@ static gint provision_compare_ap(gconstpointer a, gconstpointer b, gpointer data
/* Picks best ap, deletes the rest. Creates one if necessary */
static GSList *provision_pick_best_ap(GSList *list, const char* spn,
const enum ofono_gprs_proto default_proto,
const struct provision_ap_defaults *defaults)
{
/* Sort the list */
@@ -101,6 +102,7 @@ static GSList *provision_pick_best_ap(GSList *list, const char* spn,
struct ofono_gprs_provision_data *ap =
g_new0(struct ofono_gprs_provision_data, 1);
ap->proto = default_proto;
ap->type = defaults->type;
ap->name = g_strdup(defaults->name);
ap->apn = g_strdup(defaults->apn);
@@ -136,8 +138,10 @@ static GSList *provision_normalize_apn_list(GSList *apns, const char* spn)
/* Pick the best ap of each type and concatenate them */
return g_slist_concat(
provision_pick_best_ap(internet_apns, spn, &internet_defaults),
provision_pick_best_ap(mms_apns, spn, &mms_defaults));
provision_pick_best_ap(internet_apns, spn,
mbpi_default_internet_proto, &internet_defaults),
provision_pick_best_ap(mms_apns, spn,
mbpi_default_mms_proto, &mms_defaults));
}
int provision_get_settings(const char *mcc, const char *mnc,

View File

@@ -60,6 +60,7 @@ struct ofono_call_forwarding {
GSList *cf_conditions[4];
int flags;
DBusMessage *pending;
GSList *pending_get_prop;
int query_next;
int query_end;
struct cf_ss_request *ss_req;
@@ -529,6 +530,14 @@ static DBusMessage *cf_get_properties_reply(DBusMessage *msg,
return reply;
}
static void cf_send_properties(gpointer data, gpointer user_data)
{
DBusMessage *msg = data;
DBusMessage *reply = cf_get_properties_reply(msg, user_data);
__ofono_dbus_pending_reply(&msg, reply);
}
static void get_query_cf_callback(const struct ofono_error *error, int total,
const struct ofono_call_forwarding_condition *list,
void *data)
@@ -549,8 +558,9 @@ static void get_query_cf_callback(const struct ofono_error *error, int total,
}
if (cf->query_next == CALL_FORWARDING_TYPE_NOT_REACHABLE) {
__ofono_dbus_pending_reply(&cf->pending,
cf_get_properties_reply(cf->pending, cf));
g_slist_foreach(cf->pending_get_prop, cf_send_properties, cf);
g_slist_free(cf->pending_get_prop);
cf->pending_get_prop = NULL;
return;
}
@@ -577,11 +587,18 @@ static DBusMessage *cf_get_properties(DBusConnection *conn, DBusMessage *msg,
if (cf->driver->query == NULL)
return __ofono_error_not_implemented(msg);
if (cf->pending_get_prop) {
/* GetProperties is already in progress */
cf->pending_get_prop = g_slist_append(cf->pending_get_prop,
dbus_message_ref(msg));
return NULL;
}
if (__ofono_call_forwarding_is_busy(cf) ||
__ofono_ussd_is_busy(cf->ussd))
return __ofono_error_busy(msg);
cf->pending = dbus_message_ref(msg);
cf->pending_get_prop = g_slist_append(NULL, dbus_message_ref(msg));
cf->query_next = 0;
get_query_next_cf_cond(cf);
@@ -1268,7 +1285,7 @@ static void cf_unregister_ss_controls(struct ofono_call_forwarding *cf)
gboolean __ofono_call_forwarding_is_busy(struct ofono_call_forwarding *cf)
{
return cf->pending ? TRUE : FALSE;
return cf->pending || cf->pending_get_prop;
}
static void sim_cfis_read_cb(int ok, int total_length, int record,
@@ -1378,6 +1395,13 @@ static void sim_cphs_cff_read_cb(int ok, int total_length, int record,
DBUS_TYPE_BOOLEAN, &cfu_voice);
}
static void cf_cancel_get_prop(gpointer data)
{
DBusMessage *msg = data;
__ofono_dbus_pending_reply(&msg, __ofono_error_canceled(msg));
}
static void call_forwarding_unregister(struct ofono_atom *atom)
{
struct ofono_call_forwarding *cf = __ofono_atom_get_data(atom);
@@ -1385,6 +1409,11 @@ static void call_forwarding_unregister(struct ofono_atom *atom)
DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_modem *modem = __ofono_atom_get_modem(cf->atom);
if (cf->pending_get_prop) {
g_slist_free_full(cf->pending_get_prop, cf_cancel_get_prop);
cf->pending_get_prop = NULL;
}
ofono_modem_remove_interface(modem, OFONO_CALL_FORWARDING_INTERFACE);
g_dbus_unregister_interface(conn, path,
OFONO_CALL_FORWARDING_INTERFACE);

View File

@@ -135,6 +135,7 @@ struct pri_context {
struct ofono_gprs *gprs;
};
static void gprs_attached_update(struct ofono_gprs *gprs);
static void gprs_netreg_update(struct ofono_gprs *gprs);
static void gprs_deactivate_next(struct ofono_gprs *gprs);
static void write_context_settings(struct ofono_gprs *gprs,
@@ -1133,6 +1134,16 @@ static void pri_deactivate_callback(const struct ofono_error *error, void *data)
ofono_dbus_signal_property_changed(conn, ctx->path,
OFONO_CONNECTION_CONTEXT_INTERFACE,
"Active", DBUS_TYPE_BOOLEAN, &value);
/*
* If "Attached" property was about to be signalled as TRUE but there
* were still active contexts, try again to signal "Attached" property
* to registered applications after active contexts have been released.
*/
if (ctx->gprs->flags & GPRS_FLAG_ATTACHED_UPDATE) {
ctx->gprs->flags &= ~GPRS_FLAG_ATTACHED_UPDATE;
gprs_attached_update(ctx->gprs);
}
}
static DBusMessage *pri_set_apn(struct pri_context *ctx, DBusConnection *conn,

View File

@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013-2016 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
@@ -37,6 +38,9 @@
#include "ofono.h"
ofono_log_hook_cb_t ofono_log_hook;
static GString *ofono_debug_str;
static const char *program_exec;
static const char *program_path;
@@ -56,6 +60,12 @@ void ofono_info(const char *format, ...)
vsyslog(LOG_INFO, format, ap);
va_end(ap);
if (ofono_log_hook) {
va_start(ap, format);
ofono_log_hook(NULL, LOG_INFO, format, ap);
va_end(ap);
}
}
/**
@@ -74,6 +84,12 @@ void ofono_warn(const char *format, ...)
vsyslog(LOG_WARNING, format, ap);
va_end(ap);
if (ofono_log_hook) {
va_start(ap, format);
ofono_log_hook(NULL, LOG_WARNING, format, ap);
va_end(ap);
}
}
/**
@@ -92,6 +108,12 @@ void ofono_error(const char *format, ...)
vsyslog(LOG_ERR, format, ap);
va_end(ap);
if (ofono_log_hook) {
va_start(ap, format);
ofono_log_hook(NULL, LOG_ERR, format, ap);
va_end(ap);
}
}
/**
@@ -113,6 +135,37 @@ void ofono_debug(const char *format, ...)
vsyslog(LOG_DEBUG, format, ap);
va_end(ap);
if (ofono_log_hook) {
va_start(ap, format);
ofono_log_hook(NULL, LOG_DEBUG, format, ap);
va_end(ap);
}
}
void __ofono_dbg(const struct ofono_debug_desc *desc, const char *format, ...)
{
va_list ap;
if (!(desc->flags & OFONO_DEBUG_FLAG_PRINT))
return;
va_start(ap, format);
if (ofono_debug_str) {
g_string_vprintf(ofono_debug_str, format, ap);
syslog(LOG_DEBUG, "%s:%s", desc->file, ofono_debug_str->str);
} else {
vsyslog(LOG_DEBUG, format, ap);
}
va_end(ap);
if (ofono_log_hook) {
va_start(ap, format);
ofono_log_hook(desc, LOG_DEBUG, format, ap);
va_end(ap);
}
}
#ifdef __GLIBC__
@@ -306,6 +359,7 @@ int __ofono_log_init(const char *program, const char *debug,
program_exec = program;
program_path = getcwd(path, sizeof(path));
ofono_debug_str = g_string_sized_new(127);
if (debug != NULL)
enabled = g_strsplit_set(debug, ":, ", 0);
@@ -339,4 +393,6 @@ void __ofono_log_cleanup(ofono_bool_t backtrace)
#endif
g_strfreev(enabled);
g_string_free(ofono_debug_str, TRUE);
ofono_debug_str = NULL;
}

View File

@@ -1326,7 +1326,7 @@ void ofono_modem_remove_interface(struct ofono_modem *modem,
found = g_slist_find_custom(modem->interface_list, interface,
(GCompareFunc) strcmp);
if (found == NULL) {
ofono_error("Interface %s not found on the interface_list",
DBG("Interface %s not found on the interface_list",
interface);
return;
}

View File

@@ -1,265 +0,0 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2013 Jolla Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <errno.h>
#include <glib.h>
#include <gdbus.h>
#include <dbus/dbus.h>
#include "ofono.h"
#include "common.h"
#include "ofono/oemraw.h"
static GSList *g_drivers;
struct ofono_oem_raw {
struct ofono_atom *atom;
const struct ofono_oem_raw_driver *driver;
void *driver_data;
};
static void ofono_oem_raw_query_cb(const struct ofono_error *error,
const struct ofono_oem_raw_results *res, void *data)
{
char *ptr;
char byte;
int i;
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter subiter;
struct ofono_oem_raw_request *req = data;
if (error && error->type == OFONO_ERROR_TYPE_NO_ERROR) {
reply = dbus_message_new_method_return(req->pending);
} else {
/*
* Log error messages in driver when completing a request,
* logging here provides no extra information.
*/
goto error;
}
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
"y", &subiter)) {
DBG("Failed to open a dbus iterator");
goto error;
}
ptr = (char *)res->data;
for (i = 0; i < res->length; i++) {
byte = ptr[i];
dbus_message_iter_append_basic(&subiter, DBUS_TYPE_BYTE,
&byte);
}
dbus_message_iter_close_container(&iter, &subiter);
goto end;
error:
reply = __ofono_error_failed(req->pending);
end:
__ofono_dbus_pending_reply(&req->pending, reply);
g_free(req);
return;
}
static DBusMessage *oem_raw_make_request(DBusConnection *conn,
DBusMessage *msg, void *data)
{
char *array; /* Byte array containing client request*/
int array_len; /* Length of request byte array */
DBusMessageIter iter;
DBusMessageIter subiter;
struct ofono_oem_raw_request *req;
struct ofono_oem_raw *raw;
raw = data;
req = 0;
if (raw && raw->driver->request == NULL)
return __ofono_error_not_implemented(msg);
dbus_message_iter_init(msg, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
goto error_arg;
if (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) {
DBG("Ignoring request because dbus request element type=%c",
dbus_message_iter_get_element_type(&iter));
goto error_arg;
}
dbus_message_iter_recurse(&iter, &subiter);
dbus_message_iter_get_fixed_array(&subiter, &array, &array_len);
req = g_new0(struct ofono_oem_raw_request, 1);
req->data = array;
req->length = array_len;
/* Store msg to request struct to allow multiple parallel requests */
req->pending = dbus_message_ref(msg);
raw->driver->request(raw, req, ofono_oem_raw_query_cb, req);
return NULL;
error_arg:
DBG("DBus arg type=%c, msg signature: %s",
dbus_message_iter_get_arg_type(&iter),
dbus_message_get_signature(msg));
return __ofono_error_invalid_args(msg);
}
static const GDBusMethodTable oem_raw_methods[] = {
{ GDBUS_ASYNC_METHOD("Send",
GDBUS_ARGS({ "req", "ay" }),
GDBUS_ARGS({ "response", "ay"}),
oem_raw_make_request) },
{ }
};
static const GDBusSignalTable oem_raw_signals[] = {
{ }
};
static void oem_raw_dbus_unregister(struct ofono_atom *atom)
{
DBG("");
struct ofono_oem_raw *oemraw = __ofono_atom_get_data(atom);
const char *path = __ofono_atom_get_path(oemraw->atom);
DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_modem *modem = __ofono_atom_get_modem(oemraw->atom);
ofono_modem_remove_interface(modem, OFONO_OEM_RAW_INTERFACE);
if (!g_dbus_unregister_interface(conn, path, OFONO_OEM_RAW_INTERFACE))
ofono_error("Failed to unregister interface %s",
OFONO_OEM_RAW_INTERFACE);
}
void ofono_oem_raw_dbus_register(struct ofono_oem_raw *oemraw)
{
DBusConnection *conn;
DBG("");
conn = ofono_dbus_get_connection();
struct ofono_modem *modem = __ofono_atom_get_modem(oemraw->atom);
const char *path = __ofono_atom_get_path(oemraw->atom);
if (!g_dbus_register_interface(conn, path,
OFONO_OEM_RAW_INTERFACE,
oem_raw_methods,
oem_raw_signals,
NULL, oemraw, NULL)) {
ofono_error("Could not create interface %s",
OFONO_OEM_RAW_INTERFACE);
return;
}
ofono_modem_add_interface(modem, OFONO_OEM_RAW_INTERFACE);
__ofono_atom_register(oemraw->atom, oem_raw_dbus_unregister);
}
int ofono_oem_raw_driver_register(struct ofono_oem_raw_driver *driver)
{
if (driver->probe == NULL)
return -EINVAL;
g_drivers = g_slist_prepend(g_drivers, (void *) driver);
return 0;
}
void ofono_oem_raw_driver_unregister(struct ofono_oem_raw_driver *driver)
{
g_drivers = g_slist_remove(g_drivers, (void *) driver);
}
void ofono_oem_raw_remove(struct ofono_oem_raw *oemraw)
{
__ofono_atom_free(oemraw->atom);
}
void *ofono_oem_raw_get_data(struct ofono_oem_raw *raw)
{
return raw->driver_data;
}
void ofono_oem_raw_set_data(struct ofono_oem_raw *raw, void *cid)
{
raw->driver_data = cid;
}
static void oem_raw_remove(struct ofono_atom *atom)
{
struct ofono_oem_raw *oemraw = __ofono_atom_get_data(atom);
if (oemraw == NULL)
return;
if (oemraw->driver && oemraw->driver->remove)
oemraw->driver->remove(oemraw);
g_free(oemraw);
}
struct ofono_oem_raw *ofono_oem_raw_create(struct ofono_modem *modem,
unsigned int vendor,
const char *driver,
void *data)
{
struct ofono_oem_raw *oemraw = 0;
GSList *l;
if (driver == NULL)
return NULL;
oemraw = g_try_new0(struct ofono_oem_raw, 1);
if (oemraw == NULL)
return NULL;
oemraw->atom = __ofono_modem_add_atom(modem,
OFONO_ATOM_TYPE_OEM_RAW,
oem_raw_remove, oemraw);
for (l = g_drivers; l; l = l->next) {
const struct ofono_oem_raw_driver *drv = l->data;
if (g_strcmp0(drv->name, driver))
continue;
if (drv->probe(oemraw, vendor, data) < 0)
continue;
oemraw->driver = drv;
break;
}
return oemraw;
}

View File

@@ -152,7 +152,6 @@ enum ofono_atom_type {
OFONO_ATOM_TYPE_CDMA_SMS,
OFONO_ATOM_TYPE_CDMA_NETREG,
OFONO_ATOM_TYPE_HANDSFREE,
OFONO_ATOM_TYPE_OEM_RAW,
OFONO_ATOM_TYPE_SIRI,
};

View File

@@ -2609,6 +2609,52 @@ static void sim_free_state(struct ofono_sim *sim)
sim_free_main_state(sim);
}
static void sim_set_locked_pin(struct ofono_sim *sim,
enum ofono_sim_password_type type, gboolean locked)
{
char **locked_pins;
if (sim->locked_pins[type] == locked)
return;
sim->locked_pins[type] = locked;
locked_pins = get_locked_pins(sim);
ofono_dbus_signal_array_property_changed(ofono_dbus_get_connection(),
__ofono_atom_get_path(sim->atom),
OFONO_SIM_MANAGER_INTERFACE, "LockedPins",
DBUS_TYPE_STRING, &locked_pins);
g_strfreev(locked_pins);
}
static void sim_query_fac_imsilock_cb(const struct ofono_error *error,
ofono_bool_t status, void *data)
{
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
return;
sim_set_locked_pin(data, OFONO_SIM_PASSWORD_PHSIM_PIN, status);
}
static void sim_query_fac_networklock_cb(const struct ofono_error *error,
ofono_bool_t status, void *data)
{
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
return;
sim_set_locked_pin(data, OFONO_SIM_PASSWORD_PHNET_PIN, status);
}
static void sim_query_fac_pinlock_cb(const struct ofono_error *error,
ofono_bool_t status, void *data)
{
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
return;
sim_set_locked_pin(data, OFONO_SIM_PASSWORD_SIM_PIN, status);
}
void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted)
{
if (sim->state == OFONO_SIM_STATE_RESETTING && inserted) {
@@ -2635,6 +2681,20 @@ void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted)
call_state_watches(sim);
if (inserted) {
if (sim->driver->query_facility_lock) {
sim->driver->query_facility_lock(sim,
OFONO_SIM_PASSWORD_PHSIM_PIN,
sim_query_fac_imsilock_cb, sim);
sim->driver->query_facility_lock(sim,
OFONO_SIM_PASSWORD_PHNET_PIN,
sim_query_fac_networklock_cb, sim);
sim->driver->query_facility_lock(sim,
OFONO_SIM_PASSWORD_SIM_PIN,
sim_query_fac_pinlock_cb, sim);
}
sim_initialize(sim);
} else {
sim->pin_type = OFONO_SIM_PASSWORD_NONE;

View File

@@ -10,19 +10,19 @@ Source: %{name}-%{version}.tar.bz2
Requires: dbus
Requires: systemd
Requires: ofono-configs
Requires: libgrilio >= 1.0.8
Requires: libglibutil >= 1.0.6
Requires: libgrilio >= 1.0.10
Requires: libglibutil >= 1.0.10
Requires(preun): systemd
Requires(post): systemd
Requires(postun): systemd
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(libudev) >= 145
BuildRequires: pkgconfig(bluez) >= 4.85
BuildRequires: pkgconfig(mobile-broadband-provider-info)
BuildRequires: pkgconfig(libwspcodec) >= 2.0
BuildRequires: pkgconfig(libgrilio) >= 1.0.8
BuildRequires: pkgconfig(libglibutil) >= 1.0.6
BuildRequires: pkgconfig(libgrilio) >= 1.0.10
BuildRequires: pkgconfig(libglibutil) >= 1.0.10
BuildRequires: pkgconfig(libdbuslogserver-dbus)
BuildRequires: libtool
BuildRequires: automake
BuildRequires: autoconf
@@ -53,7 +53,6 @@ Scripts for testing oFono and its functionality
%package configs-mer
Summary: Package to provide default configs for ofono
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Provides: ofono-configs
%description configs-mer
@@ -69,7 +68,7 @@ autoreconf --force --install
%configure --disable-static \
--enable-test \
--enable-logcontrol \
--enable-debuglog \
--enable-jolla-rilmodem \
--with-systemdunitdir="/%{_lib}/systemd/system"
@@ -86,6 +85,7 @@ rm -rf %{buildroot}
mkdir -p %{buildroot}/%{_sysconfdir}/ofono/push_forwarder.d
mkdir -p %{buildroot}/%{_lib}/systemd/system/network.target.wants
mkdir -p %{buildroot}/var/lib/ofono
ln -s ../ofono.service %{buildroot}/%{_lib}/systemd/system/network.target.wants/ofono.service
%preun