Compare commits

...

292 Commits

Author SHA1 Message Date
Slava Monich
93eb292b75 Merge pull request #271 from monich/OperatorsChanged
Add NetworkRegistration.OperatorsChanged signal
2014-12-31 12:47:57 +03:00
Slava Monich
3cc42fb087 [network] Added NetworkRegistration.OperatorsChanged signal
This signal gets emitted when operator list has changed.
It contains the current list of operators.
2014-12-22 09:12:18 +01:00
Jarko Poutiainen
782f2327fd Merge pull request #270 from jpoutiai/ipv6
[RILMODEM] fix same gateway for ipv4 and ipv6 issue
2014-12-12 12:38:26 +02:00
Tommi Kenakkala
8bda4032ca Merge pull request #269 from tkenakka/master
[rilmodem] Log ril version
2014-12-12 10:40:53 +02:00
Tommi Kenakkala
b2f4bd7603 [rilmodem] Log ril version 2014-12-12 10:22:11 +02:00
Jarko Poutiainen
33bb6d829c [RILMODEM] fix same gateway for ipv4 and ipv6 issue
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-12-12 08:32:38 +02:00
Tommi Kenakkala
1bea99ac56 Merge pull request #267 from jpoutiai/ipv6
Ipv6
2014-12-10 13:46:16 +02:00
Jarko Poutiainen
aab24b3f24 Merge pull request #268 from hedayat/master
Re-enable CBS in n900 plugin and fix CBS related crash in N9
2014-12-09 07:47:42 +02:00
Jarko Poutiainen
65eea56efe [RILMODEM] use glib to split string to array and some style fixes
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-12-08 15:54:55 +02:00
Jarko Poutiainen
8ac7e502b7 [GRIL] use glib to split string to array
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-12-08 15:53:06 +02:00
Hedayat Vatankhah
9e8bdf0d64 [packaging] Fix error in changelog date format preventing mb2 builds 2014-12-08 01:46:41 +03:30
Hedayat Vatankhah
70e99152a3 Fix cbs related n900/isimodem crash
Don't remove cbs data during shutdown sequence in isimodem driver, since
it is already being removed.

[n900] Fix cbs related crash
2014-12-08 01:46:41 +03:30
Hedayat Vatankhah
a90fc92665 Revert "Remove the cbs creation for n900 plugin, this lead to crashes on n9 ofono init."
This reverts commit 804bef98ad.
2014-12-08 01:46:41 +03:30
Jarko Poutiainen
1d23793eb0 Merge pull request #266 from locusf/master
Remove the cbs creation for n900 plugin, this lead to crashes on n9 ofon...
2014-12-01 07:58:33 +02:00
Aleksi Suomalainen
804bef98ad Remove the cbs creation for n900 plugin, this lead to crashes on n9 ofono init.
For the latest release of ofono for Nemo Mobile, the modem fails to initialize
with the isimodem driver enabled. This is due to a segmentation fault occurring
in the flush of the atoms of the modem in cbs_assembly_free function. This
resulted in a segmentation fault when using n900 driver.

[n900] Remove cbs creation.
2014-11-30 16:06:58 +00:00
Jarko Poutiainen
1fdde8fecb [RILMODEM] gprs dual mode support
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-11-26 14:38:06 +02:00
Jarko Poutiainen
1c484a6d04 [GRIL] in reply parse all datacall settings
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-11-26 13:55:13 +02:00
Jarko Poutiainen
64e888ef04 [RILMODEM] ipv6 support
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-11-20 09:54:33 +02:00
Jarko Poutiainen
b33e0061d0 Merge pull request #263 from jpoutiai/sim-fix
[RILMODEM] fix hotswap regression
2014-11-18 15:27:29 +02:00
Jarko Poutiainen
2babf82823 [RILMODEM] fix hotswap regression
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-11-18 14:10:20 +02:00
Jarko Poutiainen
87a35d5d83 Merge pull request #262 from nemomobile-packages/no-fake
No fake
2014-11-17 15:48:17 +02:00
Jarko Poutiainen
3d264276de [RILMODEM] style fixes
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-11-17 15:31:51 +02:00
Jarko Poutiainen
d6bd24add3 [RILMODEM] remove gprs state faking
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-11-13 10:33:55 +02:00
Jarko Poutiainen
9624eb9ace [gprs] publish ofono_gprs_get_modem
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-31 14:55:08 +02:00
Jarko Poutiainen
14672319d2 [gprs] implement ofono_gprs_get_modem
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-31 14:54:39 +02:00
Jarko Poutiainen
0d8b576ab6 Merge pull request #261 from jpoutiai/sim-fix
[RILMODEM] query password state and prevent double sim initialisation
2014-10-30 13:59:09 +02:00
Jarko Poutiainen
c16121469b [RILMODEM] query password state and prevent double sim initialisation
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-29 10:04:06 +02:00
Jarko Poutiainen
812f552ace Merge pull request #260 from jpoutiai/vc-delay-nro-storing
[voicecall] src/voicecall.c MO call delay storing number
2014-10-28 10:38:24 +02:00
Jarko Poutiainen
fe52d1dc53 [voicecall] src/voicecall.c MO call delay storing number
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-22 11:43:14 +03:00
Jarko Poutiainen
8be724836e Merge pull request #259 from jpoutiai/gprs
rilmodem gprs fixes
2014-10-22 10:58:42 +03:00
Jarko Poutiainen
8c96a7e091 Merge pull request #258 from jpoutiai/roaming-fix
Roaming fix
2014-10-22 10:13:01 +03:00
Jarko Poutiainen
f9bd555dc0 [RILMODEM] style fix
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-22 09:16:18 +03:00
Jarko Poutiainen
71fd5c148a [RILMODEM] recheck status also in ril_data_probe_reg_cb
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-20 10:29:18 +03:00
Jarko Poutiainen
476e440f47 [RILMODEM] recheck status value before using it
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-20 10:26:54 +03:00
Jarko Poutiainen
35440277d1 [RILMODEM] prevent datacall slipping through when roaming disabled
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-20 09:56:07 +03:00
Jarko Poutiainen
4f67e6743e [RILMODEM]publish get_current_network_status
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-20 09:55:40 +03:00
Jarko Poutiainen
c9ba23ae3d [RILMODEM] get network status from core
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-20 09:50:15 +03:00
Jarko Poutiainen
dcdddee5c5 [RILMODEM] introduce ril_roaming_allowed
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-14 09:31:37 +03:00
Jarko Poutiainen
195c2c6a1e [RILMODEM] prepare ril_roaming_allowed to be published
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-14 09:30:53 +03:00
Jarko Poutiainen
51cf33c206 Merge pull request #257 from jpoutiai/master
[RILMODEM] free before calling g_strdup to avoid mem leak
2014-10-10 11:08:50 +03:00
Jarko Poutiainen
08ddddc8d2 [RILMODEM] free before calling g_strdup to avoid mem leak
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-10-10 10:51:02 +03:00
Tommi Kenakkala
dc5eed9c24 Merge pull request #256 from tkenakka/log-gprs
[rilmodem] Logging improvements to gprs
2014-10-09 15:29:08 +03:00
Tommi Kenakkala
72e656e1fb [rilmodem] Logging improvements to gprs
Rilmodem gprs logic slightly touched to store latest reg status
always to gprs_data struct. Reg status logged only when it changes
instead of always.
2014-10-08 15:26:00 +03:00
Tommi Kenakkala
af1717977d Merge pull request #255 from tkenakka/loggingnetreg
[rilmodem] Logging updates to netreg
2014-09-19 11:48:55 +03:00
Tommi Kenakkala
cb48cfa9c3 [rilmodem] Logging updates to netreg 2014-09-18 08:22:38 +03:00
Tommi Kenakkala
759c0bbde4 Merge pull request #253 from tkenakka/logging2
Minor logging improvements to rilmodem
2014-09-18 08:18:27 +03:00
Tommi Kenakkala
300695d069 Merge pull request #254 from tkenakka/ussdnotifycrash
[rilmodem] Fix ussd notify ofono crash
2014-09-18 08:02:31 +03:00
Tommi Kenakkala
f88c1c3ab2 [rilmodem] Fix ussd notify ofono crash
Fixup e23e6ac
2014-09-18 07:56:09 +03:00
Jarko Poutiainen
7415ef7418 Merge pull request #252 from mkuukkane/fix_ofono_cleanup
[ofono] Fix ofono cleanup
2014-09-17 10:11:18 +03:00
Tommi Kenakkala
887d9cf5d1 [rilmodem] Logging updates to radiosettings 2014-09-16 14:06:05 +03:00
Tommi Kenakkala
6231d5cc1c [rilmodem] Minor logging update to voicecall 2014-09-16 14:06:05 +03:00
Tommi Kenakkala
5b1f978a5c [rilmodem] Minor logging update to ussd 2014-09-16 14:06:05 +03:00
Marko Kuukkanen
1d1b9df844 [ofono] Fix ofono cleanup 2014-09-16 10:14:42 +03:00
Tommi Kenakkala
0adfefa0c4 Merge pull request #250 from tkenakka/gprs
[rilmodem] Gprs fake timer fixes
2014-09-05 12:22:21 +03:00
Tommi Kenakkala
7c8db19341 Merge pull request #249 from jpoutiai/master
[RILMODEM] fix sim mem leak and code cleaning
2014-09-02 13:35:16 +03:00
Jarko Poutiainen
37ec5f9221 [RILMODEM] fix sim mem leak and code cleaning
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-09-02 13:31:45 +03:00
Tommi Kenakkala
d2d6f57b5f [rilmodem] Gprs fake timer fixes
Fixes timer cancelation logic and a mem leak on timer
callback data cleanup.
2014-09-02 13:23:42 +03:00
Tommi Kenakkala
6a272bf700 Merge pull request #248 from tkenakka/leakfixes
Mem leak fixes
2014-09-01 14:15:43 +03:00
Tommi Kenakkala
e1c8e2e2dc [rilmodem] Call fwd mem leak fix
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-09-01 13:10:54 +03:00
Tommi Kenakkala
5fb138dc13 [rilmodem] Nw selection mem leak fix
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-09-01 12:14:48 +03:00
Tommi Kenakkala
e2790ae176 Merge pull request #247 from tkenakka/leak
Fix rilmodem memory leaks
2014-08-29 10:10:01 +03:00
Tommi Kenakkala
516700c84c [rilmodem] Fix supplementary service mem leak
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-08-28 14:32:42 +03:00
Tommi Kenakkala
e23e6aceae [rilmodem] Fix ussd mem leaks
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-08-28 14:31:34 +03:00
Tommi Kenakkala
0532e2a6ea [rilmodem] Fix stk mem leaks 2014-08-28 14:31:11 +03:00
Tommi Kenakkala
ce2f0f3642 Merge pull request #246 from tkenakka/leaksms
[rilmodem] Mem leak fixes to sms sending and receiving
2014-08-27 14:34:52 +03:00
Tommi Kenakkala
0400b250c9 [rilmodem] Mem leak fixes to sms sending and receiving
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-08-27 12:39:37 +03:00
Tommi Kenakkala
bfcad4f346 Merge pull request #245 from tkenakka/master
Minor code cleanup
2014-08-27 09:32:30 +03:00
Tommi Kenakkala
9d49e2cee1 [rilmodem] Updated devinfo comments
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-08-26 11:05:15 +03:00
Tommi Kenakkala
c99e70f97a [rilmodem] Minor phonebook code cleanup
Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-08-26 11:05:06 +03:00
Tommi Kenakkala
edc0035d18 Merge pull request #244 from jpoutiai/master
Fix memory leaks in sms and phonebook
2014-08-25 14:19:08 +03:00
Jarko Poutiainen
121f308cdb [RILMODEM] fix memory leak in sms sca query
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-08-25 10:58:26 +03:00
Jarko Poutiainen
2fcf1aee03 [RILMODEM] fix phonebook memory leaks
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-08-25 10:57:08 +03:00
Tommi Kenakkala
a14ebf50e0 Merge pull request #243 from jpoutiai/master
[RILMODEM] return failure to manufacturer and model queries
2014-08-25 10:24:59 +03:00
Jarko Poutiainen
1b0d419355 [RILMODEM] return failure to manufacturer and model queries
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-08-21 09:25:36 +03:00
Tommi Kenakkala
43f444db00 Merge pull request #242 from tigeli/master
[gprs] limit internet interface MTU by 1280
2014-08-14 09:42:10 +03:00
Pasi Sjöholm
1eb6243bc9 [gprs] limit internet interface MTU by 1280 2014-08-14 09:30:46 +03:00
Tommi Kenakkala
6ed50ecab7 Merge pull request #241 from jpoutiai/master
[RILMODEM] PB crash fix
2014-08-08 15:38:05 +03:00
Jarko Poutiainen
17ddc04788 [RILMODEM] PB crash fix add logging
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-08-08 10:26:27 +03:00
Jarko Poutiainen
4fd3c6386a [RILMODEM] PB crash fix
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-08-07 15:13:37 +03:00
Jarko Poutiainen
a069557b27 Merge pull request #240 from monich/data_calls
Fixed a problem with multiple data calls
2014-08-05 12:49:49 +03:00
Tommi Kenakkala
da81a85578 Merge pull request #239 from monich/warnings
Fixed compilation warnings
2014-08-04 15:17:11 +03:00
Slava Monich
79e18f9d77 [ofono] Fixed a problem with multiple data calls
When two contexts were active simultaneously, deactivating one of them
would mark the second one as disconnected although its data call would
actually remain active.
2014-07-21 13:46:49 +03:00
Slava Monich
38f4886a97 Fixed compilation warnings 2014-07-21 13:43:50 +03:00
Tommi Kenakkala
b154268fd9 Merge pull request #238 from tkenakka/merge1.14part
Merge upstream ofono 1.14 changes up to 9bbc986
2014-06-26 16:41:59 +03:00
Tommi Kenakkala
cb3a89a702 Merge remote-tracking branch 'martti/merge1.14' into merge1.14part 2014-06-26 13:58:35 +03:00
Tommi Kenakkala
133d92f265 Merge pull request #236 from special/master
[ofono] Encode SMS as UTF-16 instead of UCS-2
2014-06-26 08:56:29 +03:00
Tommi Kenakkala
ad6fd49dbc Merge pull request #237 from martinjones/cfu_change
[ofono] Fix call forwarding unconditional change signal emission.
Wrong property names signalled for conditional call forwarding types when status of unconditional type changed.
2014-06-24 14:01:06 +03:00
Martin Jones
888e857779 [ofono] Fix call forwarding unconditional change signal emission.
When toggling cfu the change signals for the other types didn't have the
prefix applied.
2014-06-20 02:01:37 +00:00
Tommi Kenakkala
e189cd138b Merge pull request #235 from jpoutiai/sms-on-sim
[RILMODEM] initial support to read and delete sms from sim (class2, voicemail mwi)
2014-06-18 16:21:14 +03:00
John Brooks
6b8b5d29a1 [ofono] Encode SMS as UTF-16 instead of UCS-2
UCS-2 is an older 16-bit encoding compatible with the unicode BMP.
UTF-16 extends UCS-2 to add support for surrogate pairs and the rest of
the unicode set. All valid UCS-2 text is also valid UTF-16 text, and all
UTF-16 text not containing surrogate pairs is valid UCS-2.

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

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

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

This commit adds a "voice call agent" API. It currently contains only the ringback tone notification, but can be extended later.
2014-04-16 15:31:45 +03:00
Denis Kenzior
516165c311 handsfree: Rename driver function
To be more consistent with others in the same file
2014-04-10 10:04:36 -05:00
Denis Kenzior
b37f5e842d handsfree: Simplify logic 2014-04-10 10:04:12 -05:00
Andrew Earl
e7f055385f hfp: Add CNUM query to handsfree interface for subscriber number 2014-04-10 09:52:11 -05:00
Denis Kenzior
8cfcfa4519 handsfree: Rename variable 2014-04-10 09:43:47 -05:00
Denis Kenzior
ca3ae87d0a handsfree: Reflow logic 2014-04-10 09:43:44 -05:00
Denis Kenzior
02138901d3 handsfree: Remove function
No need for one line functions that are only used once
2014-04-10 09:43:41 -05:00
Denis Kenzior
24e87d2580 handsfree: Rename function
No need for the ofono_ prefix here
2014-04-10 09:31:58 -05:00
Denis Kenzior
057c4d788f handsfree: Remove unneeded variable 2014-04-10 09:29:32 -05:00
Denis Kenzior
805c3068be handsfree: Remove unneeded variable i 2014-04-10 09:29:11 -05:00
Denis Kenzior
eb4fd9f5aa handsfree: style fixes for previous commit 2014-04-10 09:25:30 -05:00
Andrew Earl
8327d528a9 hfp: Add subscriber number to handsfree properties 2014-04-10 09:21:23 -05:00
Andrew Earl
7420d327e3 include: Add subscriber number to handsfree API 2014-04-10 09:18:15 -05:00
Andrew Earl
e589094113 doc: Add subscriber number to handsfree-api 2014-04-10 09:17:47 -05:00
Martti Piirainen
533d248288 Merge pull request #210 from nemomobile-packages/next
Merge various improvements from 'next' to 'master'
2014-04-08 10:54:18 +03:00
Martti Piirainen
4f512b6e56 Merge pull request #209 from jpoutiai/next
[RILMODEM] fix cf query callback list handling
2014-04-07 10:18:48 +03:00
Martti Piirainen
ce3a5e5a0b Merge pull request #204 from monich/ril_delayed_register
[rilmodem] Actually remove delayed register timer
2014-04-07 10:13:28 +03:00
Martti Piirainen
c97ef76c93 Merge pull request #205 from monich/ril_oemraw_delayed_register
[rilmodem] Remove delayed register timer in ril_oemraw_remove
2014-04-07 10:13:11 +03:00
Jarko Poutiainen
95659d7c49 [RILMODEM] fix cf query callback list handling
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-04 15:03:08 +03:00
Tommi Kenakkala
eb986f49e4 Merge pull request #208 from tkenakka/next
[ofono][dundee] At startup order dundee after dbus instead of syslog.
2014-04-01 15:27:26 +03:00
Tommi Kenakkala
4691d385c0 [ofono][dundee] At startup order dundee after dbus instead of syslog.
According to systemd documentation
"Newer systemd versions (v35+) do not support non-socket-activated syslog
daemons anymore and we do no longer recommend people to order their units
after syslog.target."

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

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-26 10:56:22 +02:00
Jarko Poutiainen
837fa1f8f1 Merge pull request #202 from monich/mms-pdu
[gprs] Limit MMS interface MTU by 1280
2014-03-25 15:11:34 +02:00
Slava Monich
1469b52db9 [gprs] Limit MMS interface MTU by 1280
This improves interoperability with certain operators, notably Saunalahti.
The limit of 1280 was chosen because it's the minimum MTU required from
IPv6 capable networks.
2014-03-25 15:05:55 +02:00
Claudio Takahasi
6fdcfc309c gdbus: Add g_dbus_proxy_set_property_array
This patch adds a new gdbus utility function to allow setting a property
of fixed, and non-fixed values array.
2014-03-24 14:27:51 -07:00
Denis Kenzior
4585969568 he910: Fix unused variable warning
plugins/he910.c: In function ‘qss_query_cb’:
plugins/he910.c:174:21: error: unused variable ‘data’
[-Werror=unused-variable]
2014-03-20 12:55:20 -05:00
Denis Kenzior
f8819b588b he910: Switch to permissive parser
Seems the CCFC implementation on Telit firmware is not v.250 compliant:
ofonod[445]: Aux: > AT+CCFC=0,2\r
ofonod[445]: Aux: < \r\n\r\n+CCFC:0,7\r\n\r\nOK\r\n
2014-03-19 10:30:10 -05:00
Denis Kenzior
c3f528908d he910: Fixup SIM detection
In certain cases the #QSS notification is never sent, or sent too early.
Make sure that we enable #QSS notification only after the modem has been
set as powered.  Also make sure that we explicitly query #QSS in case we
missed the earlier #QSS notification.
2014-03-19 10:30:05 -05:00
Denis Kenzior
29fefe6450 hfp: Use enum from hfp.h 2014-03-19 10:24:57 -05:00
Denis Kenzior
65e6df8e50 hfp: Fixup variable names 2014-03-19 10:20:28 -05:00
Krzysztof Wilk
8a7b8b0521 hfp: Add CHLD features to drver data 2014-03-19 10:19:53 -05:00
Denis Kenzior
5705a0078e handsfree: Fixup variable names 2014-03-19 10:19:35 -05:00
Krzysztof Wilk
b2b3943717 hfp: extend Features to three way calling and CHLD 2014-03-19 10:15:55 -05:00
Krzysztof Wilk
6b8f46a916 include: Declaration function to set CHLD features 2014-03-19 10:13:15 -05:00
Krzysztof Wilk
2e78ea1830 hfp: Define hfp_ag_chld_feature 2014-03-19 10:12:16 -05:00
Krzysztof Wilk
dafbd0da25 doc: Extend Features property 2014-03-19 10:11:40 -05:00
Martti Piirainen
c156bbf14b Merge pull request #200 from jkangas/master
Request for pulling prevention of modem data reseting if modem is not registered to master branch
2014-03-18 07:58:12 +02:00
Slava Monich
a724d6bc9d Merge pull request #199 from monich/push-length
Fix for push data length
2014-03-17 11:09:07 +02:00
Slava Monich
21b7c9bc97 [push-forwarder] Fixed push data length
Push handlers were receiving a few extra bytes beyond the end of valid data.
2014-03-16 16:11:10 +02:00
Denis Kenzior
13ce99e360 AUTHORS: Mention Alfonso's contributions 2014-03-14 12:24:54 -05:00
Alfonso Sanchez-Beato
352e3ebb76 unit: Fix test to use valid EF_PNN
test-simutil was not using EF_PNN files with a valid format.
2014-03-14 12:24:26 -05:00
Alfonso Sanchez-Beato
46de4df677 simutil: Fix EF_PNN access
EF_PNN was not being read properly (see TS 24.008, section 10.5.3.5a,
for network names format), which affected the displayed PLMN name for
some MVNOs. Some modems already read the file and return the right
string: these do not show the problem.
2014-03-14 12:24:26 -05:00
Denis Kenzior
6a96eea978 stktest: Remove some unneeded output 2014-03-14 10:32:32 -05:00
Denis Kenzior
ebe25412a4 test: Make sure test-stk-menu works with python3 2014-03-14 10:32:06 -05:00
Jussi Kangas
fc04b4cef2 [rilmodem] Do not remove unexisting modem data
If ril connection fails when called from reattempt, timer interval
should not be reset. In that case method called by timer does not
return false and that leads to double timer. If modem data does
not exist in the core it should not be removed.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-14 15:16:42 +02:00
Martti Piirainen
88f42f44c1 [unit] SMS decoding tests for Unicode 2014-03-14 09:05:22 +02:00
Martti Piirainen
2aed3c3f66 [unit] Fix EF_PNN unit test
Correct the encoding of the existing test case, and add a second test (the latter is based on Canonical rilmodem code).
2014-03-14 09:05:22 +02:00
Martti Piirainen
9c9028b164 [rpm] Run unit tests before creating .rpm 2014-03-14 09:05:22 +02:00
Martti Piirainen
6d35002f11 Merge pull request #197 from nemomobile-packages/next
Merge quite a many things from 'next' to 'master'
2014-03-13 17:23:44 +02:00
Tommi Kenakkala
803dda81ea Merge pull request #196 from marttipiirainen/next
Merge latest upstream oFono up to commit 278dba2ec8.
2014-03-13 13:19:33 +02:00
Slava Monich
31f8abf851 mbpi: Pop subparser stack after mmsc and mmsproxy 2014-03-13 13:19:33 +02:00
Marcel Holtmann
8f4aefa945 gatchat: Fix handling of WRITE_SCHEDULER_DEBUG 2014-03-13 13:19:33 +02:00
Tommi Kenakkala
58e133cbf5 Merge pull request #186 from ptakalok/call_forw
[rilmodem] Change call forwarding default service class per RIL design
2014-03-13 13:19:32 +02:00
Slava Monich
6c3992aa86 include: Be more const-correct in ofono_dbus_* 2014-03-13 13:19:32 +02:00
Jarko Poutiainen
c3352608c6 Merge pull request #192 from jkangas/next
Request for pulling direct SPDI reading without service table check to next branch
2014-03-13 13:19:32 +02:00
Petri Takalokastari
5da34324ca [rilmodem] Change call forwarding default service class per RIL design
RIL expects service class BEARER_CLASS_VOICE in
RIL_REQUEST_SET_CALL_FORWARD and SERVICE_CLASS_NONE in
RIL_REQUEST_QUERY_CALL_FORWARD_STATUS.

Signed-off-by: Petri Takalokastari <petri.takalokastari@oss.tieto.com>
2014-03-13 13:19:32 +02:00
Miia Leinonen
b64a5c2655 Merge pull request #191 from jkangas/next
Request for pulling cbs disabling and handling of non-existent response fix to next branch
2014-03-13 13:19:32 +02:00
Jussi Kangas
e11c1afdd3 [network] Do not check the service table before reading SPDI
Although it is correct to check support for service provider display
info from service table before reading, operators don't necessarily
care about such details. Direct reading is the surest way to find out
if the info is present or not. If it is not, ofono will just get
failure from modem.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-13 13:19:32 +02:00
Jussi Kangas
9834debe92 Merge pull request #190 from leinomii/next
[rilmodem] Enable SIM operations in expired SIM cards
2014-03-13 13:19:31 +02:00
Jussi Kangas
2d75463ae2 [rilmodem] Do not handle unexisting response
Running disable-modem test case seems to cause assert triggering
in gril in developer mode. Since method seems to survive just fine
from handling of zero length command queue, removing the assert
helps testing in developer mode.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-13 13:19:31 +02:00
Miia Leinonen
95b95f9af9 Merge pull request #189 from jkangas/next
Request for pulling usage of preset paths when reading ADN records to next branch
2014-03-13 13:19:31 +02:00
Miia Leinonen
d43ec9e0ed [rilmodem] Enable SIM operations also in outdated SIM cards
Following Android example for interpreting RIL_APPSTATE_ILLEGAL
as RIL_APPSTATE_READY. E.g. SIM cards that are expired can go to
this state. By mapping the state to READY we are still able to
use the SIM features such as reading phonebook. Network access
will not be permitted with such SIM card regardless or READY
state.

Signed-off-by: Miia Leinonen <miia.leinonen@oss.tieto.com>
2014-03-13 13:19:31 +02:00
Jussi Kangas
8bc1e0a300 [rilmodem] Disable cbs support
We don't know for sure if registering to listen CBS messages
causes unnecessary power consumption with our modem but since we are
not really supporting it it's better to disable the feature for now.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-13 13:19:31 +02:00
Martti Piirainen
b489dc995b Merge pull request #188 from jkangas/next
Request for pulling EFPNN 7-bit unpacking before trying convert it to UTF8 to next branch
2014-03-13 13:19:31 +02:00
Jussi Kangas
d25fd17f09 [rilmodem] Set the path for all ADN record readings
Core does not list EFpbr to it's EF list so we cannot trust
sim_ef_db_get_path_3g or sim_ef_db_get_path_2g to find the
correct path. In order to read the 2nd and later phonebook
records we have to define the path in rilmodem level.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-13 13:19:31 +02:00
Alfonso Sanchez-Beato
73a794e9f6 [src] Fix EF_PNN access
EF_PNN was not being read properly, which affected the displayed PLMN
name for some MVNOs. Some modems already read the file and return the
right string: these do not show the problem.
2014-03-13 13:19:31 +02:00
Martti Piirainen
df0e72c780 Merge pull request #180 from monich/split_wsp_payload
[push-forwarder] Split WSP payload
2014-03-13 13:19:30 +02:00
Jarko Poutiainen
7cdaa7cd13 Merge pull request #185 from marttipiirainen/next
Make libwspcodec dependency conditional
2014-03-13 13:19:30 +02:00
Slava Monich
558a6639d6 [push-forwarder] Split WSP payload
Instead of sending the whole WSP datagram to the handler we now send
content type string and WSP payload data. This way push handler won't
have to parse WSP headers just to extract the payload.
2014-03-13 13:19:30 +02:00
Jarko Poutiainen
5f2e8e24f0 Merge pull request #182 from jkangas/next
Request for pulling tech pref config possibility based on mobile country code to next branch
2014-03-13 13:19:30 +02:00
Martti Piirainen
31f85495dc [configure] Make libwspcodec dependency conditional
Signed-off-by: Martti Piirainen <martti.piirainen@oss.tieto.com>
2014-03-13 13:19:30 +02:00
Tommi Kenakkala
689d7358ba Merge pull request #183 from marttipiirainen/next
Make the push-forwarder plugin configurable
2014-03-13 13:19:30 +02:00
Jussi Kangas
b3ca644f1d [rilmodem] Mobile country code configuration
Enable limiting radio technology based on mobile country code found
from ICC.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-03-13 13:19:30 +02:00
Martti Piirainen
1e811dd49a [configure] Make the push-forwarder plugin configurable
Signed-off-by: Martti Piirainen <martti.piirainen@oss.tieto.com>
2014-03-13 13:19:30 +02:00
Tommi Kenakkala
9a520a7825 Merge pull request #179 from ptakalok/mosms
[rilmodem] Refine SMS sending response value handling
2014-03-13 13:19:29 +02:00
Tommi Kenakkala
2f51bc9e62 Merge pull request #178 from marttipiirainen/next
[gril] Fix 'unused variable' compiler warning
2014-03-13 13:19:29 +02:00
Petri Takalokastari
d8dd65b579 [rilmodem] Refine SMS sending response value handling
By this change, the SMS is resent only  in cases it is worth of retrying.

Signed-off-by: Petri Takalokastari <petri.takalokastari@oss.tieto.com>
2014-03-13 13:19:29 +02:00
Martti Piirainen
1e139cb4c6 Merge pull request #177 from monich/create-push-forwarder-d
Create /etc/ofono/push_forwarder.d directory
2014-03-13 13:19:29 +02:00
Martti Piirainen
68c0a9f164 [gril] Fix 'unused variable' compiler warning
Signed-off-by: Martti Piirainen <martti.piirainen@oss.tieto.com>
2014-03-13 13:19:29 +02:00
Slava Monich
dfe0f280de Create /etc/ofono/push_forwarder.d directory 2014-03-13 13:19:20 +02:00
Tommi Kenakkala
5a54a71fd8 Merge pull request #171 from monich/push-forwarder-next
Push forwarder plugin
2014-03-13 13:18:27 +02:00
Tommi Kenakkala
0f39bdc9c3 Merge pull request #169 from monich/create-mms-context-after-upgrade
Create and provision MMS context if it doesn't exist
2014-03-13 13:18:27 +02:00
Slava Monich
24e8514c55 Push forwarder plugin 2014-03-13 13:18:27 +02:00
Tommi Kenakkala
f1b689ed3c Merge pull request #176 from ptakalok/language
[rilmodem] Set current UI system language to environment variable
2014-03-13 13:18:27 +02:00
Slava Monich
e5df37be4b [gprs] Create and provision MMS context if it doesn't exist
This is necessary to handle the upgrade scenario from an ofono version
that doesn't support MMS to the one that does.
2014-03-13 13:18:27 +02:00
Petri Takalokastari
a61a8cc183 [rilmodem] Set current UI system language to environment variable
Read current terminal UI language from configuration file and set it as
environment variable for provide local information proactive command.

Signed-off-by: Petri Takalokastari <petri.takalokastari@oss.tieto.com>
2014-03-13 13:18:27 +02:00
Martti Piirainen
e25b5b13f9 Merge pull request #166 from marttipiirainen/next
[build] Fix network time plugin build issues
2014-03-13 13:18:26 +02:00
Jussi Kangas
3f3375442d Merge pull request #170 from leinomii/next
Clean useless cast and improve handle_unsol_req readability
2014-03-13 13:18:26 +02:00
Jussi Kangas
782669b412 Merge pull request #164 from jkangas/next
Ensure that AP list has one INTERNET and one MMS access point
2014-03-13 13:18:26 +02:00
Martti Piirainen
5a401c8b50 [build] Fix network time plugin build issues
Link clock functions explicitly to the POSIX realtime library when using glibc version < 2.17 (otherwise, some compilation environments implicitly link libpthread, others fail). Also, there was a typo that broke the '--disable-nettime' configure option.

Signed-off-by: Martti Piirainen <martti.piirainen@oss.tieto.com>
2014-03-13 13:18:26 +02:00
Miia Leinonen
3ac41bc759 [gril] Clean useless cast and improve handle_unsol_req readability 2014-03-13 13:18:26 +02:00
Slava Monich
5af079bd03 Ensure that AP list has one INTERNET and one MMS access point
Also, minimized differences with upstream version of provision.c
2014-03-13 13:18:26 +02:00
Denis Kenzior
c94c4fad54 AUTHORS: Mention Martin's contributions 2014-03-11 19:34:45 -05:00
Martin Pitt
c027ab9fbc test: Convert to Python 3
Change raw_input() to input() and unicode to str. This is *not*
compatible with Python 2. Update the hashbangs to run with Python 3.
2014-03-11 19:34:08 -05:00
Martin Pitt
ad4f90684f test: Move from static gobject bindings to GI
Use GLib gobject-introspection bindings so that we can also use the
scripts with Python 3.
2014-03-11 19:33:16 -05:00
Martin Pitt
5bf5cf8ddd test: Replace obsolete has_key() with "in"
In order to also work with Python 3
2014-03-11 19:33:04 -05:00
Martin Pitt
0393a41e35 test: Make exceptions compatible with Python 3
Use "except Type as var" syntax to work with both Python >= 2.6
and Python 3.
2014-03-11 19:32:46 -05:00
Martin Pitt
0c1fcd2b50 test: Make print calls compatible with Python 3
Turn print calls into print() function calls and avoid using
comma-separated arguments, so that they work and look the same with
both Python 2 and 3.
2014-03-11 19:32:18 -05:00
Denis Kenzior
c54e4763f8 he910: Fix whitespace 2014-03-10 11:53:22 -05:00
Claudio Takahasi
ea2b34eacd gdbus: Add g_dbus_client_set_ready_watch()
This patch adds a new gdbus helper to notify the clients that
GetManagedObjects reply was received and the last proxy has been
informed previously by the proxy_added callback.
2014-03-06 09:36:48 -08:00
Denis Kenzior
472e6650d4 AUTHORS: Mention Tony's contributions 2014-03-05 08:51:06 -06:00
Tony Espy
201d34b0a1 idmap: use UL for bitshift literals
The current bitshift logic in idmap incorrectly uses
the literal 1 for the value to shift in idmap_alloc(),
idmap_take(), and idmap_alloc_next().  This causes the
resulting value to be an int instead of a long, which
results in the wrong bit being set once the number of
bits to shift operand exceeds sizeof(int).  Also
on some platforms, the behavior of the left bitshift
operator is undefined when this overflow occurs.
2014-03-05 08:49:50 -06:00
Pekka Lundstrom
cf6278f5cc Merge pull request #181 from plundstr/master
Packaging fixes
2014-02-19 16:48:49 +02:00
Pekka Lundstrom
dd3b0c5aca No restart on update
Signed-off-by: Pekka Lundstrom <pekka.lundstrom@jollamobile.com>
2014-02-19 15:01:31 +02:00
Pekka Lundstrom
988a759e4c [packaking] Add fail safe to post scripts
Signed-off-by: Pekka Lundstrom <pekka.lundstrom@jollamobile.com>
2014-02-19 14:08:27 +02:00
Pekka Lundstrom
555585c17f [packaking] get rid off .yaml
Signed-off-by: Pekka Lundstrom <pekka.lundstrom@jollamobile.com>
2014-02-19 14:06:25 +02:00
Luiz Augusto von Dentz
76a7f9014d gdbus: Replace g_timeout_add with g_idle_add
Passing 0 as timeout to g_timeout_add should equivalent to g_idle_add.
2014-02-18 23:13:53 -08:00
Anderson Lizardo
29401d8587 gdbus: Fix incorrect DBusConnection reference counting
Commit abfc2b0dd5c3e33abfdf1a815b16d492c1751c06 attempted to fix a crash
related to improper reference counting, but the main issue was that the
reference was taken only during the function call (which is usually
unnecessary for single thread), but still passed a pointer to
DBusConnection to a function that is called by the mainloop. This left a
window where the DBusConnection can be destroyed.

Fixes this crash on unit/test-gdbus-client:

==32642== Invalid read of size 4
==32642==    at 0x690D0A6: dbus_connection_ref (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x804CEDB: message_dispatch (mainloop.c:73)
==32642==    by 0x684580E: g_timeout_dispatch (gmain.c:4450)
==32642==    by 0x6844A75: g_main_context_dispatch (gmain.c:3065)
==32642==    by 0x6844E14: g_main_context_iterate.isra.23 (gmain.c:3712)
==32642==    by 0x68452FA: g_main_loop_run (gmain.c:3906)
==32642==    by 0x804C7D3: client_connect_disconnect
(test-gdbus-client.c:188)
==32642==    by 0x6868DB2: g_test_run_suite_internal (gtestutils.c:2067)
==32642==    by 0x6868F8D: g_test_run_suite_internal (gtestutils.c:2138)
==32642==    by 0x6869320: g_test_run_suite (gtestutils.c:2189)
==32642==    by 0x686936B: g_test_run (gtestutils.c:1508)
==32642==    by 0x696D4D2: (below main) (libc-start.c:226)
==32642==  Address 0x709c6e4 is 140 bytes inside a block of size 144
free'd
==32642==    at 0x67E806C: free (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32642==    by 0x692D62E: dbus_free (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x690E1C2: ??? (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x804AAEC: destroy_context (test-gdbus-client.c:104)
==32642==    by 0x6868DB2: g_test_run_suite_internal (gtestutils.c:2067)
==32642==    by 0x6868F8D: g_test_run_suite_internal (gtestutils.c:2138)
==32642==    by 0x6869320: g_test_run_suite (gtestutils.c:2189)
==32642==    by 0x686936B: g_test_run (gtestutils.c:1508)
==32642==    by 0x696D4D2: (below main) (libc-start.c:226)
2014-02-18 23:13:53 -08:00
Anderson Lizardo
90abd44ead gdbus: Fix memory leak
data->conn and data->path must be destroyed before freeing "data".
2014-02-18 23:13:53 -08:00
Martti Piirainen
4b99034c3f Merge pull request #175 from ptakalok/subs_master
[rilmodem] Allow subscription of stk notifications only once
2014-02-13 08:10:08 +02:00
Petri Takalokastari
03e35b6757 [rilmodem] Allow subscription of stk notifications only once
Allow subscription of stk notifications only when simkit agent registers
for first time. This implementation fixes double subscription problems
which may happen if simkit agent has exited and restarts subscribing to
stk commands again.

Signed-off-by: Petri Takalokastari <petri.takalokastari@oss.tieto.com>
2014-02-11 11:00:01 +02:00
Pekka Lundstrom
b36fdce803 Merge pull request #173 from plundstr/master
[init] Added boot-time requirement to be started after dbus service
2014-02-10 18:06:38 +02:00
Pekka Lundstrom
34251bdba7 [init] Added boot-time requirement to be started after dbus service
Signed-off-by: Pekka Lundstrom <pekka.lundstrom@jollamobile.com>
2014-02-10 15:58:08 +02:00
Slava Monich
278dba2ec8 mbpi: Pop subparser stack after mmsc and mmsproxy 2014-02-07 08:56:44 -06:00
Martti Piirainen
530c66393a Merge pull request #168 from jkangas/master
Request for pulling EFECC reading when READY to main branch
2014-02-06 14:29:37 +02:00
Jussi Kangas
10c823d732 [voicecall] Read the EFECC also if SIM goes straigth to READY
It is possible that ofono starts so that SIM is already in
in READY state when voicecall gets the information. In that case
without this fix core never asks the emergency numbers

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-02-06 13:51:02 +02:00
Martti Piirainen
db6d4d1e8e Merge pull request #163 from marttipiirainen/next
Merge Call Barring support, SIM ATK support and SMS ACK bugfix from 'next' to 'master'
2014-02-03 00:46:01 -08:00
Jussi Kangas
5bcbc64e60 [rilmodem] Ack sms receiving also when error
According to ril api also the failed receiving of SMS should be
acked to ril.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-02-03 10:07:52 +02:00
Petri Takalokastari
48cec5cc58 [rilmodem] Add initial SIM ATK support
Add initial SIM ATK implementation to rilmodem driver, supporting
proactive command, terminal response and envelope.

Signed-off-by: Petri Takalokastari <petri.takalokastari@oss.tieto.com>

[rilmodem] Fix proactive command and terminal response handling

Convert the proactive commands and terminal responses to correct
format

[rilmodem] Fix for envelope sending

Fix typo in envelope sending causing ofono crash

[rilmodem] stk: adjust timings

Adjust the registeration of the rilmodem stk service and usage of timer
when reporting to RIL when ready to receive proactive commands

[rilmodem] Fix for terminal response and envelope construction

Remove usage of strlen, so the terminal responses and envelopes ending
with value 0x00 are sent properly.

[rilmodem] Remove timer usage from start up sequence

Remove usage of timers in startup sequence. Report ofono readiness to
receive proactive commands only when agent has registered.

[rilmodem] Fine tuning of start up sequence

Register to listen STK specific unsolicited messages only if UI STK agent
has registered. This because RILD will send and buffer proactive commands
also if not received RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING
previously. RILD will buffer the proactive command until receiving
RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING or terminal
response to (sent) proactive command.
By this change oFono core/rilmodem will not handle proactive commands
until STK UI agent has been registered to oFono.

[rilmodem] Change envelope sending request

Changed envelope sending request from
RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS to
RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND as it seems that RILD
does not support RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS
properly.
Also cleaned up some excessive tracing.
2014-02-03 10:07:52 +02:00
Miia Leinonen
6e40473ce9 [rilmodem] Fix for Call Barring commit
Signed-off-by: Miia Leinonen <miia.leinonen@oss.tieto.com>
2014-02-03 10:07:52 +02:00
Miia Leinonen
90cae692df [rilmodem] Add Call Barring support
Signed-off-by: Miia Leinonen <miia.leinonen@oss.tieto.com>
2014-02-03 10:07:51 +02:00
Martti Piirainen
d8270409d0 Merge pull request #156 from jpoutiai/master
[rilmodem] add missing brace characters
2014-02-02 23:48:45 -08:00
Marcel Holtmann
f83233d295 gatchat: Fix handling of WRITE_SCHEDULER_DEBUG 2014-01-19 16:48:04 -08:00
Jarko Poutiainen
e644196aa3 [rilmodem] add missing brace characters
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-01-17 13:44:32 +02:00
Slava Monich
c2e58405ee include: Be more const-correct in ofono_dbus_* 2014-01-13 10:19:54 -06:00
179 changed files with 4957 additions and 1577 deletions

View File

@@ -92,3 +92,7 @@ Jesper Larsen <jesper.larsen@ixonos.com>
Slava Monich <slava.monich@jolla.com>
Andrew Earl <andrewx.earl@intel.com>
Krzysztof Wilk <krzysztofx.wilk@intel.com>
Tony Espy <espy@canonical.com>
Martin Pitt <martin.pitt@ubuntu.com>
Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>
Jussi Pakkanen <jussi.pakkanen@canonical.com>

View File

@@ -142,7 +142,9 @@ builtin_sources += drivers/rilmodem/rilmodem.h \
drivers/rilmodem/call-settings.c \
drivers/rilmodem/call-forwarding.c \
drivers/rilmodem/cbs.c \
drivers/rilmodem/oemraw-messages.c
drivers/rilmodem/oemraw-messages.c \
drivers/rilmodem/call-barring.c \
drivers/rilmodem/stk.c
endif
@@ -512,7 +514,7 @@ if PROVISION
builtin_sources += plugins/mbpi.h plugins/mbpi.c
builtin_modules += provision
builtin_sources += plugins/provision.c
builtin_sources += plugins/provision.h plugins/provision.c
builtin_modules += cdma_provision
builtin_sources += plugins/cdma-provision.c
@@ -547,6 +549,13 @@ builtin_sources += plugins/smart-messaging.c
builtin_modules += push_notification
builtin_sources += plugins/push-notification.c
if PUSHFORWARDER
builtin_modules += push_forwarder
builtin_sources += plugins/push-forwarder.c
builtin_cflags += @WSPCODEC_CFLAGS@
builtin_libadd += @WSPCODEC_LIBS@
endif
builtin_modules += sms_history
builtin_sources += plugins/smshistory.c
@@ -578,7 +587,7 @@ src_ofonod_SOURCES = $(builtin_sources) src/ofono.ver \
src/cdma-provision.c src/handsfree.c \
src/handsfree-audio.c src/bluetooth.h \
src/hfp.h src/sim-mnclength.c src/oemraw.c \
src/siri.c
src/siri.c src/voicecallagent.c
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
@@ -711,13 +720,16 @@ test_scripts = test/backtrace \
test/set-context-property \
test/test-gnss \
test/swap-calls \
test/transfer-call \
test/release-and-answer \
test/release-and-swap \
test/hold-and-answer \
test/hangup-multiparty \
test/hangup-call \
test/display-icon \
test/set-msisdn
test/set-msisdn \
test/test-voicecallagent \
test/get-network-time
if TEST
testdir = $(pkglibdir)/test
@@ -738,7 +750,8 @@ unit_tests = unit/test-common unit/test-util unit/test-idmap \
unit/test-grilrequest \
unit/test-grilreply \
unit/test-grilunsol \
unit/test-sms unit/test-cdmasms
unit/test-sms unit/test-cdmasms \
unit/test-provision
noinst_PROGRAMS = $(unit_tests) \
unit/test-sms-root unit/test-mux unit/test-caif
@@ -805,6 +818,13 @@ unit_test_grilunsol_SOURCES = unit/test-grilunsol.c $(gril_sources) \
unit_test_grilunsol_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_grilunsol_OBJECTS)
unit_test_provision_SOURCES = unit/test-provision.c \
plugins/provision.h plugins/provision.c \
plugins/mbpi.c src/gprs-provision.c \
src/log.c
unit_test_provision_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_provision_OBJECTS)
TESTS = $(unit_tests)
if TOOLS

View File

@@ -192,7 +192,10 @@ AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
AC_ARG_ENABLE(nettime, AC_HELP_STRING([--disable-nettime],
[disable Nettime plugin]),
[enable_nettime=${enableval}])
AM_CONDITIONAL(NETTIME, test "${enable_netttime}" != "no")
if (test "${enable_nettime}" != "no"); then
AC_SEARCH_LIBS([clock_gettime], [rt])
fi
AM_CONDITIONAL(NETTIME, test "${enable_nettime}" != "no")
AC_ARG_WITH([provisiondb], AC_HELP_STRING([--with-provisiondb=FILE],
[location of provision database]), [path_provisiondb=${withval}])
@@ -223,6 +226,17 @@ AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
[enable_datafiles=${enableval}])
AM_CONDITIONAL(DATAFILES, test "${enable_datafiles}" != "no")
AC_ARG_ENABLE(pushforwarder, AC_HELP_STRING([--disable-pushforwarder],
[disable Push Forwarder plugin]),
[enable_pushforwarder=${enableval}])
AM_CONDITIONAL(PUSHFORWARDER, test "${enable_pushforwarder}" != "no")
if (test "${enable_pushforwarder}" != "no"); then
PKG_CHECK_MODULES(WSPCODEC, libwspcodec >= 2.0, dummy=yes,
AC_MSG_ERROR(WSP decoder is required))
AC_SUBST(WSPCODEC_CFLAGS)
AC_SUBST(WSPCODEC_LIBS)
fi
if (test "${prefix}" = "NONE"); then
dnl no prefix and no localstatedir, so default to /var
if (test "$localstatedir" = '${prefix}/var'); then

View File

@@ -45,6 +45,12 @@ Properties array{string} Features [readonly]
"voice-recognition"
"attach-voice-tag"
"echo-canceling-and-noise-reduction"
"three-way-calling"
"release-all-held"
"release-specified-active-call"
"private-chat"
"create-multiparty"
"transfer"
boolean InbandRinging [readonly]
@@ -70,3 +76,7 @@ Properties array{string} Features [readonly]
The current charge level of the battery. The value
can be between 0 and 5 respectively.
array{string} SubscriberNumbers [readonly]
List of subscriber numbers provided by the AG.

View File

@@ -57,6 +57,11 @@ Signals PropertyChanged(string property, variant value)
This signal indicates a changed value of the given
property.
OperatorsChanged(array{object,dict})
Signal that gets emitted when operator list has
changed. It contains the current list of operators.
Properties string Mode [readonly]
The current registration mode. The default of this

View File

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

View File

@@ -49,6 +49,7 @@ static const char *bvra_prefix[] = { "+BVRA:", NULL };
struct hf_data {
GAtChat *chat;
unsigned int ag_features;
unsigned int ag_chld_features;
int battchg_index;
guint register_source;
};
@@ -124,6 +125,87 @@ static void ciev_notify(GAtResult *result, gpointer user_data)
ofono_handsfree_battchg_notify(hf, value);
}
static void cnum_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_handsfree_cnum_query_cb_t cb = cbd->cb;
GAtResultIter iter;
struct ofono_phone_number *list = NULL;
int num = 0;
struct ofono_error error;
decode_at_error(&error, g_at_result_final_response(result));
if (!ok)
goto out;
g_at_result_iter_init(&iter, result);
while (g_at_result_iter_next(&iter, "+CNUM:"))
num++;
if (num == 0)
goto out;
list = g_new0(struct ofono_phone_number, num);
g_at_result_iter_init(&iter, result);
for (num = 0; g_at_result_iter_next(&iter, "+CNUM:"); ) {
const char *number;
int service;
int type;
if (!g_at_result_iter_skip_next(&iter))
continue;
if (!g_at_result_iter_next_string(&iter, &number))
continue;
if (!g_at_result_iter_next_number(&iter, &type))
continue;
if (!g_at_result_iter_skip_next(&iter))
continue;
if (!g_at_result_iter_next_number(&iter, &service))
continue;
/* We are only interested in Voice services */
if (service != 4)
continue;
strncpy(list[num].number, number,
OFONO_MAX_PHONE_NUMBER_LENGTH);
list[num].number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
list[num].type = type;
DBG("cnum_notify:%s", list[num].number);
num++;
}
out:
cb(&error, num, list, cbd->data);
g_free(list);
}
static void hfp_cnum_query(struct ofono_handsfree *hf,
ofono_handsfree_cnum_query_cb_t cb, void *data)
{
struct hf_data *hd = ofono_handsfree_get_data(hf);
struct cb_data *cbd = cb_data_new(cb, data);
if (g_at_chat_send(hd->chat, "AT+CNUM", NULL,
cnum_query_cb, cbd, g_free) > 0)
return;
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, -1, NULL, data);
}
static gboolean hfp_handsfree_register(gpointer user_data)
{
struct ofono_handsfree *hf = user_data;
@@ -139,6 +221,7 @@ static gboolean hfp_handsfree_register(gpointer user_data)
ofono_handsfree_set_inband_ringing(hf, TRUE);
ofono_handsfree_set_ag_features(hf, hd->ag_features);
ofono_handsfree_set_ag_chld_features(hf, hd->ag_chld_features);
ofono_handsfree_register(hf);
return FALSE;
@@ -154,6 +237,7 @@ static int hfp_handsfree_probe(struct ofono_handsfree *hf,
hd = g_new0(struct hf_data, 1);
hd->chat = g_at_chat_clone(info->chat);
hd->ag_features = info->ag_features;
hd->ag_chld_features = info->ag_mpty_features;
ofono_handsfree_set_data(hf, hd);
@@ -280,6 +364,7 @@ static struct ofono_handsfree_driver driver = {
.name = "hfpmodem",
.probe = hfp_handsfree_probe,
.remove = hfp_handsfree_remove,
.cnum_query = hfp_cnum_query,
.request_phone_number = hfp_request_phone_number,
.voice_recognition = hfp_voice_recognition,
.disable_nrec = hfp_disable_nrec,

View File

@@ -128,19 +128,19 @@ static void chld_cb(gboolean ok, GAtResult *result, gpointer user_data)
while (g_at_result_iter_next_unquoted_string(&iter, &str)) {
if (!strcmp(str, "0"))
ag_mpty_feature |= AG_CHLD_0;
ag_mpty_feature |= HFP_AG_CHLD_0;
else if (!strcmp(str, "1"))
ag_mpty_feature |= AG_CHLD_1;
ag_mpty_feature |= HFP_AG_CHLD_1;
else if (!strcmp(str, "1x"))
ag_mpty_feature |= AG_CHLD_1x;
ag_mpty_feature |= HFP_AG_CHLD_1x;
else if (!strcmp(str, "2"))
ag_mpty_feature |= AG_CHLD_2;
ag_mpty_feature |= HFP_AG_CHLD_2;
else if (!strcmp(str, "2x"))
ag_mpty_feature |= AG_CHLD_2x;
ag_mpty_feature |= HFP_AG_CHLD_2x;
else if (!strcmp(str, "3"))
ag_mpty_feature |= AG_CHLD_3;
ag_mpty_feature |= HFP_AG_CHLD_3;
else if (!strcmp(str, "4"))
ag_mpty_feature |= AG_CHLD_4;
ag_mpty_feature |= HFP_AG_CHLD_4;
}
if (!g_at_result_iter_close_list(&iter))

View File

@@ -19,14 +19,6 @@
*
*/
#define AG_CHLD_0 0x01
#define AG_CHLD_1 0x02
#define AG_CHLD_1x 0x04
#define AG_CHLD_2 0x08
#define AG_CHLD_2x 0x10
#define AG_CHLD_3 0x20
#define AG_CHLD_4 0x40
enum hfp_indicator {
HFP_INDICATOR_SERVICE = 0,
HFP_INDICATOR_CALL,

View File

@@ -37,6 +37,7 @@
#include <ofono/voicecall.h>
#include "common.h"
#include "hfp.h"
#include "hfpmodem.h"
#include "slc.h"
@@ -447,7 +448,7 @@ static void hfp_hold_all_active(struct ofono_voicecall *vc,
{
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
if (vd->ag_mpty_features & AG_CHLD_2) {
if (vd->ag_mpty_features & HFP_AG_CHLD_2) {
hfp_template("AT+CHLD=2", vc, generic_cb, 0, cb, data);
return;
}
@@ -461,7 +462,7 @@ static void hfp_release_all_held(struct ofono_voicecall *vc,
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
unsigned int held_status = 1 << CALL_STATUS_HELD;
if (vd->ag_mpty_features & AG_CHLD_0) {
if (vd->ag_mpty_features & HFP_AG_CHLD_0) {
hfp_template("AT+CHLD=0", vc, generic_cb, held_status,
cb, data);
return;
@@ -476,7 +477,7 @@ static void hfp_set_udub(struct ofono_voicecall *vc,
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
unsigned int incoming_or_waiting = 1 << CALL_STATUS_WAITING;
if (vd->ag_mpty_features & AG_CHLD_0) {
if (vd->ag_mpty_features & HFP_AG_CHLD_0) {
hfp_template("AT+CHLD=0", vc, generic_cb, incoming_or_waiting,
cb, data);
return;
@@ -528,7 +529,7 @@ static void hfp_release_all_active(struct ofono_voicecall *vc,
{
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
if (vd->ag_mpty_features & AG_CHLD_1) {
if (vd->ag_mpty_features & HFP_AG_CHLD_1) {
hfp_template("AT+CHLD=1", vc, release_all_active_cb, 0x1, cb,
data);
return;
@@ -559,7 +560,7 @@ static void hfp_release_specific(struct ofono_voicecall *vc, int id,
struct release_id_req *req = NULL;
char buf[32];
if (!(vd->ag_mpty_features & AG_CHLD_1x))
if (!(vd->ag_mpty_features & HFP_AG_CHLD_1x))
goto error;
req = g_try_new0(struct release_id_req, 1);
@@ -590,7 +591,7 @@ static void hfp_private_chat(struct ofono_voicecall *vc, int id,
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
char buf[32];
if (vd->ag_mpty_features & AG_CHLD_2x) {
if (vd->ag_mpty_features & HFP_AG_CHLD_2x) {
snprintf(buf, sizeof(buf), "AT+CHLD=2%d", id);
hfp_template(buf, vc, generic_cb, 0, cb, data);
@@ -606,7 +607,7 @@ static void hfp_create_multiparty(struct ofono_voicecall *vc,
{
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
if (vd->ag_mpty_features & AG_CHLD_3) {
if (vd->ag_mpty_features & HFP_AG_CHLD_3) {
hfp_template("AT+CHLD=3", vc, generic_cb, 0, cb, data);
return;
@@ -625,7 +626,7 @@ static void hfp_transfer(struct ofono_voicecall *vc,
*/
unsigned int transfer = 0x1 | 0x2 | 0x4 | 0x8;
if (vd->ag_mpty_features & AG_CHLD_4) {
if (vd->ag_mpty_features & HFP_AG_CHLD_4) {
hfp_template("AT+CHLD=4", vc, generic_cb, transfer, cb, data);
return;

View File

@@ -134,7 +134,9 @@ static void routing_resp_cb(const GIsiMessage *msg, void *data)
struct cbs_data *cd = ofono_cbs_get_data(cbs);
if (!check_resp(msg, SMS_GSM_CB_ROUTING_RESP)) {
ofono_cbs_remove(cbs);
/* on shutdown, cbs is already being removed */
if (g_isi_msg_error(msg) != -ESHUTDOWN)
ofono_cbs_remove(cbs);
return;
}

View File

@@ -0,0 +1,310 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2014 Jolla Ltd
* Contact: Miia Leinonen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <glib.h>
#include <ofono/log.h>
#include <ofono/modem.h>
#include "common.h"
#include "gril.h"
#include "call-barring.h"
#include "rilmodem.h"
#include "ril_constants.h"
/* See 3GPP 27.007 7.4 for possible values */
#define RIL_MAX_SERVICE_LENGTH 3
/*
* ril.h does not state that string count must be given, but that is
* still expected by the modem
*/
#define RIL_QUERY_STRING_COUNT 4
#define RIL_SET_STRING_COUNT 5
#define RIL_SET_PW_STRING_COUNT 3
#define RIL_LENGTH_ZERO 0
struct barring_data {
GRil *ril;
guint timer_id;
};
static void ril_call_barring_query_cb(struct ril_msg *message,
gpointer user_data)
{
struct cb_data *cbd = user_data;
struct parcel rilp;
struct ofono_error error;
ofono_call_barring_query_cb_t cb = cbd->cb;
int bearer_class = 0;
if (message->error != RIL_E_SUCCESS) {
ofono_error("Call Barring query failed, err: %i",
message->error);
decode_ril_error(&error, "FAIL");
goto out;
}
ril_util_init_parcel(message, &rilp);
/*
* Services for which the specified barring facility is active.
* "0" means "disabled for all, -1 if unknown"
*/
parcel_r_int32(&rilp); /* count - we know there is only 1 */
bearer_class = parcel_r_int32(&rilp);
DBG("Active services: %i", bearer_class);
decode_ril_error(&error, "OK");
out:
cb(&error, bearer_class, cbd->data);
}
static void ril_call_barring_query(struct ofono_call_barring *cb,
const char *lock, int cls,
ofono_call_barring_query_cb_t callback,
void *data)
{
struct barring_data *bd = ofono_call_barring_get_data(cb);
struct cb_data *cbd = cb_data_new(callback, data);
struct parcel rilp;
int ret = 0;
char cls_textual[RIL_MAX_SERVICE_LENGTH];
DBG("lock: %s, services to query: %i", lock, cls);
/*
* RIL modems do not support 7 as default bearer class. According to
* the 22.030 Annex C: When service code is not given it corresponds to
* "All tele and bearer services"
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = SERVICE_CLASS_NONE;
sprintf(cls_textual, "%d", cls);
/*
* See 3GPP 27.007 7.4 for parameter descriptions.
* According to ril.h password should be empty string "" when not
* needed, but in reality we only need to give string length as 0
*/
parcel_init(&rilp);
parcel_w_int32(&rilp, RIL_QUERY_STRING_COUNT); /* Nbr of strings */
parcel_w_string(&rilp, (char *) lock); /* Facility code */
parcel_w_int32(&rilp, RIL_LENGTH_ZERO); /* Password length */
parcel_w_string(&rilp, (char *) cls_textual);
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
ret = g_ril_send(bd->ril, RIL_REQUEST_QUERY_FACILITY_LOCK,
rilp.data, rilp.size, ril_call_barring_query_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
ofono_error("Sending Call Barring query failed, err: %i", ret);
g_free(cbd);
CALLBACK_WITH_FAILURE(callback, -1, data);
}
}
static void ril_call_barring_set_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
struct ofono_error error;
ofono_call_barring_set_cb_t cb = cbd->cb;
if (message->error != RIL_E_SUCCESS) {
ofono_error("Call Barring Set request failed, err: %i",
message->error);
decode_ril_error(&error, "FAIL");
goto out;
}
decode_ril_error(&error, "OK");
out:
cb(&error, cbd->data);
}
static void ril_call_barring_set(struct ofono_call_barring *cb,
const char *lock, int enable,
const char *passwd, int cls,
ofono_call_barring_set_cb_t callback,
void *data)
{
struct barring_data *bd = ofono_call_barring_get_data(cb);
struct cb_data *cbd = cb_data_new(callback, data);
struct parcel rilp;
int ret = 0;
char cls_textual[RIL_MAX_SERVICE_LENGTH];
DBG("lock: %s, enable: %i, bearer class: %i", lock, enable, cls);
/*
* RIL modem does not support 7 as default bearer class. According to
* the 22.030 Annex C: When service code is not given it corresponds to
* "All tele and bearer services"
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = SERVICE_CLASS_NONE;
sprintf(cls_textual, "%d", cls);
/* See 3GPP 27.007 7.4 for parameter descriptions */
parcel_init(&rilp);
parcel_w_int32(&rilp, RIL_SET_STRING_COUNT); /* Nbr of strings */
parcel_w_string(&rilp, (char *) lock); /* Facility code */
if (enable)
parcel_w_string(&rilp, RIL_FACILITY_LOCK);
else
parcel_w_string(&rilp, RIL_FACILITY_UNLOCK);
parcel_w_string(&rilp, (char *) passwd);
parcel_w_string(&rilp, (char *) cls_textual);
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
ret = g_ril_send(bd->ril, RIL_REQUEST_SET_FACILITY_LOCK,
rilp.data, rilp.size, ril_call_barring_set_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
ofono_error("Sending Call Barring Set request failed, err: %i",
ret);
g_free(cbd);
CALLBACK_WITH_FAILURE(callback, data);
}
}
static void ril_call_barring_set_passwd_cb(struct ril_msg *message,
gpointer user_data)
{
struct cb_data *cbd = user_data;
struct ofono_error error;
ofono_call_barring_set_cb_t cb = cbd->cb;
if (message->error != RIL_E_SUCCESS) {
ofono_error("Call Barring Set PW req failed, err: %i",
message->error);
decode_ril_error(&error, "FAIL");
goto out;
}
decode_ril_error(&error, "OK");
out:
cb(&error, cbd->data);
}
static void ril_call_barring_set_passwd(struct ofono_call_barring *barr,
const char *lock,
const char *old_passwd,
const char *new_passwd,
ofono_call_barring_set_cb_t cb,
void *data)
{
struct barring_data *bd = ofono_call_barring_get_data(barr);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
int ret = 0;
DBG("");
parcel_init(&rilp);
parcel_w_int32(&rilp, RIL_SET_PW_STRING_COUNT); /* Nbr of strings */
parcel_w_string(&rilp, (char *) lock); /* Facility code */
parcel_w_string(&rilp, (char *) old_passwd);
parcel_w_string(&rilp, (char *) new_passwd);
ret = g_ril_send(bd->ril, RIL_REQUEST_CHANGE_BARRING_PASSWORD,
rilp.data, rilp.size, ril_call_barring_set_passwd_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
ofono_error("Sending Call Barring Set PW req failed, err: %i",
ret);
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, data);
}
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_call_barring *cb = user_data;
struct barring_data *bd = ofono_call_barring_get_data(cb);
bd->timer_id = 0;
ofono_call_barring_register(cb);
return FALSE;
}
static int ril_call_barring_probe(struct ofono_call_barring *cb,
unsigned int vendor, void *user)
{
GRil *ril = user;
struct barring_data *bd = g_try_new0(struct barring_data, 1);
bd->ril = g_ril_clone(ril);
ofono_call_barring_set_data(cb, bd);
bd->timer_id = g_timeout_add_seconds(2, ril_delayed_register, cb);
return 0;
}
static void ril_call_barring_remove(struct ofono_call_barring *cb)
{
struct barring_data *data = ofono_call_barring_get_data(cb);
ofono_call_barring_set_data(cb, NULL);
if (data->timer_id > 0)
g_source_remove(data->timer_id);
g_ril_unref(data->ril);
g_free(data);
}
static struct ofono_call_barring_driver driver = {
.name = "rilmodem",
.probe = ril_call_barring_probe,
.remove = ril_call_barring_remove,
.query = ril_call_barring_query,
.set = ril_call_barring_set,
.set_passwd = ril_call_barring_set_passwd
};
void ril_call_barring_init(void)
{
ofono_call_barring_driver_register(&driver);
}
void ril_call_barring_exit(void)
{
ofono_call_barring_driver_unregister(&driver);
}

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-2014 Jolla Ltd
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -94,11 +94,10 @@ static void ril_registration(struct ofono_call_forwarding *cf, int type,
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
* returns cls:53 i.e. 1+4+16+32 as service class.
* BEARER_CLASS_VOICE as per RIL design.
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = SERVICE_CLASS_NONE;
cls = BEARER_CLASS_VOICE;
parcel_w_int32(&rilp, cls);
@@ -140,11 +139,10 @@ static void ril_send_forward_cmd(struct ofono_call_forwarding *cf,
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
* returns cls:53 i.e. 1+4+16+32 as service class.
* BEARER_CLASS_VOICE as per RIL design.
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = SERVICE_CLASS_NONE;
cls = BEARER_CLASS_VOICE;
parcel_w_int32(&rilp, cls); /* Service class */
@@ -216,7 +214,7 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
nmbr_of_resps);
for (i = 0; i < nmbr_of_resps; i++) {
const char *str;
char *str = NULL;
list[i].status = parcel_r_int32(&rilp);
@@ -227,19 +225,16 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
list[i].phone_number.type = parcel_r_int32(&rilp);
str = parcel_r_string(&rilp);
if (str) {
strncpy(list[i].phone_number.number,
str,
OFONO_MAX_PHONE_NUMBER_LENGTH);
list[i].phone_number.number[
OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
list[i].time = parcel_r_int32(&rilp);
g_free(str);
}
list[i].time = parcel_r_int32(&rilp);
}
CALLBACK_WITH_SUCCESS(cb, nmbr_of_resps, list, cbd->data);
@@ -273,8 +268,7 @@ static void ril_query(struct ofono_call_forwarding *cf, int type, int cls,
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
* returns cls:53 i.e. 1+4+16+32 as service class.
* SERVICE_CLASS_NONE as per RIL design.
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = SERVICE_CLASS_NONE;

View File

@@ -42,9 +42,8 @@
#include "rilmodem.h"
/*
* TODO: The functions in this file are stubbed out, and
* will need to be re-worked to talk to the /gril layer
* in order to get real values from RILD.
* TODO: No public RIL api to query manufacturer or model.
* Check where to get, could /system/build.prop be updated to have good values?
*/
guint timer_id;
@@ -52,30 +51,14 @@ static void ril_query_manufacturer(struct ofono_devinfo *info,
ofono_devinfo_query_cb_t cb,
void *data)
{
const char *attr = "Fake Manufacturer";
struct cb_data *cbd = cb_data_new(cb, data);
struct ofono_error error;
decode_ril_error(&error, "OK");
cb(&error, attr, cbd->data);
/* Note: this will need to change if cbd passed to gril layer */
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, "", data);
}
static void ril_query_model(struct ofono_devinfo *info,
ofono_devinfo_query_cb_t cb,
void *data)
{
const char *attr = "Fake Modem Model";
struct cb_data *cbd = cb_data_new(cb, data);
struct ofono_error error;
decode_ril_error(&error, "OK");
cb(&error, attr, cbd->data);
/* Note: this will need to change if cbd passed to gril layer */
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, "", data);
}
static void query_revision_cb(struct ril_msg *message, gpointer user_data)
@@ -98,6 +81,7 @@ static void query_revision_cb(struct ril_msg *message, gpointer user_data)
revision = parcel_r_string(&rilp);
cb(&error, revision, cbd->data);
g_free(revision);
}
static void ril_query_revision(struct ofono_devinfo *info,
@@ -137,10 +121,10 @@ static void query_serial_cb(struct ril_msg *message, gpointer user_data)
}
ril_util_init_parcel(message, &rilp);
imei = parcel_r_string(&rilp);
cb(&error, imei, cbd->data);
g_free(imei);
}
static void ril_query_serial(struct ofono_devinfo *info,

View File

@@ -43,8 +43,16 @@
#include "grilrequest.h"
#include "grilunsol.h"
#include "common.h"
#include "rilmodem.h"
enum data_call_state {
DATA_CALL_INACTIVE,
DATA_CALL_LINK_DOWN,
DATA_CALL_ACTIVE,
};
enum state {
STATE_IDLE,
STATE_ENABLING,
@@ -60,22 +68,112 @@ struct gprs_context_data {
guint regid;
};
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
unsigned int id,
ofono_gprs_context_cb_t cb, void *data);
static void set_context_disconnected(struct gprs_context_data *gcd)
{
DBG("");
gcd->active_ctx_cid = -1;
gcd->active_rild_cid = -1;
gcd->state = STATE_IDLE;
}
static void disconnect_context(struct ofono_gprs_context *gc)
static void ril_gprs_split_ip_by_protocol(char **ip_array,
char ***split_ip_addr,
char ***split_ipv6_addr,
char **ip_addr)
{
ril_gprs_context_deactivate_primary(gc, 0, NULL, NULL);
const char ipv6_delimiter = ':';
const char ip_delimiter = '.';
int i;
*split_ipv6_addr = *split_ip_addr = NULL;
for (i=0; i< g_strv_length(ip_array); i++) {
if (strchr(ip_array[i], ipv6_delimiter)) {
if (*split_ipv6_addr == NULL) {
*split_ipv6_addr = g_strsplit(
ip_array[i], "/",2);
}
} else if (strchr(ip_array[i], ip_delimiter)) {
if (*split_ip_addr == NULL) {
*ip_addr = g_strdup(ip_array[i]);
*split_ip_addr = g_strsplit(
ip_array[i], "/", 2);
}
}
}
}
static void ril_gprs_split_gw_by_protocol(char **gw_array, char **ip_gw,
char **ipv6_gw)
{
const char ipv6_delimiter = ':';
const char ip_delimiter = '.';
int i;
*ip_gw = *ipv6_gw = NULL;
for (i=0; i< g_strv_length(gw_array); i++) {
if (strchr(gw_array[i],ipv6_delimiter)) {
if (*ipv6_gw == NULL) {
*ipv6_gw = g_strdup(gw_array[i]);
}
} else if (strchr(gw_array[i],ip_delimiter)) {
if (*ip_gw == NULL)
*ip_gw = g_strdup(gw_array[i]);
}
}
}
static void ril_gprs_split_dns_by_protocol(char **dns_array, char ***dns_addr,
char ***dns_ipv6_addr)
{
const char ipv6_delimiter = ':';
const char ip_delimiter = '.';
const char dns_delimiter = ',';
char *temp = NULL;
char *temp1 = NULL;
char *dnsip = NULL;
char *dnsipv6 = NULL;
int i, dnsip_len, dnsipv6_len;
dnsip_len = dnsipv6_len = 0;
for (i=0; i< g_strv_length(dns_array); i++) {
if (strchr(dns_array[i],ipv6_delimiter)) {
if (dnsipv6 == NULL) {
dnsipv6 = g_strdup(dns_array[i]);
} else {
temp = g_strconcat(dnsipv6, ",", NULL);
g_free(dnsipv6);
temp1 = g_strconcat(temp, dns_array[i], NULL);
g_free(temp);
dnsipv6 = temp1;
}
dnsipv6_len++;
} else if (strchr(dns_array[i],ip_delimiter)) {
if (dnsip == NULL) {
dnsip = g_strdup(dns_array[i]);
} else {
temp = g_strconcat(dnsip, ",", NULL);
g_free(dnsip);
temp1 = g_strconcat(temp, dns_array[i], NULL);
g_free(temp);
dnsip = temp1;
}
dnsip_len++;
}
}
if (dnsip){
if (strchr(dnsip,dns_delimiter))
*dns_addr = g_strsplit(dnsip, ",", dnsip_len);
}
if (dnsipv6) {
if (strchr(dnsipv6,dns_delimiter))
*dns_ipv6_addr = g_strsplit(dnsipv6, ",", dnsipv6_len);
}
g_free(dnsip);
g_free(dnsipv6);
}
static void ril_gprs_context_call_list_changed(struct ril_msg *message,
@@ -85,7 +183,6 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
struct data_call *call = NULL;
struct unsol_data_call_list *unsol;
gboolean active_cid_found = FALSE;
gboolean disconnect = FALSE;
GSList *iterator = NULL;
struct ofono_error error;
@@ -100,19 +197,133 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
call = (struct data_call *) iterator->data;
if (call->cid == gcd->active_rild_cid) {
active_cid_found = TRUE;
/*
* Every context receives notifications about all data calls
* but should only handle its own.
*/
if (call->cid != gcd->active_rild_cid)
continue;
if (call->active == 0) {
disconnect = TRUE;
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
if (call->status != 0)
ofono_info("data call status:%d", call->status);
if (call->active == DATA_CALL_INACTIVE) {
disconnect = TRUE;
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
break;
}
if (call->active == DATA_CALL_ACTIVE) {
int protocol = -1;
if (call->type)
protocol = ril_protocol_string_to_ofono_protocol(call->type);
if (call->ifname)
ofono_gprs_context_set_interface(gc,
call->ifname);
if (call->addresses) {
char **split_ip_addr = NULL;
char **ip_array = NULL;
char **split_ipv6_addr = NULL;
char *ip_addr = NULL;
/*addresses to an array*/
ip_array = g_strsplit(call->addresses, " ",-1);
/*pick 1 address of each protocol*/
ril_gprs_split_ip_by_protocol(ip_array,
&split_ip_addr,
&split_ipv6_addr,
&ip_addr);
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
protocol == OFONO_GPRS_PROTO_IPV6)
&& split_ipv6_addr != NULL){
ofono_gprs_context_set_ipv6_address(gc,
split_ipv6_addr[0]);
}
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
protocol == OFONO_GPRS_PROTO_IP)
&& split_ip_addr != NULL) {
ofono_gprs_context_set_ipv4_netmask(gc,
ril_util_get_netmask(ip_addr));
ofono_gprs_context_set_ipv4_address(gc,
split_ip_addr[0], TRUE);
}
g_strfreev(split_ip_addr);
g_strfreev(split_ipv6_addr);
g_strfreev(ip_array);
g_free(ip_addr);
}
if (call->gateways) {
char **gw_array = NULL;
char *ip_gw = NULL;
char *ipv6_gw = NULL;
/*addresses to an array*/
gw_array = g_strsplit(call->gateways, " ", -1);
/*pick 1 gw for each protocol*/
ril_gprs_split_gw_by_protocol(gw_array, &ip_gw,
&ipv6_gw);
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
protocol == OFONO_GPRS_PROTO_IPV6)
&& ipv6_gw != NULL)
ofono_gprs_context_set_ipv6_gateway(gc,
ipv6_gw);
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
protocol == OFONO_GPRS_PROTO_IP)
&& ip_gw != NULL)
ofono_gprs_context_set_ipv4_gateway(gc,
ip_gw);
g_strfreev(gw_array);
g_free(ip_gw);
g_free(ipv6_gw);
}
if (call->dnses) {
char **dns_array = NULL;
char **dns_ip = NULL;
char **dns_ipv6 = NULL;
/*addresses to an array*/
dns_array = g_strsplit(call->dnses, " ", -1);
/*split based on protocol*/
ril_gprs_split_dns_by_protocol(dns_array,
&dns_ip,
&dns_ipv6);
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
protocol == OFONO_GPRS_PROTO_IPV6)
&& dns_ipv6 != NULL)
ofono_gprs_context_set_ipv6_dns_servers(
gc, (const char **) dns_ipv6);
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
protocol == OFONO_GPRS_PROTO_IP)
&& dns_ip != NULL)
ofono_gprs_context_set_ipv4_dns_servers(
gc, (const char**)dns_ip);
g_strfreev(dns_ip);
g_strfreev(dns_ipv6);
g_strfreev(dns_array);
}
break;
}
}
if (disconnect || active_cid_found == FALSE) {
if (disconnect) {
ofono_error("Clearing active context");
set_context_disconnected(gcd);
}
@@ -130,6 +341,12 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
struct ofono_error error;
struct reply_setup_data_call *reply = NULL;
char **split_ip_addr = NULL;
char **split_ipv6_addr = NULL;
char* ip_addr = NULL;
char* ip_gw = NULL;
char* ipv6_gw = NULL;
char** dns_addr = NULL;
char** dns_ipv6_addr = NULL;
ofono_info("setting up data call");
@@ -149,10 +366,7 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
gcd->active_rild_cid = reply->cid;
if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
if (gcd->active_rild_cid != -1) {
ofono_error("no active context. disconnect");
disconnect_context(gc);
}
ofono_error("no active context. disconnect");
goto error;
}
@@ -164,24 +378,16 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
error.type = OFONO_ERROR_TYPE_FAILURE;
error.error = reply->status;
set_context_disconnected(gcd);
goto error;
}
/*
* TODO: consier moving this into parse_data_reply
*
* Note - the address may optionally include a prefix size
* ( Eg. "/30" ). As this confuses NetworkManager, we
* explicitly strip any prefix after calculating the netmask.
*/
split_ip_addr = g_strsplit(reply->ip_addrs[0], "/", 2);
/*check the ip address protocol*/
ril_gprs_split_ip_by_protocol(reply->ip_addrs, &split_ip_addr,
&split_ipv6_addr, &ip_addr);
/* TODO: see note above re: invalid messages... */
if (split_ip_addr[0] == NULL) {
ofono_error("%s: invalid IP address field returned: %s",
__func__,
reply->ip_addrs[0]);
if (split_ip_addr == NULL && split_ipv6_addr == NULL) {
ofono_error("%s: No IP address returned",
__func__);
error.type = OFONO_ERROR_TYPE_FAILURE;
error.error = EINVAL;
@@ -194,33 +400,55 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
ofono_gprs_context_set_interface(gc, reply->ifname);
ril_gprs_split_gw_by_protocol(reply->gateways, &ip_gw, &ipv6_gw);
ril_gprs_split_dns_by_protocol(reply->dns_addresses, &dns_addr,
&dns_ipv6_addr);
/* TODO:
* RILD can return multiple addresses; oFono only supports
* setting a single IPv4 address. At this time, we only
* use the first address. It's possible that a RIL may
* just specify the end-points of the point-to-point
* connection, in which case this code will need to
* changed to handle such a device.
* RILD can return multiple addresses; oFono only supports setting
* a single IPv4 and single IPV6 address. At this time, we only use
* the first address. It's possible that a RIL may just specify
* the end-points of the point-to-point connection, in which case this
* code will need to changed to handle such a device.
*/
ofono_gprs_context_set_ipv4_netmask(gc,
ril_util_get_netmask(reply->ip_addrs[0]));
ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
ofono_gprs_context_set_ipv4_gateway(gc, reply->gateways[0]);
if (split_ipv6_addr != NULL &&
(reply->protocol == OFONO_GPRS_PROTO_IPV6 ||
reply->protocol == OFONO_GPRS_PROTO_IPV4V6)) {
ofono_gprs_context_set_ipv4_dns_servers(gc,
(const char **) reply->dns_addresses);
ofono_gprs_context_set_ipv6_address(gc, split_ipv6_addr[0]);
ofono_gprs_context_set_ipv6_gateway(gc, ipv6_gw);
ofono_gprs_context_set_ipv6_dns_servers(gc,
(const char **) dns_ipv6_addr);
}
if (split_ip_addr != NULL &&
(reply->protocol == OFONO_GPRS_PROTO_IP ||
reply->protocol == OFONO_GPRS_PROTO_IPV4V6)) {
ofono_gprs_context_set_ipv4_netmask(gc,
ril_util_get_netmask(ip_addr));
ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
ofono_gprs_context_set_ipv4_gateway(gc, ip_gw);
ofono_gprs_context_set_ipv4_dns_servers(gc,
(const char **) dns_addr);
}
error:
g_ril_reply_free_setup_data_call(reply);
g_strfreev(split_ip_addr);
g_strfreev(split_ipv6_addr);
g_strfreev(dns_addr);
g_strfreev(dns_ipv6_addr);
g_free(ip_addr);
g_free(ip_gw);
g_free(ipv6_gw);
cb(&error, cbd->data);
}
static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
const struct ofono_gprs_primary_context *ctx,
ofono_gprs_context_cb_t cb, void *data)
const struct ofono_gprs_primary_context *ctx,
ofono_gprs_context_cb_t cb, void *data)
{
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
struct cb_data *cbd = cb_data_new(cb, data);
@@ -229,9 +457,19 @@ static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
struct ofono_error error;
int reqid = RIL_REQUEST_SETUP_DATA_CALL;
int ret = 0;
int netreg_status;
int roaming = NETWORK_REGISTRATION_STATUS_ROAMING;
ofono_info("Activating context: %d", ctx->cid);
/* Let's make sure that we aren't connecting when roaming not allowed */
netreg_status = get_current_network_status();
if (netreg_status == roaming) {
if (!ril_roaming_allowed() && (roaming
== check_if_really_roaming(netreg_status)))
goto exit;
}
cbd->user = gc;
/* TODO: implement radio technology selection. */
@@ -245,6 +483,7 @@ static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
request.username = g_strdup(ctx->username);
request.password = g_strdup(ctx->password);
request.auth_type = RIL_AUTH_BOTH;
request.protocol = ctx->proto;
if (g_ril_request_setup_data_call(gcd->ril,
@@ -273,7 +512,7 @@ error:
g_free(request.apn);
g_free(request.username);
g_free(request.password);
exit:
if (ret <= 0) {
ofono_error("Send RIL_REQUEST_SETUP_DATA_CALL failed.");
@@ -284,7 +523,8 @@ error:
}
}
static void ril_deactivate_data_call_cb(struct ril_msg *message, gpointer user_data)
static void ril_deactivate_data_call_cb(struct ril_msg *message,
gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_gprs_context_cb_t cb = cbd->cb;
@@ -322,7 +562,8 @@ static void ril_deactivate_data_call_cb(struct ril_msg *message, gpointer user_d
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc,
unsigned int id,
ofono_gprs_context_cb_t cb, void *data)
ofono_gprs_context_cb_t cb,
void *data)
{
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
struct cb_data *cbd = NULL;
@@ -375,6 +616,7 @@ error:
if (ret <= 0) {
ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");
g_free(cbd);
if (cb)
CALLBACK_WITH_FAILURE(cb, data);
}
@@ -402,7 +644,6 @@ static int ril_gprs_context_probe(struct ofono_gprs_context *gc,
set_context_disconnected(gcd);
ofono_gprs_context_set_data(gc, gcd);
gcd->regid = -1;
gcd->regid = g_ril_register(gcd->ril, RIL_UNSOL_DATA_CALL_LIST_CHANGED,
ril_gprs_context_call_list_changed, gc);
@@ -415,14 +656,13 @@ static void ril_gprs_context_remove(struct ofono_gprs_context *gc)
DBG("");
if (gcd->state != STATE_IDLE) {
if (gcd->state != STATE_IDLE)
ril_gprs_context_detach_shutdown(gc, 0);
}
ofono_gprs_context_set_data(gc, NULL);
if (gcd->regid != -1)
g_ril_unregister(gcd->ril,gcd->regid);
g_ril_unregister(gcd->ril, gcd->regid);
g_ril_unref(gcd->ril);
g_free(gcd);
@@ -432,9 +672,9 @@ static struct ofono_gprs_context_driver driver = {
.name = RILMODEM,
.probe = ril_gprs_context_probe,
.remove = ril_gprs_context_remove,
.activate_primary = ril_gprs_context_activate_primary,
.deactivate_primary = ril_gprs_context_deactivate_primary,
.detach_shutdown = ril_gprs_context_detach_shutdown,
.activate_primary = ril_gprs_context_activate_primary,
.deactivate_primary = ril_gprs_context_deactivate_primary,
.detach_shutdown = ril_gprs_context_detach_shutdown,
};
void ril_gprs_context_init(void)

View File

@@ -45,6 +45,8 @@
#include "rilmodem.h"
#include <ofono/netreg.h>
#include <ofono/sim.h>
#include "storage.h"
/*
* This module is the ofono_gprs_driver implementation for rilmodem.
@@ -67,12 +69,18 @@ struct gprs_data {
GRil *ril;
gboolean ofono_attached;
int max_cids;
int rild_status;
gboolean notified;
int rild_status; /* Driver Status */
guint registerid;
guint timer_id;
};
/* Following constants are purely to improve readability */
static const int roaming = NETWORK_REGISTRATION_STATUS_ROAMING;
static const int registered = NETWORK_REGISTRATION_STATUS_REGISTERED;
/*if we have called ofono_gprs_register or not*/
static gboolean ofono_registered;
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
ofono_gprs_status_cb_t cb,
void *data);
@@ -81,7 +89,10 @@ static void ril_gprs_state_change(struct ril_msg *message, gpointer user_data)
{
struct ofono_gprs *gprs = user_data;
g_assert(message->req == RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
g_assert(message->req ==
RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
DBG("");
/* We need to notify core always to cover situations when
* connection drops temporarily for example when user is
@@ -97,6 +108,7 @@ static gboolean ril_gprs_set_attached_callback(gpointer user_data)
ofono_gprs_cb_t cb = cbd->cb;
struct ofono_gprs *gprs = cbd->user;
struct gprs_data *gd = ofono_gprs_get_data(gprs);
DBG("");
gd->timer_id = 0;
@@ -133,7 +145,6 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
cbd->user = gprs;
ril_gprs_registration_status(gprs, NULL, NULL);
/*
* However we cannot respond immediately, since core sets the
* value of driver_attached after calling set_attached and that
@@ -144,6 +155,30 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
cbd);
}
gboolean ril_roaming_allowed()
{
GError *error;
error = NULL;
GKeyFile *settings;
struct ofono_sim *sim;
sim = get_sim();
const char *imsi = ofono_sim_get_imsi(sim);
settings = storage_open(imsi, "gprs");
gboolean roaming_allowed = g_key_file_get_boolean(settings,
"Settings",
"RoamingAllowed",
&error);
if (error)
g_error_free(error);
storage_close(imsi, "gprs", settings, FALSE);
DBG("roaming_allowed: %d", roaming_allowed);
return roaming_allowed;
}
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
@@ -151,9 +186,9 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
struct ofono_gprs *gprs = cbd->user;
struct gprs_data *gd = ofono_gprs_get_data(gprs);
struct ofono_error error;
int status, lac, ci, tech;
int lac, ci, tech;
int max_cids = 1;
int id = RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED;
int status = -1;
if (gd && message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
@@ -162,24 +197,22 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
ril_error_to_string(message->error));
decode_ril_error(&error, "FAIL");
error.error = message->error;
status = -1;
goto error;
goto exit;
}
if (ril_util_parse_reg(gd->ril, message, &status,
&lac, &ci, &tech, &max_cids) == FALSE) {
ofono_error("Failure parsing data registration response.");
decode_ril_error(&error, "FAIL");
status = -1;
goto error;
goto exit;
}
if (gd->rild_status == -1) {
ofono_gprs_register(gprs);
if (status > 10)
status = status - 10;
DBG("Starting to listen network status");
gd->registerid = g_ril_register(gd->ril,
id, ril_gprs_state_change, gprs);
if (!ofono_registered) {
ofono_gprs_register(gprs);
ofono_registered = TRUE;
}
if (max_cids > gd->max_cids) {
@@ -188,70 +221,129 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
ofono_gprs_set_cid_range(gprs, 1, max_cids);
}
ofono_info("data registration status is %d", status);
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
if (status == roaming)
status = check_if_really_roaming(status);
if (gd->ofono_attached && !gd->notified) {
if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
DBG("connection becomes available");
/* Let's minimize logging */
if (status != gd->rild_status)
ofono_info("data reg changes %d (%d), attached %d",
status, gd->rild_status, gd->ofono_attached);
/* Must be attached if registered or roaming */
if ((gd->rild_status != registered) && (gd->rild_status != roaming)) {
if (status == registered)
gd->ofono_attached = TRUE;
else if ((status == roaming) && (ril_roaming_allowed() == TRUE))
gd->ofono_attached = TRUE;
ofono_gprs_status_notify(gprs, status);
gd->notified = TRUE;
gd->rild_status = status;
}
goto error;
}
if (gd->ofono_attached &&
status != NETWORK_REGISTRATION_STATUS_SEARCHING) {
DBG("ofono attached, start faking responses");
if (status != NETWORK_REGISTRATION_STATUS_ROAMING) {
if (!ofono_modem_get_online(ofono_gprs_get_modem(gprs)))
gd->ofono_attached = FALSE;
/* if unsolicitated and no state change let's not notify core */
if ((status == gd->rild_status) && gd->ofono_attached)
goto cb_out;
if (!gd->ofono_attached) {
if (!cb) {
if (status == roaming) {
if (ril_roaming_allowed() == FALSE)
ofono_gprs_detached_notify(gprs);
/*
* This prevents core ending
* into eternal loop with driver
*/
decode_ril_error(&error, "FAIL");
}
ofono_gprs_status_notify(gprs, status);
} else {
/*
* Only core can succesfully drop the connection
* If we drop the connection from here it leads
* to race situation where core asks context
* deactivation and at the same time we get
* Registered notification from modem.
*/
status = NETWORK_REGISTRATION_STATUS_REGISTERED;
* This prevents core ending
* into eternal loop with driver
*/
decode_ril_error(&error, "FAIL");
}
if (gd->registerid != -1)
g_ril_unregister(gd->ril, gd->registerid);
gd->registerid = -1;
} else {
/*
* Client is not approving succesful result
* This covers the situation when context is
* active in roaming situation and client closes
* it directly by calling RoamingAllowed in API
*/
DBG("data registration status is %d", status);
if (status != NETWORK_REGISTRATION_STATUS_SEARCHING) {
DBG("ofono not attached, notify core");
status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
ofono_gprs_detached_notify(gprs);
gd->notified = FALSE;
gd->ofono_attached = FALSE;
} else if (gd->notified) {
DBG("hide the searching state");
status = NETWORK_REGISTRATION_STATUS_REGISTERED;
ofono_gprs_status_notify(gprs, status);
gd->ofono_attached = TRUE;
}
gd->rild_status = status;
goto exit;
}
if (!cb)
ofono_gprs_status_notify(gprs, status);
gd->rild_status = status;
error:
exit:
DBG("data reg status %d, rild_status %d, attached %d",
status, gd->rild_status, gd->ofono_attached);
cb_out:
if (cb)
cb(&error, status, cbd->data);
}
static void ril_data_probe_reg_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
struct ofono_gprs *gprs = cbd->user;
struct gprs_data *gd = ofono_gprs_get_data(gprs);
struct ofono_error error;
int status, lac, ci, tech;
int max_cids = 1;
int id = RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED;
DBG("");
if (!(gd && message->error == RIL_E_SUCCESS)) {
ofono_error("ril_data_reg_cb: reply failure: %s",
ril_error_to_string(message->error));
decode_ril_error(&error, "FAIL");
error.error = message->error;
status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
goto out;
}
decode_ril_error(&error, "OK");
status = -1;
if (ril_util_parse_reg(gd->ril, message, &status,
&lac, &ci, &tech, &max_cids) == FALSE) {
ofono_error("Failure parsing data registration response.");
decode_ril_error(&error, "FAIL");
if (status == -1)
status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
goto out;
}
if (status > 10)
status = status - 10;
ofono_gprs_register(gprs);
ofono_registered = TRUE;
if (max_cids > gd->max_cids) {
DBG("Setting max cids to %d", max_cids);
gd->max_cids = max_cids;
ofono_gprs_set_cid_range(gprs, 1, max_cids);
}
if (status == roaming)
status = check_if_really_roaming(status);
out:
ofono_info("data reg status probed %d", status);
gd->registerid = g_ril_register(gd->ril,
id, ril_gprs_state_change, gprs);
gd->rild_status = status;
}
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
ofono_gprs_status_cb_t cb,
void *data)
@@ -261,20 +353,27 @@ static void ril_gprs_registration_status(struct ofono_gprs *gprs,
int request = RIL_REQUEST_DATA_REGISTRATION_STATE;
guint ret;
DBG("");
if (gd == NULL || cbd == NULL)
return;
cbd->user = gprs;
ret = g_ril_send(gd->ril, request,
NULL, 0, ril_data_reg_cb, cbd, g_free);
NULL, 0,
((gd->rild_status == -1)
? ril_data_probe_reg_cb
: ril_data_reg_cb), cbd, g_free);
g_ril_print_request_no_args(gd->ril, ret, request);
if (ret <= 0) {
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE failed.");
ofono_error("Send RIL_REQUEST_DATA_RESTISTRATION_STATE fail.");
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, -1, data);
if (cb)
CALLBACK_WITH_FAILURE(cb, -1, data);
}
}
@@ -292,9 +391,11 @@ static int ril_gprs_probe(struct ofono_gprs *gprs,
gd->ofono_attached = FALSE;
gd->max_cids = 0;
gd->rild_status = -1;
gd->notified = FALSE;
gd->registerid = -1;
gd->timer_id = 0;
ofono_registered = FALSE;
ofono_gprs_set_data(gprs, gd);
ril_gprs_registration_status(gprs, NULL, NULL);

View File

@@ -55,6 +55,7 @@ struct netreg_data {
guint nitz_timeout;
unsigned int vendor;
guint timer_id;
int corestatus; /* Registration status previously reported to core */
};
/* 27.007 Section 7.3 <stat> */
@@ -78,25 +79,20 @@ static void extract_mcc_mnc(const char *str, char *mcc, char *mnc)
mnc[OFONO_MAX_MNC_LENGTH] = '\0';
}
/*
* TODO: The functions in this file are stubbed out, and
* will need to be re-worked to talk to the /gril layer
* in order to get real values from RILD.
*/
static void ril_creg_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_netreg_status_cb_t cb = cbd->cb;
struct netreg_data *nd = cbd->user;
struct ofono_error error;
int status, lac, ci, tech;
int status, logstatus, lac, ci, tech;
DBG("");
if (message->error != RIL_E_SUCCESS) {
decode_ril_error(&error, "FAIL");
ofono_error("Failed to pull registration state");
ofono_error("voice registration status query fail");
nd->corestatus = -1;
cb(&error, -1, -1, -1, -1, cbd->data);
return;
}
@@ -105,20 +101,31 @@ static void ril_creg_cb(struct ril_msg *message, gpointer user_data)
if (ril_util_parse_reg(nd->ril, message, &status,
&lac, &ci, &tech, NULL) == FALSE) {
DBG("voice registration status parsing fail");
nd->corestatus = -1;
CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
return;
}
DBG("voice registration status is %d", status);
if (status > 10)
status = status - 10;
logstatus = status;
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
status = check_if_really_roaming(status);
ofono_info("voice registration status is %d", status);
DBG("status:%d corestatus:%d", status, nd->corestatus);
if (status != logstatus)
ofono_info("voice registration modified %d (%d)",
status, logstatus);
if (nd->corestatus != status)
ofono_info("voice registration changes %d (%d)",
status, nd->corestatus);
nd->corestatus = status;
nd->tech = tech;
cb(&error, status, lac, ci, tech, cbd->data);
}
@@ -128,15 +135,16 @@ static void ril_creg_notify(struct ofono_error *error, int status, int lac,
{
struct ofono_netreg *netreg = user_data;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG("Error during status notification");
return;
}
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG("Error during status notification");
return;
}
ofono_netreg_status_notify(netreg, status, lac, ci, tech);
}
static void ril_network_state_change(struct ril_msg *message, gpointer user_data)
static void ril_network_state_change(struct ril_msg *message,
gpointer user_data)
{
struct ofono_netreg *netreg = user_data;
struct netreg_data *nd = ofono_netreg_get_data(netreg);
@@ -364,6 +372,7 @@ static void ril_cops_list_cb(struct ril_msg *message, gpointer user_data)
cb(&error, noperators, list, cbd->data);
g_free(list);
return;
error:
@@ -405,7 +414,8 @@ static void ril_register_cb(struct ril_msg *message, gpointer user_data)
g_ril_print_response_no_args(nd->ril, message);
} else {
ofono_error("registration failed");
ofono_error("registration failed, ril result %d",
message->error);
decode_ril_error(&error, "FAIL");
}
@@ -421,6 +431,8 @@ static void ril_register_auto(struct ofono_netreg *netreg,
int ret;
cbd->user = nd;
ofono_info("nw select automatic");
ret = g_ril_send(nd->ril, request,
NULL, 0, ril_register_cb, cbd, g_free);
@@ -444,6 +456,8 @@ static void ril_register_manual(struct ofono_netreg *netreg,
int request = RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL;
int ret;
ofono_info("nw select manual: %s%s", mcc, mnc);
/* add *netreg_data to callback */
cbd->user = nd;
@@ -573,6 +587,17 @@ error:
ofono_error("Unable to notify ofono about nitz");
}
gboolean check_if_ok_to_attach()
{
int status = NETWORK_REGISTRATION_STATUS_SEARCHING;
status = ofono_netreg_get_status(current_netreg);
if (status == NETWORK_REGISTRATION_STATUS_SEARCHING
|| status == NETWORK_REGISTRATION_STATUS_ROAMING
|| status == NETWORK_REGISTRATION_STATUS_REGISTERED)
return TRUE;
return FALSE;
}
gint check_if_really_roaming(gint status)
{
const char *net_mcc = ofono_netreg_get_mcc(current_netreg);
@@ -580,14 +605,20 @@ gint check_if_really_roaming(gint status)
struct sim_spdi *spdi = ofono_netreg_get_spdi(current_netreg);
if (spdi && net_mcc && net_mnc) {
if (sim_spdi_lookup(spdi, net_mcc, net_mnc))
if (sim_spdi_lookup(spdi, net_mcc, net_mnc)) {
ofono_info("voice reg: not roaming based on spdi");
return NETWORK_REGISTRATION_STATUS_REGISTERED;
else
} else
return status;
} else
return status;
}
gint get_current_network_status()
{
return ofono_netreg_get_status(current_netreg);
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_netreg *netreg = user_data;
@@ -632,6 +663,7 @@ static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
nd->time.year = -1;
nd->time.dst = 0;
nd->time.utcoff = 0;
nd->corestatus = -1;
current_netreg = netreg;
ofono_netreg_set_data(netreg, nd);
@@ -658,6 +690,7 @@ static void ril_netreg_remove(struct ofono_netreg *netreg)
g_source_remove(nd->nitz_timeout);
ofono_netreg_set_data(netreg, NULL);
current_netreg = NULL;
if (nd->timer_id > 0)
g_source_remove(nd->timer_id);

View File

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

View File

@@ -6,7 +6,6 @@
* Copyright (C) ST-Ericsson SA 2010.
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013 Jolla Ltd
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -162,11 +161,18 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
char *number, struct pb_file_info *next_file,
struct pb_data *pbd)
{
const uint8_t name_length = len - 14;
const uint8_t number_start = name_length;
uint8_t name_length;
uint8_t number_start;
uint8_t number_length = 0;
uint8_t extension_record = UNUSED;
uint8_t i, prefix;
if (len < 14)
return;
name_length = len - 14;
number_start = name_length;
name = sim_string_to_utf8(msg, name_length);
/* Length contains also TON&NPI */
number_length = msg[number_start];
@@ -256,15 +262,19 @@ void handle_adn(size_t len, char *name, const unsigned char *msg,
}
}
void handle_sne(size_t len,
const unsigned char *msg,
char *sne)
void handle_sne(size_t len, const unsigned char *msg, char *sne)
{
const uint8_t sne_length = len - 2;
uint8_t phonebook_entry_nbr = msg[len - 1];
uint8_t sne_length;
uint8_t phonebook_entry_nbr;
DBG("SNE");
if (len < 2)
return;
sne_length = len - 2;
phonebook_entry_nbr = msg[len - 1];
sne = sim_string_to_utf8(msg, sne_length);
if (sne) {
@@ -299,20 +309,26 @@ void handle_sne(size_t len,
}
}
void handle_anr(size_t len,
const unsigned char *msg,
char *anr,
struct pb_file_info *next_file,
struct pb_data *pbd)
void handle_anr(size_t len,const unsigned char *msg,char *anr,
struct pb_file_info *next_file, struct pb_data *pbd)
{
uint8_t number_length = 0;
uint8_t extension_record = UNUSED;
uint8_t aas_record = UNUSED;
uint8_t i, prefix;
uint8_t phonebook_entry_nbr = msg[len - 1];
uint8_t phonebook_entry_nbr;
GSList *list_entry;
DBG("ANR");
if (!msg)
return;
if (len < 1)
return;
phonebook_entry_nbr = msg[len - 1];
if (msg[0] == UNUSED)
return;
@@ -328,7 +344,7 @@ void handle_anr(size_t len,
prefix = 0;
if ((msg[2] & TON_MASK) ==
TON_INTERNATIONAL) {
TON_INTERNATIONAL) {
anr[0] = '+';
prefix = 1;
}
@@ -398,11 +414,18 @@ void handle_anr(size_t len,
}
}
void handle_email(size_t len,
const unsigned char *msg,
char *email)
void handle_email(size_t len, const unsigned char *msg, char *email)
{
uint8_t phonebook_entry_nbr = msg[len - 1];
uint8_t phonebook_entry_nbr;
if (!msg)
return;
if (len < 1)
return;
phonebook_entry_nbr = msg[len - 1];
email = sim_string_to_utf8(msg, len - 2);
/* GSlist nth counts from 0, PB entries from 1 */
@@ -434,13 +457,13 @@ void handle_email(size_t len,
}
}
void handle_ext1(struct pb_data *pbd,
const unsigned char *msg,
char *ext_number,
struct pb_file_info *next_file)
void handle_ext1(struct pb_data *pbd, const unsigned char *msg,
char *ext_number, struct pb_file_info *next_file)
{
uint8_t number_length, i, next_extension_record;
if (!msg)
return;
number_length = msg[1];
@@ -494,7 +517,7 @@ void handle_ext1(struct pb_data *pbd,
list_entry->data;
if (entry) {
strcat(entry->anr,
ext_number);
ext_number);
}
}
}
@@ -610,8 +633,10 @@ static void pb_adn_sim_data_cb(const struct ofono_error *error,
file_info = cbd_outer->user;
cbd = cbd_outer->data;
if (!cbd)
if (!cbd) {
g_free(cbd_outer);
return;
}
pb = cbd->user;
cb = cbd->cb;
@@ -694,8 +719,10 @@ static void pb_adn_sim_data_cb(const struct ofono_error *error,
g_slist_free(phonebook_entry_start);
g_slist_free(pb_files);
g_free(cbd_outer);
void *pb = cbd->data;
g_free(cbd);
DBG("Finally all PB data read");
CALLBACK_WITH_SUCCESS(cb, cbd->data);
CALLBACK_WITH_SUCCESS(cb, pb);
return;
}
}
@@ -720,9 +747,6 @@ static void pb_adn_sim_info_cb(const struct ofono_error *error,
if (!cbd)
goto error;
pb = cbd->user;
cb = cbd->cb;
pbd = ofono_phonebook_get_data(pb);
file_info = NULL;
if (!pbd)
@@ -765,8 +789,12 @@ static void pb_adn_sim_info_cb(const struct ofono_error *error,
return;
error:
if (cb && cbd)
CALLBACK_WITH_FAILURE(cb, cbd->data);
if (cbd){
void *pb = cbd->data;
g_free(cbd);
if(cb)
CALLBACK_WITH_FAILURE(cb, pb);
}
}
static gboolean is_reading_required(uint8_t file_type)
@@ -799,9 +827,28 @@ static void pb_content_data_cb(const struct ofono_error *error,
if (extension_file_info)
file_info = decode_read_response(extension_file_info, sdata,
length, pb);
else
else {
/*
* These checks are crash hacks.
* AFAIK there's a possibility that we end up here and pb_next is NULL
* in case remove has been called while phonebook reading is in
* process. If you find better solution to this issue feel free to
* change this.
*/
if (pb_next == NULL) {
ofono_error("phonebook reading failed");
if (cbd){
void *pb = cbd->data;
g_free(cbd);
if(cb && pbd)
CALLBACK_WITH_FAILURE(cb, pb);
}
return;
}
file_info =
decode_read_response(pb_next->data, sdata, length, pb);
}
if (file_info) {
DBG("Reading extension file %04X, record %d, structure %d",
@@ -818,7 +865,7 @@ static void pb_content_data_cb(const struct ofono_error *error,
file_info = pb_next->data;
if (((file_info->structure ==
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
OFONO_SIM_FILE_STRUCTURE_FIXED) ||
(file_info->structure ==
OFONO_SIM_FILE_STRUCTURE_CYCLIC))
&& (file_info->record <
@@ -855,7 +902,7 @@ static void pb_content_data_cb(const struct ofono_error *error,
DBG("All data requested, start vCard creation");
while (list_entry) {
struct phonebook_entry *entry =
list_entry->data;
list_entry->data;
if (entry) {
DBG("vCard:\nname=%s\n",
@@ -892,8 +939,10 @@ static void pb_content_data_cb(const struct ofono_error *error,
g_slist_free(phonebook_entry_start);
g_slist_free(pb_files);
void *pb = cbd->data;
g_free(cbd);
DBG("Finally all PB data read");
CALLBACK_WITH_SUCCESS(cb, cbd->data);
CALLBACK_WITH_SUCCESS(cb, pb);
return;
}
@@ -958,8 +1007,12 @@ static void pb_content_data_read(struct pb_data *pbd,
return;
error:
if (cb && cbd)
CALLBACK_WITH_FAILURE(cb, cbd->data);
if (cbd){
void *pb = cbd->data;
g_free(cbd);
if(cb)
CALLBACK_WITH_FAILURE(cb, pb);
}
out:
DBG("Exiting");
@@ -1032,9 +1085,11 @@ static void pb_content_info_cb(const struct ofono_error *error,
return;
error:
if (cb && cbd) {
DBG("Error cbd=%p, pbd=%p, file_info=%p", cbd, pbd, file_info);
CALLBACK_WITH_FAILURE(cb, cbd->data);
if (cbd){
void *pb = cbd->data;
g_free(cbd);
if(cb)
CALLBACK_WITH_FAILURE(cb, pb);
}
}
@@ -1107,15 +1162,27 @@ static void pb_reference_data_cb(const struct ofono_error *error,
pbd->pb_reference_file_info.record_length)) {
pbd->pb_reference_file_info.record++;
DBG("Next EFpbr record %d", pbd->pb_reference_file_info.record);
pbd->sim_driver->read_file_linear(get_sim(),
pbd->pb_reference_file_info.
file_id,
pbd->pb_reference_file_info.
record,
pbd->pb_reference_file_info.
record_length,
NULL, 0,
pb_reference_data_cb, cbd);
if (RIL_APPTYPE_SIM == ril_get_app_type()) {
pbd->sim_driver->read_file_linear(get_sim(),
pbd->pb_reference_file_info.
file_id,
pbd->pb_reference_file_info.
record,
pbd->pb_reference_file_info.
record_length,
sim_path, sizeof(sim_path),
pb_reference_data_cb, cbd);
} else {
pbd->sim_driver->read_file_linear(get_sim(),
pbd->pb_reference_file_info.
file_id,
pbd->pb_reference_file_info.
record,
pbd->pb_reference_file_info.
record_length,
usim_path, sizeof(usim_path),
pb_reference_data_cb, cbd);
}
} else {
struct pb_file_info *file_info;
DBG("All EFpbr records read");
@@ -1137,8 +1204,12 @@ static void pb_reference_data_cb(const struct ofono_error *error,
return;
error:
if (cb && cbd)
CALLBACK_WITH_FAILURE(cb, cbd->data);
if (cbd){
void *pb = cbd->data;
g_free(cbd);
if(cb)
CALLBACK_WITH_FAILURE(cb, pb);
}
}
static void pb_reference_info_cb(const struct ofono_error *error,
@@ -1189,8 +1260,12 @@ static void pb_reference_info_cb(const struct ofono_error *error,
pb_reference_data_cb, cbd);
return;
error:
if (cb && cbd)
CALLBACK_WITH_FAILURE(cb, cbd->data);
if (cbd){
void *pb = cbd->data;
g_free(cbd);
if(cb)
CALLBACK_WITH_FAILURE(cb, pb);
}
}
static void ril_export_entries(struct ofono_phonebook *pb,
@@ -1229,10 +1304,12 @@ static void ril_export_entries(struct ofono_phonebook *pb,
error:
if (cb && cbd)
CALLBACK_WITH_FAILURE(cb, cbd->data);
g_free(cbd);
if (cbd){
void *pb = cbd->data;
g_free(cbd);
if(cb)
CALLBACK_WITH_FAILURE(cb, pb);
}
}
static gboolean ril_delayed_register(gpointer user_data)
@@ -1280,7 +1357,7 @@ static struct ofono_phonebook_driver driver = {
.name = "rilmodem",
.probe = ril_phonebook_probe,
.remove = ril_phonebook_remove,
.export_entries = ril_export_entries
.export_entries = ril_export_entries
};
void ril_phonebook_init(void)

View File

@@ -35,6 +35,7 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/radio-settings.h>
#include <ofono/sim.h>
#include "gril.h"
#include "grilutil.h"
@@ -74,7 +75,7 @@ static void ril_set_rat_mode(struct ofono_radio_settings *rs,
int pref = rd->ratmode;
int ret = 0;
ofono_info("setting rat mode");
ofono_info("rat mode set %d", mode);
parcel_init(&rilp);
@@ -115,6 +116,8 @@ static void ril_force_rat_mode(struct radio_data *rd, int pref)
if (pref == rd->ratmode)
return;
DBG("pref ril rat mode %d, ril current %d", pref, rd->ratmode);
parcel_init(&rilp);
parcel_w_int32(&rilp, 1);
parcel_w_int32(&rilp, rd->ratmode);
@@ -136,7 +139,7 @@ static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data)
if (message->error == RIL_E_SUCCESS) {
ril_util_init_parcel(message, &rilp);
/*first item in int[] is len so let's skip that*/
/* first item in int[] is len so let's skip that */
parcel_r_int32(&rilp);
pref = parcel_r_int32(&rilp);
@@ -166,6 +169,7 @@ static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data)
default:
break;
}
ofono_info("rat mode %d (ril %d)", mode, pref);
if (cb)
CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
} else {
@@ -200,11 +204,17 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
{
GKeyFile *keyfile;
GError *err = NULL;
char *path = RIL_CONFIG;
char *config_path = RIL_CONFIG_DIR;
char **alreadyset = NULL;
gboolean needsconfig = FALSE;
gboolean value = FALSE;
gboolean found = FALSE;
rsd->ratmode = PREF_NET_TYPE_GSM_WCDMA_AUTO;
GDir *config_dir;
const gchar *config_file;
gsize length;
gchar **codes = NULL;
int i;
/*
* First we need to check should the LTE be on
@@ -215,15 +225,45 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
g_key_file_set_list_separator(keyfile, ',');
if (g_key_file_load_from_file(keyfile, path, 0, &err)) {
config_dir = g_dir_open(config_path, 0, NULL);
while ((config_file = g_dir_read_name(config_dir)) != NULL) {
char *path = g_strconcat(RIL_CONFIG_DIR "/", config_file, NULL);
DBG("Rilconfig handling %s", path);
gboolean ok = g_key_file_load_from_file(keyfile, path, 0, &err);
g_free(path);
if (!ok) {
g_error_free(err);
DBG("Rilconfig file skipped");
continue;
}
if (g_key_file_has_group(keyfile, LTE_FLAG))
found = TRUE;
else if (g_key_file_has_group(keyfile, MCC_LIST)) {
codes = g_key_file_get_string_list(keyfile, MCC_LIST,
MCC_KEY, &length, NULL);
if (codes) {
for (i = 0; codes[i]; i++) {
if (g_str_equal(codes[i],
ofono_sim_get_mcc(get_sim()))
== TRUE) {
found = TRUE;
break;
}
}
g_strfreev(codes);
}
}
if (found) {
rsd->ratmode = PREF_NET_TYPE_LTE_GSM_WCDMA;
} else {
g_error_free(err);
needsconfig = TRUE;
break;
}
}
g_key_file_free(keyfile);
g_dir_close(config_dir);
/* Then we need to check if it already set */
@@ -250,6 +290,7 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
storage_close(NULL, RIL_STORE, keyfile, TRUE);
DBG("needsconfig %d, rat mode %d", needsconfig, rsd->ratmode);
return needsconfig;
}

View File

@@ -53,8 +53,10 @@ static int rilmodem_init(void)
ril_ussd_init();
ril_call_settings_init();
ril_call_forwarding_init();
ril_call_barring_init();
ril_cbs_init();
ril_oemraw_init();
ril_stk_init();
return 0;
}
@@ -76,8 +78,10 @@ static void rilmodem_exit(void)
ril_ussd_exit();
ril_call_settings_exit();
ril_call_forwarding_exit();
ril_call_barring_exit();
ril_cbs_exit();
ril_oemraw_exit();
ril_stk_exit();
}
OFONO_PLUGIN_DEFINE(rilmodem, "RIL modem driver", VERSION,

View File

@@ -28,9 +28,14 @@
/* Shared constants */
#define EF_STATUS_INVALIDATED 0
#define EF_STATUS_VALID 1
#define RIL_CONFIG "/etc/ofono/ril_subscription.conf"
#define RIL_HW_CONFIG "/etc/ofono/ril_subscription.conf"
#define RIL_CONFIG_DIR "/etc/ofono/"
#define RIL_STORE "rilmodem"
#define LTE_FLAG "4gOn"
#define MCC_LIST "MCC-whitelist"
#define MCC_KEY "Countries"
#define UI_LANG "/var/lib/environment/nemo/locale.conf"
#define CFG_LANG "LANG="
extern void ril_devinfo_init(void);
extern void ril_devinfo_exit(void);
@@ -68,6 +73,9 @@ extern void ril_call_settings_exit(void);
extern void ril_call_forwarding_init(void);
extern void ril_call_forwarding_exit(void);
extern void ril_call_barring_init(void);
extern void ril_call_barring_exit(void);
extern void ril_cbs_init(void);
extern void ril_cbs_exit(void);
@@ -76,3 +84,7 @@ extern void ril_phonebook_exit(void);
extern void ril_oemraw_init(void);
extern void ril_oemraw_exit(void);
extern void ril_stk_init(void);
extern void ril_stk_exit(void);

View File

@@ -402,13 +402,25 @@ gboolean ril_util_parse_sim_status(GRil *gril,
apps[i]->app_type = parcel_r_int32(&rilp);
apps[i]->app_state = parcel_r_int32(&rilp);
/*
* Consider RIL_APPSTATE_ILLEGAL also READY. Even if app state
* is RIL_APPSTATE_ILLEGAL (-1), ICC operations must be
* permitted. Network access requests will anyway be rejected
* and ME will be in limited service.
*/
if (apps[i]->app_state == RIL_APPSTATE_ILLEGAL) {
DBG("RIL_APPSTATE_ILLEGAL => RIL_APPSTATE_READY");
apps[i]->app_state = RIL_APPSTATE_READY;
}
apps[i]->perso_substate = parcel_r_int32(&rilp);
/* TODO: we need a way to instruct parcel to skip
* a string, without allocating memory...
*/
apps[i]->aid_str = parcel_r_string(&rilp); /* application ID (AID) */
apps[i]->app_str = parcel_r_string(&rilp); /* application label */
apps[i]->aid_str = parcel_r_string(&rilp); /* app ID (AID) */
apps[i]->app_str = parcel_r_string(&rilp); /* app label */
apps[i]->pin_replaced = parcel_r_int32(&rilp);
apps[i]->pin1_state = parcel_r_int32(&rilp);
@@ -459,7 +471,8 @@ gboolean ril_util_parse_reg(GRil *gril,
* >= 4 for VOICE_REG reply
* >= 5 for DATA_REG reply
*/
if ((tmp = parcel_r_int32(&rilp)) < 4) {
tmp = parcel_r_int32(&rilp);
if (tmp < 4) {
DBG("Size of response array is too small: %d", tmp);
goto error;
}
@@ -482,10 +495,12 @@ gboolean ril_util_parse_reg(GRil *gril,
* voice & data response.
*/
if (tmp--) {
sreason = parcel_r_string(&rilp); /* TODO: different use for CDMA */
/* TODO: different use for CDMA */
sreason = parcel_r_string(&rilp);
if (tmp--) {
smax = parcel_r_string(&rilp); /* TODO: different use for CDMA */
/* TODO: different use for CDMA */
smax = parcel_r_string(&rilp);
if (smax && max_calls)
*max_calls = atoi(smax);
@@ -518,7 +533,7 @@ gboolean ril_util_parse_reg(GRil *gril,
if (tech) {
if (stech) {
switch(atoi(stech)) {
switch (atoi(stech)) {
case RADIO_TECH_UNKNOWN:
*tech = -1;
break;
@@ -659,7 +674,8 @@ gint ril_util_get_signal(GRil *gril, struct ril_msg *message)
return -1;
}
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps) {
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps)
{
guint i;
for (i = 0; i < num_apps; i++) {

View File

@@ -62,29 +62,6 @@ enum at_util_charset {
RIL_UTIL_CHARSET_8859_H = 0x10000,
};
/* TODO: consider moving these to ril_constants.h */
enum app_state {
APPSTATE_UNKNOWN,
APPSTATE_DETECTED,
APPSTATE_PIN,
APPSTATE_PUK,
APPSTATE_SUBSCRIPTION_PERSO,
APPSTATE_READY,
};
enum perso_state {
PERSOSUBSTATE_SIM_NETWORK = 3,
PERSOSUBSTATE_SIM_NETWORK_SUBSET,
PERSOSUBSTATE_SIM_CORPORATE,
PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
PERSOSUBSTATE_SIM_SIM,
PERSOSUBSTATE_SIM_NETWORK_PUK,
PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK,
PERSOSUBSTATE_SIM_CORPORATE_PUK,
PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
PERSOSUBSTATE_SIM_SIM_PUK,
};
#define MAX_UICC_APPS 16
struct sim_status {
@@ -146,6 +123,12 @@ struct ofono_sim *get_sim();
gint check_if_really_roaming(gint status);
gboolean ril_roaming_allowed();
gboolean check_if_ok_to_attach();
gint get_current_network_status();
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps);
struct cb_data {
@@ -170,7 +153,7 @@ static inline struct cb_data *cb_data_new2(void *user, void *cb,
{
struct cb_data *ret;
ret = g_try_new0(struct cb_data, 1);
ret = g_new0(struct cb_data, 1);
if (ret) {
ret->cb = cb;
@@ -193,7 +176,7 @@ static inline int ril_util_convert_signal_strength(int strength)
return result;
}
#define DECLARE_FAILURE(e) \
#define DECLARE_FAILURE(e) \
struct ofono_error e; \
e.type = OFONO_ERROR_TYPE_FAILURE; \
e.error = 0 \

View File

@@ -4,6 +4,7 @@
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013 Canonical, Ltd. All rights reserved.
* Copyright (C) 2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -74,10 +75,6 @@
#define ENTER_SIM_PUK_PARAMS 3
#define CHANGE_SIM_PIN_PARAMS 3
/* RIL_FACILITY_LOCK parameters */
#define RIL_FACILITY_UNLOCK "0"
#define RIL_FACILITY_LOCK "1"
/* Current SIM */
static struct ofono_sim *current_sim;
/* Current active app */
@@ -106,6 +103,8 @@ struct sim_data {
enum ofono_sim_password_type passwd_state;
guint card_state;
guint idle_id;
gboolean initialized;
gboolean removed;
};
static void ril_pin_change_state_cb(struct ril_msg *message,
@@ -183,6 +182,15 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
DBG("");
/* In case sim card has been removed prior to this callback has been
* called we must not call the core call back method as otherwise the
* core will crash.
*/
if (sd->removed == TRUE) {
ofono_error("RIL_CARDSTATE_ABSENT");
return;
}
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
@@ -217,11 +225,13 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
if (response_len) {
if (response[0] == 0x62) {
ok = sim_parse_3g_get_response(response, response_len,
&flen, &rlen, &str, access, NULL);
ok = sim_parse_3g_get_response(
response, response_len,
&flen, &rlen, &str, access, NULL);
} else
ok = sim_parse_2g_get_response(response, response_len,
&flen, &rlen, &str, access, &file_status);
ok = sim_parse_2g_get_response(
response, response_len,
&flen, &rlen, &str, access, &file_status);
}
if (!ok) {
@@ -240,7 +250,8 @@ error:
}
static void ril_sim_read_info(struct ofono_sim *sim, int fileid,
const unsigned char *path, unsigned int path_len,
const unsigned char *path,
unsigned int path_len,
ofono_sim_file_info_cb_t cb,
void *data)
{
@@ -315,7 +326,7 @@ static void ril_file_io_cb(struct ril_msg *message, gpointer user_data)
decode_ril_error(&error, "OK");
} else {
ofono_error("RILD reply failure: %s",
ril_error_to_string(message->error));
ril_error_to_string(message->error));
goto error;
}
@@ -340,7 +351,8 @@ error:
static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
int start, int length,
const unsigned char *path, unsigned int path_len,
const unsigned char *path,
unsigned int path_len,
ofono_sim_read_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
@@ -393,7 +405,8 @@ static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
static void ril_sim_read_record(struct ofono_sim *sim, int fileid,
int record, int length,
const unsigned char *path, unsigned int path_len,
const unsigned char *path,
unsigned int path_len,
ofono_sim_read_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
@@ -506,10 +519,10 @@ static void ril_read_imsi(struct ofono_sim *sim, ofono_sim_imsi_cb_t cb,
}
}
void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
void set_pin_lock_state(struct ofono_sim *sim, struct sim_app *app)
{
DBG("pin1:%u,pin2:%u",app->pin1_state,app->pin2_state);
/*
DBG("pin1:%u,pin2:%u", app->pin1_state, app->pin2_state);
/*
* Updates only pin and pin2 state. Other locks are not dealt here. For
* that a RIL_REQUEST_QUERY_FACILITY_LOCK request should be used.
*/
@@ -518,10 +531,11 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
case RIL_PINSTATE_ENABLED_VERIFIED:
case RIL_PINSTATE_ENABLED_BLOCKED:
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,TRUE);
ofono_set_pin_lock_state(sim, OFONO_SIM_PASSWORD_SIM_PIN, TRUE);
break;
case RIL_PINSTATE_DISABLED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,FALSE);
ofono_set_pin_lock_state(
sim, OFONO_SIM_PASSWORD_SIM_PIN, FALSE);
break;
default:
break;
@@ -531,10 +545,12 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
case RIL_PINSTATE_ENABLED_VERIFIED:
case RIL_PINSTATE_ENABLED_BLOCKED:
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,TRUE);
ofono_set_pin_lock_state(
sim, OFONO_SIM_PASSWORD_SIM_PIN2, TRUE);
break;
case RIL_PINSTATE_DISABLED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,FALSE);
ofono_set_pin_lock_state(
sim, OFONO_SIM_PASSWORD_SIM_PIN2, FALSE);
break;
default:
break;
@@ -546,48 +562,53 @@ static void configure_active_app(struct sim_data *sd,
guint index)
{
sd->app_type = app->app_type;
g_free(sd->aid_str);
sd->aid_str = g_strdup(app->aid_str);
g_free(sd->app_str);
sd->app_str = g_strdup(app->app_str);
sd->app_index = index;
DBG("setting aid_str (AID) to: %s", sd->aid_str);
switch (app->app_state) {
case APPSTATE_PIN:
case RIL_APPSTATE_PIN:
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
break;
case APPSTATE_PUK:
case RIL_APPSTATE_PUK:
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
break;
case APPSTATE_SUBSCRIPTION_PERSO:
case RIL_APPSTATE_SUBSCRIPTION_PERSO:
switch (app->perso_substate) {
case PERSOSUBSTATE_SIM_NETWORK:
case RIL_PERSOSUBSTATE_SIM_NETWORK:
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PIN;
break;
case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET:
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PIN;
break;
case PERSOSUBSTATE_SIM_CORPORATE:
case RIL_PERSOSUBSTATE_SIM_CORPORATE:
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PIN;
break;
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PIN;
break;
case PERSOSUBSTATE_SIM_SIM:
case RIL_PERSOSUBSTATE_SIM_SIM:
sd->passwd_state = OFONO_SIM_PASSWORD_PHSIM_PIN;
break;
case PERSOSUBSTATE_SIM_NETWORK_PUK:
case RIL_PERSOSUBSTATE_SIM_NETWORK_PUK:
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PUK;
break;
case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PUK;
break;
case PERSOSUBSTATE_SIM_CORPORATE_PUK:
case RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK:
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PUK;
break;
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PUK;
break;
case PERSOSUBSTATE_SIM_SIM_PUK:
case RIL_PERSOSUBSTATE_SIM_SIM_PUK:
sd->passwd_state = OFONO_SIM_PASSWORD_PHFSIM_PUK;
break;
default:
@@ -595,11 +616,11 @@ static void configure_active_app(struct sim_data *sd,
break;
};
break;
case APPSTATE_READY:
case RIL_APPSTATE_READY:
sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
break;
case APPSTATE_UNKNOWN:
case APPSTATE_DETECTED:
case RIL_APPSTATE_UNKNOWN:
case RIL_APPSTATE_DETECTED:
default:
sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
break;
@@ -618,7 +639,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
DBG("");
if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
status.num_apps) {
DBG("num_apps: %d gsm_umts_index: %d", status.num_apps,
@@ -642,7 +663,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
if (sd->sim_registered == FALSE) {
ofono_sim_register(sim);
sd->sim_registered = TRUE;
} else
} else {
/* TODO: There doesn't seem to be any other
* way to force the core SIM code to
* recheck the PIN.
@@ -650,15 +671,17 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
* more appropriate call here??
* __ofono_sim_refresh(sim, NULL, TRUE, TRUE);
*/
DBG("sd->card_state:%u",sd->card_state);
DBG("sd->card_state:%u", sd->card_state);
if (sd->card_state != RIL_CARDSTATE_PRESENT) {
ofono_sim_inserted_notify(sim, TRUE);
sd->card_state = RIL_CARDSTATE_PRESENT;
sd->removed = FALSE;
}
}
if (current_passwd) {
if (!strcmp(current_passwd, defaultpasswd)) {
__ofono_sim_recheck_pin(sim);
__ofono_sim_recheck_pin(sim);
} else if (sd->passwd_state !=
OFONO_SIM_PASSWORD_SIM_PIN) {
__ofono_sim_recheck_pin(sim);
@@ -684,12 +707,11 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
if (current_online_state == RIL_ONLINE_PREF) {
parcel_init(&rilp);
parcel_init(&rilp);
parcel_w_int32(&rilp, 1);
parcel_w_int32(&rilp, 1);
ofono_info("RIL_REQUEST_RADIO_POWER ON");
g_ril_send(sd->ril,
RIL_REQUEST_RADIO_POWER,
rilp.data,
@@ -709,11 +731,16 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
if (status.card_state == RIL_CARDSTATE_ABSENT) {
DBG("sd->card_state:%u,status.card_state:%u,",
sd->card_state, status.card_state);
ofono_info("RIL_CARDSTATE_ABSENT");
ofono_sim_inserted_notify(sim, FALSE);
if (sd->card_state == RIL_CARDSTATE_PRESENT)
sd->removed = TRUE;
sd->card_state = RIL_CARDSTATE_ABSENT;
if (current_passwd)
g_stpcpy(current_passwd, defaultpasswd);
sd->initialized = FALSE;
}
}
@@ -754,16 +781,81 @@ static void ril_query_pin_retries(struct ofono_sim *sim,
CALLBACK_WITH_SUCCESS(cb, sd->retries, data);
}
static void ril_query_passwd_state_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
struct ofono_sim *sim = cbd->user;
struct sim_data *sd = ofono_sim_get_data(sim);
ofono_sim_passwd_cb_t cb = cbd->cb;
void *data = cbd->data;
struct sim_app *apps[MAX_UICC_APPS];
struct sim_status status;
guint i = 0;
guint search_index = -1;
gint state = ofono_sim_get_state(sim);
if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
status.num_apps) {
DBG("num_apps: %d gsm_umts_index: %d", status.num_apps,
status.gsm_umts_index);
/* TODO(CDMA): need some kind of logic to
* set the correct app_index,
*/
search_index = status.gsm_umts_index;
for (i = 0; i < status.num_apps; i++) {
if (i == search_index &&
apps[i]->app_type != RIL_APPTYPE_UNKNOWN) {
current_active_app = apps[i]->app_type;
configure_active_app(sd, apps[i], i);
set_pin_lock_state(sim, apps[i]);
break;
}
}
ril_util_free_sim_apps(apps, status.num_apps);
}
DBG("passwd_state %u", sd->passwd_state);
/* if pin code required cannot be initialized yet*/
if (sd->passwd_state == OFONO_SIM_PASSWORD_SIM_PIN)
sd->initialized = FALSE;
/*
* To prevent double call to sim_initialize_after_pin from
* sim_pin_query_cb we must prevent calling sim_pin_query_cb
* when !OFONO_SIM_STATE_READY && OFONO_SIM_PASSWORD_NONE
*/
if ((state == OFONO_SIM_STATE_READY) || (sd->initialized == FALSE) ||
(sd->passwd_state != OFONO_SIM_PASSWORD_NONE)){
if (sd->passwd_state == OFONO_SIM_PASSWORD_NONE)
sd->initialized = TRUE;
if (state == OFONO_SIM_STATE_LOCKED_OUT)
sd->initialized = FALSE;
if (sd->passwd_state == OFONO_SIM_PASSWORD_INVALID)
CALLBACK_WITH_FAILURE(cb, -1, data);
else
CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
}
}
static void ril_query_passwd_state(struct ofono_sim *sim,
ofono_sim_passwd_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
DBG("passwd_state %u", sd->passwd_state);
struct cb_data *cbd = cb_data_new2(sim, cb, data);
int request = RIL_REQUEST_GET_SIM_STATUS;
guint ret;
ret = g_ril_send(sd->ril, request,
NULL, 0, ril_query_passwd_state_cb, cbd, g_free);
g_ril_print_request_no_args(sd->ril, ret, request);
if (sd->passwd_state == OFONO_SIM_PASSWORD_INVALID)
CALLBACK_WITH_FAILURE(cb, -1, data);
else
CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
}
static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
@@ -787,8 +879,8 @@ static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
retries[passwd_type] = retry_count;
sd->retries[passwd_type] = retries[passwd_type];
/* TODO: re-bfactor to not use macro for FAILURE; doesn't return error! */
DBG("result=%d passwd_type=%d retry_count=%d",
message->error, passwd_type, retry_count);
if (message->error == RIL_E_SUCCESS) {
CALLBACK_WITH_SUCCESS(cb, cbd->data);
g_ril_print_response_no_args(sd->ril, message);
@@ -837,11 +929,53 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
}
}
static void ril_pin_change_state(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data)
static int ril_perso_change_state(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
int request = 0;
int ret = 0;
sd->passwd_type = passwd_type;
cbd->user = sd;
parcel_init(&rilp);
switch (passwd_type) {
case OFONO_SIM_PASSWORD_PHNET_PIN:
if (enable) {
DBG("Not supported, enable=%d", enable);
goto end;
}
request = RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION;
parcel_w_int32(&rilp, RIL_PERSOSUBSTATE_SIM_NETWORK);
parcel_w_string(&rilp, (char *) passwd);
break;
default:
DBG("Not supported, type=%d", passwd_type);
goto end;
}
ret = g_ril_send(sd->ril, request,
rilp.data, rilp.size, ril_pin_change_state_cb,
cbd, g_free);
g_ril_print_request(sd->ril, ret, request);
end:
parcel_free(&rilp);
return ret;
}
static void ril_pin_change_state(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data)
{
DBG("passwd_type=%d", passwd_type);
struct sim_data *sd = ofono_sim_get_data(sim);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
@@ -879,9 +1013,9 @@ static void ril_pin_change_state(struct ofono_sim *sim,
parcel_w_string(&rilp, "P2");
break;
case OFONO_SIM_PASSWORD_PHNET_PIN:
g_ril_append_print_buf(sd->ril, "(PN,");
parcel_w_string(&rilp, "PN");
break;
ret = ril_perso_change_state(sim, passwd_type, enable, passwd,
cb, data);
goto end;
case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
g_ril_append_print_buf(sd->ril, "(PU,");
parcel_w_string(&rilp, "PU");
@@ -895,8 +1029,7 @@ static void ril_pin_change_state(struct ofono_sim *sim,
parcel_w_string(&rilp, "PC");
break;
default:
CALLBACK_WITH_FAILURE(cb, data);
return;
goto end;
}
if (enable)
@@ -923,6 +1056,7 @@ static void ril_pin_change_state(struct ofono_sim *sim,
g_ril_print_request(sd->ril, ret, request);
end:
parcel_free(&rilp);
if (ret <= 0) {
@@ -1045,13 +1179,6 @@ static int ril_sim_probe(struct ofono_sim *sim, unsigned int vendor,
sd = g_new0(struct sim_data, 1);
sd->ril = g_ril_clone(ril);
sd->aid_str = NULL;
sd->app_str = NULL;
sd->app_type = RIL_APPTYPE_UNKNOWN;
sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
sd->passwd_type = OFONO_SIM_PASSWORD_NONE;
sd->sim_registered = FALSE;
sd->card_state = RIL_CARDSTATE_ABSENT;
for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
sd->retries[i] = -1;
@@ -1085,6 +1212,8 @@ static void ril_sim_remove(struct ofono_sim *sim)
if (sd->idle_id > 0)
g_source_remove(sd->idle_id);
g_free(sd->aid_str);
g_free(sd->app_str);
g_ril_unref(sd->ril);
g_free(sd);
}
@@ -1105,17 +1234,6 @@ static struct ofono_sim_driver driver = {
.change_passwd = ril_change_passwd,
.query_pin_retries = ril_query_pin_retries,
/*
* TODO: Implmenting PIN/PUK support requires defining
* the following driver methods.
*
* In the meanwhile, as long as the SIM card is present,
* and unlocked, the core SIM code will check for the
* presence of query_passwd_state, and if null, then the
* function sim_initialize_after_pin() is called.
*
* .query_pin_retries = ril_pin_retries_query,
* .query_locked = ril_pin_query_enabled,
*
* TODO: Implementing SIM write file IO support requires
* the following functions to be defined.
*

View File

@@ -38,10 +38,18 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/sms.h>
#include <ofono/types.h>
#include <ofono/sim.h>
#include "smsutil.h"
#include "util.h"
#include "rilmodem.h"
#include "simutil.h"
#define SIM_EFSMS_FILEID 0x6F3C
#define EFSMS_LENGTH 176
unsigned char path[4] = {0x3F, 0x00, 0x7F, 0x10};
struct sms_data {
GRil *ril;
@@ -131,7 +139,7 @@ static void ril_csca_query_cb(struct ril_msg *message, gpointer user_data)
sca.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
DBG("csca_query_cb: %s, %d", sca.number, sca.type);
g_free(temp_buf); /*g_utf16_to_utf8 used by parcel_r_string*/
cb(&error, &sca, cbd->data);
} else {
ofono_error("return value invalid");
@@ -168,10 +176,14 @@ static void submit_sms_cb(struct ril_msg *message, gpointer user_data)
int mr;
if (message->error == RIL_E_SUCCESS) {
ofono_info("sms sending succesful");
ofono_info("sms sending successful");
decode_ril_error(&error, "OK");
} else if (message->error == RIL_E_GENERIC_FAILURE) {
ofono_info("not allowed by MO SMS control, do not retry");
error.type = OFONO_ERROR_TYPE_CMS;
error.error = 500;
} else {
ofono_error("sms sending failed");
ofono_error("sms sending failed, retry");
decode_ril_error(&error, "FAIL");
}
@@ -230,6 +242,8 @@ static void ril_cmgs(struct ofono_sms *sms, const unsigned char *pdu,
submit_sms_cb, cbd, g_free);
g_ril_append_print_buf(sd->ril, "(%s)", tpdu);
g_free(tpdu);
tpdu = NULL;
g_ril_print_request(sd->ril, ret, request);
parcel_free(&rilp);
@@ -248,19 +262,21 @@ static void ril_ack_delivery_cb(struct ril_msg *message, gpointer user_data)
"SMS acknowledgement failed: Further SMS reception is not guaranteed");
}
static void ril_ack_delivery(struct ofono_sms *sms)
static void ril_ack_delivery(struct ofono_sms *sms, int error)
{
struct sms_data *sd = ofono_sms_get_data(sms);
struct parcel rilp;
int ret;
int request = RIL_REQUEST_SMS_ACKNOWLEDGE;
int code = 0;
if (!error)
code = 0xFF;
parcel_init(&rilp);
parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
parcel_w_int32(&rilp, 1); /* Successful receipt */
parcel_w_int32(&rilp, 0); /* error code */
/* TODO: should ACK be sent for either of the error cases? */
parcel_w_int32(&rilp, error); /* Successful (1)/Failed (0) receipt */
parcel_w_int32(&rilp, code); /* error code */
/* ACK the incoming NEW_SMS */
ret = g_ril_send(sd->ril, request,
@@ -285,6 +301,9 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
long ril_buf_len;
guchar *ril_data;
ril_pdu = NULL;
ril_data = NULL;
DBG("req: %d; data_len: %d", message->req, message->buf_len);
switch (message->req) {
@@ -317,6 +336,8 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
ofono_info("sms received, smsc_len is %d", smsc_len);
g_ril_append_print_buf(sd->ril, "(%s)", ril_pdu);
g_free(ril_pdu);
ril_pdu = NULL;
g_ril_print_unsol(sd->ril, message);
if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS) {
@@ -329,14 +350,116 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
ril_buf_len - smsc_len);
}
ril_ack_delivery(sms);
g_free(ril_data);
ril_data = NULL;
ril_ack_delivery(sms, TRUE);
return;
error:
g_free(ril_pdu);
ril_pdu = NULL;
g_free(ril_data);
ril_data = NULL;
ril_ack_delivery(sms, FALSE);
ofono_error("Unable to parse NEW_SMS notification");
}
static void ril_new_sms_on_sim_cb(struct ril_msg *message, gpointer user_data)
{
DBG("");
if (message->error == RIL_E_SUCCESS)
ofono_info("sms deleted from sim");
else
ofono_error("deleting sms from sim failed");
}
static void ril_request_delete_sms_om_sim(struct ofono_sms *sms,int record)
{
struct sms_data *data = ofono_sms_get_data(sms);
struct parcel rilp;
int request = RIL_REQUEST_DELETE_SMS_ON_SIM;
int ret;
DBG("Deleting record: %d", record);
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* Number of int32 values in array */
parcel_w_int32(&rilp, record);
ret = g_ril_send(data->ril, request, rilp.data,
rilp.size, ril_new_sms_on_sim_cb, NULL, NULL);
parcel_free(&rilp);
if (ret <= 0)
ofono_error("cannot delete sms from sim");
}
static void ril_read_sms_on_sim_cb(const struct ofono_error *error,
const unsigned char *sdata,
int length, void *data)
{
struct cb_data *cbd = data;
struct ofono_sms *sms = cbd->user;
int record;
unsigned int smsc_len;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_error("cannot read sms from sim");
goto exit;
}
/*
* It seems when reading EFsms RIL returns the whole record including
* the first status byte therefore we ignore that as we are only
* interested of the following pdu
*/
/* The first octect in the pdu contains the SMSC address length
* which is the X following octects it reads. We add 1 octet to
* the read length to take into account this read octet in order
* to calculate the proper tpdu length.
*/
smsc_len = sdata[1] + 1;
ofono_sms_deliver_notify(sms, sdata + 1, length - 1,
length - smsc_len - 1);
record = (int)cbd->data;
ril_request_delete_sms_om_sim(sms,record);
exit:
g_free(cbd);
}
static void ril_new_sms_on_sim(struct ril_msg *message, gpointer user_data)
{
struct ofono_sms *sms = user_data;
struct parcel rilp;
int record;
ofono_info("new sms on sim");
ril_util_init_parcel(message, &rilp);
/* data length of the response */
record = parcel_r_int32(&rilp);
if (record > 0) {
record = parcel_r_int32(&rilp);
struct cb_data *cbd = cb_data_new2(sms, NULL, (void*)record);
DBG(":%d", record);
get_sim_driver()->read_file_linear(get_sim(), SIM_EFSMS_FILEID,
record, EFSMS_LENGTH, path,
sizeof(path),
ril_read_sms_on_sim_cb, cbd);
}
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_sms *sms = user_data;
@@ -352,6 +475,8 @@ static gboolean ril_delayed_register(gpointer user_data)
ril_sms_notify, sms);
g_ril_register(data->ril, RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
ril_sms_notify, sms);
g_ril_register(data->ril, RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM,
ril_new_sms_on_sim, sms);
/* This makes the timeout a single-shot */
return FALSE;

View File

@@ -0,0 +1,342 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2014 Jolla Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <glib.h>
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/stk.h>
#include "gril.h"
#include "util.h"
#include "rilmodem.h"
#include "ril_constants.h"
struct stk_data {
GRil *ril;
};
gboolean subscribed;
static void ril_envelope_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_stk_envelope_cb_t cb = cbd->cb;
struct ofono_error error;
DBG("");
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
DBG("Envelope reply failure: %s",
ril_error_to_string(message->error));
decode_ril_error(&error, "FAIL");
}
cb(&error, NULL, 0, cbd->data);
}
static void ril_stk_envelope(struct ofono_stk *stk, int length,
const unsigned char *command,
ofono_stk_envelope_cb_t cb, void *data)
{
struct stk_data *sd = ofono_stk_get_data(stk);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
char *hex_envelope = NULL;
int request = RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND;
guint ret;
DBG("");
hex_envelope = encode_hex(command, length, 0);
DBG("rilmodem envelope: %s", hex_envelope);
parcel_init(&rilp);
parcel_w_string(&rilp, hex_envelope);
g_free(hex_envelope);
hex_envelope = NULL;
ret = g_ril_send(sd->ril, request,
rilp.data, rilp.size, ril_envelope_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, NULL, -1, data);
}
}
static void ril_tr_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_stk_generic_cb_t cb = cbd->cb;
struct ofono_error error;
DBG("");
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
DBG("Error in sending terminal response");
ofono_error("Error in sending terminal response");
decode_ril_error(&error, "FAIL");
}
cb(&error, cbd->data);
}
static void ril_stk_terminal_response(struct ofono_stk *stk, int length,
const unsigned char *resp,
ofono_stk_generic_cb_t cb, void *data)
{
struct stk_data *sd = ofono_stk_get_data(stk);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
char *hex_tr = NULL;
int request = RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE;
guint ret;
DBG("");
hex_tr = encode_hex(resp, length, 0);
DBG("rilmodem terminal response: %s", hex_tr);
parcel_init(&rilp);
parcel_w_string(&rilp, hex_tr);
g_free(hex_tr);
hex_tr = NULL;
ret = g_ril_send(sd->ril, request,
rilp.data, rilp.size, ril_tr_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, data);
}
}
static void ril_stk_user_confirmation(struct ofono_stk *stk,
ofono_bool_t confirm)
{
struct stk_data *sd = ofono_stk_get_data(stk);
struct parcel rilp;
int request = RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM;
int ret;
DBG("");
/* Only pcmd needing user confirmation is call set up
* RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
*/
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* size of array */
parcel_w_int32(&rilp, confirm); /* yes/no */
/* fire and forget i.e. not waiting for the callback*/
ret = g_ril_send(sd->ril, request, rilp.data,
rilp.size, NULL, NULL, NULL);
g_ril_print_request_no_args(sd->ril, ret, request);
parcel_free(&rilp);
}
static void ril_stk_pcmd_notify(struct ril_msg *message, gpointer user_data)
{
struct ofono_stk *stk = user_data;
struct parcel rilp;
char *pcmd = NULL;
guchar *pdu = NULL;
long len;
DBG("");
ril_util_init_parcel(message, &rilp);
pcmd = parcel_r_string(&rilp);
DBG("pcmd: %s", pcmd);
pdu = decode_hex((const char *) pcmd,
strlen(pcmd),
&len, -1);
g_free(pcmd);
ofono_stk_proactive_command_notify(stk, len, (const guchar *)pdu);
g_free(pdu);
}
static void ril_stk_event_notify(struct ril_msg *message, gpointer user_data)
{
struct ofono_stk *stk = user_data;
struct parcel rilp;
char *pcmd = NULL;
guchar *pdu = NULL;
long len;
DBG("");
/* Proactive command has been handled by the modem. */
ril_util_init_parcel(message, &rilp);
pcmd = parcel_r_string(&rilp);
DBG("pcmd: %s", pcmd);
pdu = decode_hex((const char *) pcmd,
strlen(pcmd),
&len, -1);
g_free(pcmd);
pcmd = NULL;
ofono_stk_proactive_command_handled_notify(stk, len,
(const guchar *)pdu);
g_free(pdu);
}
static void ril_stk_session_end_notify(struct ril_msg *message,
gpointer user_data)
{
struct ofono_stk *stk = user_data;
DBG("");
ofono_stk_proactive_session_end_notify(stk);
}
static void ril_stk_agent_ready(struct ofono_stk *stk)
{
struct stk_data *sd = ofono_stk_get_data(stk);
int request = RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING;
int ret;
DBG("");
if (!subscribed) {
DBG("Subscribing notifications");
g_ril_register(sd->ril, RIL_UNSOL_STK_PROACTIVE_COMMAND,
ril_stk_pcmd_notify, stk);
g_ril_register(sd->ril, RIL_UNSOL_STK_SESSION_END,
ril_stk_session_end_notify, stk);
g_ril_register(sd->ril, RIL_UNSOL_STK_EVENT_NOTIFY,
ril_stk_event_notify, stk);
subscribed = TRUE;
}
/* fire and forget i.e. not waiting for the callback*/
ret = g_ril_send(sd->ril, request, NULL, 0,
NULL, NULL, NULL);
g_ril_print_request_no_args(sd->ril, ret, request);
}
void ril_stk_set_lang()
{
gchar *contents;
GError *err = NULL;
if (!g_file_get_contents(UI_LANG, &contents, NULL, &err)) {
if (err)
ofono_error("cannot open %s error: %d: message: %s",
UI_LANG, err->code, err->message);
g_error_free(err);
} else {
gchar *pch = g_strrstr(contents, CFG_LANG);
/* Set System UI lang to env LANG */
if (pch) {
setenv("LANG", pch + strlen(CFG_LANG), 1);
DBG("LANG %s", getenv("LANG"));
}
g_free(contents);
}
}
static int ril_stk_probe(struct ofono_stk *stk, unsigned int vendor, void *data)
{
GRil *ril = data;
struct stk_data *sd;
DBG("");
sd = g_try_new0(struct stk_data, 1);
if (sd == NULL)
return -ENOMEM;
sd->ril = g_ril_clone(ril);
ofono_stk_set_data(stk, sd);
/* Register interface in this phase for stk agent */
ofono_stk_register(stk);
subscribed = FALSE;
/* UI language for local info */
ril_stk_set_lang();
return 0;
}
static void ril_stk_remove(struct ofono_stk *stk)
{
struct stk_data *sd = ofono_stk_get_data(stk);
DBG("");
ofono_stk_set_data(stk, NULL);
g_ril_unref(sd->ril);
g_free(sd);
}
static struct ofono_stk_driver driver = {
.name = "rilmodem",
.probe = ril_stk_probe,
.remove = ril_stk_remove,
.envelope = ril_stk_envelope,
.terminal_response = ril_stk_terminal_response,
.user_confirmation = ril_stk_user_confirmation,
.ready = ril_stk_agent_ready
};
void ril_stk_init(void)
{
ofono_stk_driver_register(&driver);
}
void ril_stk_exit(void)
{
ofono_stk_driver_unregister(&driver);
}

View File

@@ -68,19 +68,37 @@ static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
enum sms_charset charset;
int ret = -1;
ofono_info("send ussd");
ofono_info("send ussd, len:%d", len);
if (cbs_dcs_decode(dcs, NULL, NULL, &charset,
NULL, NULL, NULL)) {
if (charset == SMS_CHARSET_7BIT) {
unsigned char unpacked_buf[182] = "";
long written;
int length;
unpack_7bit_own_buf(pdu, len, 0, TRUE,
sizeof(unpacked_buf), &written, 0,
unpacked_buf);
if (written >= 1) {
/*
* When USSD was packed, additional CR
might have been added (according to
23.038 6.1.2.3.1). So if the last
character is CR, it should be removed
here. And in addition written doesn't
contain correct length...
Over 2 characters long USSD string must
end with # (checked in
valid_ussd_string() ), so it should be
safe to remove extra CR.
*/
length = strlen((char *)unpacked_buf);
if (length > 2 &&
unpacked_buf[length-1] == '\r')
unpacked_buf[length-1] = 0;
struct parcel rilp;
parcel_init(&rilp);
parcel_w_string(&rilp, (char *)unpacked_buf);
@@ -149,9 +167,9 @@ static void ril_ussd_notify(struct ril_msg *message, gpointer user_data)
{
struct ofono_ussd *ussd = user_data;
struct parcel rilp;
gchar *ussd_from_network;
gchar *type;
gint ussdtype;
gchar *ussd_from_network = NULL;
gchar *type = NULL;
gint ussdtype = 0;
ofono_info("ussd_received");
@@ -159,13 +177,17 @@ static void ril_ussd_notify(struct ril_msg *message, gpointer user_data)
parcel_r_int32(&rilp);
type = parcel_r_string(&rilp);
ussdtype = g_ascii_xdigit_value(*type);
g_free(type);
type = NULL;
ussd_from_network = parcel_r_string(&rilp);
if (ussd_from_network)
/* ussd_from_network not freed because core does that if dcs is 0xFF */
if (ussd_from_network) {
DBG("ussd_received, length %d", strlen(ussd_from_network));
ofono_ussd_notify(ussd, ussdtype, 0xFF,
(const unsigned char *)ussd_from_network,
strlen(ussd_from_network));
else
} else
ofono_ussd_notify(ussd, ussdtype, 0, NULL, 0);
return;

View File

@@ -4,7 +4,7 @@
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2012 Canonical Ltd.
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -45,9 +45,7 @@
/* Amount of ms we wait between CLCC calls */
#define POLL_CLCC_INTERVAL 300
#define FLAG_NEED_CLIP 1
#define MAX_DTMF_BUFFER 32
struct voicecall_data {
@@ -86,6 +84,21 @@ struct lastcause_req {
static void send_one_dtmf(struct voicecall_data *vd);
static void clear_dtmf_queue(struct voicecall_data *vd);
/*
* structs ofono_voicecall and voicecall are fully defined
* in src/voicecall.c; we need (read) access to the
* call objects, so partially redefine them here.
*/
struct ofono_voicecall {
GSList *call_list;
/* ... */
};
struct voicecall {
struct ofono_call *call;
/* ... */
};
static void lastcause_cb(struct ril_msg *message, gpointer user_data)
{
struct lastcause_req *reqdata = user_data;
@@ -99,11 +112,38 @@ static void lastcause_cb(struct ril_msg *message, gpointer user_data)
if (parcel_r_int32(&rilp) > 0)
last_cause = parcel_r_int32(&rilp);
/*
* Not all call control cause values specified in 3GPP TS 24.008
* "Mobile radio interface Layer 3 specification; Core network protocols",
* Annex H, are properly reflected in the RIL API. For example, cause
* #21 "call rejected" is mapped to CALL_FAIL_ERROR_UNSPECIFIED, and
* thus indistinguishable from a network failure.
* We signal disconnect reason "remote" for cause values
* - #16 "normal call clearing"
* - #17 "user busy"
* - UNSPECIFIED for MO calls that are not yet connected
* , and disconnect reason "network" otherwise.
*/
ofono_info("Call %d ended with RIL cause %d", id, last_cause);
if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) {
reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
}
if (last_cause == CALL_FAIL_ERROR_UNSPECIFIED) {
GSList *l;
struct voicecall *v;
for (l = vc->call_list; l; l = l->next) {
v = l->data;
if (v->call->id == id) {
if (v->call->status == CALL_STATUS_DIALING
|| v->call->status == CALL_STATUS_ALERTING) {
reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
}
break;
}
}
}
ofono_voicecall_disconnected(vc, id, reason, NULL);
}
@@ -236,6 +276,8 @@ static void generic_cb(struct ril_msg *message, gpointer user_data)
int request = RIL_REQUEST_GET_CURRENT_CALLS;
int ret;
ofono_info("request:%d",message->req);
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
@@ -340,15 +382,17 @@ static void ril_dial(struct ofono_voicecall *vc,
struct parcel rilp;
int request = RIL_REQUEST_DIAL;
int ret;
char *phstr = NULL;
ofono_info("dialing");
phstr = (char *) phone_number_to_string(ph);
ofono_info("dialing \"%s\"", phstr);
cbd->user = vc;
parcel_init(&rilp);
/* Number to dial */
parcel_w_string(&rilp, (char *) phone_number_to_string(ph));
parcel_w_string(&rilp, phstr);
/* CLIR mode */
parcel_w_int32(&rilp, clir);
/* USS, need it twice for absent */
@@ -481,6 +525,7 @@ static void ril_ss_notify(struct ril_msg *message, gpointer user_data)
strncpy(number.number, tmp_number,
OFONO_MAX_PHONE_NUMBER_LENGTH);
g_free(tmp_number);
DBG("RIL data: MT/MO: %i, code: %i, index: %i",
notification_type, code, index);
break;
@@ -634,6 +679,13 @@ static void ril_create_multiparty(struct ofono_voicecall *vc,
cb(&error, data);
}
static void ril_transfer(struct ofono_voicecall *vc,
ofono_voicecall_cb_t cb, void *data)
{
ril_template(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, vc, generic_cb, 0,
NULL, 0, cb, data);
}
static void private_chat_cb(struct ril_msg *message, gpointer user_data)
{
struct ofono_error error;
@@ -727,6 +779,23 @@ static gboolean enable_supp_svc(gpointer user_data)
return FALSE;
}
static void ril_ringback_tone_notify(struct ril_msg *message,
gpointer user_data)
{
struct parcel rilp;
struct ofono_voicecall *vc = user_data;
gboolean playTone = FALSE;
ril_util_init_parcel(message, &rilp);
if (message->req == RIL_UNSOL_RINGBACK_TONE) {
if (parcel_r_int32(&rilp) > 0)
playTone = parcel_r_int32(&rilp);
DBG("play ringback tone: %d", playTone);
ofono_voicecall_ringback_tone_notify(vc, playTone);
}
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_voicecall *vc = user_data;
@@ -747,6 +816,10 @@ static gboolean ril_delayed_register(gpointer user_data)
g_ril_register(vd->ril, RIL_UNSOL_SUPP_SVC_NOTIFICATION,
ril_ss_notify, vc);
/* Register for ringback tone notifications */
g_ril_register(vd->ril, RIL_UNSOL_RINGBACK_TONE,
ril_ringback_tone_notify, vc);
/* request supplementary service notifications*/
enable_supp_svc(vc);
@@ -803,6 +876,7 @@ static void ril_voicecall_remove(struct ofono_voicecall *vc)
if (vd->timer_id > 0)
g_source_remove(vd->timer_id);
g_free(vd->tone_queue);
g_ril_unref(vd->ril);
g_free(vd);
}
@@ -817,12 +891,13 @@ static struct ofono_voicecall_driver driver = {
.release_specific = ril_hangup_specific,
.send_tones = ril_send_dtmf,
.create_multiparty = ril_create_multiparty,
.transfer = ril_transfer,
.private_chat = ril_private_chat,
.swap_without_accept = ril_swap_without_accept,
.hold_all_active = ril_hold_all_active,
.release_all_held = ril_release_all_held,
.set_udub = ril_set_udub,
.release_all_active = ril_release_all_active,
.release_all_active = ril_release_all_active,
};
void ril_voicecall_init(void)

View File

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

View File

@@ -835,6 +835,9 @@ static gboolean can_write_data(gpointer data)
gsize len;
char *cr;
gboolean wakeup_first = FALSE;
#ifdef WRITE_SCHEDULER_DEBUG
int limiter;
#endif
/* Grab the first command off the queue and write as
* much of it as we can
@@ -886,13 +889,20 @@ static gboolean can_write_data(gpointer data)
towrite = cr - (cmd->cmd + chat->cmd_bytes_written) + 1;
#ifdef WRITE_SCHEDULER_DEBUG
if (towrite > 5)
towrite = 5;
limiter = towrite;
if (limiter > 5)
limiter = 5;
#endif
bytes_written = g_at_io_write(chat->io,
cmd->cmd + chat->cmd_bytes_written,
towrite);
#ifdef WRITE_SCHEDULER_DEBUG
limiter
#else
towrite
#endif
);
if (bytes_written == 0)
return FALSE;

View File

@@ -56,6 +56,8 @@ struct GDBusClient {
void *signal_data;
GDBusProxyFunction proxy_added;
GDBusProxyFunction proxy_removed;
GDBusClientFunction ready;
void *ready_data;
GDBusPropertyFunction property_changed;
void *user_data;
GList *proxy_list;
@@ -725,6 +727,93 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
return TRUE;
}
gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
const char *name, int type, const void *value,
size_t size, GDBusResultFunction function,
void *user_data, GDBusDestroyFunction destroy)
{
struct set_property_data *data;
GDBusClient *client;
DBusMessage *msg;
DBusMessageIter iter, variant, array;
DBusPendingCall *call;
char array_sig[3];
char type_sig[2];
if (!proxy || !name || !value)
return FALSE;
if (!dbus_type_is_basic(type))
return FALSE;
client = proxy->client;
if (!client)
return FALSE;
data = g_try_new0(struct set_property_data, 1);
if (!data)
return FALSE;
data->function = function;
data->user_data = user_data;
data->destroy = destroy;
msg = dbus_message_new_method_call(client->service_name,
proxy->obj_path,
DBUS_INTERFACE_PROPERTIES,
"Set");
if (!msg) {
g_free(data);
return FALSE;
}
array_sig[0] = DBUS_TYPE_ARRAY;
array_sig[1] = (char) type;
array_sig[2] = '\0';
type_sig[0] = (char) type;
type_sig[1] = '\0';
dbus_message_iter_init_append(msg, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
&proxy->interface);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
array_sig, &variant);
dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
type_sig, &array);
if (dbus_type_is_fixed(type))
dbus_message_iter_append_fixed_array(&array, type, &value,
size);
else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
const char **str = (const char **) value;
size_t i;
for (i = 0; i < size; i++)
dbus_message_iter_append_basic(&array, type, &str[i]);
}
dbus_message_iter_close_container(&variant, &array);
dbus_message_iter_close_container(&iter, &variant);
if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, -1) == FALSE) {
dbus_message_unref(msg);
g_free(data);
return FALSE;
}
dbus_pending_call_set_notify(call, set_property_reply, data, g_free);
dbus_pending_call_unref(call);
dbus_message_unref(msg);
return TRUE;
}
struct method_call_data {
GDBusReturnFunction function;
void *user_data;
@@ -982,6 +1071,9 @@ static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
dbus_message_iter_next(&dict);
}
if (client->ready)
client->ready(client, client->ready_data);
}
static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
@@ -1243,6 +1335,18 @@ gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
return TRUE;
}
gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
GDBusClientFunction ready, void *user_data)
{
if (client == NULL)
return FALSE;
client->ready = ready;
client->ready_data = user_data;
return TRUE;
}
gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
GDBusProxyFunction proxy_added,
GDBusProxyFunction proxy_removed,

View File

@@ -329,6 +329,11 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
GDBusResultFunction function, void *user_data,
GDBusDestroyFunction destroy);
gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
const char *name, int type, const void *value,
size_t size, GDBusResultFunction function,
void *user_data, GDBusDestroyFunction destroy);
typedef void (* GDBusSetupFunction) (DBusMessageIter *iter, void *user_data);
typedef void (* GDBusReturnFunction) (DBusMessage *message, void *user_data);
@@ -337,6 +342,7 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
GDBusReturnFunction function, void *user_data,
GDBusDestroyFunction destroy);
typedef void (* GDBusClientFunction) (GDBusClient *client, void *user_data);
typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
DBusMessageIter *iter, void *user_data);
@@ -359,7 +365,8 @@ gboolean g_dbus_client_set_disconnect_watch(GDBusClient *client,
GDBusWatchFunction function, void *user_data);
gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
GDBusMessageFunction function, void *user_data);
gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
GDBusClientFunction ready, void *user_data);
gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
GDBusProxyFunction proxy_added,
GDBusProxyFunction proxy_removed,

View File

@@ -30,8 +30,6 @@
#include "gdbus.h"
#define DISPATCH_TIMEOUT 0
#define info(fmt...)
#define error(fmt...)
#define debug(fmt...)
@@ -70,8 +68,6 @@ static gboolean message_dispatch(void *data)
{
DBusConnection *conn = data;
dbus_connection_ref(conn);
/* Dispatch messages */
while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
@@ -84,7 +80,7 @@ static inline void queue_dispatch(DBusConnection *conn,
DBusDispatchStatus status)
{
if (status == DBUS_DISPATCH_DATA_REMAINS)
g_timeout_add(DISPATCH_TIMEOUT, message_dispatch, conn);
g_idle_add(message_dispatch, dbus_connection_ref(conn));
}
static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
@@ -92,9 +88,6 @@ static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
struct watch_info *info = data;
unsigned int flags = 0;
DBusDispatchStatus status;
DBusConnection *conn;
conn = dbus_connection_ref(info->conn);
if (cond & G_IO_IN) flags |= DBUS_WATCH_READABLE;
if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
@@ -103,10 +96,8 @@ static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
dbus_watch_handle(info->watch, flags);
status = dbus_connection_get_dispatch_status(conn);
queue_dispatch(conn, status);
dbus_connection_unref(conn);
status = dbus_connection_get_dispatch_status(info->conn);
queue_dispatch(info->conn, status);
return TRUE;
}

View File

@@ -1253,6 +1253,8 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
if (!dbus_connection_register_object_path(connection, path,
&generic_table, data)) {
dbus_connection_unref(data->conn);
g_free(data->path);
g_free(data->introspect);
g_free(data);
return NULL;

View File

@@ -85,6 +85,7 @@ struct ril_s {
guint next_cmd_id; /* Next command id */
guint next_notify_id; /* Next notify id */
guint next_gid; /* Next group id */
int sk; /* Socket */
GRilIO *io; /* GRil IO */
GQueue *command_queue; /* Command queue */
GQueue *out_queue; /* Commands sent/been sent */
@@ -355,7 +356,8 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
int i;
guint len, id;
g_assert(count > 0);
if (!count)
return;
for (i = 0; i < count; i++) {
req = g_queue_peek_nth(p->command_queue, i);
@@ -373,13 +375,13 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
message->error));
req = g_queue_pop_nth(p->command_queue, i);
if (req->callback) {
if (req->callback)
req->callback(message, req->user_data);
}
len = g_queue_get_length(p->out_queue);
for (i = 0; i < len; i++) {
id = *(guint *) g_queue_peek_nth(p->out_queue, i);
id = *(guint *) g_queue_peek_nth(
p->out_queue, i);
if (id == req->id) {
g_queue_pop_nth(p->out_queue, i);
break;
@@ -403,14 +405,21 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
}
static void notify_call_callback(gpointer data, gpointer user_data)
{
struct ril_notify_node *node = data;
struct ril_msg *message = user_data;
node->callback(message, node->user_data);
}
static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
{
GHashTableIter iter;
struct ril_notify *notify;
int req_key;
gpointer key, value;
GList *list_item;
struct ril_notify_node *node;
GSList *list_item;
gboolean found = FALSE;
if (p->notify_list == NULL)
@@ -430,15 +439,12 @@ static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
if (req_key != message->req)
continue;
list_item = (GList *) notify->nodes;
list_item = notify->nodes;
while (list_item != NULL) {
node = list_item->data;
node->callback(message, node->user_data);
if (list_item)
found = TRUE;
list_item = (GList *) g_slist_next(list_item);
}
g_slist_foreach(notify->nodes, notify_call_callback, message);
}
/* Only log events not being listended for... */
@@ -582,9 +588,8 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
while (p->suspended == FALSE && (p->read_so_far < len)) {
gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
if (rbytes < 4) {
if (rbytes < 4)
return;
}
/* this function attempts to read the next full length
* fixed message from the stream. if not all bytes are
@@ -595,9 +600,8 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
message = read_fixed_record(p, buf, &rbytes);
/* wait for the rest of the record... */
if (message == NULL) {
if (message == NULL)
break;
}
buf += rbytes;
p->read_so_far += rbytes;
@@ -642,7 +646,8 @@ static gboolean can_write_data(gpointer data)
for (i = 0; i < qlen; i++) {
req = g_queue_peek_nth(ril->command_queue, i);
if (req) {
id = *(guint *) g_queue_peek_head(ril->out_queue);
id = *(guint *) g_queue_peek_head(
ril->out_queue);
if (req->id == id)
goto out;
} else {
@@ -782,6 +787,7 @@ static void ril_unref(struct ril_s *ril)
g_ril_io_unref(ril->io);
ril->io = NULL;
ril_cleanup(ril);
close(ril->sk);
}
if (ril->in_read_handler)
@@ -806,7 +812,6 @@ static struct ril_s *create_ril()
{
struct ril_s *ril;
struct sockaddr_un addr;
int sk;
GIOChannel *io;
GKeyFile *keyfile;
char **subscriptions = NULL;
@@ -827,8 +832,8 @@ static struct ril_s *create_ril()
ril->trace = FALSE;
ril->connected = FALSE;
sk = socket(AF_UNIX, SOCK_STREAM, 0);
if (sk < 0) {
ril->sk = socket(AF_UNIX, SOCK_STREAM, 0);
if (ril->sk < 0) {
ofono_error("create_ril: can't create unix socket: %s (%d)\n",
strerror(errno), errno);
goto error;
@@ -838,13 +843,13 @@ static struct ril_s *create_ril()
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, RILD_CMD_SOCKET, sizeof(addr.sun_path) - 1);
if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
if (connect(ril->sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
strerror(errno), errno);
goto error;
}
io = g_io_channel_unix_new(sk);
io = g_io_channel_unix_new(ril->sk);
if (io == NULL) {
ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
strerror(errno), errno);

View File

@@ -73,6 +73,7 @@ static void read_watcher_destroy_notify(gpointer user_data)
io->read_handler = NULL;
io->read_data = NULL;
g_io_channel_unref(io->channel);
io->channel = NULL;
if (io->destroyed)

View File

@@ -159,19 +159,8 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
}
/* TODO:
* RILD can return multiple addresses; oFono only supports
* setting a single IPv4 address. At this time, we only
* use the first address. It's possible that a RIL may
* just specify the end-points of the point-to-point
* connection, in which case this code will need to
* changed to handle such a device.
*
* For now split into a maximum of three, and only use
* the first address for the remaining operations.
*/
if (raw_ip_addrs)
reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", 3);
reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", -1);
else
reply->ip_addrs = NULL;
@@ -191,7 +180,7 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
* setting a single IPv4 gateway.
*/
if (raw_gws)
reply->gateways = g_strsplit(raw_gws, " ", 3);
reply->gateways = g_strsplit(raw_gws, " ", -1);
else
reply->gateways = NULL;
@@ -203,7 +192,7 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
/* Split DNS addresses */
if (dnses)
reply->dns_addresses = g_strsplit(dnses, " ", 3);
reply->dns_addresses = g_strsplit(dnses, " ", -1);
else
reply->dns_addresses = NULL;

View File

@@ -191,6 +191,7 @@
#define RIL_PERSOSUBSTATE_RUIM_RUIM_PUK 24
/* SIM - App states */
#define RIL_APPSTATE_ILLEGAL -1
#define RIL_APPSTATE_UNKNOWN 0
#define RIL_APPSTATE_DETECTED 1
#define RIL_APPSTATE_PIN 2
@@ -387,4 +388,8 @@
/* Suplementary services Service class*/
#define SERVICE_CLASS_NONE 0
/* RIL_FACILITY_LOCK parameters */
#define RIL_FACILITY_UNLOCK "0"
#define RIL_FACILITY_LOCK "1"
#endif /*__RIL_CONSTANTS_H*/

View File

@@ -80,29 +80,29 @@ extern "C" {
DBusConnection *ofono_dbus_get_connection(void);
void ofono_dbus_dict_append(DBusMessageIter *dict, const char *key, int type,
void *value);
const void *value);
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
int type, void *val);
int type, const void *val);
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
int type, void *val);
int type, const void *val);
int ofono_dbus_signal_property_changed(DBusConnection *conn, const char *path,
const char *interface, const char *name,
int type, void *value);
int type, const void *value);
int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
const char *path,
const char *interface,
const char *name, int type,
void *value);
const void *value);
int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
const char *path,
const char *interface,
const char *name, int type,
void *value);
const void *value);
#ifdef __cplusplus
}

View File

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

View File

@@ -78,6 +78,8 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
void ofono_gprs_add_context(struct ofono_gprs *gprs,
struct ofono_gprs_context *gc);
struct ofono_modem *ofono_gprs_get_modem(struct ofono_gprs *gprs);
#ifdef __cplusplus
}
#endif

View File

@@ -36,12 +36,18 @@ typedef void (*ofono_handsfree_cb_t)(const struct ofono_error *error,
typedef void (*ofono_handsfree_phone_cb_t)(const struct ofono_error *error,
const struct ofono_phone_number *number,
void *data);
typedef void (*ofono_handsfree_cnum_query_cb_t)(const struct ofono_error *error,
int total,
const struct ofono_phone_number *numbers,
void *data);
struct ofono_handsfree_driver {
const char *name;
int (*probe)(struct ofono_handsfree *hf, unsigned int vendor,
void *data);
void (*remove)(struct ofono_handsfree *hf);
void (*cnum_query)(struct ofono_handsfree *hf,
ofono_handsfree_cnum_query_cb_t cb, void *data);
void (*request_phone_number) (struct ofono_handsfree *hf,
ofono_handsfree_phone_cb_t cb,
void *data);
@@ -54,6 +60,8 @@ struct ofono_handsfree_driver {
void ofono_handsfree_set_ag_features(struct ofono_handsfree *hf,
unsigned int ag_features);
void ofono_handsfree_set_ag_chld_features(struct ofono_handsfree *hf,
unsigned int ag_chld_features);
void ofono_handsfree_set_inband_ringing(struct ofono_handsfree *hf,
ofono_bool_t enabled);
void ofono_handsfree_voice_recognition_notify(struct ofono_handsfree *hf,

View File

@@ -48,6 +48,7 @@ struct ofono_stk_driver {
int length, const unsigned char *resp,
ofono_stk_generic_cb_t cb, void *data);
void (*user_confirmation)(struct ofono_stk *stk, ofono_bool_t confirm);
void (*ready)(struct ofono_stk *stk);
};
int ofono_stk_driver_register(const struct ofono_stk_driver *d);

View File

@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -171,6 +172,9 @@ void ofono_voicecall_ssn_mt_notify(struct ofono_voicecall *vc, unsigned int id,
int code, int index,
const struct ofono_phone_number *ph);
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
const ofono_bool_t playTone);
#ifdef __cplusplus
}
#endif

View File

@@ -59,6 +59,7 @@
#include <drivers/atmodem/vendor.h>
static const char *none_prefix[] = { NULL };
static const char *qss_prefix[] = { "#QSS:", NULL };
struct he910_data {
GAtChat *chat; /* AT chat */
@@ -101,7 +102,7 @@ static GAtChat *open_device(struct ofono_modem *modem,
if (channel == NULL)
return NULL;
syntax = g_at_syntax_new_gsmv1();
syntax = g_at_syntax_new_gsm_permissive();
chat = g_at_chat_new(channel, syntax);
g_at_syntax_unref(syntax);
g_io_channel_unref(channel);
@@ -167,6 +168,31 @@ static void he910_qss_notify(GAtResult *result, gpointer user_data)
switch_sim_state_status(modem, status);
}
static void qss_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_modem *modem = user_data;
int status, mode;
GAtResultIter iter;
DBG("%p", modem);
if (!ok)
return;
g_at_result_iter_init(&iter, result);
if (!g_at_result_iter_next(&iter, "#QSS:"))
return;
if (!g_at_result_iter_next_number(&iter, &mode))
return;
if (!g_at_result_iter_next_number(&iter, &status))
return;
switch_sim_state_status(modem, status);
}
static void cfun_enable_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_modem *modem = user_data;
@@ -204,6 +230,15 @@ static void cfun_enable_cb(gboolean ok, GAtResult *result, gpointer user_data)
g_at_chat_send(data->chat, "AT#AUTOATT=0", none_prefix,
NULL, NULL, NULL);
/* Follow sim state */
g_at_chat_register(data->chat, "#QSS:", he910_qss_notify,
FALSE, modem, NULL);
/* Enable sim state notification */
g_at_chat_send(data->chat, "AT#QSS=2", none_prefix, NULL, NULL, NULL);
g_at_chat_send(data->chat, "AT#QSS?", qss_prefix,
qss_query_cb, modem, NULL);
}
static int he910_enable(struct ofono_modem *modem)
@@ -232,13 +267,6 @@ static int he910_enable(struct ofono_modem *modem)
g_at_chat_send(data->chat, "ATE0 +CMEE=1", none_prefix,
NULL, NULL, NULL);
/* Follow sim state */
g_at_chat_register(data->chat, "#QSS:", he910_qss_notify,
FALSE, modem, NULL);
/* Enable sim state notification */
g_at_chat_send(data->chat, "AT#QSS=2", none_prefix, NULL, NULL, NULL);
/* Set phone functionality */
g_at_chat_send(data->chat, "AT+CFUN=1", none_prefix,
cfun_enable_cb, modem, NULL);

View File

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

View File

@@ -188,11 +188,11 @@ static int nettime_probe(struct ofono_nettime_context *context)
NULL, // GDBusPropertyTable *properties
NULL, // user data
NULL)) { // GDBusDestroyFunction destroy
ofono_error("Networkt time: Could not register interface %s, path %s",
ofono_error("Network time: Could not register interface %s, path %s",
OFONO_NETWORK_TIME_INTERFACE, path);
return 1;
} else {
ofono_info("Network time: Registered inteface %s, path %s",
ofono_info("Network time: Registered interface %s, path %s",
OFONO_NETWORK_TIME_INTERFACE, path);
}
@@ -235,6 +235,12 @@ static void nettime_info_received(struct ofono_nettime_context *context,
netreg = __ofono_atom_get_data(__ofono_modem_find_atom(
context->modem, OFONO_ATOM_TYPE_NETREG));
if (!(ofono_netreg_get_mcc(netreg) && ofono_netreg_get_mnc(netreg))) {
DBG("Incomplete network time received, ignoring");
return;
}
ntd->path = ofono_modem_get_path(context->modem);
ntd->mcc = ofono_netreg_get_mcc(netreg);
ntd->mnc = ofono_netreg_get_mnc(netreg);

View File

@@ -1071,6 +1071,7 @@ done:
static int phonesim_init(void)
{
int err;
char *conf_override = getenv("OFONO_PHONESIM_CONFIG");
err = ofono_modem_driver_register(&phonesim_driver);
if (err < 0)
@@ -1081,7 +1082,10 @@ static int phonesim_init(void)
ofono_gprs_context_driver_register(&context_driver);
ofono_ctm_driver_register(&ctm_driver);
parse_config(CONFIGDIR "/phonesim.conf");
if (conf_override)
parse_config(conf_override);
else
parse_config(CONFIGDIR "/phonesim.conf");
return 0;
}

View File

@@ -24,6 +24,7 @@
#include <config.h>
#endif
#define _GNU_SOURCE
#include <errno.h>
#include <string.h>
@@ -36,9 +37,134 @@
#include <ofono/modem.h>
#include <ofono/gprs-provision.h>
#include "provision.h"
#include "mbpi.h"
static int provision_get_settings(const char *mcc, const char *mnc,
/* Returns the list containing exactly one INTERNET and one MMS access point */
static GSList *provision_normalize_apn_list(GSList *apns, const char* spn)
{
struct ofono_gprs_provision_data *best_internet = NULL;
struct ofono_gprs_provision_data *best_mms = NULL;
struct ofono_gprs_provision_data *second_best_internet = NULL;
struct ofono_gprs_provision_data *second_best_mms = NULL;
GSList *best_apns = NULL;
GSList *l;
/* 1. save the first found internet APN and the first MMS APN */
l = apns;
while (l != NULL) {
GSList *next = l->next;
struct ofono_gprs_provision_data *ap = l->data;
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
&& !best_internet) {
best_internet = ap;
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
&& !best_mms) {
best_mms = ap;
}
l = next;
}
/*
* 2. look for a "primary" provider (i.e. an MNO, not
* an MVNO on the same radio network)
*/
second_best_internet = best_internet;
best_internet = NULL;
second_best_mms = best_mms;
best_mms = NULL;
l = apns;
while (l != NULL) {
GSList *next = l->next;
struct ofono_gprs_provision_data *ap = l->data;
if (ap->provider_primary) {
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
&& !best_internet) {
best_internet = ap;
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
&& !best_mms) {
best_mms = ap;
}
}
l = next;
}
/* no better match found */
if (!best_internet)
best_internet = second_best_internet;
if (!best_mms)
best_mms = second_best_mms;
/*
* 3. if there is an SPN given, save the first internet APN and the
* first MMS APN matching the SPN (partially, case-insensitively)
* */
if (spn) {
second_best_internet = best_internet;
best_internet = NULL;
second_best_mms = best_mms;
best_mms = NULL;
l = apns;
while (l != NULL) {
GSList *next = l->next;
struct ofono_gprs_provision_data *ap = l->data;
if ((ap->provider_name && strcasestr(ap->provider_name, spn))
|| (ap->name && strcasestr(ap->name, spn))
|| (ap->apn && strcasestr(ap->apn, spn))) {
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
&& !best_internet) {
best_internet = ap;
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
&& !best_mms) {
best_mms = ap;
}
}
l = next;
}
/* no better match found */
if (!best_internet)
best_internet = second_best_internet;
if (!best_mms)
best_mms = second_best_mms;
}
/* 4. if none found yet, create APNs with default values */
if (!best_internet) {
best_internet = g_try_new0(struct ofono_gprs_provision_data, 1);
if (best_internet) {
best_internet->type =
OFONO_GPRS_CONTEXT_TYPE_INTERNET;
best_internet->name =
g_strdup("Internet");
best_internet->apn =
g_strdup("internet");
}
}
if (!best_mms) {
best_mms = g_try_new0(struct ofono_gprs_provision_data, 1);
if (best_mms) {
best_mms->type =
OFONO_GPRS_CONTEXT_TYPE_MMS;
best_mms->name =
g_strdup("MMS");
best_mms->apn =
g_strdup("mms");
}
}
best_apns = g_slist_append(best_apns, best_internet);
best_apns = g_slist_append(best_apns, best_mms);
return best_apns;
}
int provision_get_settings(const char *mcc, const char *mnc,
const char *spn,
struct ofono_gprs_provision_data **settings,
int *count)
@@ -49,36 +175,26 @@ static int provision_get_settings(const char *mcc, const char *mnc,
int ap_count;
int i;
DBG("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
ofono_info("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
/*
* TODO: review with upstream. Default behavior was to
* disallow duplicate APN entries, which unfortunately exist
* in the mobile-broadband-provider-info db.
* Passing FALSE to mbpi_lookup_apn() would return
* an empty list if duplicates are found.
*/
apns = mbpi_lookup_apn(mcc, mnc, TRUE, &error);
if (apns == NULL) {
if (error != NULL) {
ofono_error("%s", error->message);
g_error_free(error);
}
return -ENOENT;
if (error != NULL) {
ofono_error("%s", error->message);
g_error_free(error);
}
ofono_info("Found %d APs in MBPI", g_slist_length(apns));
apns = provision_normalize_apn_list(apns, spn);
if (apns == NULL)
return -ENOENT;
ap_count = g_slist_length(apns);
ofono_info("GPRS Provisioning found %d matching APNs for SPN: %s MCC: %s MNC: %s",
ap_count, spn, mcc, mnc);
/*
* Only keep the first APN found.
*
* This allows auto-provisioning to work most of the time vs.
* passing FALSE to mbpi_lookup_apn() which would return an
* an empty list if duplicates are found.
*/
if (ap_count > 1)
ap_count = 1;
ofono_info("Provisioning %d APs", ap_count);
*settings = g_try_new0(struct ofono_gprs_provision_data, ap_count);
if (*settings == NULL) {
@@ -97,25 +213,16 @@ static int provision_get_settings(const char *mcc, const char *mnc,
for (l = apns, i = 0; l; l = l->next, i++) {
struct ofono_gprs_provision_data *ap = l->data;
/*
* Only create a data context for the first matching APN.
* See comment above that restricts restricts apn_count.
*/
if (i == 0) {
ofono_info("Name: '%s'", ap->name);
ofono_info("APN: '%s'", ap->apn);
ofono_info("Type: %s", mbpi_ap_type(ap->type));
ofono_info("Username: '%s'", ap->username);
ofono_info("Password: '%s'", ap->password);
ofono_info("Name: '%s'", ap->name);
ofono_info("APN: '%s'", ap->apn);
ofono_info("Type: %s", mbpi_ap_type(ap->type));
ofono_info("Username: '%s'", ap->username);
ofono_info("Password: '%s'", ap->password);
memcpy(*settings + i, ap,
sizeof(struct ofono_gprs_provision_data));
g_free(ap);
} else {
mbpi_ap_free(ap);
}
memcpy(*settings + i, ap,
sizeof(struct ofono_gprs_provision_data));
g_free(ap);
}
g_slist_free(apns);

28
ofono/plugins/provision.h Normal file
View File

@@ -0,0 +1,28 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2014 Jolla. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
struct ofono_gprs_provision_data;
int provision_get_settings(const char *mcc, const char *mnc,
const char *spn,
struct ofono_gprs_provision_data **settings,
int *count);

View File

@@ -0,0 +1,541 @@
/*
* Copyright (C) 2013-2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/inotify.h>
#include <wspcodec.h>
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono.h>
#include <plugin.h>
/*
* Push forwarder plugin is looking for configuration files in
* /etc/ofono/push_forwarder.d directory. Confiration files are
* glib key files that look like this:
*
* [Jolla MMS Handler]
* ContentType = application/vnd.wap.mms-message
* Interface = com.jolla.MmsEngine.
* Service = com.jolla.MmsEngine
* Method = HandlePush
* Path = /
*
* Only files with .conf suffix are loaded. In addition to the keys
* from the above example, SourcePort and DestinationPort port keys
* are supported. All other keys are ignored. One file may describe
* several push handlers. See pf_parse_config() function for details.
*
* When push fowarder receives a WAP push, it goes through the list
* of registered handlers and invokes all of them that match content
* type and/or port numbers. The rest is up to the D-Bus service
* handling the call.
*/
#define PF_CONFIG_DIR CONFIGDIR "/push_forwarder.d"
struct pf_modem {
struct ofono_modem *modem;
struct ofono_sms *sms;
struct ofono_sim *sim;
unsigned int sim_watch_id;
unsigned int sms_watch_id;
unsigned int push_watch_id;
};
struct push_datagram_handler {
char *name;
char *content_type;
char *interface;
char *service;
char *method;
char *path;
int dst_port;
int src_port;
};
static GSList *handlers;
static GSList *modems;
static unsigned int modem_watch_id;
static int inotify_fd = -1;
static int inotify_watch_id = -1;
static guint inotify_watch_source_id;
static GIOChannel *inotify_watch_channel;
static void pf_notify_handler(struct push_datagram_handler *h,
const char *imsi, const char *from, const struct tm *remote,
const struct tm *local, int dst, int src,
const char *ct, const void *data, unsigned int len)
{
struct tm remote_tm = *remote;
struct tm local_tm = *local;
dbus_uint32_t remote_time_arg = mktime(&remote_tm);
dbus_uint32_t local_time_arg = mktime(&local_tm);
dbus_int32_t dst_arg = dst;
dbus_int32_t src_arg = src;
DBusMessageIter iter, array;
DBusMessage *msg = dbus_message_new_method_call(h->service,
h->path, h->interface, h->method);
dbus_message_append_args(msg,
DBUS_TYPE_STRING, &imsi,
DBUS_TYPE_STRING, &from,
DBUS_TYPE_UINT32, &remote_time_arg,
DBUS_TYPE_UINT32, &local_time_arg,
DBUS_TYPE_INT32, &dst_arg,
DBUS_TYPE_INT32, &src_arg,
DBUS_TYPE_STRING, &ct,
DBUS_TYPE_INVALID);
dbus_message_iter_init_append(msg, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE_AS_STRING, &array);
dbus_message_iter_append_fixed_array(&array,
DBUS_TYPE_BYTE, &data, len);
dbus_message_iter_close_container(&iter, &array);
dbus_message_set_no_reply(msg, TRUE);
dbus_connection_send(ofono_dbus_get_connection(), msg, NULL);
dbus_message_unref(msg);
}
static gboolean pf_match_port(int port, int expected_port)
{
if (expected_port < 0)
return TRUE;
if (expected_port == port)
return TRUE;
return FALSE;
}
static gboolean pf_match_handler(struct push_datagram_handler *h,
const char *ct, int dst, int src)
{
if (pf_match_port(dst, h->dst_port) == FALSE)
return FALSE;
if (pf_match_port(src, h->src_port) == FALSE)
return FALSE;
if (h->content_type == NULL)
return TRUE;
if (strcmp(h->content_type, ct) == 0)
return TRUE;
return FALSE;
}
static void pf_handle_datagram(const char *from,
const struct tm *remote, const struct tm *local, int dst,
int src, const unsigned char *buffer, unsigned int len,
void *userdata)
{
struct pf_modem *pm = userdata;
guint remain;
const guint8 *data;
unsigned int hdrlen;
unsigned int off;
const void *ct;
const char *imsi;
GSList *link;
DBG("received push of size: %u", len);
if (pm->sim == NULL)
return;
imsi = ofono_sim_get_imsi(pm->sim);
if (len < 3)
return;
if (buffer[1] != 6)
return;
remain = len - 2;
data = buffer + 2;
if (wsp_decode_uintvar(data, remain, &hdrlen, &off) == FALSE)
return;
if ((off + hdrlen) > remain)
return;
data += off;
remain -= off;
DBG(" WAP header %u bytes", hdrlen);
if (wsp_decode_content_type(data, hdrlen, &ct, &off, NULL) == FALSE)
return;
data += hdrlen;
remain -= hdrlen;
DBG(" content type %s", (char *)ct);
DBG(" imsi %s", imsi);
DBG(" data size %u", remain);
link = handlers;
while (link) {
struct push_datagram_handler *h = link->data;
if (pf_match_handler(h, ct, dst, src) != FALSE) {
DBG("notifying %s", h->name);
pf_notify_handler(h, imsi, from, remote, local, dst,
src, ct, data, remain);
}
link = link->next;
}
}
static void pf_sms_watch(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond, void *userdata)
{
struct pf_modem *pm = userdata;
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
DBG("registered");
pm->sms = __ofono_atom_get_data(atom);
pm->push_watch_id = __ofono_sms_datagram_watch_add(pm->sms,
pf_handle_datagram, -1, -1, pm, NULL);
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
DBG("unregistered");
pm->sms = NULL;
pm->push_watch_id = 0;
}
}
static void pf_sms_watch_done(void *userdata)
{
struct pf_modem *pm = userdata;
pm->sms_watch_id = 0;
}
static void pf_sim_watch(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond, void *userdata)
{
struct pf_modem *pm = userdata;
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
DBG("registered");
pm->sim = __ofono_atom_get_data(atom);
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
DBG("unregistered");
pm->sim = NULL;
}
}
static void pf_sim_watch_done(void *userdata)
{
struct pf_modem *pm = userdata;
pm->sim_watch_id = 0;
}
static void pf_free_modem(struct pf_modem *pm)
{
if (pm == NULL)
return;
if (pm->push_watch_id != 0)
__ofono_sms_datagram_watch_remove(pm->sms, pm->push_watch_id);
if (pm->sim_watch_id != 0)
__ofono_modem_remove_atom_watch(pm->modem, pm->sim_watch_id);
if (pm->sms_watch_id != 0)
__ofono_modem_remove_atom_watch(pm->modem, pm->sms_watch_id);
g_free(pm);
}
static void pf_modem_watch(struct ofono_modem *modem,
gboolean added, void *userdata)
{
DBG("modem: %p, added: %d", modem, added);
if (added != FALSE) {
struct pf_modem *pm;
pm = g_try_new0(struct pf_modem, 1);
if (pm == NULL)
return;
pm->modem = modem;
pm->sms_watch_id = __ofono_modem_add_atom_watch(modem,
OFONO_ATOM_TYPE_SMS, pf_sms_watch, pm,
pf_sms_watch_done);
pm->sim_watch_id = __ofono_modem_add_atom_watch(modem,
OFONO_ATOM_TYPE_SIM, pf_sim_watch, pm,
pf_sim_watch_done);
modems = g_slist_append(modems, pm);
} else {
GSList *link = modems;
while (link) {
struct pf_modem *pm = link->data;
if (pm->modem == modem) {
modems = g_slist_delete_link(modems, link);
pf_free_modem(pm);
break;
}
link = link->next;
}
}
}
static void pf_modem_init(struct ofono_modem *modem,
void *userdata)
{
pf_modem_watch(modem, TRUE, NULL);
}
static void pf_free_handler(void *data)
{
struct push_datagram_handler *h = data;
g_free(h->content_type);
g_free(h->interface);
g_free(h->service);
g_free(h->method);
g_free(h->path);
g_free(h->name);
g_free(h);
}
static void pf_parse_handler(GKeyFile *conf, const char *g)
{
GError *err = NULL;
struct push_datagram_handler *h;
char *interface;
char *service;
char *method;
char *path;
interface = g_key_file_get_string(conf, g, "Interface", NULL);
if (interface == NULL)
goto no_interface;
service = g_key_file_get_string(conf, g, "Service", NULL);
if (service == NULL)
goto no_service;
method = g_key_file_get_string(conf, g, "Method", NULL);
if (method == NULL)
goto no_method;
path = g_key_file_get_string(conf, g, "Path", NULL);
if (path == NULL)
goto no_path;
h = g_try_new0(struct push_datagram_handler, 1);
if (h == NULL)
goto no_memory;
h->name = g_strdup(g);
h->interface = interface;
h->service = service;
h->method = method;
h->path = path;
h->content_type = g_key_file_get_string(conf, g, "ContentType", NULL);
h->dst_port = g_key_file_get_integer(conf, g, "DestinationPort", &err);
if (h->dst_port == 0 && err != NULL) {
h->dst_port = -1;
g_error_free(err);
err = NULL;
}
h->src_port = g_key_file_get_integer(conf, g, "SourcePort", &err);
if (h->src_port == 0 && err != NULL) {
h->src_port = -1;
g_error_free(err);
err = NULL;
}
DBG("registered %s", h->name);
if (h->content_type != NULL)
DBG(" ContentType: %s", h->content_type);
if (h->dst_port >= 0)
DBG(" DestinationPort: %d", h->dst_port);
if (h->src_port >= 0)
DBG(" SourcePort: %d", h->src_port);
DBG(" Interface: %s", interface);
DBG(" Service: %s", service);
DBG(" Method: %s", method);
DBG(" Path: %s", path);
handlers = g_slist_append(handlers, h);
return;
no_memory:
g_free(path);
no_path:
g_free(method);
no_method:
g_free(service);
no_service:
g_free(interface);
no_interface:
return;
}
static void pf_parse_config(void)
{
GDir *dir;
const gchar *file;
g_slist_free_full(handlers, pf_free_handler);
handlers = NULL;
dir = g_dir_open(PF_CONFIG_DIR, 0, NULL);
if (dir == NULL) {
DBG(PF_CONFIG_DIR " not found.");
return;
}
DBG("loading configuration from " PF_CONFIG_DIR);
while ((file = g_dir_read_name(dir)) != NULL) {
GError *err;
GKeyFile *conf;
char *path;
if (g_str_has_suffix(file, ".conf") == FALSE)
continue;
err = NULL;
conf = g_key_file_new();
path = g_strconcat(PF_CONFIG_DIR "/", file, NULL);
DBG("reading %s", file);
if (g_key_file_load_from_file(conf, path, 0, &err) != FALSE) {
gsize i, n;
char **names = g_key_file_get_groups(conf, &n);
for (i = 0; i < n; i++)
pf_parse_handler(conf, names[i]);
g_strfreev(names);
} else {
ofono_warn("%s", err->message);
g_error_free(err);
}
g_key_file_free(conf);
g_free(path);
}
g_dir_close(dir);
}
static gboolean pf_inotify(GIOChannel *gio, GIOCondition c, gpointer data)
{
int avail;
gsize len;
void *buf;
GError *error;
if (ioctl(inotify_fd, FIONREAD, &avail) < 0)
return FALSE;
buf = g_try_malloc(avail);
if (buf == NULL)
return FALSE;
error = NULL;
if (g_io_channel_read_chars(gio, buf, avail, &len, &error) !=
G_IO_STATUS_NORMAL) {
g_free(buf);
return FALSE;
}
pf_parse_config();
g_free(buf);
return TRUE;
}
static int pf_plugin_init(void)
{
DBG("");
pf_parse_config();
modem_watch_id = __ofono_modemwatch_add(pf_modem_watch, NULL, NULL);
__ofono_modem_foreach(pf_modem_init, NULL);
inotify_fd = inotify_init();
if (inotify_fd < 0)
return 0;
inotify_watch_id = inotify_add_watch(inotify_fd,
PF_CONFIG_DIR,
IN_CLOSE_WRITE | IN_DELETE | IN_MOVE);
if (inotify_watch_id < 0)
goto no_inotify_watch_id;
inotify_watch_channel = g_io_channel_unix_new(inotify_fd);
if (inotify_watch_channel == NULL)
goto no_inotify_watch_channel;
g_io_channel_set_encoding(inotify_watch_channel, NULL, NULL);
g_io_channel_set_buffered(inotify_watch_channel, FALSE);
inotify_watch_source_id = g_io_add_watch(inotify_watch_channel,
G_IO_IN, pf_inotify, NULL);
if (inotify_watch_source_id != 0)
return 0;
g_io_channel_unref(inotify_watch_channel);
inotify_watch_channel = NULL;
no_inotify_watch_channel:
inotify_rm_watch(inotify_fd, inotify_watch_id);
inotify_watch_id = -1;
no_inotify_watch_id:
close(inotify_fd);
inotify_fd = -1;
return 0;
}
static void pf_plugin_exit(void)
{
DBG("");
__ofono_modemwatch_remove(modem_watch_id);
modem_watch_id = 0;
g_slist_free_full(modems, (GDestroyNotify)pf_free_modem);
modems = NULL;
g_slist_free_full(handlers, pf_free_handler);
handlers = NULL;
if (inotify_watch_source_id == 0)
return;
g_source_remove(inotify_watch_source_id);
inotify_watch_source_id = 0;
g_io_channel_unref(inotify_watch_channel);
inotify_watch_channel = NULL;
inotify_rm_watch(inotify_fd, inotify_watch_id);
inotify_watch_id = -1;
close(inotify_fd);
inotify_fd = -1;
}
OFONO_PLUGIN_DEFINE(push_forwarder, "Push Forwarder Plugin", VERSION,
OFONO_PLUGIN_PRIORITY_DEFAULT, pf_plugin_init,
pf_plugin_exit)

View File

@@ -63,6 +63,7 @@
#include <ofono/types.h>
#include <ofono/message-waiting.h>
#include <ofono/oemraw.h>
#include <ofono/stk.h>
#include "drivers/rilmodem/rilmodem.h"
@@ -97,10 +98,10 @@ struct ril_data {
static guint mce_daemon_watch;
static guint signal_watch;
static DBusConnection *connection;
gboolean reconnecting = FALSE;
static int ril_init(void);
guint reconnect_timer;
static void ril_exit(void);
static int send_get_sim_status(struct ofono_modem *modem);
static void ril_debug(const char *str, void *user_data)
@@ -112,13 +113,12 @@ static void ril_debug(const char *str, void *user_data)
static void sim_status_cb(struct ril_msg *message, gpointer user_data)
{
DBG("error=%d", message->error);
struct ofono_modem *modem = user_data;
struct ril_data *ril = ofono_modem_get_data(modem);
struct sim_status status;
struct sim_app *apps[MAX_UICC_APPS];
DBG("");
/*
* ril.h claims this should NEVER fail!
* However this isn't quite true. So,
@@ -154,9 +154,12 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
} else {
ofono_warn("No SIM card present.");
}
// We cannot power on modem, but we need to get
// certain interfaces up to be able to make emergency calls
// in offline mode and without SIM
/*
* We cannot power on modem, but we need to get
* certain interfaces up to be able to make emergency calls
* in offline mode and without SIM
*/
ofono_modem_set_powered(modem, TRUE);
}
}
@@ -185,6 +188,7 @@ static int send_get_sim_status(struct ofono_modem *modem)
static int ril_probe(struct ofono_modem *modem)
{
DBG("");
struct ril_data *ril = NULL;
ril = g_try_new0(struct ril_data, 1);
@@ -207,9 +211,9 @@ error:
static void ril_remove(struct ofono_modem *modem)
{
DBG("");
struct ril_data *ril = ofono_modem_get_data(modem);
ofono_modem_set_data(modem, NULL);
if (!ril)
@@ -218,9 +222,6 @@ static void ril_remove(struct ofono_modem *modem)
if (ril->timer_id > 0)
g_source_remove(ril->timer_id);
if (reconnect_timer > 0)
g_source_remove(ril->timer_id);
g_ril_unref(ril->modem);
g_free(ril);
@@ -228,7 +229,7 @@ static void ril_remove(struct ofono_modem *modem)
static void ril_pre_sim(struct ofono_modem *modem)
{
DBG("enter");
DBG("");
struct ril_data *ril = ofono_modem_get_data(modem);
struct ofono_sim *sim;
@@ -241,6 +242,7 @@ static void ril_pre_sim(struct ofono_modem *modem)
static void ril_post_sim(struct ofono_modem *modem)
{
DBG("");
struct ril_data *ril = ofono_modem_get_data(modem);
struct ofono_gprs *gprs;
struct ofono_gprs_context *gc;
@@ -258,7 +260,7 @@ static void ril_post_sim(struct ofono_modem *modem)
ril->modem);
if (gc == NULL)
break;
ofono_gprs_add_context(gprs, gc);
}
}
@@ -266,6 +268,8 @@ static void ril_post_sim(struct ofono_modem *modem)
ofono_radio_settings_create(modem, 0, "rilmodem", ril->modem);
ofono_phonebook_create(modem, 0, "rilmodem", ril->modem);
ofono_call_forwarding_create(modem, 0, "rilmodem", ril->modem);
ofono_call_barring_create(modem, 0, "rilmodem", ril->modem);
ofono_stk_create(modem, 0, "rilmodem", ril->modem);
mw = ofono_message_waiting_create(modem);
if (mw)
@@ -274,7 +278,7 @@ static void ril_post_sim(struct ofono_modem *modem)
static void ril_post_online(struct ofono_modem *modem)
{
DBG("enter");
DBG("");
struct ril_data *ril = ofono_modem_get_data(modem);
ofono_call_volume_create(modem, 0, "rilmodem", ril->modem);
@@ -282,19 +286,17 @@ static void ril_post_online(struct ofono_modem *modem)
ofono_netreg_create(modem, 0, "rilmodem", ril->modem);
ofono_ussd_create(modem, 0, "rilmodem", ril->modem);
ofono_call_settings_create(modem, 0, "rilmodem", ril->modem);
ofono_cbs_create(modem, 0, "rilmodem", ril->modem);
ofono_oem_raw_create(modem, 0, "rilmodem", ril->modem);
}
static void ril_set_online_cb(struct ril_msg *message, gpointer user_data)
{
DBG("enter");
DBG("");
struct cb_data *cbd = user_data;
ofono_modem_online_cb_t cb = cbd->cb;
if (message->error == RIL_E_SUCCESS) {
if (message->error == RIL_E_SUCCESS)
CALLBACK_WITH_SUCCESS(cb, cbd->data);
}
else
CALLBACK_WITH_FAILURE(cb, cbd->data);
}
@@ -311,12 +313,13 @@ static void ril_set_online(struct ofono_modem *modem, ofono_bool_t online,
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* Number of params */
parcel_w_int32(&rilp, online); /* Radio ON = 1, Radio OFF = 0 */
DBG("1");
ofono_info("RIL_REQUEST_RADIO_POWER %d", online);
ret = g_ril_send(ril->modem, RIL_REQUEST_RADIO_POWER, rilp.data,
rilp.size, ril_set_online_cb, cbd, g_free);
parcel_free(&rilp);
DBG("2");
DBG("RIL_REQUEST_RADIO_POWER done");
if (ret <= 0) {
g_free(cbd);
CALLBACK_WITH_FAILURE(callback, data);
@@ -354,6 +357,7 @@ static int ril_screen_state(struct ofono_modem *modem, ofono_bool_t state)
static gboolean display_changed(DBusConnection *conn,
DBusMessage *message, void *user_data)
{
DBG("");
struct ofono_modem *modem = user_data;
DBusMessageIter iter;
const char *value;
@@ -376,6 +380,7 @@ static gboolean display_changed(DBusConnection *conn,
static void mce_connect(DBusConnection *conn, void *user_data)
{
DBG("");
signal_watch = g_dbus_add_signal_watch(conn,
MCE_SERVICE, NULL,
MCE_SIGNAL_IF,
@@ -386,45 +391,60 @@ static void mce_connect(DBusConnection *conn, void *user_data)
static void mce_disconnect(DBusConnection *conn, void *user_data)
{
DBG("");
g_dbus_remove_watch(conn, signal_watch);
signal_watch = 0;
}
static void ril_connected(struct ril_msg *message, gpointer user_data)
{
DBG("");
struct ofono_modem *modem = (struct ofono_modem *) user_data;
struct ril_data *ril = ofono_modem_get_data(modem);
int ril_version = 0;
struct parcel rilp;
/* TODO: make conditional */
ofono_debug("[UNSOL]< %s", ril_unsol_request_to_string(message->req));
/* TODO: make conditional */
ril_util_init_parcel(message, &rilp);
ril_version = parcel_r_int32(&rilp);
ofono_debug("[UNSOL]< %s, RIL_VERSION %d",
ril_unsol_request_to_string(message->req), ril_version);
/* TODO: need a disconnect function to restart things! */
ril->connected = TRUE;
send_get_sim_status(modem);
connection = ofono_dbus_get_connection();
mce_daemon_watch = g_dbus_add_service_watch(connection, MCE_SERVICE,
mce_connect, mce_disconnect, modem, NULL);
mce_connect, mce_disconnect, modem, NULL);
}
static gboolean ril_re_init(gpointer user_data)
{
ril_init();
return FALSE;
DBG("");
if (reconnecting) {
ril_init();
return TRUE;
} else {
return FALSE;
}
}
static void gril_disconnected(gpointer user_data)
{
/* Signal clients modem going down */
/* Signal clients modem going down
*/
struct ofono_modem *modem = user_data;
DBusConnection *conn = ofono_dbus_get_connection();
if (modem) {
if (ofono_modem_is_registered(modem)) {
ofono_modem_remove(modem);
mce_disconnect(conn, user_data);
reconnect_timer = g_timeout_add_seconds(2, ril_re_init, NULL);
}
if (!reconnecting) {
reconnecting = TRUE;
g_timeout_add_seconds(2, ril_re_init, NULL);
}
}
@@ -434,10 +454,10 @@ void ril_switchUser()
ofono_error("prctl(PR_SET_KEEPCAPS) failed:%s,%d",
strerror(errno), errno);
if (setgid(RADIO_ID) < 0 )
if (setgid(RADIO_ID) < 0)
ofono_error("setgid(%d) failed:%s,%d",
RADIO_ID, strerror(errno), errno);
if (setuid(RADIO_ID) < 0 )
if (setuid(RADIO_ID) < 0)
ofono_error("setuid(%d) failed:%s,%d",
RADIO_ID, strerror(errno), errno);
@@ -457,7 +477,7 @@ void ril_switchUser()
static int ril_enable(struct ofono_modem *modem)
{
DBG("enter");
DBG("%p", modem);
struct ril_data *ril = ofono_modem_get_data(modem);
ril->have_sim = FALSE;
@@ -482,6 +502,8 @@ static int ril_enable(struct ofono_modem *modem)
return -EIO;
}
reconnecting = FALSE;
if (getenv("OFONO_RIL_TRACE"))
g_ril_set_trace(ril->modem, TRUE);
@@ -498,17 +520,18 @@ static int ril_enable(struct ofono_modem *modem)
static int ril_disable(struct ofono_modem *modem)
{
DBG("%p", modem);
struct ril_data *ril = ofono_modem_get_data(modem);
struct parcel rilp;
int request = RIL_REQUEST_RADIO_POWER;
guint ret;
DBG("%p", modem);
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* size of array */
parcel_w_int32(&rilp, 0); /* POWER=OFF */
ofono_info("RIL_REQUEST_RADIO_POWER OFF");
/* fire and forget i.e. not waiting for the callback*/
ret = g_ril_send(ril->modem, request, rilp.data,
rilp.size, NULL, NULL, NULL);
@@ -518,6 +541,10 @@ static int ril_disable(struct ofono_modem *modem)
parcel_free(&rilp);
/* this will trigger the cleanup of g_io_channel */
g_ril_unref(ril->modem);
ril->modem = NULL;
return 0;
}
@@ -552,7 +579,7 @@ static struct ofono_modem_driver ril_driver = {
*/
static int ril_init(void)
{
DBG("enter");
DBG("");
int retval = 0;
struct ofono_modem *modem;
@@ -577,23 +604,6 @@ static int ril_init(void)
retval = ofono_modem_register(modem);
DBG("ofono_modem_register returned: %d", retval);
/* kickstart the modem:
* causes core modem code to call
* - set_powered(TRUE) - which in turn
* calls driver->enable()
*
* - driver->pre_sim()
*
* Could also be done via:
*
* - a DBus call to SetProperties w/"Powered=TRUE" *1
* - sim_state_watch ( handles SIM removal? LOCKED states? **2
* - ofono_modem_set_powered()
*/
ofono_modem_reset(modem);
reconnect_timer = 0;
return retval;
}

View File

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

View File

@@ -48,7 +48,7 @@ struct error_mapping_entry cme_errors_mapping[] = {
};
static void append_variant(DBusMessageIter *iter,
int type, void *value)
int type, const void *value)
{
char sig[2];
DBusMessageIter valueiter;
@@ -65,7 +65,7 @@ static void append_variant(DBusMessageIter *iter,
}
void ofono_dbus_dict_append(DBusMessageIter *dict,
const char *key, int type, void *value)
const char *key, int type, const void *value)
{
DBusMessageIter keyiter;
@@ -85,7 +85,8 @@ void ofono_dbus_dict_append(DBusMessageIter *dict,
dbus_message_iter_close_container(dict, &keyiter);
}
static void append_array_variant(DBusMessageIter *iter, int type, void *val)
static void append_array_variant(DBusMessageIter *iter, int type,
const void *val)
{
DBusMessageIter variant, array;
char typesig[2];
@@ -113,7 +114,7 @@ static void append_array_variant(DBusMessageIter *iter, int type, void *val)
}
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
int type, void *val)
int type, const void *val)
{
DBusMessageIter entry;
@@ -127,7 +128,8 @@ void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
dbus_message_iter_close_container(dict, &entry);
}
static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
static void append_dict_variant(DBusMessageIter *iter, int type,
const void *val)
{
DBusMessageIter variant, array, entry;
char typesig[5];
@@ -182,7 +184,7 @@ static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
}
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
int type, void *val)
int type, const void *val)
{
DBusMessageIter entry;
@@ -200,7 +202,7 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
const char *path,
const char *interface,
const char *name,
int type, void *value)
int type, const void *value)
{
DBusMessage *signal;
DBusMessageIter iter;
@@ -225,7 +227,7 @@ int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
const char *path,
const char *interface,
const char *name,
int type, void *value)
int type, const void *value)
{
DBusMessage *signal;
@@ -251,7 +253,7 @@ int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
const char *path,
const char *interface,
const char *name,
int type, void *value)
int type, const void *value)
{
DBusMessage *signal;

View File

@@ -57,6 +57,8 @@
#define MAX_MESSAGE_CENTER_LENGTH 255
#define MAX_CONTEXTS 256
#define SUSPEND_TIMEOUT 8
#define MAX_MMS_MTU 1280
#define MAX_GPRS_MTU 1280
/* 27.007 Section 7.29 */
enum packet_bearer {
@@ -758,6 +760,31 @@ static void pri_reset_context_settings(struct pri_context *ctx)
g_free(interface);
}
static void pri_limit_mtu(const char *interface, int max_mtu)
{
struct ifreq ifr;
int sk;
if (interface == NULL)
return;
sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0)
return;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, interface, IFNAMSIZ);
if (ioctl(sk, SIOCGIFMTU, &ifr) < 0 || ifr.ifr_mtu > max_mtu) {
ifr.ifr_mtu = max_mtu;
if (ioctl(sk, SIOCSIFMTU, &ifr) < 0)
ofono_error("Failed to set MTU");
}
close(sk);
}
static void pri_update_mms_context_settings(struct pri_context *ctx)
{
struct ofono_gprs_context *gc = ctx->context_driver;
@@ -774,6 +801,8 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
if (ctx->proxy_host)
pri_setproxy(settings->interface, ctx->proxy_host);
pri_limit_mtu(settings->interface, MAX_MMS_MTU);
}
static void append_context_properties(struct pri_context *ctx,
@@ -881,6 +910,9 @@ static void pri_activate_callback(const struct ofono_error *error, void *data)
pri_context_signal_settings(ctx, gc->settings->ipv4 != NULL,
gc->settings->ipv6 != NULL);
if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET)
pri_limit_mtu(gc->settings->interface, MAX_GPRS_MTU);
}
value = ctx->active;
@@ -3016,14 +3048,56 @@ static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
__ofono_atom_register(gprs->atom, gprs_unregister);
}
static gboolean mms_context_configured(struct ofono_gprs *gprs)
{
GSList *l;
for (l = gprs->contexts; l; l = l->next) {
struct pri_context *ctx = l->data;
if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS)
return TRUE;
}
return FALSE;
}
static void provision_mms_context(struct ofono_gprs *gprs, const char *mcc,
const char *mnc, const char *spn)
{
struct ofono_gprs_provision_data *settings;
int count;
int i;
if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
&settings, &count) == FALSE) {
ofono_warn("Provisioning failed");
return;
}
for (i = 0; i < count; i++) {
if (settings[i].type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
provision_context(&settings[i], gprs);
break;
}
}
__ofono_gprs_provision_free_settings(settings, count);
}
static void spn_read_cb(const char *spn, const char *dc, void *data)
{
struct ofono_gprs *gprs = data;
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
provision_contexts(gprs, ofono_sim_get_mcc(sim),
if (gprs->contexts == NULL) {
provision_contexts(gprs, ofono_sim_get_mcc(sim),
ofono_sim_get_mnc(sim), spn);
} else if (!mms_context_configured(gprs)) {
provision_mms_context(gprs, ofono_sim_get_mcc(sim),
ofono_sim_get_mnc(sim), spn);
}
ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
@@ -3040,7 +3114,7 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
if (gprs->contexts)
if (mms_context_configured(gprs))
goto finish;
ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
@@ -3064,3 +3138,8 @@ void *ofono_gprs_get_data(struct ofono_gprs *gprs)
{
return gprs->driver_data;
}
struct ofono_modem *ofono_gprs_get_modem(struct ofono_gprs *gprs)
{
return __ofono_atom_get_modem(gprs->atom);
}

View File

@@ -44,25 +44,34 @@
static GSList *g_drivers = NULL;
#define HANDSFREE_FLAG_CACHED 0x1
struct ofono_handsfree {
ofono_bool_t nrec;
ofono_bool_t inband_ringing;
ofono_bool_t voice_recognition;
ofono_bool_t voice_recognition_pending;
unsigned int ag_features;
unsigned int ag_chld_features;
unsigned char battchg;
GSList *subscriber_numbers;
const struct ofono_handsfree_driver *driver;
void *driver_data;
struct ofono_atom *atom;
DBusMessage *pending;
int flags;
};
static const char **ag_features_list(unsigned int features)
static const char **ag_features_list(unsigned int features,
unsigned int chld_features)
{
static const char *list[33];
static const char *list[10];
unsigned int i = 0;
if (features & HFP_AG_FEATURE_3WAY)
list[i++] = "three-way-calling";
if (features & HFP_AG_FEATURE_ECNR)
list[i++] = "echo-canceling-and-noise-reduction";
@@ -72,6 +81,21 @@ static const char **ag_features_list(unsigned int features)
if (features & HFP_AG_FEATURE_ATTACH_VOICE_TAG)
list[i++] = "attach-voice-tag";
if (chld_features & HFP_AG_CHLD_0)
list[i++] = "release-all-held";
if (chld_features & HFP_AG_CHLD_1x)
list[i++] = "release-specified-active-call";
if (chld_features & HFP_AG_CHLD_2x)
list[i++] = "private-chat";
if (chld_features & HFP_AG_CHLD_3)
list[i++] = "create-multiparty";
if (chld_features & HFP_AG_CHLD_4)
list[i++] = "transfer";
list[i] = NULL;
return list;
@@ -125,6 +149,15 @@ void ofono_handsfree_set_ag_features(struct ofono_handsfree *hf,
hf->ag_features = ag_features;
}
void ofono_handsfree_set_ag_chld_features(struct ofono_handsfree *hf,
unsigned int ag_chld_features)
{
if (hf == NULL)
return;
hf->ag_chld_features = ag_chld_features;
}
void ofono_handsfree_battchg_notify(struct ofono_handsfree *hf,
unsigned char level)
{
@@ -148,10 +181,44 @@ void ofono_handsfree_battchg_notify(struct ofono_handsfree *hf,
&level);
}
static DBusMessage *handsfree_get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
static void append_subscriber_numbers(GSList *subscriber_numbers,
DBusMessageIter *iter)
{
DBusMessageIter entry;
DBusMessageIter variant, array;
GSList *l;
const char *subscriber_number_string;
char arraysig[3];
const char *key = "SubscriberNumbers";
arraysig[0] = DBUS_TYPE_ARRAY;
arraysig[1] = DBUS_TYPE_STRING;
arraysig[2] = '\0';
dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
NULL, &entry);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
&key);
dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
arraysig, &variant);
dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING, &array);
for (l = subscriber_numbers; l; l = l->next) {
subscriber_number_string = phone_number_to_string(l->data);
dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING,
&subscriber_number_string);
}
dbus_message_iter_close_container(&variant, &array);
dbus_message_iter_close_container(&entry, &variant);
dbus_message_iter_close_container(iter, &entry);
}
static DBusMessage *generate_get_properties_reply(struct ofono_handsfree *hf,
DBusMessage *msg)
{
struct ofono_handsfree *hf = data;
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter dict;
@@ -181,18 +248,90 @@ static DBusMessage *handsfree_get_properties(DBusConnection *conn,
ofono_dbus_dict_append(&dict, "VoiceRecognition", DBUS_TYPE_BOOLEAN,
&voice_recognition);
features = ag_features_list(hf->ag_features);
features = ag_features_list(hf->ag_features, hf->ag_chld_features);
ofono_dbus_dict_append_array(&dict, "Features", DBUS_TYPE_STRING,
&features);
ofono_dbus_dict_append(&dict, "BatteryChargeLevel", DBUS_TYPE_BYTE,
&hf->battchg);
if (hf->subscriber_numbers)
append_subscriber_numbers(hf->subscriber_numbers, &dict);
dbus_message_iter_close_container(&iter, &dict);
return reply;
}
static void hf_cnum_callback(const struct ofono_error *error, int total,
const struct ofono_phone_number *numbers,
void *data)
{
struct ofono_handsfree *hf = data;
int num;
struct ofono_phone_number *subscriber_number;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
goto out;
for (num = 0; num < total; num++) {
subscriber_number = g_new0(struct ofono_phone_number, 1);
subscriber_number->type = numbers[num].type;
strncpy(subscriber_number->number, numbers[num].number,
OFONO_MAX_PHONE_NUMBER_LENGTH + 1);
hf->subscriber_numbers = g_slist_prepend(hf->subscriber_numbers,
subscriber_number);
}
hf->subscriber_numbers = g_slist_reverse(hf->subscriber_numbers);
out:
hf->flags |= HANDSFREE_FLAG_CACHED;
if (hf->pending) {
DBusMessage *reply =
generate_get_properties_reply(hf, hf->pending);
__ofono_dbus_pending_reply(&hf->pending, reply);
}
}
static void query_cnum(struct ofono_handsfree *hf)
{
DBusMessage *reply;
if (hf->driver->cnum_query != NULL) {
hf->driver->cnum_query(hf, hf_cnum_callback, hf);
return;
}
if (hf->pending == NULL)
return;
reply = generate_get_properties_reply(hf, hf->pending);
__ofono_dbus_pending_reply(&hf->pending, reply);
}
static DBusMessage *handsfree_get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_handsfree *hf = data;
if (hf->pending != NULL)
return __ofono_error_busy(msg);
if (hf->flags & HANDSFREE_FLAG_CACHED)
return generate_get_properties_reply(hf, msg);
/* Query the settings and report back */
hf->pending = dbus_message_ref(msg);
query_cnum(hf);
return NULL;
}
static void voicerec_set_cb(const struct ofono_error *error, void *data)
{
struct ofono_handsfree *hf = data;
@@ -424,6 +563,10 @@ static void handsfree_unregister(struct ofono_atom *atom)
__ofono_dbus_pending_reply(&hf->pending, reply);
}
g_slist_foreach(hf->subscriber_numbers, (GFunc) g_free, NULL);
g_slist_free(hf->subscriber_numbers);
hf->subscriber_numbers = NULL;
ofono_modem_remove_interface(modem, OFONO_HANDSFREE_INTERFACE);
g_dbus_unregister_interface(conn, path,
OFONO_HANDSFREE_INTERFACE);

View File

@@ -45,6 +45,17 @@ enum hfp_hf_feature {
HFP_HF_FEATURE_CODEC_NEGOTIATION = 0x80,
};
/* HFP AG supported call hold and multiparty services bitmap. Bluetooth HFP 1.6 spec page 76 */
enum hfp_ag_chld_feature {
HFP_AG_CHLD_0 = 0x1,
HFP_AG_CHLD_1 = 0x2,
HFP_AG_CHLD_1x = 0x4,
HFP_AG_CHLD_2 = 0x8,
HFP_AG_CHLD_2x = 0x10,
HFP_AG_CHLD_3 = 0x20,
HFP_AG_CHLD_4 = 0x40,
};
enum hfp_sdp_hf_features {
HFP_SDP_HF_FEATURE_ECNR = 0x1,
HFP_SDP_HF_FEATURE_3WAY = 0x2,

View File

@@ -135,7 +135,7 @@ void idmap_put(struct idmap *idmap, unsigned int id)
id %= BITS_PER_LONG;
idmap->bits[offset] &= ~(1 << id);
idmap->bits[offset] &= ~(1UL << id);
}
unsigned int idmap_alloc(struct idmap *idmap)
@@ -149,7 +149,7 @@ unsigned int idmap_alloc(struct idmap *idmap)
return idmap->max + 1;
offset = bit / BITS_PER_LONG;
idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG);
idmap->bits[offset] |= 1UL << (bit % BITS_PER_LONG);
return bit + idmap->min;
}
@@ -163,7 +163,7 @@ void idmap_take(struct idmap *idmap, unsigned int id)
return;
offset = bit / BITS_PER_LONG;
idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG);
idmap->bits[offset] |= 1UL << (bit % BITS_PER_LONG);
}
/*
@@ -186,7 +186,7 @@ unsigned int idmap_alloc_next(struct idmap *idmap, unsigned int last)
return idmap_alloc(idmap);
offset = bit / BITS_PER_LONG;
idmap->bits[offset] |= 1 << (bit % BITS_PER_LONG);
idmap->bits[offset] |= 1UL << (bit % BITS_PER_LONG);
return bit + idmap->min;
}

View File

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

View File

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

View File

@@ -414,7 +414,9 @@ static void flush_atoms(struct ofono_modem *modem, enum modem_state new_state)
while (cur) {
struct ofono_atom *atom = cur->data;
if (atom->modem_state <= new_state) {
/* in case we are powering off the modem, flush everything */
if (atom->modem_state <= new_state &&
new_state > MODEM_STATE_POWER_OFF) {
prev = cur;
cur = cur->next;
continue;

View File

@@ -934,6 +934,40 @@ static void append_operator_struct_list(struct ofono_netreg *netreg,
dbus_free_string_array(children);
}
static void network_signal_operators_changed(struct ofono_netreg *netreg)
{
const char *path = __ofono_atom_get_path(netreg->atom);
DBusConnection *conn = ofono_dbus_get_connection();
DBusMessage *signal;
DBusMessageIter iter;
DBusMessageIter array;
signal = dbus_message_new_signal(path,
OFONO_NETWORK_REGISTRATION_INTERFACE, "OperatorsChanged");
if (signal == NULL) {
ofono_error("Unable to allocate new "
OFONO_NETWORK_REGISTRATION_INTERFACE
".OperatorsChanged signal");
return;
}
dbus_message_iter_init_append(signal, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
DBUS_STRUCT_BEGIN_CHAR_AS_STRING
DBUS_TYPE_OBJECT_PATH_AS_STRING
DBUS_TYPE_ARRAY_AS_STRING
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
DBUS_STRUCT_END_CHAR_AS_STRING,
&array);
append_operator_struct_list(netreg, &array);
dbus_message_iter_close_container(&iter, &array);
g_dbus_send_message(conn, signal);
}
static void operator_list_callback(const struct ofono_error *error, int total,
const struct ofono_network_operator *list,
void *data)
@@ -942,6 +976,7 @@ static void operator_list_callback(const struct ofono_error *error, int total,
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter array;
gboolean changed;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG("Error occurred during operator list");
@@ -950,7 +985,7 @@ static void operator_list_callback(const struct ofono_error *error, int total,
return;
}
update_operator_list(netreg, total, list);
changed = update_operator_list(netreg, total, list);
reply = dbus_message_new_method_return(netreg->pending);
@@ -970,6 +1005,11 @@ static void operator_list_callback(const struct ofono_error *error, int total,
dbus_message_iter_close_container(&iter, &array);
__ofono_dbus_pending_reply(&netreg->pending, reply);
DBG("operator list %schanged", changed ? "" : "not ");
if (changed)
network_signal_operators_changed(netreg);
}
static DBusMessage *network_scan(DBusConnection *conn,
@@ -1041,6 +1081,8 @@ static const GDBusMethodTable network_registration_methods[] = {
static const GDBusSignalTable network_registration_signals[] = {
{ GDBUS_SIGNAL("PropertyChanged",
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
{ GDBUS_SIGNAL("OperatorsChanged",
GDBUS_ARGS({ "operators", "a(oa{sv})"})) },
{ }
};
@@ -2106,18 +2148,14 @@ void ofono_netreg_register(struct ofono_netreg *netreg)
ofono_sim_add_spn_watch(netreg->sim, &netreg->spn_watch,
spn_read_cb, netreg, NULL);
if (__ofono_sim_service_available(netreg->sim,
SIM_UST_SERVICE_PROVIDER_DISPLAY_INFO,
SIM_SST_SERVICE_PROVIDER_DISPLAY_INFO)) {
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_spdi_read_cb, netreg);
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_spdi_read_cb, netreg);
ofono_sim_add_file_watch(netreg->sim_context,
SIM_EFSPDI_FILEID,
sim_spdi_changed,
netreg, NULL);
}
ofono_sim_add_file_watch(netreg->sim_context,
SIM_EFSPDI_FILEID,
sim_spdi_changed,
netreg, NULL);
}
__ofono_atom_register(netreg->atom, netreg_unregister);

View File

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

View File

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

View File

@@ -1,13 +1,14 @@
[Unit]
Description=Telephony service
After=syslog.target
Requires=dbus.service
After=dbus.service
[Service]
Type=dbus
BusName=org.ofono
User=root
EnvironmentFile=-/var/lib/environment/ofono/*.conf
ExecStart=@prefix@/sbin/ofonod -n $OFONO_ARGS
ExecStart=@prefix@/sbin/ofonod -n --nobacktrace $OFONO_ARGS
StandardError=null
Restart=always
RestartSec=3

View File

@@ -767,12 +767,14 @@ static char *sim_network_name_parse(const unsigned char *buffer, int length,
gboolean *add_ci)
{
char *ret = NULL;
unsigned char *endp;
unsigned char dcs;
int i;
gboolean ci = FALSE;
unsigned char *unpacked_buf;
long num_char, written;
int spare_bits;
if (length < 1)
if (length < 2)
return NULL;
dcs = *buffer++;
@@ -787,11 +789,18 @@ static char *sim_network_name_parse(const unsigned char *buffer, int length,
switch (dcs & (7 << 4)) {
case 0x00:
endp = memchr(buffer, 0xff, length);
if (endp)
length = endp - buffer;
ret = convert_gsm_to_utf8(buffer, length,
NULL, NULL, 0xff);
spare_bits = dcs & 0x07;
num_char = (length * 8 - spare_bits) / 7;
unpacked_buf = unpack_7bit(buffer, length, 0, FALSE,
num_char, &written, 0);
if (unpacked_buf == NULL)
break;
ret = convert_gsm_to_utf8(unpacked_buf, written, NULL, NULL, 0);
g_free(unpacked_buf);
break;
case 0x10:
if ((length % 2) == 1) {

View File

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

View File

@@ -737,6 +737,11 @@ static DBusMessage *stk_register_agent(DBusConnection *conn,
if (stk->session_agent == NULL)
stk->current_agent = stk->default_agent;
if (stk->driver && stk->driver->ready) {
DBG("Report driver agent is ready");
stk->driver->ready(stk);
}
return dbus_message_new_method_return(msg);
}

View File

@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -38,6 +39,7 @@
#include "simutil.h"
#include "smsutil.h"
#include "storage.h"
#include "voicecallagent.h"
#define MAX_VOICE_CALLS 16
@@ -75,6 +77,7 @@ struct ofono_voicecall {
ofono_voicecall_cb_t release_queue_done_cb;
struct ofono_emulator *pending_em;
unsigned int pending_id;
struct voicecall_agent *vc_agent;
};
struct voicecall {
@@ -555,6 +558,11 @@ static DBusMessage *voicecall_hangup(DBusConnection *conn,
struct ofono_voicecall *vc = v->vc;
struct ofono_call *call = v->call;
gboolean single_call = vc->call_list->next == 0;
struct tone_queue_entry *tone_entry = NULL;
/* clear any remaining tones */
while ((tone_entry = g_queue_peek_head(vc->toneq)))
tone_request_finish(vc, tone_entry, ENOENT, TRUE);
if (vc->pending || vc->pending_em)
return __ofono_error_busy(msg);
@@ -1494,6 +1502,19 @@ static void manager_dial_callback(const struct ofono_error *error, void *data)
if (is_emergency_number(vc, number) == TRUE)
__ofono_modem_dec_emergency_mode(modem);
if (vc->settings) {
/*Save the last dialled number for HFP AT+BLDN*/
if (number) {
g_key_file_set_string(vc->settings,
SETTINGS_GROUP,
"Number", number);
storage_sync(vc->imsi, SETTINGS_STORE,
vc->settings);
}
}
reply = __ofono_error_failed(vc->pending);
}
@@ -1537,12 +1558,6 @@ static int voicecall_dial(struct ofono_voicecall *vc, const char *number,
string_to_phone_number(number, &ph);
if (vc->settings) {
g_key_file_set_string(vc->settings, SETTINGS_GROUP,
"Number", number);
storage_sync(vc->imsi, SETTINGS_STORE, vc->settings);
}
vc->driver->dial(vc, &ph, clir, cb, vc);
return 0;
@@ -2140,6 +2155,72 @@ static DBusMessage *manager_get_calls(DBusConnection *conn,
return reply;
}
static void voicecall_agent_notify(gpointer user_data)
{
struct ofono_voicecall *vc = user_data;
vc->vc_agent = NULL;
}
static DBusMessage *voicecall_register_agent(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_voicecall *vc = data;
const char *agent_path;
if (vc->vc_agent)
return __ofono_error_busy(msg);
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH,
&agent_path, DBUS_TYPE_INVALID) == FALSE)
return __ofono_error_invalid_args(msg);
if (!__ofono_dbus_valid_object_path(agent_path))
return __ofono_error_invalid_format(msg);
vc->vc_agent = voicecall_agent_new(agent_path,
dbus_message_get_sender(msg));
if (vc->vc_agent == NULL)
return __ofono_error_failed(msg);
voicecall_agent_set_removed_notify(vc->vc_agent,
voicecall_agent_notify, vc);
return dbus_message_new_method_return(msg);
}
static DBusMessage *voicecall_unregister_agent(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_voicecall *vc = data;
const char *agent_path;
const char *agent_bus = dbus_message_get_sender(msg);
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &agent_path,
DBUS_TYPE_INVALID) == FALSE)
return __ofono_error_invalid_args(msg);
if (vc->vc_agent == NULL)
return __ofono_error_failed(msg);
if (!voicecall_agent_matches(vc->vc_agent, agent_path, agent_bus))
return __ofono_error_access_denied(msg);
if (vc->vc_agent) {
voicecall_agent_free(vc->vc_agent);
vc->vc_agent = NULL;
}
return dbus_message_new_method_return(msg);
}
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
const ofono_bool_t playTone)
{
if (vc->vc_agent)
voicecall_agent_ringback_tone(vc->vc_agent, playTone);
}
static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
@@ -2172,6 +2253,12 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetCalls",
NULL, GDBUS_ARGS({ "calls_with_properties", "a(oa{sv})" }),
manager_get_calls) },
{ GDBUS_ASYNC_METHOD("RegisterVoicecallAgent",
GDBUS_ARGS({ "path", "o" }), NULL,
voicecall_register_agent) },
{ GDBUS_ASYNC_METHOD("UnregisterVoicecallAgent",
GDBUS_ARGS({ "path", "o" }), NULL,
voicecall_unregister_agent) },
{ }
};
@@ -2237,6 +2324,19 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id,
voicecall_emit_disconnect_reason(call, reason);
number = phone_number_to_string(&call->call->phone_number);
if (vc->settings) {
/*Save the last dialled number for HFP AT+BLDN*/
if (call->call->direction == CALL_DIRECTION_MOBILE_ORIGINATED
&& number) {
g_key_file_set_string(vc->settings, SETTINGS_GROUP,
"Number", number);
storage_sync(vc->imsi, SETTINGS_STORE, vc->settings);
}
}
if (is_emergency_number(vc, number) == TRUE)
__ofono_modem_dec_emergency_mode(modem);
@@ -2348,6 +2448,21 @@ void ofono_voicecall_notify(struct ofono_voicecall *vc,
return;
error:
if (vc->settings) {
/*Save the last dialled number for HFP AT+BLDN*/
if (call->direction == CALL_DIRECTION_MOBILE_ORIGINATED
&& call->phone_number.number) {
const char *number =
phone_number_to_string(&call->phone_number);
g_key_file_set_string(vc->settings, SETTINGS_GROUP,
"Number", number);
storage_sync(vc->imsi, SETTINGS_STORE, vc->settings);
}
}
if (newcall)
g_free(newcall);
@@ -2744,6 +2859,11 @@ static void voicecall_unregister(struct ofono_atom *atom)
voicecall_close_settings(vc);
if (vc->vc_agent) {
voicecall_agent_free(vc->vc_agent);
vc->vc_agent = 0;
}
if (vc->sim_state_watch) {
ofono_sim_remove_state_watch(vc->sim, vc->sim_state_watch);
vc->sim_state_watch = 0;
@@ -2859,19 +2979,24 @@ static void read_sim_ecc_numbers(int id, void *userdata)
ecc_g3_read_cb, vc);
}
static void get_ecc_numbers(struct ofono_voicecall *vc)
{
if (vc->sim_context == NULL) {
vc->sim_context = ofono_sim_context_create(vc->sim);
ofono_sim_add_file_watch(vc->sim_context, SIM_EFECC_FILEID,
read_sim_ecc_numbers, vc, NULL);
}
read_sim_ecc_numbers(SIM_EFECC_FILEID, vc);
}
static void sim_state_watch(enum ofono_sim_state new_state, void *user)
{
struct ofono_voicecall *vc = user;
switch (new_state) {
case OFONO_SIM_STATE_INSERTED:
if (vc->sim_context == NULL)
vc->sim_context = ofono_sim_context_create(vc->sim);
read_sim_ecc_numbers(SIM_EFECC_FILEID, vc);
ofono_sim_add_file_watch(vc->sim_context, SIM_EFECC_FILEID,
read_sim_ecc_numbers, vc, NULL);
get_ecc_numbers(vc);
break;
case OFONO_SIM_STATE_NOT_PRESENT:
case OFONO_SIM_STATE_RESETTING:
@@ -2888,6 +3013,8 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *user)
voicecall_close_settings(vc);
break;
case OFONO_SIM_STATE_READY:
get_ecc_numbers(vc);
voicecall_load_settings(vc);
break;
case OFONO_SIM_STATE_LOCKED_OUT:

131
ofono/src/voicecallagent.c Normal file
View File

@@ -0,0 +1,131 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2014 Jolla Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <glib.h>
#include <gdbus.h>
#include "ofono.h"
#include "voicecallagent.h"
#define OFONO_VOICECALL_AGENT_INTERFACE "org.ofono.VoiceCallAgent"
struct voicecall_agent {
char *path; /* Agent Path */
char *bus; /* Agent bus */
guint disconnect_watch; /* DBus disconnect watch */
ofono_destroy_func removed_cb;
void *removed_data;
};
void voicecall_agent_ringback_tone(struct voicecall_agent *agent,
const ofono_bool_t playTone)
{
DBusConnection *conn = ofono_dbus_get_connection();
DBusMessage *message = dbus_message_new_method_call(
agent->bus, agent->path,
OFONO_VOICECALL_AGENT_INTERFACE,
"RingbackTone");
if (message == NULL)
return;
if (!dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &playTone,
DBUS_TYPE_INVALID))
return;
dbus_message_set_no_reply(message, TRUE);
g_dbus_send_message(conn, message);
}
void voicecall_agent_send_release(struct voicecall_agent *agent)
{
DBusConnection *conn = ofono_dbus_get_connection();
DBusMessage *message = dbus_message_new_method_call(
agent->bus, agent->path,
OFONO_VOICECALL_AGENT_INTERFACE,
"Release");
if (message == NULL)
return;
dbus_message_set_no_reply(message, TRUE);
g_dbus_send_message(conn, message);
}
void voicecall_agent_set_removed_notify(struct voicecall_agent *agent,
ofono_destroy_func destroy,
void *user_data)
{
agent->removed_cb = destroy;
agent->removed_data = user_data; /* voicecall atom (not owned) */
}
void voicecall_agent_free(struct voicecall_agent *agent)
{
DBusConnection *conn = ofono_dbus_get_connection();
if (agent->disconnect_watch) {
voicecall_agent_send_release(agent);
g_dbus_remove_watch(conn, agent->disconnect_watch);
agent->disconnect_watch = 0;
}
if (agent->removed_cb)
agent->removed_cb(agent->removed_data);
g_free(agent->path);
g_free(agent->bus);
g_free(agent);
}
ofono_bool_t voicecall_agent_matches(struct voicecall_agent *agent,
const char *path, const char *sender)
{
return g_str_equal(agent->path, path) &&
g_str_equal(agent->bus, sender);
}
void voicecall_agent_disconnect_cb(DBusConnection *conn, void *user_data)
{
struct voicecall_agent *agent = user_data;
agent->disconnect_watch = 0;
voicecall_agent_free(agent);
}
struct voicecall_agent *voicecall_agent_new(const char *path,
const char *sender)
{
struct voicecall_agent *agent = g_try_new0(struct voicecall_agent, 1);
DBusConnection *conn = ofono_dbus_get_connection();
if (agent == NULL)
return NULL;
agent->path = g_strdup(path);
agent->bus = g_strdup(sender);
agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
voicecall_agent_disconnect_cb,
agent, NULL);
return agent;
}

View File

@@ -0,0 +1,40 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2014 Jolla Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
struct voicecall_agent;
void voicecall_agent_ringback_tone(struct voicecall_agent *agent,
const ofono_bool_t playTone);
void voicecall_agent_set_removed_notify(struct voicecall_agent *agent,
ofono_destroy_func removed_cb,
void *user_data);
void voicecall_agent_free(struct voicecall_agent *agent);
ofono_bool_t voicecall_agent_matches(struct voicecall_agent *agent,
const char *path, const char *sender);
struct voicecall_agent *voicecall_agent_new(const char *path,
const char *sender);
void voicecall_agent_disconnect_cb(DBusConnection *conn,
void *user_data);

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
@@ -20,7 +20,7 @@ for path, properties in modems:
contexts = connman.GetContexts()
if (len(contexts) == 0):
print "No context available"
print("No context available")
sys.exit(1)
connman.SetProperty("Powered", dbus.Boolean(1))
@@ -35,6 +35,6 @@ for path, properties in modems:
try:
context.SetProperty("Active", dbus.Boolean(1), timeout = 100)
except dbus.DBusException, e:
print "Error activating %s: %s" % (path, str(e))
except dbus.DBusException as e:
print("Error activating %s: %s" % (path, str(e)))
exit(2)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
@@ -10,7 +10,7 @@ manager = dbus.Interface(bus.get_object('org.ofono', '/'),
modems = manager.GetModems()
for path, properties in modems:
print "[ %s ]" % (path)
print("[ %s ]" % (path))
if "org.ofono.VoiceCallManager" not in properties["Interfaces"]:
continue
@@ -22,7 +22,7 @@ for path, properties in modems:
for path, properties in calls:
state = properties["State"]
print "[ %s ] %s" % (path, state)
print("[ %s ] %s" % (path, state))
if state != "incoming":
continue

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python
#!/usr/bin/python3
import gobject
from gi.repository import GLib
import dbus
import dbus.mainloop.glib
@@ -12,23 +12,23 @@ def answer_call(path):
'org.ofono.VoiceCall')
time.sleep(2)
call.Answer()
print " Voice Call [ %s ] Answered" % (path)
print(" Voice Call [ %s ] Answered" % (path))
def voicecalls_call_added(path, properties):
print " Voice Call [ %s ] Added" % (path)
print(" Voice Call [ %s ] Added" % (path))
for key in properties.keys():
val = str(properties[key])
print " %s = %s" % (key, val)
print
print(" %s = %s" % (key, val))
print()
state = properties["State"]
if state == "incoming":
answer_call(path)
def voicecalls_call_removed(path):
print " Voice Call [ %s ] Removed" % (path)
print
print(" Voice Call [ %s ] Removed" % (path))
print()
if __name__ == "__main__":
global vcmanager
@@ -43,7 +43,7 @@ if __name__ == "__main__":
modems = manager.GetModems()
modem = modems[0][0]
print "Using modem %s" % modem
print("Using modem %s" % modem)
vcmanager = dbus.Interface(bus.get_object('org.ofono', modem),
'org.ofono.VoiceCallManager')
@@ -52,6 +52,6 @@ if __name__ == "__main__":
vcmanager.connect_to_signal("CallRemoved", voicecalls_call_removed)
mainloop = gobject.MainLoop()
mainloop = GLib.MainLoop()
mainloop.run()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import os
import re
@@ -6,7 +6,7 @@ import sys
import subprocess
if (len(sys.argv) < 3):
print "Usage: %s [binary] [log]" % (sys.argv[0])
print("Usage: %s [binary] [log]" % (sys.argv[0]))
sys.exit(1)
binary = sys.argv[1]
@@ -50,8 +50,8 @@ child_stdout.close()
frame_count = len(frames);
count = 0
print "-------- backtrace --------"
print("-------- backtrace --------")
while count < frame_count:
print "[%d]: %s() [%s]" % (count/2, frames[count], frames[count + 1])
print("[%d]: %s() [%s]" % (count/2, frames[count], frames[count + 1]))
count = count + 2
print "---------------------------"
print("---------------------------")

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
@@ -21,7 +21,7 @@ ussd = dbus.Interface(bus.get_object('org.ofono', path),
properties = ussd.GetProperties()
state = properties["State"]
print "State: %s" % (state)
print("State: %s" % (state))
if state != "idle":
ussd.Cancel()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
modems = manager.GetModems()
path = modems[0][0]
print "Disconnecting CDMA Packet Data Service on modem %s..." % path
print("Disconnecting CDMA Packet Data Service on modem %s..." % path)
cm = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.cdma.ConnectionManager')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
modems = manager.GetModems()
path = modems[0][0]
print "Connecting CDMA Packet Data Service on modem %s..." % path
print("Connecting CDMA Packet Data Service on modem %s..." % path)
cm = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.cdma.ConnectionManager')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
@@ -16,7 +16,7 @@ else:
path, properties = modems[0]
number = sys.argv[1]
print "Using modem %s" % path
print("Using modem %s" % path)
manager = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.cdma.VoiceCallManager')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
@@ -10,7 +10,7 @@ manager = dbus.Interface(bus.get_object('org.ofono', '/'),
modems = manager.GetModems()
for path, properties in modems:
print "[ %s ]" % (path)
print("[ %s ]" % (path))
if "org.ofono.cdma.VoiceCallManager" not in properties["Interfaces"]:
continue
@@ -22,4 +22,4 @@ for path, properties in modems:
for key in properties.keys():
val = str(properties[key])
print " %s = %s" % (key, val)
print(" %s = %s" % (key, val))

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -17,12 +17,12 @@ for path, properties in modems:
cm = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.cdma.ConnectionManager')
print "Connecting CDMA Packet Data Service on modem %s..." % path
print("Connecting CDMA Packet Data Service on modem %s..." % path)
if len(sys.argv) > 1:
cm.SetProperty("Username", (sys.argv[1]))
print "Setting Username to %s" % (sys.argv[1])
print("Setting Username to %s" % (sys.argv[1]))
if len(sys.argv) > 2:
cm.SetProperty("Password", (sys.argv[2]))
print "Setting Password to %s" % (sys.argv[2])
print("Setting Password to %s" % (sys.argv[2]))

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -19,10 +19,10 @@ elif len(sys.argv) == 3:
old_pin = sys.argv[2]
new_pin = sys.argv[3]
else:
print "%s [PATH] pin_type old_pin new_pin" % (sys.argv[0])
print("%s [PATH] pin_type old_pin new_pin" % (sys.argv[0]))
sys.exit(0)
print "Change %s for modem %s..." % (pin_type, path)
print("Change %s for modem %s..." % (pin_type, path))
simmanager = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.SimManager')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
@@ -27,21 +27,21 @@ for path, properties in modems:
if path == "":
path = connman.AddContext("internet")
print "Created new context %s" % (path)
print("Created new context %s" % (path))
else:
print "Found context %s" % (path)
print("Found context %s" % (path))
context = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.ConnectionContext')
if len(sys.argv) > 1:
context.SetProperty("AccessPointName", sys.argv[1])
print "Setting APN to %s" % (sys.argv[1])
print("Setting APN to %s" % (sys.argv[1]))
if len(sys.argv) > 2:
context.SetProperty("Username", sys.argv[2])
print "Setting username to %s" % (sys.argv[2])
print("Setting username to %s" % (sys.argv[2]))
if len(sys.argv) > 3:
context.SetProperty("Password", sys.argv[3])
print "Setting password to %s" % (sys.argv[3])
print("Setting password to %s" % (sys.argv[3]))

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
@@ -27,21 +27,21 @@ for path, properties in modems:
if path == "":
path = connman.AddContext("mms")
print "Created new context %s" % (path)
print("Created new context %s" % (path))
else:
print "Found context %s" % (path)
print("Found context %s" % (path))
context = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.ConnectionContext')
if len(sys.argv) > 1:
context.SetProperty("AccessPointName", sys.argv[1])
print "Setting APN to %s" % (sys.argv[1])
print("Setting APN to %s" % (sys.argv[1]))
if len(sys.argv) > 2:
context.SetProperty("Username", sys.argv[2])
print "Setting username to %s" % (sys.argv[2])
print("Setting username to %s" % (sys.argv[2]))
if len(sys.argv) > 3:
context.SetProperty("Password", sys.argv[3])
print "Setting password to %s" % (sys.argv[3])
print("Setting password to %s" % (sys.argv[3]))

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
@@ -21,4 +21,4 @@ manager = dbus.Interface(bus.get_object('org.ofono', path),
mpty = manager.CreateMultiparty()
for path in mpty:
print path
print(path)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
@@ -20,7 +20,7 @@ for path, properties in modems:
contexts = connman.GetContexts()
if (len(contexts) == 0):
print "No context available"
print("No context available")
sys.exit(1)
if len(sys.argv) > 1:
@@ -33,6 +33,6 @@ for path, properties in modems:
try:
context.SetProperty("Active", dbus.Boolean(0))
except dbus.DBusException, e:
print "Error activating %s: %s" % (path, str(e))
except dbus.DBusException as e:
print("Error activating %s: %s" % (path, str(e)))
exit(2)

View File

@@ -1,10 +1,10 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
if (len(sys.argv) < 2):
print "Usage: %s [modem] <number> [hide_callerid]" % (sys.argv[0])
print("Usage: %s [modem] <number> [hide_callerid]" % (sys.argv[0]))
sys.exit(1)
bus = dbus.SystemBus()
@@ -32,11 +32,11 @@ else:
number = sys.argv[2]
hide_callerid = sys.argv[3]
print "Using modem %s" % modem
print("Using modem %s" % modem)
vcm = dbus.Interface(bus.get_object('org.ofono', modem),
'org.ofono.VoiceCallManager')
path = vcm.Dial(number, hide_callerid)
print path
print(path)

View File

@@ -1,24 +1,24 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import gobject
from gi.repository import GLib
import dbus
import dbus.mainloop.glib
def property_changed(property, value):
if len(value.__str__()) > 0:
print "CF property %s changed to %s" % (property, value)
print("CF property %s changed to %s" % (property, value))
else:
print "CF property %s changed to disabled" % (property)
print("CF property %s changed to disabled" % (property))
if canexit:
mainloop.quit();
if __name__ == "__main__":
if len(sys.argv) < 2:
print "Usage: %s <type>" % (sys.argv[0])
print "Type can be: all, conditional"
print("Usage: %s <type>" % (sys.argv[0]))
print("Type can be: all, conditional")
sys.exit(1)
canexit = False
@@ -41,13 +41,13 @@ if __name__ == "__main__":
try:
cf.DisableAll(type, timeout = 100)
except dbus.DBusException, e:
print "Unable to DisableAll", e
except dbus.DBusException as e:
print("Unable to DisableAll %s" % e)
sys.exit(1);
print "DisableAll successful"
print("DisableAll successful")
canexit = True
mainloop = gobject.MainLoop()
mainloop = GLib.MainLoop()
mainloop.run()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
modems = manager.GetModems()
path = modems[0][0]
print "Disconnecting GPRS on modem %s..." % path
print("Disconnecting GPRS on modem %s..." % path)
cm = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.ConnectionManager')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
modems = manager.GetModems()
path = modems[0][0]
print "Disconnecting modem %s..." % path
print("Disconnecting modem %s..." % path)
modem = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.Modem')

View File

@@ -1,10 +1,10 @@
#!/usr/bin/python
#!/usr/bin/python3
import sys
import dbus
if (len(sys.argv) < 2):
print "Usage: %s [modem] icon_id" % (sys.argv[0])
print("Usage: %s [modem] icon_id" % (sys.argv[0]))
sys.exit(1)
bus = dbus.SystemBus()
@@ -21,7 +21,7 @@ elif (len(sys.argv) == 3):
modem = sys.argv[1]
icon = sys.argv[2]
print "Using modem %s" % modem
print("Using modem %s" % modem)
sim = dbus.Interface(bus.get_object('org.ofono', modem),
'org.ofono.SimManager')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
devices = manager.GetDevices()
path = devices[0][0]
print "Connect device %s..." % path
print("Connect device %s..." % path)
device = dbus.Interface(bus.get_object('org.ofono.dundee', path),
'org.ofono.dundee.Device')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
devices = manager.GetDevices()
path = devices[0][0]
print "Disconnect device %s..." % path
print("Disconnect device %s..." % path)
device = dbus.Interface(bus.get_object('org.ofono.dundee', path),
'org.ofono.dundee.Device')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
modems = manager.GetModems()
path = modems[0][0]
print "Enabling cell broadcast on modem %s..." % path
print("Enabling cell broadcast on modem %s..." % path)
cbs = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.CellBroadcast')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
modems = manager.GetModems()
path = modems[0][0]
print "Connecting modem %s..." % path
print("Connecting modem %s..." % path)
cm = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.ConnectionManager')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -13,7 +13,7 @@ else:
modems = manager.GetModems()
path = modems[0][0]
print "Connecting modem %s..." % path
print("Connecting modem %s..." % path)
modem = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.Modem')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
import dbus
import sys
@@ -17,10 +17,10 @@ elif len(sys.argv) == 3:
pin_type = sys.argv[1]
pin = sys.argv[2]
else:
print "%s [PATH] pin_type pin" % (sys.argv[0])
print("%s [PATH] pin_type pin" % (sys.argv[0]))
sys.exit(0)
print "Enter Pin for modem %s..." % path
print("Enter Pin for modem %s..." % path)
simmanager = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.SimManager')

Some files were not shown because too many files have changed in this diff Show More