Merge lp:~awe/phablet-extras/ofono-raring into lp:phablet-extras/ofono

Proposed by Tony Espy
Status: Merged
Approved by: Ricardo Salveti
Approved revision: 35
Merged at revision: 30
Proposed branch: lp:~awe/phablet-extras/ofono-raring
Merge into: lp:phablet-extras/ofono
Prerequisite: lp:~awe/phablet-extras/ofono-flatten
Diff against target: 6188 lines (+5905/-14)
31 files modified
Makefile.am (+37/-9)
configure.ac (+5/-0)
debian/changelog (+56/-0)
debian/control (+3/-0)
debian/ofono.install (+0/-2)
debian/ofono.upstart (+6/-1)
debian/rules (+2/-2)
drivers/rilmodem/call-volume.c (+186/-0)
drivers/rilmodem/devinfo.c (+171/-0)
drivers/rilmodem/network-registration.c (+595/-0)
drivers/rilmodem/rilmodem.c (+61/-0)
drivers/rilmodem/rilmodem.h (+38/-0)
drivers/rilmodem/rilutil.c (+372/-0)
drivers/rilmodem/rilutil.h (+125/-0)
drivers/rilmodem/sms.c (+357/-0)
drivers/rilmodem/voicecall.c (+537/-0)
gril/gfunc.h (+42/-0)
gril/gril.c (+1160/-0)
gril/gril.h (+102/-0)
gril/grilio.c (+396/-0)
gril/grilio.h (+69/-0)
gril/grilresponse.h (+46/-0)
gril/grilutil.c (+499/-0)
gril/grilutil.h (+53/-0)
gril/parcel.c (+181/-0)
gril/parcel.h (+43/-0)
gril/ril_constants.h (+244/-0)
gril/ringbuffer.h (+107/-0)
include/modem.h (+1/-0)
plugins/ril.c (+395/-0)
src/modem.c (+16/-0)
To merge this branch: bzr merge lp:~awe/phablet-extras/ofono-raring
Reviewer Review Type Date Requested Status
Ricardo Salveti (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+156908@code.launchpad.net

Commit message

Re-based ofono/RILD code on new upstream version ofono-1.12-0ubuntu2b1 from Raring.

Description of the change

This MR represents a re-base of the oFono RILD code from the quantal version (ofono-1.9) to the raring version (ofono-1.12).

Basic functional testing was run on a Galaxy Nexus using a recent daily build. Phone calls and SMSs were both tested.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

There are quite a few things missing here:
* Not running autoreconf during configure (as we change configure.ac and makefile.am)
* makefile.am not covering all changes we had (missing -lwaudio for example)
* build fails when building the plugins:
plugins/phonesim.o: In function `localhfp_enable':
/home/phablet/ofono/ofono-raring/plugins/phonesim.c:883: undefined reference to `hfp_slc_info_init'
/home/phablet/ofono/ofono-raring/plugins/phonesim.c:885: undefined reference to `hfp_slc_establish'
plugins/hfp_hf.o: In function `hfp_agent_new_connection':
/home/phablet/ofono/ofono-raring/plugins/hfp_hf.c:173: undefined reference to `hfp_slc_info_init'
plugins/hfp_hf.o: In function `service_level_connection':
/home/phablet/ofono/ofono-raring/plugins/hfp_hf.c:156: undefined reference to `hfp_slc_establish'
collect2: error: ld returned 1 exit status
make[2]: *** [src/ofonod] Error 1
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/phablet/ofono/ofono-raring'
make: *** [debian/stamp-makefile-build] Error 2
dpkg-buildpackage: error: debian/rules build gave error exit status 2

Trying to build the package with dpkg-buildpackage -uc -us.

review: Needs Fixing
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Needed changes just to make it get to the failed point pointed above:
$ bzr diff
=== modified file 'Makefile.am'
--- Makefile.am 2013-03-28 12:50:26 +0000
+++ Makefile.am 2013-04-09 02:28:20 +0000
@@ -526,7 +526,7 @@
    src/cdma-sms.c src/private-network.c src/cdma-netreg.c \
    src/cdma-provision.c src/handsfree.c

-src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ -ldl
+src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ -ldl -lwaudio

 src_ofonod_LDFLAGS = -Wl,--export-dynamic \
     -Wl,--version-script=$(srcdir)/src/ofono.ver

=== modified file 'debian/control'
--- debian/control 2013-03-28 12:50:26 +0000
+++ debian/control 2013-04-09 02:14:30 +0000
@@ -6,10 +6,12 @@
 Uploaders: Jonny Lamb <email address hidden>, Hector Oron <email address hidden>, Konstantinos Margaritis <email address hidden>
 Build-Depends: debhelper (>= 7.0.50~),
                cdbs,
+ dh-autoreconf,
                libtool,
                libglib2.0-dev (>= 2.22),
                libdbus-glib-1-dev,
                libudev-dev,
+ libwaudio1-dev (>= 1.4~quantal1),
                udev,
                libbluetooth-dev (>= 4.30),
                mobile-broadband-provider-info

=== modified file 'debian/rules'
--- debian/rules 2012-08-22 19:59:08 +0000
+++ debian/rules 2013-04-09 02:05:25 +0000
@@ -2,6 +2,7 @@
 DEB_AUTO_CLEANUP_RCS := yes

 include /usr/share/cdbs/1/class/autotools.mk
+include /usr/share/cdbs/1/rules/autoreconf.mk
 include /usr/share/cdbs/1/rules/debhelper.mk
 #include /usr/share/cdbs/1/rules/simple-patchsys.mk
 include /usr/share/cdbs/1/rules/utils.mk

lp:~awe/phablet-extras/ofono-raring updated
32. By Tony Espy

Fix build problems by enabled autoreconf, disabling Bluetooth, and fixing
the android audio system dependency.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~awe/phablet-extras/ofono-raring updated
33. By Tony Espy

Remove dundee reference in debian/ofono.install.

34. By Tony Espy

Removed udev references from debian/ofono.install.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~awe/phablet-extras/ofono-raring updated
35. By Tony Espy

Disable udev in debian/rules.

Revision history for this message
Tony Espy (awe) wrote :

Should be all set.

I verified the latest branch builds, installs and runs on a quantal touch daily ( today's ). I verified that incoming/outgoing sms and voice calls worked.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Good, worked fine at both quantal and raring, with phone calls and sms.

Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile.am'
--- Makefile.am 2013-01-28 16:25:32 +0000
+++ Makefile.am 2013-04-09 20:01:20 +0000
@@ -89,6 +89,12 @@
89 gisi/server.c gisi/server.h \89 gisi/server.c gisi/server.h \
90 gisi/socket.c gisi/socket.h90 gisi/socket.c gisi/socket.h
9191
92gril_sources = gril/gril.h gril/gril.c gril/grilio.h \
93 gril/grilio.c gril/grilutil.h \
94 gril/grilutil.c gril/ringbuffer.h \
95 gril/gfunc.h gril/ril.h \
96 gril/parcel.c gril/parcel.h
97
92btio_sources = btio/btio.h btio/btio.c98btio_sources = btio/btio.h btio/btio.c
9399
94if UDEV100if UDEV
@@ -101,6 +107,25 @@
101builtin_sources += plugins/udevng.c107builtin_sources += plugins/udevng.c
102endif108endif
103109
110if RILMODEM
111builtin_sources += $(gril_sources)
112
113builtin_modules += ril
114builtin_sources += plugins/ril.c
115
116builtin_modules += rilmodem
117builtin_sources += drivers/rilmodem/rilmodem.h \
118 drivers/rilmodem/rilmodem.c \
119 drivers/rilmodem/devinfo.c \
120 drivers/rilmodem/network-registration.c \
121 drivers/rilmodem/voicecall.c \
122 drivers/rilmodem/call-volume.c \
123 drivers/rilmodem/sms.c \
124 drivers/rilmodem/rilutil.c \
125 drivers/rilmodem/rilutil.h
126
127endif
128
104if ISIMODEM129if ISIMODEM
105builtin_modules += isimodem130builtin_modules += isimodem
106builtin_sources += $(gisi_sources) \131builtin_sources += $(gisi_sources) \
@@ -210,7 +235,7 @@
210 drivers/atmodem/gprs-context.c \235 drivers/atmodem/gprs-context.c \
211 drivers/atmodem/sim-auth.c \236 drivers/atmodem/sim-auth.c \
212 drivers/atmodem/gnss.c237 drivers/atmodem/gnss.c
213238if !RILMODEM
214builtin_modules += nwmodem239builtin_modules += nwmodem
215builtin_sources += drivers/atmodem/atutil.h \240builtin_sources += drivers/atmodem/atutil.h \
216 drivers/nwmodem/nwmodem.h \241 drivers/nwmodem/nwmodem.h \
@@ -299,6 +324,13 @@
299 drivers/dunmodem/network-registration.c \324 drivers/dunmodem/network-registration.c \
300 drivers/dunmodem/gprs.c325 drivers/dunmodem/gprs.c
301326
327builtin_modules += speedupmodem
328builtin_sources += drivers/atmodem/atutil.h \
329 drivers/speedupmodem/speedupmodem.h \
330 drivers/speedupmodem/speedupmodem.c \
331 drivers/speedupmodem/ussd.c
332endif
333
302builtin_modules += hfpmodem334builtin_modules += hfpmodem
303builtin_sources += drivers/atmodem/atutil.h \335builtin_sources += drivers/atmodem/atutil.h \
304 drivers/hfpmodem/hfpmodem.h \336 drivers/hfpmodem/hfpmodem.h \
@@ -311,12 +343,6 @@
311 drivers/hfpmodem/devinfo.c \343 drivers/hfpmodem/devinfo.c \
312 drivers/hfpmodem/handsfree.c344 drivers/hfpmodem/handsfree.c
313345
314builtin_modules += speedupmodem
315builtin_sources += drivers/atmodem/atutil.h \
316 drivers/speedupmodem/speedupmodem.h \
317 drivers/speedupmodem/speedupmodem.c \
318 drivers/speedupmodem/ussd.c
319
320if PHONESIM346if PHONESIM
321builtin_modules += phonesim347builtin_modules += phonesim
322builtin_sources += plugins/phonesim.c348builtin_sources += plugins/phonesim.c
@@ -335,6 +361,7 @@
335 drivers/cdmamodem/connman.c361 drivers/cdmamodem/connman.c
336endif362endif
337363
364if !RILMODEM
338builtin_modules += g1365builtin_modules += g1
339builtin_sources += plugins/g1.c366builtin_sources += plugins/g1.c
340367
@@ -406,6 +433,7 @@
406433
407builtin_modules += sim900434builtin_modules += sim900
408builtin_sources += plugins/sim900.c435builtin_sources += plugins/sim900.c
436endif
409437
410if BLUETOOTH438if BLUETOOTH
411builtin_modules += bluetooth439builtin_modules += bluetooth
@@ -498,7 +526,7 @@
498 src/cdma-sms.c src/private-network.c src/cdma-netreg.c \526 src/cdma-sms.c src/private-network.c src/cdma-netreg.c \
499 src/cdma-provision.c src/handsfree.c527 src/cdma-provision.c src/handsfree.c
500528
501src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ -ldl529src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ -ldl -lwaudio
502530
503src_ofonod_LDFLAGS = -Wl,--export-dynamic \531src_ofonod_LDFLAGS = -Wl,--export-dynamic \
504 -Wl,--version-script=$(srcdir)/src/ofono.ver532 -Wl,--version-script=$(srcdir)/src/ofono.ver
@@ -522,7 +550,7 @@
522550
523INCLUDES = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/src \551INCLUDES = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/src \
524 -I$(srcdir)/gdbus -I$(srcdir)/gisi -I$(srcdir)/gatchat \552 -I$(srcdir)/gdbus -I$(srcdir)/gisi -I$(srcdir)/gatchat \
525 -I$(srcdir)/btio553 -I$(srcdir)/btio -I$(srcdir)/gril
526554
527doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \555doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
528 doc/manager-api.txt doc/modem-api.txt doc/network-api.txt \556 doc/manager-api.txt doc/modem-api.txt doc/network-api.txt \
529557
=== modified file 'configure.ac'
--- configure.ac 2013-01-28 16:25:32 +0000
+++ configure.ac 2013-04-09 20:01:20 +0000
@@ -167,6 +167,11 @@
167 [enable_isimodem=${enableval}])167 [enable_isimodem=${enableval}])
168AM_CONDITIONAL(ISIMODEM, test "${enable_isimodem}" != "no")168AM_CONDITIONAL(ISIMODEM, test "${enable_isimodem}" != "no")
169169
170AC_ARG_ENABLE(rilmodem, AC_HELP_STRING([--disable-rilmodem],
171 [disable RIL modem support]),
172 [enable_rilmodem=${enableval}])
173AM_CONDITIONAL(RILMODEM, test "${enable_rilmodem}" != "no")
174
170AC_ARG_ENABLE(qmimodem, AC_HELP_STRING([--disable-qmimodem],175AC_ARG_ENABLE(qmimodem, AC_HELP_STRING([--disable-qmimodem],
171 [disable Qualcomm QMI modem support]),176 [disable Qualcomm QMI modem support]),
172 [enable_qmimodem=${enableval}])177 [enable_qmimodem=${enableval}])
173178
=== modified file 'debian/changelog'
--- debian/changelog 2013-04-03 16:11:02 +0000
+++ debian/changelog 2013-04-09 20:01:20 +0000
@@ -1,5 +1,61 @@
1ofono (1.12phablet1) UNRELEASED; urgency=low1ofono (1.12phablet1) UNRELEASED; urgency=low
22
3 [ Ricardo Salveti de Araujo ]
4 * ofono.upstart: not starting with debug by default, not needed anymore
5 * drivers/rilmodem/devinfo.c: fake data should just use Fake instead of
6 Galaxy Nexus
7
8 [ Tony Espy ]
9 * gril/*, plugins/ril.c, drivers/rilmodem/*: fixed copyright headers,
10 sanitized comments.
11
12 [ Ricardo Salveti de Araujo ]
13 * Fixing audio states during and after a call, previously broken with
14 JellyBean (LP: #1101339)
15
16 [ Tony Espy ]
17 * Re-named the galaxynexus plugin to ril.
18 * [galaxynexus] Add SIM checking to modem initialization.
19 * [gril] Add ril_request_id_to_string function.
20 * [core] Modify ofono_modem_set_online() to call modem_change_state(),
21 which triggers our new modem initialization logic in galaxynexus'
22 post_online function.
23
24 [ Ricardo Salveti de Araujo ]
25 * parcel.c: fixing data padding boundary for parcel_w_string (LP: #1088559)
26 * Only setting audio mode in call when actually dialing or answering (to
27 allow ringtones at the ubuntu side)
28
29 [ Tony Espy ]
30 * Disable atmodem plugin on starup.
31
32 [ Ricardo Salveti de Araujo ]
33 * Adding proper support for network registration and network state changes
34 * Support registering for network time update reports
35 * Extending network registration to support current operator, list of
36 operators and auto/manual registration
37 * Enabling support to retrieve the signal strength
38 * Enabling initial support for DTMF
39 * Adding support for answering a call
40 * Tuning start sleep for 8 and running with debug messages enabled
41 * Sync ril_delayed_register timeout to 2 for all services in rilmodem
42 * Setting up voice state and enabling voice call support at AudioFlinger
43
44 [ Tony Espy ]
45 * Initial version of notification framework for RIL
46 unsolicited events ( signal strength, new sms, ... ).
47 * Support for incoming SMS messages (LP: #1085896).
48
49 [ Ricardo Salveti de Araujo ]
50 * Adding support for voice call (LP: #1085893)
51 * Adding utils files for parcel and string handling
52 * Enable basic support for voice volume (mute/unmute)
53
54 [ Michael Frey ]
55 * debian/ofono.upstart: Fix for hang on shutdown.
56
57 [ Tony Espy ]
58 * First hard-coded support for RIL modem on Galaxy Nexus.
3 * Initial phablet version, converted to native for59 * Initial phablet version, converted to native for
4 easier development of new RIL driver/plugin code.60 easier development of new RIL driver/plugin code.
5 - debian/source/format: changed to 3.0 (native)61 - debian/source/format: changed to 3.0 (native)
662
=== modified file 'debian/control'
--- debian/control 2012-08-22 19:59:08 +0000
+++ debian/control 2013-04-09 20:01:20 +0000
@@ -6,9 +6,12 @@
6Uploaders: Jonny Lamb <jonny@debian.org>, Hector Oron <zumbi@debian.org>, Konstantinos Margaritis <markos@debian.org>6Uploaders: Jonny Lamb <jonny@debian.org>, Hector Oron <zumbi@debian.org>, Konstantinos Margaritis <markos@debian.org>
7Build-Depends: debhelper (>= 7.0.50~),7Build-Depends: debhelper (>= 7.0.50~),
8 cdbs,8 cdbs,
9 dh-autoreconf,
10 libtool,
9 libglib2.0-dev (>= 2.22),11 libglib2.0-dev (>= 2.22),
10 libdbus-glib-1-dev,12 libdbus-glib-1-dev,
11 libudev-dev,13 libudev-dev,
14 libwaudio1-dev,
12 udev,15 udev,
13 libbluetooth-dev (>= 4.30),16 libbluetooth-dev (>= 4.30),
14 mobile-broadband-provider-info17 mobile-broadband-provider-info
1518
=== modified file 'debian/ofono.install'
--- debian/ofono.install 2012-08-22 19:59:08 +0000
+++ debian/ofono.install 2013-04-09 20:01:20 +0000
@@ -1,6 +1,4 @@
1debian/tmp/etc/dbus-1/system.d/*1debian/tmp/etc/dbus-1/system.d/*
2debian/tmp/usr/sbin/ofonod2debian/tmp/usr/sbin/ofonod
3debian/tmp/usr/sbin/dundee
4debian/tmp/etc/ofono3debian/tmp/etc/ofono
5debian/tmp/lib/udev/rules.d/*
6debian/tmp/usr/share/man4debian/tmp/usr/share/man
75
=== modified file 'debian/ofono.upstart'
--- debian/ofono.upstart 2010-09-02 18:21:57 +0000
+++ debian/ofono.upstart 2013-04-09 20:01:20 +0000
@@ -6,4 +6,9 @@
6expect fork6expect fork
7respawn7respawn
88
9exec ofonod9exec ofonod --noplugin=atmodem
10
11pre-start script
12 sleep 8
13end script
14
1015
=== modified file 'debian/rules'
--- debian/rules 2012-08-22 19:59:08 +0000
+++ debian/rules 2013-04-09 20:01:20 +0000
@@ -2,14 +2,14 @@
2DEB_AUTO_CLEANUP_RCS := yes2DEB_AUTO_CLEANUP_RCS := yes
33
4include /usr/share/cdbs/1/class/autotools.mk4include /usr/share/cdbs/1/class/autotools.mk
5include /usr/share/cdbs/1/rules/autoreconf.mk
5include /usr/share/cdbs/1/rules/debhelper.mk6include /usr/share/cdbs/1/rules/debhelper.mk
6#include /usr/share/cdbs/1/rules/simple-patchsys.mk
7include /usr/share/cdbs/1/rules/utils.mk7include /usr/share/cdbs/1/rules/utils.mk
88
9DEB_DH_INSTALLINIT_ARGS := --no-restart-on-upgrade9DEB_DH_INSTALLINIT_ARGS := --no-restart-on-upgrade
1010
11common-binary-post-install-arch:: list-missing11common-binary-post-install-arch:: list-missing
1212
13DEB_CONFIGURE_EXTRA_FLAGS := --enable-bluetooth --enable-dundee13DEB_CONFIGURE_EXTRA_FLAGS := --disable-bluetooth --disable-dundee --disable-udev
1414
15include $(CURDIR)/debian/update-patches.mk15include $(CURDIR)/debian/update-patches.mk
1616
=== added directory 'drivers/rilmodem'
=== added file 'drivers/rilmodem/call-volume.c'
--- drivers/rilmodem/call-volume.c 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/call-volume.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,186 @@
1/*
2 *
3 * oFono - Open Source Telephony
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#define _GNU_SOURCE
28#include <string.h>
29#include <stdio.h>
30#include <errno.h>
31
32#include <glib.h>
33
34#include <ofono/log.h>
35#include <ofono/modem.h>
36#include <ofono/call-volume.h>
37
38#include "gril.h"
39#include "grilutil.h"
40
41#include "common.h"
42
43#include "rilmodem.h"
44#include "parcel.h"
45
46struct cv_data {
47 GRil *ril;
48 unsigned int vendor;
49};
50
51static void volume_mute_cb(struct ril_msg *message, gpointer user_data)
52{
53 struct cb_data *cbd = user_data;
54 ofono_call_volume_cb_t cb = cbd->cb;
55 struct ofono_error error;
56
57 DBG("");
58
59 if (message->error == RIL_E_SUCCESS) {
60 decode_ril_error(&error, "OK");
61 } else {
62 ofono_error("Could not set the ril mute state");
63 decode_ril_error(&error, "FAIL");
64 }
65
66 cb(&error, cbd->data);
67}
68
69static void ril_call_volume_mute(struct ofono_call_volume *cv, int muted,
70 ofono_call_volume_cb_t cb, void *data)
71{
72 struct cv_data *cvd = ofono_call_volume_get_data(cv);
73 struct cb_data *cbd = cb_data_new(cb, data);
74 struct parcel rilp;
75
76 DBG("");
77
78 parcel_init(&rilp);
79 parcel_w_int32(&rilp, 1);
80 parcel_w_int32(&rilp, muted);
81 g_ril_send(cvd->ril, RIL_REQUEST_SET_MUTE, rilp.data,
82 rilp.size, volume_mute_cb, cbd, g_free);
83 parcel_free(&rilp);
84
85 return;
86}
87
88static void probe_mute_cb(struct ril_msg *message, gpointer user_data)
89{
90 struct ofono_call_volume *cv = user_data;
91 struct parcel rilp;
92 int muted;
93
94 DBG("");
95
96 if (message->error != RIL_E_SUCCESS) {
97 ofono_error("Could not retrive the ril mute state");
98 return;
99 }
100
101 /* Set up Parcel struct for proper parsing */
102 rilp.data = message->buf;
103 rilp.size = message->buf_len;
104 rilp.capacity = message->buf_len;
105 rilp.offset = 0;
106
107 muted = parcel_r_int32(&rilp);
108 DBG("Initial ril muted state: %d", muted);
109
110 ofono_call_volume_set_muted(cv, muted);
111}
112
113static void call_probe_mute(gpointer user_data)
114{
115 struct ofono_call_volume *cv = user_data;
116 struct cv_data *cvd = ofono_call_volume_get_data(cv);
117
118 DBG("Requesting mute from RIL");
119
120 g_ril_send(cvd->ril, RIL_REQUEST_GET_MUTE, NULL, 0,
121 probe_mute_cb, cv, NULL);
122
123 return;
124}
125
126static gboolean ril_delayed_register(gpointer user_data)
127{
128 struct ofono_call_volume *cv = user_data;
129 DBG("");
130 ofono_call_volume_register(cv);
131
132 /* Probe the mute state */
133 call_probe_mute(user_data);
134
135 /* This makes the timeout a single-shot */
136 return FALSE;
137}
138
139static int ril_call_volume_probe(struct ofono_call_volume *cv,
140 unsigned int vendor, void *data)
141{
142 GRil *ril = data;
143 struct cv_data *cvd;
144
145 DBG("");
146
147 cvd = g_new0(struct cv_data, 1);
148 if (cvd == NULL)
149 return -ENOMEM;
150
151 cvd->ril = g_ril_clone(ril);
152 cvd->vendor = vendor;
153
154 ofono_call_volume_set_data(cv, cvd);
155
156 g_timeout_add_seconds(2, ril_delayed_register, cv);
157
158 return 0;
159}
160
161static void ril_call_volume_remove(struct ofono_call_volume *cv)
162{
163 struct cv_data *cvd = ofono_call_volume_get_data(cv);
164
165 ofono_call_volume_set_data(cv, NULL);
166
167 g_ril_unref(cvd->ril);
168 g_free(cvd);
169}
170
171static struct ofono_call_volume_driver driver = {
172 .name = "rilmodem",
173 .probe = ril_call_volume_probe,
174 .remove = ril_call_volume_remove,
175 .mute = ril_call_volume_mute,
176};
177
178void ril_call_volume_init(void)
179{
180 ofono_call_volume_driver_register(&driver);
181}
182
183void ril_call_volume_exit(void)
184{
185 ofono_call_volume_driver_unregister(&driver);
186}
0187
=== added file 'drivers/rilmodem/devinfo.c'
--- drivers/rilmodem/devinfo.c 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/devinfo.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,171 @@
1/*
2 *
3 * oFono - Open Source Telephony - RIL Modem Support
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#define _GNU_SOURCE
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <errno.h>
32
33#include <glib.h>
34
35#include <ofono/log.h>
36#include <ofono/modem.h>
37#include <ofono/devinfo.h>
38
39#include "gril.h"
40
41#include "rilmodem.h"
42
43/*
44 * TODO: The functions in this file are stubbed out, and
45 * will need to be re-worked to talk to the /gril layer
46 * in order to get real values from RILD.
47 */
48
49static void ril_query_manufacturer(struct ofono_devinfo *info,
50 ofono_devinfo_query_cb_t cb,
51 void *data)
52{
53 const char *attr = "Fake Manufacturer";
54 struct cb_data *cbd = cb_data_new(cb, data);
55 struct ofono_error error;
56 decode_ril_error(&error, "OK");
57
58 cb(&error, attr, cbd->data);
59
60 /* Note: this will need to change if cbd passed to gril layer */
61 g_free(cbd);
62}
63
64static void ril_query_model(struct ofono_devinfo *info,
65 ofono_devinfo_query_cb_t cb,
66 void *data)
67{
68 const char *attr = "Fake Modem Model";
69 struct cb_data *cbd = cb_data_new(cb, data);
70 struct ofono_error error;
71 decode_ril_error(&error, "OK");
72
73 cb(&error, attr, cbd->data);
74
75 /* Note: this will need to change if cbd passed to gril layer */
76 g_free(cbd);
77}
78
79static void ril_query_revision(struct ofono_devinfo *info,
80 ofono_devinfo_query_cb_t cb,
81 void *data)
82{
83 const char *attr = "Fake Revision";
84 struct cb_data *cbd = cb_data_new(cb, data);
85 struct ofono_error error;
86 decode_ril_error(&error, "OK");
87
88 cb(&error, attr, cbd->data);
89
90 /* Note: this will need to change if cbd passed to gril layer */
91 g_free(cbd);
92}
93
94static void ril_query_serial(struct ofono_devinfo *info,
95 ofono_devinfo_query_cb_t cb,
96 void *data)
97{
98 const char *attr = "THIS-IS-A-FAKE-SERIAL-NO";
99 struct cb_data *cbd = cb_data_new(cb, data);
100 struct ofono_error error;
101 decode_ril_error(&error, "OK");
102
103 cb(&error, attr, cbd->data);
104
105 /* Note: this will need to change if cbd passed to gril layer */
106 g_free(cbd);
107}
108
109static gboolean ril_delayed_register(gpointer user_data)
110{
111 struct ofono_devinfo *info = user_data;
112 DBG("");
113 ofono_devinfo_register(info);
114
115 /* This makes the timeout a single-shot */
116 return FALSE;
117}
118
119static int ril_devinfo_probe(struct ofono_devinfo *info, unsigned int vendor,
120 void *data)
121{
122 GRil *ril = NULL;
123
124 if (data != NULL)
125 ril = g_ril_clone(data);
126
127 ofono_devinfo_set_data(info, ril);
128
129 DBG("");
130
131 /* Nothing to send...
132 *
133 * ofono_devinfo_register() needs to be called after
134 * the driver has been set in devinfo_create() which
135 * calls this function. Most other drivers use a
136 * callback after getting some return from the modem
137 * itself...
138 */
139 g_timeout_add_seconds(1, ril_delayed_register, info);
140
141 return 0;
142}
143
144static void ril_devinfo_remove(struct ofono_devinfo *info)
145{
146 GRil *ril = ofono_devinfo_get_data(info);
147
148 ofono_devinfo_set_data(info, NULL);
149
150 g_ril_unref(ril);
151}
152
153static struct ofono_devinfo_driver driver = {
154 .name = "rilmodem",
155 .probe = ril_devinfo_probe,
156 .remove = ril_devinfo_remove,
157 .query_manufacturer = ril_query_manufacturer,
158 .query_model = ril_query_model,
159 .query_revision = ril_query_revision,
160 .query_serial = ril_query_serial
161};
162
163void ril_devinfo_init(void)
164{
165 ofono_devinfo_driver_register(&driver);
166}
167
168void ril_devinfo_exit(void)
169{
170 ofono_devinfo_driver_unregister(&driver);
171}
0172
=== added file 'drivers/rilmodem/network-registration.c'
--- drivers/rilmodem/network-registration.c 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/network-registration.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,595 @@
1/*
2 *
3 * oFono - Open Source Telephony - RIL Modem Support
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2010 ST-Ericsson AB.
7 * Copyright (C) 2012 Canonical Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#define _GNU_SOURCE
29#include <string.h>
30#include <stdlib.h>
31#include <stdio.h>
32
33#include <glib.h>
34
35#include <ofono/log.h>
36#include <ofono/modem.h>
37#include <ofono/netreg.h>
38
39#include "gril.h"
40
41#include "rilmodem.h"
42#include "parcel.h"
43#include "common.h"
44#include "parcel.h"
45
46struct netreg_data {
47 GRil *ril;
48 char mcc[OFONO_MAX_MCC_LENGTH + 1];
49 char mnc[OFONO_MAX_MNC_LENGTH + 1];
50 int signal_index; /* If strength is reported via CIND */
51 int signal_min; /* min strength reported via CIND */
52 int signal_max; /* max strength reported via CIND */
53 int signal_invalid; /* invalid strength reported via CIND */
54 int tech;
55 struct ofono_network_time time;
56 guint nitz_timeout;
57 unsigned int vendor;
58};
59
60/* 27.007 Section 7.3 <stat> */
61enum operator_status {
62 OPERATOR_STATUS_UNKNOWN = 0,
63 OPERATOR_STATUS_AVAILABLE = 1,
64 OPERATOR_STATUS_CURRENT = 2,
65 OPERATOR_STATUS_FORBIDDEN = 3,
66};
67
68static void extract_mcc_mnc(const char *str, char *mcc, char *mnc)
69{
70 /* Three digit country code */
71 strncpy(mcc, str, OFONO_MAX_MCC_LENGTH);
72 mcc[OFONO_MAX_MCC_LENGTH] = '\0';
73
74 /* Usually a 2 but sometimes 3 digit network code */
75 strncpy(mnc, str + OFONO_MAX_MCC_LENGTH, OFONO_MAX_MNC_LENGTH);
76 mnc[OFONO_MAX_MNC_LENGTH] = '\0';
77}
78
79/*
80 * TODO: The functions in this file are stubbed out, and
81 * will need to be re-worked to talk to the /gril layer
82 * in order to get real values from RILD.
83 */
84
85static void ril_creg_cb(struct ril_msg *message, gpointer user_data)
86{
87 struct cb_data *cbd = user_data;
88 ofono_netreg_status_cb_t cb = cbd->cb;
89 struct netreg_data *nd = cbd->user;
90 struct ofono_error error;
91 int status, lac, ci, tech;
92
93 DBG("");
94
95 if (message->error != RIL_E_SUCCESS) {
96 decode_ril_error(&error, "FAIL");
97 ofono_error("Failed to pull registration state");
98 cb(&error, -1, -1, -1, -1, cbd->data);
99 return;
100 }
101
102 decode_ril_error(&error, "OK");
103
104 if (ril_util_parse_reg(message, &status,
105 &lac, &ci, &tech) == FALSE) {
106 CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
107 return;
108 }
109
110 DBG("oFono reg - status: %s, lac: %x, ci: %x, tech: %s",
111 registration_status_to_string(status),
112 lac, ci,
113 registration_tech_to_string(tech));
114
115 nd->tech = tech;
116 cb(&error, status, lac, ci, tech, cbd->data);
117}
118
119static void ril_creg_notify(struct ofono_error *error, int status, int lac,
120 int ci, int tech, gpointer user_data)
121{
122 struct ofono_netreg *netreg = user_data;
123
124 DBG("");
125
126 if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
127 DBG("Error during status notification");
128 return;
129 }
130
131 ofono_netreg_status_notify(netreg, status, lac, ci, tech);
132}
133
134static void ril_network_state_change(struct ril_msg *message, gpointer user_data)
135{
136 struct ofono_netreg *netreg = user_data;
137 struct netreg_data *nd = ofono_netreg_get_data(netreg);
138 struct cb_data *cbd = cb_data_new(ril_creg_notify, netreg);
139
140 DBG("");
141
142 cbd->user = nd;
143
144 if (message->req != RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED)
145 goto error;
146
147 if (g_ril_send(nd->ril, RIL_REQUEST_VOICE_REGISTRATION_STATE, NULL,
148 0, ril_creg_cb, cbd, g_free) > 0)
149 return;
150
151 /* For operator update ofono will use the current_operator cb
152 * so we don't need to probe ril here */
153
154error:
155 g_free(cbd);
156
157 ofono_error("Unable to request network state changed");
158}
159
160static void ril_registration_status(struct ofono_netreg *netreg,
161 ofono_netreg_status_cb_t cb,
162 void *data)
163{
164 struct netreg_data *nd = ofono_netreg_get_data(netreg);
165 struct cb_data *cbd = cb_data_new(cb, data);
166
167 cbd->user = nd;
168
169 if (g_ril_send(nd->ril, RIL_REQUEST_VOICE_REGISTRATION_STATE, NULL,
170 0, ril_creg_cb, cbd, g_free) > 0)
171 return;
172
173 g_free(cbd);
174
175 CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, data);
176}
177
178static void ril_cops_cb(struct ril_msg *message, gpointer user_data)
179{
180 struct cb_data *cbd = user_data;
181 ofono_netreg_operator_cb_t cb = cbd->cb;
182 struct netreg_data *nd = cbd->user;
183 struct ofono_error error;
184 struct parcel rilp;
185 struct ofono_network_operator op;
186 gchar *lalpha, *salpha, *numeric;
187
188 if (message->error == RIL_E_SUCCESS) {
189 decode_ril_error(&error, "OK");
190 } else {
191 ofono_error("Failed to retrive the current operator");
192 goto error;
193 }
194
195 /* Set up Parcel struct for proper parsing */
196 rilp.data = message->buf;
197 rilp.size = message->buf_len;
198 rilp.capacity = message->buf_len;
199 rilp.offset = 0;
200
201 /* Size of char ** */
202 if (parcel_r_int32(&rilp) == 0)
203 goto error;
204
205 lalpha = parcel_r_string(&rilp);
206 salpha = parcel_r_string(&rilp);
207 numeric = parcel_r_string(&rilp);
208
209 DBG("RIL cops - lalpha: %s, salpha: %s, numeric: %s",
210 lalpha, salpha, numeric);
211
212 /* Try to use long by default */
213 if (lalpha)
214 strncpy(op.name, lalpha, OFONO_MAX_OPERATOR_NAME_LENGTH);
215 else
216 strncpy(op.name, salpha, OFONO_MAX_OPERATOR_NAME_LENGTH);
217
218 extract_mcc_mnc(numeric, op.mcc, op.mnc);
219
220 /* Set to current */
221 op.status = OPERATOR_STATUS_CURRENT;
222 op.tech = nd->tech;
223
224 DBG("ril_cops_cb: %s, %s, %s, %s", op.name, op.mcc, op.mnc,
225 registration_tech_to_string(op.tech));
226
227 g_free(lalpha);
228 g_free(salpha);
229 g_free(numeric);
230
231 cb(&error, &op, cbd->data);
232
233 return;
234
235error:
236 CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
237}
238
239static void ril_current_operator(struct ofono_netreg *netreg,
240 ofono_netreg_operator_cb_t cb, void *data)
241{
242 struct netreg_data *nd = ofono_netreg_get_data(netreg);
243 struct cb_data *cbd = cb_data_new(cb, data);
244
245 cbd->user = nd;
246
247 if (g_ril_send(nd->ril, RIL_REQUEST_OPERATOR, NULL,
248 0, ril_cops_cb, cbd, g_free) > 0)
249 return;
250
251 g_free(cbd);
252
253 CALLBACK_WITH_FAILURE(cb, NULL, data);
254}
255
256static void ril_cops_list_cb(struct ril_msg *message, gpointer user_data)
257{
258 struct cb_data *cbd = user_data;
259 ofono_netreg_operator_list_cb_t cb = cbd->cb;
260 struct ofono_network_operator *list;
261 struct ofono_error error;
262 struct parcel rilp;
263 int noperators, i;
264 gchar *lalpha, *salpha, *numeric, *status;
265
266 if (message->error == RIL_E_SUCCESS) {
267 decode_ril_error(&error, "OK");
268 } else {
269 ofono_error("Failed to retrive the list of operators");
270 goto error;
271 }
272
273 /* Set up Parcel struct for proper parsing */
274 rilp.data = message->buf;
275 rilp.size = message->buf_len;
276 rilp.capacity = message->buf_len;
277 rilp.offset = 0;
278
279 /* Number of operators at the list (4 strings for every operator) */
280 noperators = parcel_r_int32(&rilp) / 4;
281 DBG("noperators = %d", noperators);
282
283 list = g_try_new0(struct ofono_network_operator, noperators);
284 if (list == NULL)
285 goto error;
286
287 for (i = 0; i < noperators; i++) {
288 lalpha = parcel_r_string(&rilp);
289 salpha = parcel_r_string(&rilp);
290 numeric = parcel_r_string(&rilp);
291 status = parcel_r_string(&rilp);
292
293 /* Try to use long by default */
294 if (lalpha) {
295 strncpy(list[i].name, lalpha,
296 OFONO_MAX_OPERATOR_NAME_LENGTH);
297 } else {
298 strncpy(list[i].name, salpha,
299 OFONO_MAX_OPERATOR_NAME_LENGTH);
300 }
301
302 extract_mcc_mnc(numeric, list[i].mcc, list[i].mnc);
303
304 /* Use GSM as default, as RIL doesn't pass that info to us */
305 list[i].tech = ACCESS_TECHNOLOGY_GSM;
306
307 /* Set the proper status */
308 if (!strcmp(status, "unknown"))
309 list[i].status = OPERATOR_STATUS_UNKNOWN;
310 else if (!strcmp(status, "available"))
311 list[i].status = OPERATOR_STATUS_AVAILABLE;
312 else if (!strcmp(status, "current"))
313 list[i].status = OPERATOR_STATUS_CURRENT;
314 else if (!strcmp(status, "forbidden"))
315 list[i].status = OPERATOR_STATUS_FORBIDDEN;
316
317 DBG("Operator: %s, %s, %s, status: %s",
318 list[i].name, list[i].mcc,
319 list[i].mnc, status);
320
321 g_free(lalpha);
322 g_free(salpha);
323 g_free(numeric);
324 g_free(status);
325 }
326
327 cb(&error, noperators, list, cbd->data);
328
329 return;
330
331error:
332 CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data);
333}
334
335static void ril_list_operators(struct ofono_netreg *netreg,
336 ofono_netreg_operator_list_cb_t cb, void *data)
337{
338 struct netreg_data *nd = ofono_netreg_get_data(netreg);
339 struct cb_data *cbd = cb_data_new(cb, data);
340
341 cbd->user = nd;
342
343 if (g_ril_send(nd->ril, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, NULL,
344 0, ril_cops_list_cb, cbd, g_free) > 0)
345 return;
346
347 g_free(cbd);
348
349 CALLBACK_WITH_FAILURE(cb, 0, NULL, data);
350}
351
352static void ril_register_cb(struct ril_msg *message, gpointer user_data)
353{
354 struct cb_data *cbd = user_data;
355 ofono_netreg_register_cb_t cb = cbd->cb;
356 struct ofono_error error;
357
358 if (message->error == RIL_E_SUCCESS) {
359 decode_ril_error(&error, "OK");
360 } else {
361 decode_ril_error(&error, "FAIL");
362 }
363
364 cb(&error, cbd->data);
365}
366
367static void ril_register_auto(struct ofono_netreg *netreg,
368 ofono_netreg_register_cb_t cb, void *data)
369{
370 struct netreg_data *nd = ofono_netreg_get_data(netreg);
371 struct cb_data *cbd = cb_data_new(cb, data);
372
373 if (g_ril_send(nd->ril, RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
374 NULL, 0, ril_register_cb, cbd, g_free) > 0)
375 return;
376
377 g_free(cbd);
378
379 CALLBACK_WITH_FAILURE(cb, data);
380}
381
382static void ril_register_manual(struct ofono_netreg *netreg,
383 const char *mcc, const char *mnc,
384 ofono_netreg_register_cb_t cb, void *data)
385{
386 struct netreg_data *nd = ofono_netreg_get_data(netreg);
387 struct cb_data *cbd = cb_data_new(cb, data);
388 char buf[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1];
389 struct parcel rilp;
390 int ret;
391
392 parcel_init(&rilp);
393
394 /* RIL expects a char * specifying MCCMNC of network to select */
395 snprintf(buf, sizeof(buf), "%s%s", mcc, mnc);
396 parcel_w_string(&rilp, buf);
397
398 ret = g_ril_send(nd->ril, RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
399 rilp.data, rilp.size, ril_register_cb,
400 cbd, g_free);
401 parcel_free(&rilp);
402
403 /* In case of error free cbd and return the cb with failure */
404 if (ret <= 0) {
405 g_free(cbd);
406 CALLBACK_WITH_FAILURE(cb, data);
407 }
408}
409
410static void ril_strength_notify(struct ril_msg *message, gpointer user_data)
411{
412 struct ofono_netreg *netreg = user_data;
413 int strength;
414
415 g_assert(message->req == RIL_UNSOL_SIGNAL_STRENGTH);
416
417 strength = ril_util_get_signal(message);
418 ofono_netreg_strength_notify(netreg, strength);
419
420 return;
421}
422
423static void ril_strength_cb(struct ril_msg *message, gpointer user_data)
424{
425 struct cb_data *cbd = user_data;
426 ofono_netreg_strength_cb_t cb = cbd->cb;
427 struct ofono_error error;
428 int strength;
429
430 if (message->error == RIL_E_SUCCESS) {
431 decode_ril_error(&error, "OK");
432 } else {
433 ofono_error("Failed to retrive the signal strength");
434 goto error;
435 }
436
437 strength = ril_util_get_signal(message);
438 cb(&error, strength, cbd->data);
439
440 return;
441
442error:
443 CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
444}
445
446static void ril_signal_strength(struct ofono_netreg *netreg,
447 ofono_netreg_strength_cb_t cb, void *data)
448{
449 struct netreg_data *nd = ofono_netreg_get_data(netreg);
450 struct cb_data *cbd = cb_data_new(cb, data);
451
452 cbd->user = nd;
453
454 if (g_ril_send(nd->ril, RIL_REQUEST_SIGNAL_STRENGTH,
455 NULL, 0, ril_strength_cb, cbd, g_free) > 0)
456 return;
457
458 g_free(cbd);
459
460 CALLBACK_WITH_FAILURE(cb, -1, data);
461}
462
463static void ril_nitz_notify(struct ril_msg *message, gpointer user_data)
464{
465 struct ofono_netreg *netreg = user_data;
466 struct netreg_data *nd = ofono_netreg_get_data(netreg);
467 struct parcel rilp;
468 int year, mon, mday, hour, min, sec, dst, tzi;
469 char tzs, tz[4];
470 gchar *nitz;
471
472 if (message->req != RIL_UNSOL_NITZ_TIME_RECEIVED)
473 goto error;
474
475 /* Set up Parcel struct for proper parsing */
476 rilp.data = message->buf;
477 rilp.size = message->buf_len;
478 rilp.capacity = message->buf_len;
479 rilp.offset = 0;
480
481 nitz = parcel_r_string(&rilp);
482
483 DBG("RIL NITZ: %s", nitz);
484
485 sscanf(nitz, "%u/%u/%u,%u:%u:%u%c%u,%u", &year, &mon, &mday,
486 &hour, &min, &sec, &tzs, &tzi, &dst);
487 sprintf(tz, "%c%d", tzs, tzi);
488
489 nd->time.utcoff = atoi(tz) * 15 * 60;
490 nd->time.dst = dst;
491 nd->time.sec = sec;
492 nd->time.min = min;
493 nd->time.hour = hour;
494 nd->time.mday = mday;
495 nd->time.mon = mon;
496 nd->time.year = 2000 + year;
497
498 ofono_netreg_time_notify(netreg, &nd->time);
499
500 g_free(nitz);
501
502 return;
503
504error:
505 ofono_error("Unable to notify ofono about nitz");
506}
507
508static gboolean ril_delayed_register(gpointer user_data)
509{
510 struct ofono_netreg *netreg = user_data;
511 struct netreg_data *nd = ofono_netreg_get_data(netreg);
512 ofono_netreg_register(netreg);
513
514 /* Register for network state changes */
515 g_ril_register(nd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
516 ril_network_state_change, netreg);
517
518 /* Register for network time update reports */
519 g_ril_register(nd->ril, RIL_UNSOL_NITZ_TIME_RECEIVED,
520 ril_nitz_notify, netreg);
521
522 /* Register for signal strength changes */
523 g_ril_register(nd->ril, RIL_UNSOL_SIGNAL_STRENGTH,
524 ril_strength_notify, netreg);
525
526 /* This makes the timeout a single-shot */
527 return FALSE;
528}
529
530static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
531 void *data)
532{
533 GRil *ril = data;
534 struct netreg_data *nd;
535
536 nd = g_new0(struct netreg_data, 1);
537
538 nd->ril = g_ril_clone(ril);
539 nd->vendor = vendor;
540 nd->tech = -1;
541 nd->time.sec = -1;
542 nd->time.min = -1;
543 nd->time.hour = -1;
544 nd->time.mday = -1;
545 nd->time.mon = -1;
546 nd->time.year = -1;
547 nd->time.dst = 0;
548 nd->time.utcoff = 0;
549 ofono_netreg_set_data(netreg, nd);
550
551 /* ofono_netreg_register() needs to be called after
552 * the driver has been set in devinfo_create() which
553 * calls this function. Most other drivers use a
554 * callback after getting some return from the modem
555 * itself...
556 */
557 g_timeout_add_seconds(1, ril_delayed_register, netreg);
558
559 return 0;
560}
561
562static void ril_netreg_remove(struct ofono_netreg *netreg)
563{
564 struct netreg_data *nd = ofono_netreg_get_data(netreg);
565
566 if (nd->nitz_timeout)
567 g_source_remove(nd->nitz_timeout);
568
569 ofono_netreg_set_data(netreg, NULL);
570
571 g_ril_unref(nd->ril);
572 g_free(nd);
573}
574
575static struct ofono_netreg_driver driver = {
576 .name = "rilmodem",
577 .probe = ril_netreg_probe,
578 .remove = ril_netreg_remove,
579 .registration_status = ril_registration_status,
580 .current_operator = ril_current_operator,
581 .list_operators = ril_list_operators,
582 .register_auto = ril_register_auto,
583 .register_manual = ril_register_manual,
584 .strength = ril_signal_strength,
585};
586
587void ril_netreg_init(void)
588{
589 ofono_netreg_driver_register(&driver);
590}
591
592void ril_netreg_exit(void)
593{
594 ofono_netreg_driver_unregister(&driver);
595}
0596
=== added file 'drivers/rilmodem/rilmodem.c'
--- drivers/rilmodem/rilmodem.c 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/rilmodem.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,61 @@
1/*
2 *
3 * oFono - Open Source Telephony - RIL Modem Support
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <glib.h>
28#include <gril.h>
29
30#define OFONO_API_SUBJECT_TO_CHANGE
31#include <ofono/plugin.h>
32#include <ofono/log.h>
33
34#include "rilmodem.h"
35
36static int rilmodem_init(void)
37{
38 DBG("");
39
40 ril_devinfo_init();
41 ril_voicecall_init();
42 ril_sms_init();
43 ril_netreg_init();
44 ril_call_volume_init();
45
46 return 0;
47}
48
49static void rilmodem_exit(void)
50{
51 DBG("");
52
53 ril_devinfo_exit();
54 ril_voicecall_exit();
55 ril_sms_exit();
56 ril_netreg_exit();
57 ril_call_volume_exit();
58}
59
60OFONO_PLUGIN_DEFINE(rilmodem, "RIL modem driver", VERSION,
61 OFONO_PLUGIN_PRIORITY_DEFAULT, rilmodem_init, rilmodem_exit)
062
=== added file 'drivers/rilmodem/rilmodem.h'
--- drivers/rilmodem/rilmodem.h 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/rilmodem.h 2013-04-09 20:01:20 +0000
@@ -0,0 +1,38 @@
1/*
2 *
3 * oFono - Open Source Telephony - RIL Modem Support
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#include "rilutil.h"
24
25extern void ril_devinfo_init(void);
26extern void ril_devinfo_exit(void);
27
28extern void ril_call_volume_init(void);
29extern void ril_call_volume_exit(void);
30
31extern void ril_voicecall_init(void);
32extern void ril_voicecall_exit(void);
33
34extern void ril_sms_init(void);
35extern void ril_sms_exit(void);
36
37extern void ril_netreg_init(void);
38extern void ril_netreg_exit(void);
039
=== added file 'drivers/rilmodem/rilutil.c'
--- drivers/rilmodem/rilutil.c 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/rilutil.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,372 @@
1/*
2 *
3 * oFono - Open Source Telephony
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <glib.h>
28#include <gril.h>
29#include <string.h>
30#include <stdlib.h>
31
32#define OFONO_API_SUBJECT_TO_CHANGE
33#include <ofono/log.h>
34#include <ofono/types.h>
35
36#include "common.h"
37#include "rilutil.h"
38#include "parcel.h"
39
40struct ril_util_sim_state_query {
41 GRil *ril;
42 guint cpin_poll_source;
43 guint cpin_poll_count;
44 guint interval;
45 guint num_times;
46 ril_util_sim_inserted_cb_t cb;
47 void *userdata;
48 GDestroyNotify destroy;
49};
50
51static gboolean cpin_check(gpointer userdata);
52
53void decode_ril_error(struct ofono_error *error, const char *final)
54{
55 if (!strcmp(final, "OK")) {
56 error->type = OFONO_ERROR_TYPE_NO_ERROR;
57 error->error = 0;
58 } else {
59 error->type = OFONO_ERROR_TYPE_FAILURE;
60 error->error = 0;
61 }
62}
63
64gint ril_util_call_compare_by_status(gconstpointer a, gconstpointer b)
65{
66 const struct ofono_call *call = a;
67 int status = GPOINTER_TO_INT(b);
68
69 if (status != call->status)
70 return 1;
71
72 return 0;
73}
74
75gint ril_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b)
76{
77 const struct ofono_call *call = a;
78 const struct ofono_phone_number *pb = b;
79
80 return memcmp(&call->phone_number, pb,
81 sizeof(struct ofono_phone_number));
82}
83
84gint ril_util_call_compare_by_id(gconstpointer a, gconstpointer b)
85{
86 const struct ofono_call *call = a;
87 unsigned int id = GPOINTER_TO_UINT(b);
88
89 if (id < call->id)
90 return -1;
91
92 if (id > call->id)
93 return 1;
94
95 return 0;
96}
97
98gint ril_util_call_compare(gconstpointer a, gconstpointer b)
99{
100 const struct ofono_call *ca = a;
101 const struct ofono_call *cb = b;
102
103 if (ca->id < cb->id)
104 return -1;
105
106 if (ca->id > cb->id)
107 return 1;
108
109 return 0;
110}
111
112static gboolean cpin_check(gpointer userdata)
113{
114 struct ril_util_sim_state_query *req = userdata;
115
116 req->cpin_poll_source = 0;
117
118 return FALSE;
119}
120
121struct ril_util_sim_state_query *ril_util_sim_state_query_new(GRil *ril,
122 guint interval, guint num_times,
123 ril_util_sim_inserted_cb_t cb,
124 void *userdata,
125 GDestroyNotify destroy)
126{
127 struct ril_util_sim_state_query *req;
128
129 req = g_new0(struct ril_util_sim_state_query, 1);
130
131 req->ril = ril;
132 req->interval = interval;
133 req->num_times = num_times;
134 req->cb = cb;
135 req->userdata = userdata;
136 req->destroy = destroy;
137
138 cpin_check(req);
139
140 return req;
141}
142
143void ril_util_sim_state_query_free(struct ril_util_sim_state_query *req)
144{
145 if (req == NULL)
146 return;
147
148 if (req->cpin_poll_source > 0)
149 g_source_remove(req->cpin_poll_source);
150
151 if (req->destroy)
152 req->destroy(req->userdata);
153
154 g_free(req);
155}
156
157GSList *ril_util_parse_clcc(struct ril_msg *message)
158{
159 struct ofono_call *call;
160 struct parcel rilp;
161 GSList *l = NULL;
162 int num, i;
163 gchar *number, *name;
164
165 /* Set up Parcel struct for proper parsing */
166 rilp.data = message->buf;
167 rilp.size = message->buf_len;
168 rilp.capacity = message->buf_len;
169 rilp.offset = 0;
170
171 /* Number of RIL_Call structs */
172 num = parcel_r_int32(&rilp);
173 for (i = 0; i < num; i++) {
174 call = g_try_new(struct ofono_call, 1);
175 if (call == NULL)
176 break;
177
178 ofono_call_init(call);
179 call->status = parcel_r_int32(&rilp);
180 call->id = parcel_r_int32(&rilp);
181 call->phone_number.type = parcel_r_int32(&rilp);
182 parcel_r_int32(&rilp); /* isMpty */
183 parcel_r_int32(&rilp); /* isMT */
184 parcel_r_int32(&rilp); /* als */
185 call->type = parcel_r_int32(&rilp); /* isVoice */
186 parcel_r_int32(&rilp); /* isVoicePrivacy */
187 number = parcel_r_string(&rilp);
188 if (number) {
189 strncpy(call->phone_number.number, number,
190 OFONO_MAX_PHONE_NUMBER_LENGTH);
191 g_free(number);
192 }
193 parcel_r_int32(&rilp); /* numberPresentation */
194 name = parcel_r_string(&rilp);
195 if (name) {
196 strncpy(call->name, name,
197 OFONO_MAX_CALLER_NAME_LENGTH);
198 g_free(name);
199 }
200 parcel_r_int32(&rilp); /* namePresentation */
201 parcel_r_int32(&rilp); /* uusInfo */
202
203 if (strlen(call->phone_number.number) > 0)
204 call->clip_validity = 0;
205 else
206 call->clip_validity = 2;
207
208 DBG("Adding call - id: %d, status: %d, type: %d, number: %s, name: %s",
209 call->id, call->status, call->type,
210 call->phone_number.number, call->name);
211
212 l = g_slist_insert_sorted(l, call, ril_util_call_compare);
213 }
214
215 return l;
216}
217
218gboolean ril_util_parse_reg(struct ril_msg *message, int *status,
219 int *lac, int *ci, int *tech)
220{
221 struct parcel rilp;
222 gchar *sstatus, *slac, *sci, *stech;
223
224 /* Set up Parcel struct for proper parsing */
225 rilp.data = message->buf;
226 rilp.size = message->buf_len;
227 rilp.capacity = message->buf_len;
228 rilp.offset = 0;
229
230 /* Size of char ** */
231 if (parcel_r_int32(&rilp) == 0)
232 return FALSE;
233
234 sstatus = parcel_r_string(&rilp);
235 slac = parcel_r_string(&rilp);
236 sci = parcel_r_string(&rilp);
237 stech = parcel_r_string(&rilp);
238
239 DBG("RIL reg - status: %s, lac: %s, ci: %s, radio tech: %s",
240 sstatus, slac, sci, stech);
241
242 if (status)
243 *status = atoi(sstatus);
244 if (lac) {
245 if (slac)
246 *lac = strtol(slac, NULL, 16);
247 else
248 *lac = -1;
249 }
250 if (ci) {
251 if (sci)
252 *ci = strtol(sci, NULL, 16);
253 else
254 *ci = -1;
255 }
256 if (tech) {
257 switch(atoi(stech)) {
258 case RADIO_TECH_UNKNOWN:
259 *tech = -1;
260 break;
261 case RADIO_TECH_GPRS:
262 *tech = ACCESS_TECHNOLOGY_GSM;
263 break;
264 case RADIO_TECH_EDGE:
265 *tech = ACCESS_TECHNOLOGY_GSM_EGPRS;
266 break;
267 case RADIO_TECH_UMTS:
268 *tech = ACCESS_TECHNOLOGY_UTRAN;
269 break;
270 case RADIO_TECH_HSDPA:
271 *tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA;
272 break;
273 case RADIO_TECH_HSUPA:
274 *tech = ACCESS_TECHNOLOGY_UTRAN_HSUPA;
275 break;
276 case RADIO_TECH_HSPA:
277 *tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA;
278 break;
279 default:
280 *tech = -1;
281 }
282 }
283
284 /* Free our parcel handlers */
285 g_free(sstatus);
286 g_free(slac);
287 g_free(sci);
288 g_free(stech);
289
290 return TRUE;
291}
292
293gint ril_util_parse_sms_response(struct ril_msg *message)
294{
295 struct parcel rilp;
296 int error, mr;
297 char *ack_pdu;
298
299 /* Set up Parcel struct for proper parsing */
300 rilp.data = message->buf;
301 rilp.size = message->buf_len;
302 rilp.capacity = message->buf_len;
303 rilp.offset = 0;
304
305 /* TP-Message-Reference for GSM/
306 * BearerData MessageId for CDMA
307 */
308 mr = parcel_r_int32(&rilp);
309 ack_pdu = parcel_r_int32(&rilp);
310 error = parcel_r_int32(&rilp);
311
312 DBG("SMS_Response mr: %d, ackPDU: %d, error: %d",
313 mr, ack_pdu, error);
314
315 return mr;
316}
317
318gint ril_util_get_signal(struct ril_msg *message)
319{
320 struct parcel rilp;
321 int gw_signal, cdma_dbm, evdo_dbm, lte_signal;
322
323 /* Set up Parcel struct for proper parsing */
324 rilp.data = message->buf;
325 rilp.size = message->buf_len;
326 rilp.capacity = message->buf_len;
327 rilp.offset = 0;
328
329 /* RIL_SignalStrength_v6 */
330 /* GW_SignalStrength */
331 gw_signal = parcel_r_int32(&rilp);
332 parcel_r_int32(&rilp); /* bitErrorRate */
333
334 /* CDMA_SignalStrength */
335 cdma_dbm = parcel_r_int32(&rilp);
336 parcel_r_int32(&rilp); /* ecio */
337
338 /* EVDO_SignalStrength */
339 evdo_dbm = parcel_r_int32(&rilp);
340 parcel_r_int32(&rilp); /* ecio */
341 parcel_r_int32(&rilp); /* signalNoiseRatio */
342
343 /* LTE_SignalStrength */
344 lte_signal = parcel_r_int32(&rilp);
345 parcel_r_int32(&rilp); /* rsrp */
346 parcel_r_int32(&rilp); /* rsrq */
347 parcel_r_int32(&rilp); /* rssnr */
348 parcel_r_int32(&rilp); /* cqi */
349
350 DBG("RIL SignalStrength - gw: %d, cdma: %d, evdo: %d, lte: %d",
351 gw_signal, cdma_dbm, evdo_dbm, lte_signal);
352
353 /* Return the first valid one */
354 if ((gw_signal != 99) && (gw_signal != -1))
355 return (gw_signal * 100) / 31;
356 if ((lte_signal != 99) && (lte_signal != -1))
357 return (lte_signal * 100) / 31;
358
359 /* In case of dbm, return the value directly */
360 if (cdma_dbm != -1) {
361 if (cdma_dbm > 100)
362 cdma_dbm = 100;
363 return cdma_dbm;
364 }
365 if (evdo_dbm != -1) {
366 if (evdo_dbm > 100)
367 evdo_dbm = 100;
368 return evdo_dbm;
369 }
370
371 return -1;
372}
0373
=== added file 'drivers/rilmodem/rilutil.h'
--- drivers/rilmodem/rilutil.h 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/rilutil.h 2013-04-09 20:01:20 +0000
@@ -0,0 +1,125 @@
1/*
2 *
3 * oFono - Open Source Telephony
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23enum ril_util_sms_store {
24 RIL_UTIL_SMS_STORE_SM = 0,
25 RIL_UTIL_SMS_STORE_ME = 1,
26 RIL_UTIL_SMS_STORE_MT = 2,
27 RIL_UTIL_SMS_STORE_SR = 3,
28 RIL_UTIL_SMS_STORE_BM = 4,
29};
30
31/* 3GPP TS 27.007 Release 8 Section 5.5 */
32enum at_util_charset {
33 RIL_UTIL_CHARSET_GSM = 0x1,
34 RIL_UTIL_CHARSET_HEX = 0x2,
35 RIL_UTIL_CHARSET_IRA = 0x4,
36 RIL_UTIL_CHARSET_PCCP437 = 0x8,
37 RIL_UTIL_CHARSET_PCDN = 0x10,
38 RIL_UTIL_CHARSET_UCS2 = 0x20,
39 RIL_UTIL_CHARSET_UTF8 = 0x40,
40 RIL_UTIL_CHARSET_8859_1 = 0x80,
41 RIL_UTIL_CHARSET_8859_2 = 0x100,
42 RIL_UTIL_CHARSET_8859_3 = 0x200,
43 RIL_UTIL_CHARSET_8859_4 = 0x400,
44 RIL_UTIL_CHARSET_8859_5 = 0x800,
45 RIL_UTIL_CHARSET_8859_6 = 0x1000,
46 RIL_UTIL_CHARSET_8859_C = 0x2000,
47 RIL_UTIL_CHARSET_8859_A = 0x4000,
48 RIL_UTIL_CHARSET_8859_G = 0x8000,
49 RIL_UTIL_CHARSET_8859_H = 0x10000,
50};
51
52typedef void (*ril_util_sim_inserted_cb_t)(gboolean present, void *userdata);
53
54void decode_ril_error(struct ofono_error *error, const char *final);
55gint ril_util_call_compare_by_status(gconstpointer a, gconstpointer b);
56gint ril_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b);
57gint ril_util_call_compare_by_id(gconstpointer a, gconstpointer b);
58gint ril_util_call_compare(gconstpointer a, gconstpointer b);
59
60struct ril_util_sim_state_query *ril_util_sim_state_query_new(GRil *ril,
61 guint interval, guint num_times,
62 ril_util_sim_inserted_cb_t cb,
63 void *userdata,
64 GDestroyNotify destroy);
65void ril_util_sim_state_query_free(struct ril_util_sim_state_query *req);
66
67GSList *ril_util_parse_clcc(struct ril_msg *message);
68
69gboolean ril_util_parse_reg(struct ril_msg *message, int *status,
70 int *lac, int *ci, int *tech);
71
72gint ril_util_parse_sms_response(struct ril_msg *message);
73
74gint ril_util_get_signal(struct ril_msg *message);
75
76struct cb_data {
77 void *cb;
78 void *data;
79 void *user;
80};
81
82static inline struct cb_data *cb_data_new(void *cb, void *data)
83{
84 struct cb_data *ret;
85
86 ret = g_new0(struct cb_data, 1);
87 ret->cb = cb;
88 ret->data = data;
89
90 return ret;
91}
92
93static inline int ril_util_convert_signal_strength(int strength)
94{
95 int result;
96
97 if (strength == 99)
98 result = -1;
99 else
100 result = (strength * 100) / 31;
101
102 return result;
103}
104
105#define DECLARE_FAILURE(e) \
106 struct ofono_error e; \
107 e.type = OFONO_ERROR_TYPE_FAILURE; \
108 e.error = 0 \
109
110#define CALLBACK_WITH_FAILURE(cb, args...) \
111 do { \
112 struct ofono_error cb_e; \
113 cb_e.type = OFONO_ERROR_TYPE_FAILURE; \
114 cb_e.error = 0; \
115 \
116 cb(&cb_e, ##args); \
117 } while (0) \
118
119#define CALLBACK_WITH_SUCCESS(f, args...) \
120 do { \
121 struct ofono_error e; \
122 e.type = OFONO_ERROR_TYPE_NO_ERROR; \
123 e.error = 0; \
124 f(&e, ##args); \
125 } while (0)
0126
=== added file 'drivers/rilmodem/sms.c'
--- drivers/rilmodem/sms.c 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/sms.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,357 @@
1/*
2 *
3 * oFono - Open Source Telephony - RIL Modem Support
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#define _GNU_SOURCE
28#include <ctype.h>
29#include <string.h>
30#include <stdlib.h>
31#include <stdio.h>
32
33#include <glib.h>
34#include <gril.h>
35#include <parcel.h>
36
37#include <ofono/log.h>
38#include <ofono/modem.h>
39#include <ofono/sms.h>
40#include "smsutil.h"
41#include "util.h"
42
43#include "rilmodem.h"
44
45struct sms_data {
46 GRil *ril;
47 unsigned int vendor;
48};
49
50static void sms_debug(const gchar *str, gpointer user_data)
51{
52 const char *prefix = user_data;
53
54 ofono_info("%s%s", prefix, str);
55}
56
57static void ril_csca_set(struct ofono_sms *sms,
58 const struct ofono_phone_number *sca,
59 ofono_sms_sca_set_cb_t cb, void *user_data)
60{
61 /* TODO:
62 *
63 * (1) Need to determine if RIL supports setting the
64 * SMSC number.
65 *
66 * (2) In the short term, this function should return
67 * a 'not-supported' error.
68 */
69
70 DBG("");
71
72 CALLBACK_WITH_FAILURE(cb, user_data);
73}
74
75static void ril_csca_query_cb(gboolean ok, gpointer user_data)
76{
77 struct cb_data *cbd = user_data;
78 ofono_sms_sca_query_cb_t cb = cbd->cb;
79 struct ofono_error error;
80 struct ofono_phone_number sca;
81
82 /* For now setup dummy number */
83 const char *number = "6176666666";
84
85 if (number[0] == '+') {
86 number = number + 1;
87 sca.type = 145;
88 } else {
89 sca.type = 129;
90 }
91
92 strncpy(sca.number, number, OFONO_MAX_PHONE_NUMBER_LENGTH);
93 sca.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0';
94
95 DBG("csca_query_cb: %s, %d", sca.number, sca.type);
96
97 cb(&error, &sca, cbd->data);
98
99 return;
100}
101
102static void ril_csca_query(struct ofono_sms *sms, ofono_sms_sca_query_cb_t cb,
103 void *user_data)
104{
105 /* TODO:
106 *
107 * (1) Need to determine if RIL supports querying the
108 * SMSC number.
109 *
110 * (2) In the short term, this function should return
111 * a 'not-supported' error.
112 */
113
114 CALLBACK_WITH_FAILURE(cb, NULL, user_data);
115}
116
117static void submit_sms_cb(struct ril_msg *message, gpointer user_data)
118{
119 struct cb_data *cbd = user_data;
120 struct ofono_error error;
121 ofono_sms_submit_cb_t cb = cbd->cb;
122 int mr;
123
124 if (message->error == RIL_E_SUCCESS) {
125 decode_ril_error(&error, "OK");
126 } else {
127 decode_ril_error(&error, "FAIL");
128 }
129
130 mr = ril_util_parse_sms_response(message);
131
132 cb(&error, mr, cbd->data);
133}
134
135static void ril_cmgs(struct ofono_sms *sms, const unsigned char *pdu,
136 int pdu_len, int tpdu_len, int mms,
137 ofono_sms_submit_cb_t cb, void *user_data)
138{
139 struct sms_data *data = ofono_sms_get_data(sms);
140 struct cb_data *cbd = cb_data_new(cb, user_data);
141 struct parcel rilp;
142 char *tpdu;
143 int ret, smsc_len;
144
145 DBG("pdu_len: %d, tpdu_len: %d mms: %d", pdu_len, tpdu_len, mms);
146 g_ril_util_debug_hexdump(FALSE, pdu, pdu_len, sms_debug, "sms-pdu: ");
147
148 /* TODO: if (mms) { ... } */
149
150 parcel_init(&rilp);
151 parcel_w_int32(&rilp, 2); /* Number of strings */
152
153 /* SMSC address:
154 *
155 * smsc_len == 1, then zero-length SMSC was spec'd
156 * RILD expects a NULL string in this case instead
157 * of a zero-length string.
158 */
159 smsc_len = pdu_len - tpdu_len;
160 if (smsc_len > 1) {
161 /* TODO: encode SMSC & write to parcel */
162 DBG("SMSC address specified (smsc_len %d); NOT-IMPLEMENTED", smsc_len);
163 }
164
165 parcel_w_string(&rilp, NULL); /* SMSC address; NULL == default */
166
167 /* TPDU:
168 *
169 * 'pdu' is a raw hexadecimal string
170 * encode_hex() turns it into an ASCII/hex UTF8 buffer
171 * parcel_w_string() encodes utf8 -> utf16
172 */
173 tpdu = encode_hex(pdu + smsc_len, tpdu_len, 0);
174 g_ril_util_debug_hexdump(FALSE, (guchar *) tpdu, (tpdu_len * 2),
175 sms_debug, "tpdu: ");
176
177 parcel_w_string(&rilp, tpdu);
178
179 /* Dump the entire parcel */
180 g_ril_util_debug_hexdump(FALSE, (guchar *) rilp.data, rilp.size,
181 sms_debug, "sms-encoded-buf: ");
182 ret = g_ril_send(data->ril,
183 RIL_REQUEST_SEND_SMS,
184 rilp.data,
185 rilp.size,
186 submit_sms_cb, cbd, g_free);
187
188 parcel_free(&rilp);
189
190 if (ret <= 0) {
191 g_free(cbd);
192 CALLBACK_WITH_FAILURE(cb, -1, data);
193 }
194}
195
196static void ril_cgsms_set(struct ofono_sms *sms, int bearer,
197 ofono_sms_bearer_set_cb_t cb, void *user_data)
198{
199 /* TODO: same as csca_set */
200 DBG("");
201
202 CALLBACK_WITH_FAILURE(cb, user_data);
203}
204
205static void ril_cgsms_query(struct ofono_sms *sms,
206 ofono_sms_bearer_query_cb_t cb, void *user_data)
207{
208 /* TODO: same as csca_query */
209 DBG("");
210
211 CALLBACK_WITH_FAILURE(cb, -1, user_data);
212}
213
214static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
215{
216 struct ofono_sms *sms = user_data;
217 struct sms_data *data = ofono_sms_get_data(sms);
218 struct parcel rilp;
219 char *ril_pdu;
220 int ril_pdu_len;
221 long ril_buf_len;
222 guchar *ril_data;
223
224 DBG("req: %d; data_len: %d", message->req, message->buf_len);
225
226 if (message->req != RIL_UNSOL_RESPONSE_NEW_SMS)
227 goto error;
228
229 /* Set up Parcel struct for proper parsing */
230 rilp.data = message->buf;
231 rilp.size = message->buf_len;
232 rilp.capacity = message->buf_len;
233 rilp.offset = 0;
234
235 g_ril_util_debug_hexdump(FALSE, (guchar *) message->buf,
236 message->buf_len, sms_debug, "sms-notify: ");
237
238 ril_pdu = parcel_r_string(&rilp);
239 if (ril_pdu == NULL)
240 goto error;
241
242 ril_pdu_len = strlen(ril_pdu);
243
244 DBG("ril_pdu_len is %d", ril_pdu_len);
245 ril_data = decode_hex(ril_pdu, ril_pdu_len, &ril_buf_len, -1);
246 if (ril_data == NULL)
247 goto error;
248
249 g_ril_util_debug_hexdump(FALSE, ril_data,
250 ril_buf_len,
251 sms_debug,
252 "sms-notify-decoded: ");
253
254 /* Last parameter is 'tpdu_len' ( substract SMSC length ) */
255 ofono_sms_deliver_notify(sms, ril_data,
256 ril_buf_len,
257 ril_buf_len - 8);
258
259 /* Re-use rilp, so initilize */
260 parcel_init(&rilp);
261 parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
262 parcel_w_int32(&rilp, 1); /* Successful receipt */
263 parcel_w_int32(&rilp, 0); /* error code */
264
265 /* TODO: should ACK be sent for either of the error cases? */
266
267 /* ACK the incoming NEW_SMS; ignore response so no cb needed */
268 g_ril_send(data->ril, RIL_REQUEST_SMS_ACKNOWLEDGE,
269 rilp.data,
270 rilp.size,
271 NULL, NULL, NULL);
272
273 parcel_free(&rilp);
274 return;
275
276error:
277 ofono_error("Unable to parse NEW_SMS notification");
278}
279
280static gboolean ril_delayed_register(gpointer user_data)
281{
282 struct ofono_sms *sms = user_data;
283 struct sms_data *data = ofono_sms_get_data(sms);
284
285 DBG("");
286 ofono_sms_register(sms);
287
288 /* register to receive INCOMING_SMS */
289 g_ril_register(data->ril, RIL_UNSOL_RESPONSE_NEW_SMS,
290 ril_sms_notify, sms);
291
292 DBG("registered NEW_SMS callback");
293
294 /* This makes the timeout a single-shot */
295 return FALSE;
296}
297
298static int ril_sms_probe(struct ofono_sms *sms, unsigned int vendor,
299 void *user)
300{
301 GRil *ril = user;
302 struct sms_data *data;
303
304 DBG("");
305
306 data = g_new0(struct sms_data, 1);
307 data->ril = g_ril_clone(ril);
308 data->vendor = vendor;
309
310 ofono_sms_set_data(sms, data);
311
312 /* ofono_devinfo_register() needs to be called after
313 * the driver has been set in devinfo_create() which
314 * calls this function. Most other drivers use a
315 * callback after getting some return from the modem
316 * itself...
317 */
318 g_timeout_add_seconds(2, ril_delayed_register, sms);
319
320 return 0;
321}
322
323static void ril_sms_remove(struct ofono_sms *sms)
324{
325 struct sms_data *data = ofono_sms_get_data(sms);
326
327 DBG("");
328
329 g_ril_unref(data->ril);
330 g_free(data);
331
332 ofono_sms_set_data(sms, NULL);
333}
334
335static struct ofono_sms_driver driver = {
336 .name = "rilmodem",
337 .probe = ril_sms_probe,
338 .remove = ril_sms_remove,
339 .sca_query = ril_csca_query,
340 .sca_set = ril_csca_set,
341 .submit = ril_cmgs,
342 .bearer_query = NULL, /* FIXME: needs investigation. */
343 .bearer_set = NULL,
344};
345
346void ril_sms_init(void)
347{
348 DBG("");
349 if (ofono_sms_driver_register(&driver))
350 DBG("ofono_sms_driver_register failed!");
351}
352
353void ril_sms_exit(void)
354{
355 DBG("");
356 ofono_sms_driver_unregister(&driver);
357}
0358
=== added file 'drivers/rilmodem/voicecall.c'
--- drivers/rilmodem/voicecall.c 1970-01-01 00:00:00 +0000
+++ drivers/rilmodem/voicecall.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,537 @@
1/*
2 *
3 * oFono - Open Source Telephony
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#define _GNU_SOURCE
28#include <string.h>
29#include <stdlib.h>
30#include <stdio.h>
31#include <errno.h>
32
33#include <glib.h>
34
35/* For AudioFlinger settings */
36#include <waudio.h>
37
38#include <ofono/log.h>
39#include <ofono/modem.h>
40#include <ofono/voicecall.h>
41
42#include "gril.h"
43#include "grilutil.h"
44
45#include "common.h"
46
47#include "rilmodem.h"
48#include "parcel.h"
49
50/* Amount of ms we wait between CLCC calls */
51#define POLL_CLCC_INTERVAL 300
52
53/* When +VTD returns 0, an unspecified manufacturer-specific delay is used */
54#define TONE_DURATION 1000
55
56#define FLAG_NEED_CLIP 1
57
58struct voicecall_data {
59 GSList *calls;
60 unsigned int local_release;
61 unsigned int clcc_source;
62 GRil *ril;
63 unsigned int vendor;
64 unsigned int tone_duration;
65 guint vts_source;
66 unsigned int vts_delay;
67 unsigned char flags;
68};
69
70struct release_id_req {
71 struct ofono_voicecall *vc;
72 ofono_voicecall_cb_t cb;
73 void *data;
74 int id;
75};
76
77struct change_state_req {
78 struct ofono_voicecall *vc;
79 ofono_voicecall_cb_t cb;
80 void *data;
81 int affected_types;
82};
83
84static void audioflinger_set_call_mode()
85{
86 char parameter[20];
87 int i;
88
89 /* Set the call mode in AudioFlinger */
90 DBG("Setting AudioFlinger to call state");
91 AudioSystem_setMode(AUDIO_MODE_IN_CALL);
92
93 DBG("Setting sound route to earpiece");
94 sprintf(parameter, "routing=%d", AUDIO_DEVICE_OUT_EARPIECE);
95
96 /* Try the first 3 threads, as this is not fixed and there's no easy
97 * way to retrieve the default thread/output from Android */
98 for (i = 1; i <= 3; i++) {
99 if (AudioSystem_setParameters(i, parameter) >= 0)
100 break;
101 }
102}
103
104static void audioflinger_set_normal_mode()
105{
106 char parameter[20];
107 int i;
108
109 DBG("Setting AudioFlinger to normal mode");
110 AudioSystem_setMode(AUDIO_MODE_NORMAL);
111
112 DBG("Setting sound route back to speaker");
113
114 /* Get device back to speaker mode, as by default in_call
115 * mode sets up device out to earpiece */
116 sprintf(parameter, "routing=%d", AUDIO_DEVICE_OUT_SPEAKER);
117
118 /* Try the first 3 threads, as this is not fixed and there's no easy
119 * way to retrieve the default thread/output from Android */
120 for (i = 1; i <= 3; i++) {
121 if (AudioSystem_setParameters(i, parameter) >= 0)
122 break;
123 }
124}
125
126static void clcc_poll_cb(struct ril_msg *message, gpointer user_data)
127{
128 struct ofono_voicecall *vc = user_data;
129 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
130 GSList *calls;
131 GSList *n, *o;
132 struct ofono_call *nc, *oc;
133
134 if (message->error != RIL_E_SUCCESS) {
135 ofono_error("We are polling CLCC and received an error");
136 ofono_error("All bets are off for call management");
137 return;
138 }
139
140 calls = ril_util_parse_clcc(message);
141
142 n = calls;
143 o = vd->calls;
144
145 while (n || o) {
146 nc = n ? n->data : NULL;
147 oc = o ? o->data : NULL;
148
149 if (oc && (nc == NULL || (nc->id > oc->id))) {
150 enum ofono_disconnect_reason reason;
151
152 if (vd->local_release & (1 << oc->id))
153 reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
154 else
155 reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
156
157 if (oc->type)
158 ofono_voicecall_disconnected(vc, oc->id,
159 reason, NULL);
160
161 o = o->next;
162 } else if (nc && (oc == NULL || (nc->id < oc->id))) {
163 /* new call, signal it */
164 if (nc->type)
165 ofono_voicecall_notify(vc, nc);
166
167 n = n->next;
168 } else {
169 /*
170 * Always use the clip_validity from old call
171 * the only place this is truly told to us is
172 * in the CLIP notify, the rest are fudged
173 * anyway. Useful when RING, CLIP is used,
174 * and we're forced to use CLCC and clip_validity
175 * is 1
176 */
177 if (oc->clip_validity == 1)
178 nc->clip_validity = oc->clip_validity;
179
180 nc->cnap_validity = oc->cnap_validity;
181
182 /*
183 * CDIP doesn't arrive as part of CLCC, always
184 * re-use from the old call
185 */
186 memcpy(&nc->called_number, &oc->called_number,
187 sizeof(oc->called_number));
188
189 /*
190 * If the CLIP is not provided and the CLIP never
191 * arrives, or RING is used, then signal the call
192 * here
193 */
194 if (nc->status == CALL_STATUS_INCOMING &&
195 (vd->flags & FLAG_NEED_CLIP)) {
196 if (nc->type)
197 ofono_voicecall_notify(vc, nc);
198
199 vd->flags &= ~FLAG_NEED_CLIP;
200 } else if (memcmp(nc, oc, sizeof(*nc)) && nc->type)
201 ofono_voicecall_notify(vc, nc);
202
203 n = n->next;
204 o = o->next;
205 }
206 }
207
208 /* No other calls, get audioflinger into normal state */
209 if (vd->calls && !calls) {
210 audioflinger_set_normal_mode();
211 }
212
213 g_slist_foreach(vd->calls, (GFunc) g_free, NULL);
214 g_slist_free(vd->calls);
215
216 vd->calls = calls;
217 vd->local_release = 0;
218}
219
220static gboolean poll_clcc(gpointer user_data)
221{
222 struct ofono_voicecall *vc = user_data;
223 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
224
225 g_ril_send(vd->ril, RIL_REQUEST_GET_CURRENT_CALLS, NULL,
226 0, clcc_poll_cb, vc, NULL);
227
228 vd->clcc_source = 0;
229
230 return FALSE;
231}
232
233static void generic_cb(struct ril_msg *message, gpointer user_data)
234{
235 struct change_state_req *req = user_data;
236 struct voicecall_data *vd = ofono_voicecall_get_data(req->vc);
237 struct ofono_error error;
238
239 if (message->error == RIL_E_SUCCESS) {
240 decode_ril_error(&error, "OK");
241 } else {
242 decode_ril_error(&error, "FAIL");
243 goto out;
244 }
245
246 if (req->affected_types) {
247 GSList *l;
248 struct ofono_call *call;
249
250 for (l = vd->calls; l; l = l->next) {
251 call = l->data;
252
253 if (req->affected_types & (1 << call->status))
254 vd->local_release |= (1 << call->id);
255 }
256 }
257
258out:
259 g_ril_send(vd->ril, RIL_REQUEST_GET_CURRENT_CALLS, NULL,
260 0, clcc_poll_cb, req->vc, NULL);
261
262 /* We have to callback after we schedule a poll if required */
263 if (req->cb)
264 req->cb(&error, req->data);
265}
266
267static void ril_template(const guint rreq, struct ofono_voicecall *vc,
268 GRilResponseFunc func, unsigned int affected_types,
269 gpointer pdata, const gsize psize,
270 ofono_voicecall_cb_t cb, void *data)
271{
272 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
273 struct change_state_req *req = g_try_new0(struct change_state_req, 1);
274
275 if (req == NULL)
276 goto error;
277
278 req->vc = vc;
279 req->cb = cb;
280 req->data = data;
281 req->affected_types = affected_types;
282
283 if (g_ril_send(vd->ril, rreq, pdata, psize, func, req, g_free) > 0)
284 return;
285
286error:
287 g_free(req);
288
289 if (cb)
290 CALLBACK_WITH_FAILURE(cb, data);
291}
292
293static void rild_cb(struct ril_msg *message, gpointer user_data)
294{
295 struct cb_data *cbd = user_data;
296 struct ofono_voicecall *vc = cbd->user;
297 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
298 ofono_voicecall_cb_t cb = cbd->cb;
299 struct ofono_error error;
300 struct ofono_call *call;
301 GSList *l;
302
303 if (message->error == RIL_E_SUCCESS) {
304 decode_ril_error(&error, "OK");
305 } else {
306 decode_ril_error(&error, "FAIL");
307 goto out;
308 }
309
310 /* On a success, make sure to put all active calls on hold */
311 for (l = vd->calls; l; l = l->next) {
312 call = l->data;
313
314 if (call->status != CALL_STATUS_ACTIVE)
315 continue;
316
317 call->status = CALL_STATUS_HELD;
318 ofono_voicecall_notify(vc, call);
319 }
320
321 /* CLCC will update the oFono call list with proper ids */
322 if (!vd->clcc_source)
323 vd->clcc_source = g_timeout_add(POLL_CLCC_INTERVAL,
324 poll_clcc, vc);
325
326 audioflinger_set_call_mode();
327
328out:
329 cb(&error, cbd->data);
330}
331
332static void ril_dial(struct ofono_voicecall *vc,
333 const struct ofono_phone_number *ph,
334 enum ofono_clir_option clir, ofono_voicecall_cb_t cb,
335 void *data)
336{
337 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
338 struct cb_data *cbd = cb_data_new(cb, data);
339 struct parcel rilp;
340 int ret;
341
342 cbd->user = vc;
343
344 parcel_init(&rilp);
345
346 /* Number to dial */
347 parcel_w_string(&rilp, phone_number_to_string(ph));
348 /* CLIR mode */
349 parcel_w_int32(&rilp, clir);
350 /* USS, need it twice for absent */
351 /* TODO: Deal with USS properly */
352 parcel_w_int32(&rilp, 0);
353 parcel_w_int32(&rilp, 0);
354
355 /* Send request to RIL */
356 ret = g_ril_send(vd->ril, RIL_REQUEST_DIAL, rilp.data,
357 rilp.size, rild_cb, cbd, g_free);
358 parcel_free(&rilp);
359
360 /* In case of error free cbd and return the cb with failure */
361 if (ret <= 0) {
362 g_free(cbd);
363 CALLBACK_WITH_FAILURE(cb, data);
364 }
365}
366
367static void ril_hangup_all(struct ofono_voicecall *vc,
368 ofono_voicecall_cb_t cb, void *data)
369{
370 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
371 struct parcel rilp;
372 struct ofono_error error;
373 struct ofono_call *call;
374 GSList *l;
375
376 for (l = vd->calls; l; l = l->next) {
377 call = l->data;
378 /* TODO: Hangup just the active ones once we have call
379 * state tracking (otherwise it can't handle ringing) */
380 DBG("Hanging up call with id %d", call->id);
381 parcel_init(&rilp);
382 parcel_w_int32(&rilp, 1); /* Always 1 - AT+CHLD=1x */
383 parcel_w_int32(&rilp, call->id);
384
385 /* Send request to RIL */
386 ril_template(RIL_REQUEST_HANGUP, vc, generic_cb, 0x3f,
387 rilp.data, rilp.size, NULL, NULL);
388 parcel_free(&rilp);
389 }
390
391 /* TODO: Deal in case of an error at hungup */
392 decode_ril_error(&error, "OK");
393 cb(&error, data);
394}
395
396static void ril_call_state_notify(struct ril_msg *message, gpointer user_data)
397{
398 struct ofono_voicecall *vc = user_data;
399
400 if (message->req != RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED)
401 goto error;
402
403 /* Just need to request the call list again */
404 poll_clcc(vc);
405
406 return;
407
408error:
409 ofono_error("Unable to notify about call state changes");
410}
411
412static void ril_answer(struct ofono_voicecall *vc,
413 ofono_voicecall_cb_t cb, void *data)
414{
415 DBG("Answering current call");
416
417 /* Send request to RIL */
418 ril_template(RIL_REQUEST_ANSWER, vc, generic_cb, 0,
419 NULL, 0, cb, data);
420
421 audioflinger_set_call_mode();
422}
423
424static void ril_send_dtmf(struct ofono_voicecall *vc, const char *dtmf,
425 ofono_voicecall_cb_t cb, void *data)
426{
427 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
428 int len = strlen(dtmf);
429 struct parcel rilp;
430 struct ofono_error error;
431 char *ril_dtmf = g_try_malloc(sizeof(char) * 2);
432 int i;
433
434 DBG("");
435
436 /* Ril wants just one character, but we need to send as string */
437 ril_dtmf[1] = '\0';
438
439 for (i = 0; i < len; i++) {
440 parcel_init(&rilp);
441 ril_dtmf[0] = dtmf[i];
442 parcel_w_string(&rilp, ril_dtmf);
443 DBG("DTMF: Sending %s", ril_dtmf);
444 g_ril_send(vd->ril, RIL_REQUEST_DTMF, rilp.data,
445 rilp.size, NULL, NULL, NULL);
446 parcel_free(&rilp);
447 }
448
449 free(ril_dtmf);
450
451 /* We don't really care about errors here */
452 decode_ril_error(&error, "OK");
453 cb(&error, data);
454}
455
456static gboolean ril_delayed_register(gpointer user_data)
457{
458 struct ofono_voicecall *vc = user_data;
459 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
460 ofono_voicecall_register(vc);
461
462 /* Initialize call list */
463 poll_clcc(vc);
464
465 /* Unsol when call state changes */
466 g_ril_register(vd->ril, RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
467 ril_call_state_notify, vc);
468
469 /* This makes the timeout a single-shot */
470 return FALSE;
471}
472
473static int ril_voicecall_probe(struct ofono_voicecall *vc, unsigned int vendor,
474 void *data)
475{
476 GRil *ril = data;
477 struct voicecall_data *vd;
478
479 vd = g_try_new0(struct voicecall_data, 1);
480 if (vd == NULL)
481 return -ENOMEM;
482
483 vd->ril = g_ril_clone(ril);
484 vd->vendor = vendor;
485 vd->tone_duration = TONE_DURATION;
486
487 ofono_voicecall_set_data(vc, vd);
488
489 /* ofono_devinfo_register() needs to be called after
490 * the driver has been set in devinfo_create() which
491 * calls this function. Most other drivers use a
492 * callback after getting some return from the modem
493 * itself...
494 */
495 g_timeout_add_seconds(2, ril_delayed_register, vc);
496
497 return 0;
498}
499
500static void ril_voicecall_remove(struct ofono_voicecall *vc)
501{
502 struct voicecall_data *vd = ofono_voicecall_get_data(vc);
503
504 if (vd->clcc_source)
505 g_source_remove(vd->clcc_source);
506
507 if (vd->vts_source)
508 g_source_remove(vd->vts_source);
509
510 g_slist_foreach(vd->calls, (GFunc) g_free, NULL);
511 g_slist_free(vd->calls);
512
513 ofono_voicecall_set_data(vc, NULL);
514
515 g_ril_unref(vd->ril);
516 g_free(vd);
517}
518
519static struct ofono_voicecall_driver driver = {
520 .name = "rilmodem",
521 .probe = ril_voicecall_probe,
522 .remove = ril_voicecall_remove,
523 .dial = ril_dial,
524 .answer = ril_answer,
525 .hangup_all = ril_hangup_all,
526 .send_tones = ril_send_dtmf
527};
528
529void ril_voicecall_init(void)
530{
531 ofono_voicecall_driver_register(&driver);
532}
533
534void ril_voicecall_exit(void)
535{
536 ofono_voicecall_driver_unregister(&driver);
537}
0538
=== added directory 'gril'
=== added file 'gril/gfunc.h'
--- gril/gfunc.h 1970-01-01 00:00:00 +0000
+++ gril/gfunc.h 2013-04-09 20:01:20 +0000
@@ -0,0 +1,42 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef __GFUNC_H
24#define __GFUNC_H
25
26#include <glib.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32typedef void (*GRilDisconnectFunc)(gpointer user_data);
33typedef void (*GRilReceiveFunc)(const unsigned char *data, gsize size,
34 gpointer user_data);
35typedef void (*GRilDebugFunc)(const char *str, gpointer user_data);
36typedef void (*GRilSuspendFunc)(gpointer user_data);
37
38#ifdef __cplusplus
39}
40#endif
41
42#endif /* __GFUNC_H */
043
=== added file 'gril/gril.c'
--- gril/gril.c 1970-01-01 00:00:00 +0000
+++ gril/gril.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,1160 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdio.h>
28#include <unistd.h>
29#include <string.h>
30#include <assert.h>
31#include <ctype.h>
32#include <errno.h>
33#include <sys/socket.h>
34#include <sys/un.h>
35#include <netinet/in.h>
36
37#include <glib.h>
38
39#include "log.h"
40#include "ringbuffer.h"
41#include "gril.h"
42
43#define COMMAND_FLAG_EXPECT_PDU 0x1
44#define COMMAND_FLAG_EXPECT_SHORT_PROMPT 0x2
45
46#define RILD_CMD_SOCKET "/dev/socket/rild"
47#define RILD_DBG_SOCKET "/dev/socket/rild-debug"
48
49struct ril_request {
50 gchar *req;
51 guint req_len;
52 guint id;
53 guint gid;
54 GRilResponseFunc callback;
55 gpointer user_data;
56 GDestroyNotify notify;
57};
58
59struct ril_notify_node {
60 guint id;
61 guint gid;
62 GRilNotifyFunc callback;
63 gpointer user_data;
64 gboolean destroyed;
65};
66
67typedef gboolean (*node_remove_func)(struct ril_notify_node *node,
68 gpointer user_data);
69
70struct ril_notify {
71 GSList *nodes;
72};
73
74struct ril_s {
75 gint ref_count; /* Ref count */
76 guint next_cmd_id; /* Next command id */
77 guint next_notify_id; /* Next notify id */
78 guint next_gid; /* Next group id */
79 GRilIO *io; /* GRil IO */
80 GQueue *command_queue; /* Command queue */
81 guint req_bytes_written; /* bytes written from req */
82 GHashTable *notify_list; /* List of notification reg */
83 GRilDisconnectFunc user_disconnect; /* user disconnect func */
84 gpointer user_disconnect_data; /* user disconnect data */
85 guint read_so_far; /* Number of bytes processed */
86 gboolean suspended; /* Are we suspended? */
87 GRilDebugFunc debugf; /* debugging output function */
88 gpointer debug_data; /* Data to pass to debug func */
89 GSList *response_lines; /* char * lines of the response */
90 gint timeout_source;
91 gboolean destroyed; /* Re-entrancy guard */
92 gboolean in_read_handler; /* Re-entrancy guard */
93 gboolean in_notify;
94};
95
96struct _GRil {
97 gint ref_count;
98 struct ril_s *parent;
99 guint group;
100};
101
102/*
103 * This struct represents the header of a RIL reply.
104 * It does not include the Big Endian UINT32 length prefix.
105 */
106struct ril_reply {
107 guint32 reply; /* LE: should be 0 */
108 guint32 serial_no; /* LE: used to match requests */
109 guint32 error_code; /* LE: */
110};
111
112static void ril_wakeup_writer(struct ril_s *ril);
113
114static void ril_notify_node_destroy(gpointer data, gpointer user_data)
115{
116 struct ril_notify_node *node = data;
117 g_free(node);
118}
119
120static void ril_notify_destroy(gpointer user_data)
121{
122 struct ril_notify *notify = user_data;
123
124 g_slist_foreach(notify->nodes, ril_notify_node_destroy, NULL);
125 g_slist_free(notify->nodes);
126 g_free(notify);
127}
128
129static gint ril_notify_node_compare_by_id(gconstpointer a, gconstpointer b)
130{
131 const struct ril_notify_node *node = a;
132 guint id = GPOINTER_TO_UINT(b);
133
134 if (node->id < id)
135 return -1;
136
137 if (node->id > id)
138 return 1;
139
140 return 0;
141}
142
143static gboolean ril_unregister_all(struct ril_s *ril,
144 gboolean mark_only,
145 node_remove_func func,
146 gpointer userdata)
147{
148 GHashTableIter iter;
149 struct ril_notify *notify;
150 struct ril_notify_node *node;
151 gpointer key, value;
152 GSList *p;
153 GSList *c;
154 GSList *t;
155
156 if (ril->notify_list == NULL)
157 return FALSE;
158
159 g_hash_table_iter_init(&iter, ril->notify_list);
160
161 while (g_hash_table_iter_next(&iter, &key, &value)) {
162 notify = value;
163
164 p = NULL;
165 c = notify->nodes;
166
167 while (c) {
168 node = c->data;
169
170 if (func(node, userdata) != TRUE) {
171 p = c;
172 c = c->next;
173 continue;
174 }
175
176 if (mark_only) {
177 node->destroyed = TRUE;
178 p = c;
179 c = c->next;
180 continue;
181 }
182
183 if (p)
184 p->next = c->next;
185 else
186 notify->nodes = c->next;
187
188 ril_notify_node_destroy(node, NULL);
189
190 t = c;
191 c = c->next;
192 g_slist_free_1(t);
193 }
194
195 if (notify->nodes == NULL)
196 g_hash_table_iter_remove(&iter);
197 }
198
199 return TRUE;
200}
201
202/* TODO: move to grilutil.h */
203static const char *err_name(int error)
204{
205 switch(error) {
206 case RIL_E_SUCCESS: return "SUCCESS";
207 case RIL_E_RADIO_NOT_AVAILABLE: return "RADIO_NOT_AVAILABLE";
208 case RIL_E_GENERIC_FAILURE: return "GENERIC_FAILURE";
209 case RIL_E_PASSWORD_INCORRECT: return "PASSWORD_INCORRECT";
210 case RIL_E_SIM_PIN2: return "SIM_PIN2";
211 case RIL_E_SIM_PUK2: return "SIM_PUK2";
212 case RIL_E_REQUEST_NOT_SUPPORTED: return "REQUEST_NOT_SUPPORTED";
213 case RIL_E_CANCELLED: return "CANCELLED";
214 case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "OP_NOT_ALLOWED_DURING_VOICE_CALL";
215 case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
216 case RIL_E_SMS_SEND_FAIL_RETRY: return "SMS_SEND_FAIL_RETRY";
217 case RIL_E_SIM_ABSENT: return "SIM_ABSENT";
218 case RIL_E_SUBSCRIPTION_NOT_AVAILABLE: return "SUBSCRIPTION_NOT_AVAILABLE";
219 case RIL_E_MODE_NOT_SUPPORTED: return "MODE_NOT_SUPPORTED";
220 case RIL_E_FDN_CHECK_FAILURE: return "FDN_CHECK_FAILURE";
221 case RIL_E_ILLEGAL_SIM_OR_ME: return "ILLEGAL_SIM_OR_ME";
222 default: return "<unknown errno>";
223 }
224}
225
226/* TODO: move to grilutil.h */
227static const char *unsol_request_name(int request)
228{
229 switch(request) {
230 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
231 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
232 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
233 case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
234 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
235 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
236 case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
237 case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
238 case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
239 case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
240 case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
241 case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
242 case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
243 case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
244 case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
245 case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
246 case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
247 case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
248 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
249 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
250 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
251 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
252 case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
253 case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
254 case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
255 case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
256 case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
257 case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
258 case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
259 case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
260 case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
261 case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
262 case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
263 case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
264 default:
265 DBG("Got unknown request number %d", request);
266 return "<unknown request>";
267 }
268}
269
270/*
271 * This function creates a RIL request. For a good reference on
272 * the layout of RIL requests, responses, and unsolicited requests
273 * see:
274 *
275 * https://wiki.mozilla.org/B2G/RIL
276 *
277 */
278static struct ril_request *ril_request_create(struct ril_s *ril,
279 guint gid,
280 const guint req,
281 const guint id,
282 const char *data,
283 const gsize data_len,
284 GRilResponseFunc func,
285 gpointer user_data,
286 GDestroyNotify notify,
287 gboolean wakeup)
288{
289 struct ril_request *r;
290 gsize len;
291 gchar *cur_bufp;
292 guint32 *net_length, *request, *serial_no;
293
294 r = g_try_new0(struct ril_request, 1);
295 if (r == NULL)
296 return 0;
297
298 DBG("req: %s, id: %d, data_len: %d",
299 ril_request_id_to_string(req), id, data_len);
300
301 /* RIL request: 8 byte header + data */
302 len = 8 + data_len;
303
304 /* Add 4 bytes to buffer length to include length prefix */
305 r->req_len = len + 4;
306
307 r->req = g_try_new(char, r->req_len);
308 if (r->req == NULL) {
309 ofono_error("ril_request: can't allocate new request.");
310 g_free(r);
311 return 0;
312 }
313
314 /* convert length to network byte order (Big Endian) */
315 net_length = (guint32 *) r->req;
316 *net_length = htonl(len);
317
318 /* advance past initial length */
319 cur_bufp = r->req + 4;
320
321 /* write request code */
322 request = (guint32 *) cur_bufp;
323 *request = req;
324 cur_bufp += 4;
325
326 /* write serial number */
327 serial_no = (guint32 *) cur_bufp;
328 *serial_no = id;
329 cur_bufp += 4;
330
331 /* copy request data */
332 memcpy(cur_bufp, (const void *) data, data_len);
333
334 r->gid = gid;
335 r->id = id;
336 r->callback = func;
337 r->user_data = user_data;
338 r->notify = notify;
339
340 return r;
341}
342
343static void ril_request_destroy(struct ril_request *req)
344{
345 if (req->notify)
346 req->notify(req->user_data);
347
348 g_free(req->req);
349 g_free(req);
350}
351
352static void ril_cleanup(struct ril_s *p)
353{
354 /* Cleanup pending commands */
355
356 g_queue_free(p->command_queue);
357 p->command_queue = NULL;
358
359 /* Cleanup any response lines we have pending */
360 g_slist_foreach(p->response_lines, (GFunc)g_free, NULL);
361 g_slist_free(p->response_lines);
362 p->response_lines = NULL;
363
364 /* Cleanup registered notifications */
365
366 if (p->notify_list)
367 g_hash_table_destroy(p->notify_list);
368
369 p->notify_list = NULL;
370
371 if (p->timeout_source) {
372 g_source_remove(p->timeout_source);
373 p->timeout_source = 0;
374 }
375}
376
377static void io_disconnect(gpointer user_data)
378{
379 struct ril_s *ril = user_data;
380
381 ril_cleanup(ril);
382 g_ril_io_unref(ril->io);
383 ril->io = NULL;
384
385 if (ril->user_disconnect)
386 ril->user_disconnect(ril->user_disconnect_data);
387}
388
389static void handle_response(struct ril_s *p, struct ril_msg *message)
390{
391 gsize count = g_queue_get_length(p->command_queue);
392 struct ril_request *req;
393 int i;
394
395 g_assert(count > 0);
396
397 for (i = 0; i < count; i++) {
398 req = g_queue_peek_nth(p->command_queue, i);
399 DBG("comparing req->id: %d to message->serial_no: %d",
400 req->id, message->serial_no);
401
402 if (req->id == message->serial_no) {
403 req = g_queue_pop_nth(p->command_queue, i);
404
405 if (req->callback)
406 req->callback(message, req->user_data);
407
408 ril_request_destroy(req);
409
410 if (g_queue_peek_head(p->command_queue))
411 ril_wakeup_writer(p);
412 /*
413 * TODO: there's a flaw in the current logic.
414 * If a matching response isn't received,
415 * req_bytes_written doesn't get reset.
416 * gatchat has the concept of modem wakeup,
417 * which is a failsafe way of making sure
418 * cmd_bytes_written gets reset, however if
419 * the modem isn't configured for wakeup,
420 * it may have the same problem. Perhaps
421 * we should consider adding a timer?
422 */
423 p->req_bytes_written = 0;
424
425 /* Found our matching one */
426 break;
427 }
428 }
429}
430
431static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
432{
433 GHashTableIter iter;
434 struct ril_notify *notify;
435 int req_key;
436 gpointer key, value;
437 GList *list_item;
438 struct ril_notify_node *node;
439
440 if (p->notify_list == NULL)
441 return;
442
443 p->in_notify = TRUE;
444
445 g_hash_table_iter_init(&iter, p->notify_list);
446
447 while (g_hash_table_iter_next(&iter, &key, &value)) {
448 req_key = *((int *)key);
449 notify = value;
450
451 DBG("checking req_key: %d to req: %d", req_key, message->req);
452
453 if (req_key != message->req)
454 continue;
455
456 list_item = notify->nodes;
457
458 while (list_item != NULL) {
459 node = list_item->data;
460
461 DBG("about to callback: notify: %x, node: %x, notify->nodes: %x, callback: %x",
462 notify, node, notify->nodes, node->callback);
463
464 node->callback(message, node->user_data);
465
466 list_item = g_slist_next(list_item);
467 }
468 }
469
470 p->in_notify = FALSE;
471}
472
473static void dispatch(struct ril_s *p, struct ril_msg *message)
474{
475 guint32 *unsolicited_field, *id_num_field;
476 gchar *bufp = message->buf;
477 gchar *datap;
478 gsize data_len;
479
480 /* This could be done with a struct/union... */
481 unsolicited_field = (guint32 *) bufp;
482 if (*unsolicited_field)
483 message->unsolicited = TRUE;
484 else
485 message->unsolicited = FALSE;
486
487 bufp += 4;
488
489 id_num_field = (guint32 *) bufp;
490 if (message->unsolicited) {
491 message->req = (int) *id_num_field;
492
493 /*
494 * A RIL Unsolicited Event is two UINT32 fields ( unsolicited, and req/ev ),
495 * so subtract the length of the header from the overall length to calculate
496 * the length of the Event Data.
497 */
498 data_len = message->buf_len - 8;
499 } else {
500 message->serial_no = (int) *id_num_field;
501
502 bufp += 4;
503 message->error = *((guint32 *) bufp);
504
505 /*
506 * A RIL Solicited Response is three UINT32 fields ( unsolicied, serial_no
507 * and error ), so subtract the length of the header from the overall length
508 * to calculate the length of the Event Data.
509 */
510 data_len = message->buf_len - 12;
511 }
512
513 /* advance to start of data.. */
514 bufp += 4;
515
516 /* Now, allocate new buffer for data only, copy from
517 * original, and free the original...
518 */
519 if (data_len) {
520 datap = g_try_malloc(data_len);
521 if (datap == NULL)
522 goto error;
523
524 /* Copy bytes into new buffer */
525 memmove(datap, (const void *) bufp, data_len);
526
527 /* Free old buffer */
528 g_free(message->buf);
529
530 /* ...and replace with new buffer */
531 message->buf = datap;
532 message->buf_len = data_len;
533 }
534
535 if (message->unsolicited == TRUE) {
536 DBG("RIL Event: %s\n", unsol_request_name(message->req));
537
538 handle_unsol_req(p, message);
539 } else {
540 DBG("RIL Reply: serial-no: %d errno: %s\n",
541 message->serial_no,
542 err_name(message->error));
543
544 handle_response(p, message);
545 }
546error:
547 g_free(message->buf);
548 g_free(message);
549}
550
551static struct ril_msg *read_fixed_record(struct ril_s *p,
552 const guchar *bytes, gsize *len)
553{
554 struct ril_msg *message;
555 int message_len, plen;
556
557 /* First four bytes are length in TCP byte order (Big Endian) */
558 plen = ntohl(*((uint32_t *) bytes));
559 bytes += 4;
560
561 /* TODO: Verify that 4k is the max message size from rild.
562 *
563 * These conditions shouldn't happen. If it does
564 * there are three options:
565 *
566 * 1) ASSERT; ofono will restart via DBus
567 * 2) Consume the bytes & continue
568 * 3) force a disconnect
569 */
570 g_assert(plen >= 8 && plen <= 4092);
571
572 /* If we don't have the whole fixed record in the ringbuffer
573 * then return NULL & leave ringbuffer as is.
574 */
575
576 message_len = *len - 4;
577 if (message_len < plen) {
578 return NULL;
579 }
580
581 /* FIXME: add check for message_len = 0? */
582
583 message = g_try_malloc(sizeof(struct ril_msg));
584 g_assert(message != NULL);
585
586 /* allocate ril_msg->buffer */
587 message->buf_len = plen;
588 message->buf = g_try_malloc(plen);
589 g_assert(message->buf != NULL);
590
591 /* Copy bytes into message buffer */
592 memmove(message->buf, (const void *) bytes, plen);
593
594 /* Indicate to caller size of record we extracted */
595 *len = plen + 4;
596 return message;
597}
598
599static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
600{
601 struct ril_msg *message;
602 struct ril_s *p = user_data;
603 unsigned int len = ring_buffer_len(rbuf);
604 unsigned int wrap = ring_buffer_len_no_wrap(rbuf);
605 guchar *buf = ring_buffer_read_ptr(rbuf, p->read_so_far);
606
607 p->in_read_handler = TRUE;
608
609 DBG("len: %d, wrap: %d", len, wrap);
610
611 while (p->suspended == FALSE && (p->read_so_far < len)) {
612 gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
613
614 if (rbytes < 4) {
615 DBG("Not enough bytes for header length: len: %d", len);
616 return;
617 }
618
619 /* this function attempts to read the next full length
620 * fixed message from the stream. if not all bytes are
621 * available, it returns NULL. otherwise it allocates
622 * and returns a ril_message with the copied bytes, and
623 * drains those bytes from the ring_buffer
624 */
625 message = read_fixed_record(p, buf, &rbytes);
626
627 /* wait for the rest of the record... */
628 if (message == NULL) {
629 DBG("Not enough bytes for fixed record");
630 break;
631 }
632
633 buf += rbytes;
634 p->read_so_far += rbytes;
635
636 /* TODO: need to better understand how wrap works! */
637 if (p->read_so_far == wrap) {
638 buf = ring_buffer_read_ptr(rbuf, p->read_so_far);
639 wrap = len;
640 }
641
642 dispatch(p, message);
643
644 ring_buffer_drain(rbuf, p->read_so_far);
645
646 len -= p->read_so_far;
647 wrap -= p->read_so_far;
648 p->read_so_far = 0;
649 }
650
651 p->in_read_handler = FALSE;
652
653 if (p->destroyed)
654 g_free(p);
655}
656
657static gboolean can_write_data(gpointer data)
658{
659 struct ril_s *ril = data;
660 struct ril_request *req;
661 gsize bytes_written;
662 gsize towrite;
663 gsize len;
664
665 /* Grab the first command off the queue and write as
666 * much of it as we can
667 */
668 req = g_queue_peek_head(ril->command_queue);
669
670 /* For some reason command queue is empty, cancel write watcher */
671 if (req == NULL)
672 return FALSE;
673
674 len = req->req_len;
675 DBG("len: %d, req_bytes_written: %d", len, ril->req_bytes_written);
676
677 /* For some reason write watcher fired, but we've already
678 * written the entire command out to the io channel,
679 * cancel write watcher
680 */
681 if (ril->req_bytes_written >= len)
682 return FALSE;
683
684 /*
685 * AT modems need to be woken up via a command set by the
686 * upper layers. RIL has no such concept, hence wakeup needed
687 * NOTE - I'm keeping the if statement here commented out, just
688 * in case this concept needs to be added back in...
689 *
690 * if (ril->req_bytes_written == 0 && wakeup_first == TRUE) {
691 * cmd = at_command_create(0, chat->wakeup, none_prefix, 0,
692 * NULL, wakeup_cb, chat, NULL, TRUE);
693 * g_queue_push_head(chat->command_queue, cmd);
694 * len = strlen(chat->wakeup);
695 * chat->timeout_source = g_timeout_add(chat->wakeup_timeout,
696 * wakeup_no_response, chat);
697 * }
698 */
699
700 towrite = len - ril->req_bytes_written;
701
702#ifdef WRITE_SCHEDULER_DEBUG
703 if (towrite > 5)
704 towrite = 5;
705#endif
706
707 bytes_written = g_ril_io_write(ril->io,
708 req->req + ril->req_bytes_written,
709 towrite);
710
711 DBG("bytes_written: %d", bytes_written);
712
713 if (bytes_written == 0)
714 return FALSE;
715
716 ril->req_bytes_written += bytes_written;
717 if (bytes_written < towrite)
718 return TRUE;
719
720 return FALSE;
721}
722
723static void ril_wakeup_writer(struct ril_s *ril)
724{
725 g_ril_io_set_write_handler(ril->io, can_write_data, ril);
726}
727
728static void ril_suspend(struct ril_s *ril)
729{
730 ril->suspended = TRUE;
731
732 g_ril_io_set_write_handler(ril->io, NULL, NULL);
733 g_ril_io_set_read_handler(ril->io, NULL, NULL);
734 g_ril_io_set_debug(ril->io, NULL, NULL);
735}
736
737/*
738 * TODO: need to determine when ril_resume/suspend are called.
739 *
740 * Most likely, this is in response to DBUS messages sent to
741 * oFono to tell it the system is suspending/resuming.
742 */
743static void ril_resume(struct ril_s *ril)
744{
745 ril->suspended = FALSE;
746
747 if (g_ril_io_get_channel(ril->io) == NULL) {
748 io_disconnect(ril);
749 return;
750 }
751
752 g_ril_io_set_disconnect_function(ril->io, io_disconnect, ril);
753
754 g_ril_io_set_debug(ril->io, ril->debugf, ril->debug_data);
755
756 g_ril_io_set_read_handler(ril->io, new_bytes, ril);
757
758 if (g_queue_get_length(ril->command_queue) > 0)
759 ril_wakeup_writer(ril);
760}
761
762static gboolean ril_set_debug(struct ril_s *ril,
763 GRilDebugFunc func, gpointer user_data)
764{
765
766 ril->debugf = func;
767 ril->debug_data = user_data;
768
769 if (ril->io)
770 g_ril_io_set_debug(ril->io, func, user_data);
771
772 return TRUE;
773}
774
775static void ril_unref(struct ril_s *ril)
776{
777 gboolean is_zero;
778
779 is_zero = g_atomic_int_dec_and_test(&ril->ref_count);
780
781 if (is_zero == FALSE)
782 return;
783
784 if (ril->io) {
785 ril_suspend(ril);
786 g_ril_io_unref(ril->io);
787 ril->io = NULL;
788 ril_cleanup(ril);
789 }
790
791 if (ril->in_read_handler)
792 ril->destroyed = TRUE;
793 else
794 g_free(ril);
795}
796
797static gboolean node_compare_by_group(struct ril_notify_node *node,
798 gpointer userdata)
799{
800 guint group = GPOINTER_TO_UINT(userdata);
801
802 if (node->gid == group)
803 return TRUE;
804
805 return FALSE;
806}
807
808static struct ril_s *create_ril()
809
810{
811 struct ril_s *ril;
812 struct sockaddr_un addr;
813 int sk;
814 GIOChannel *io;
815
816 ril = g_try_new0(struct ril_s, 1);
817 if (ril == NULL)
818 return ril;
819
820 ril->ref_count = 1;
821 ril->next_cmd_id = 1;
822 ril->next_notify_id = 1;
823 ril->next_gid = 0;
824 ril->debugf = NULL;
825 ril->req_bytes_written = 0;
826
827 sk = socket(AF_UNIX, SOCK_STREAM, 0);
828 if (sk < 0) {
829 ofono_error("create_ril: can't create unix socket: %s (%d)\n",
830 strerror(errno), errno);
831 goto error;
832 }
833
834 memset(&addr, 0, sizeof(addr));
835 addr.sun_family = AF_UNIX;
836 strncpy(addr.sun_path, RILD_CMD_SOCKET, sizeof(addr.sun_path) - 1);
837
838 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
839 ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
840 strerror(errno), errno);
841 goto error;
842 }
843
844 io = g_io_channel_unix_new(sk);
845 if (io == NULL) {
846 ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
847 strerror(errno), errno);
848 return NULL;
849 }
850
851 g_io_channel_set_buffered(io, FALSE);
852 g_io_channel_set_encoding(io, NULL, NULL);
853 g_io_channel_set_close_on_unref(io, TRUE);
854 g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
855
856 ril->io = g_ril_io_new(io);
857 if (ril->io == NULL) {
858 ofono_error("create_ril: can't create ril->io");
859 goto error;
860 }
861
862 g_ril_io_set_disconnect_function(ril->io, io_disconnect, ril);
863
864 ril->command_queue = g_queue_new();
865 if (ril->command_queue == NULL) {
866 ofono_error("create_ril: Couldn't create command_queue.");
867 goto error;
868 }
869
870 ril->notify_list = g_hash_table_new_full(g_int_hash, g_int_equal,
871 g_free, ril_notify_destroy);
872
873 g_ril_io_set_read_handler(ril->io, new_bytes, ril);
874
875 return ril;
876
877error:
878 g_ril_io_unref(ril->io);
879
880 if (ril->command_queue)
881 g_queue_free(ril->command_queue);
882
883 if (ril->notify_list)
884 g_hash_table_destroy(ril->notify_list);
885
886 g_free(ril);
887 return NULL;
888}
889
890static struct ril_notify *ril_notify_create(struct ril_s *ril,
891 const int req)
892{
893 struct ril_notify *notify;
894 int *key;
895
896 notify = g_try_new0(struct ril_notify, 1);
897 if (notify == NULL)
898 return 0;
899
900 key = g_try_new0(int, 1);
901 if (key == NULL)
902 return 0;
903
904 *key = req;
905
906 g_hash_table_insert(ril->notify_list, key, notify);
907
908 return notify;
909}
910
911static guint ril_register(struct ril_s *ril, guint group,
912 const int req, GRilNotifyFunc func,
913 gpointer user_data)
914{
915 struct ril_notify *notify;
916 struct ril_notify_node *node;
917
918 if (ril->notify_list == NULL)
919 return 0;
920
921 if (func == NULL)
922 return 0;
923
924 notify = g_hash_table_lookup(ril->notify_list, &req);
925
926 if (notify == NULL)
927 notify = ril_notify_create(ril, req);
928
929 if (notify == NULL)
930 return 0;
931
932 node = g_try_new0(struct ril_notify_node, 1);
933 if (node == NULL)
934 return 0;
935
936 node->id = ril->next_notify_id++;
937 node->gid = group;
938 node->callback = func;
939 node->user_data = user_data;
940
941 notify->nodes = g_slist_prepend(notify->nodes, node);
942 DBG("after pre-pend; notify: %x, node %x, notify->nodes: %x, callback: %x",
943 notify, node, notify->nodes, node->callback);
944
945 return node->id;
946}
947
948static gboolean ril_unregister(struct ril_s *ril, gboolean mark_only,
949 guint group, guint id)
950{
951 GHashTableIter iter;
952 struct ril_notify *notify;
953 struct ril_notify_node *node;
954 gpointer key, value;
955 GSList *l;
956
957 if (ril->notify_list == NULL)
958 return FALSE;
959
960 g_hash_table_iter_init(&iter, ril->notify_list);
961
962 while (g_hash_table_iter_next(&iter, &key, &value)) {
963 notify = value;
964
965 l = g_slist_find_custom(notify->nodes, GUINT_TO_POINTER(id),
966 ril_notify_node_compare_by_id);
967
968 if (l == NULL)
969 continue;
970
971 node = l->data;
972
973 if (node->gid != group)
974 return FALSE;
975
976 if (mark_only) {
977 node->destroyed = TRUE;
978 return TRUE;
979 }
980
981 ril_notify_node_destroy(node, NULL);
982 notify->nodes = g_slist_remove(notify->nodes, node);
983
984 if (notify->nodes == NULL)
985 g_hash_table_iter_remove(&iter);
986
987 return TRUE;
988 }
989
990 return FALSE;
991}
992
993GRil *g_ril_new()
994{
995 GRil *ril;
996
997 ril = g_try_new0(GRil, 1);
998 if (ril == NULL)
999 return NULL;
1000
1001 ril->parent = create_ril();
1002 if (ril->parent == NULL) {
1003 g_free(ril);
1004 return NULL;
1005 }
1006
1007 ril->group = ril->parent->next_gid++;
1008 ril->ref_count = 1;
1009
1010 return ril;
1011}
1012
1013GRil *g_ril_clone(GRil *clone)
1014{
1015 GRil *ril;
1016
1017 if (clone == NULL)
1018 return NULL;
1019
1020 ril = g_try_new0(GRil, 1);
1021 if (ril == NULL)
1022 return NULL;
1023
1024 ril->parent = clone->parent;
1025 ril->group = ril->parent->next_gid++;
1026 ril->ref_count = 1;
1027 g_atomic_int_inc(&ril->parent->ref_count);
1028
1029 return ril;
1030}
1031
1032GIOChannel *g_ril_get_channel(GRil *ril)
1033{
1034 if (ril == NULL || ril->parent->io == NULL)
1035 return NULL;
1036
1037 return g_ril_io_get_channel(ril->parent->io);
1038
1039}
1040
1041GRilIO *g_ril_get_io(GRil *ril)
1042{
1043 if (ril == NULL)
1044 return NULL;
1045
1046 return ril->parent->io;
1047}
1048
1049GRil *g_ril_ref(GRil *ril)
1050{
1051 if (ril == NULL)
1052 return NULL;
1053
1054 g_atomic_int_inc(&ril->ref_count);
1055
1056 return ril;
1057}
1058
1059guint g_ril_send(GRil *ril, const guint req, const char *data,
1060 const gsize data_len, GRilResponseFunc func,
1061 gpointer user_data, GDestroyNotify notify)
1062{
1063 struct ril_request *r;
1064 struct ril_s *p;
1065
1066 if (ril == NULL || ril->parent == NULL || ril->parent->command_queue == NULL)
1067 return 0;
1068
1069 p = ril->parent;
1070
1071 r = ril_request_create(p, ril->group, req, p->next_cmd_id,
1072 data, data_len, func,
1073 user_data, notify, FALSE);
1074 if (r == NULL)
1075 return 0;
1076
1077 p->next_cmd_id++;
1078
1079 g_queue_push_tail(p->command_queue, r);
1080
1081 if (g_queue_get_length(p->command_queue) == 1) {
1082 DBG("calling wakeup_writer: qlen: %d", g_queue_get_length(p->command_queue));
1083 ril_wakeup_writer(p);
1084 }
1085
1086 return r->id;
1087}
1088
1089void g_ril_suspend(GRil *ril)
1090{
1091 if (ril == NULL)
1092 return;
1093
1094 ril_suspend(ril->parent);
1095}
1096
1097void g_ril_resume(GRil *ril)
1098{
1099 if (ril == NULL)
1100 return;
1101
1102 ril_resume(ril->parent);
1103}
1104
1105void g_ril_unref(GRil *ril)
1106{
1107 gboolean is_zero;
1108
1109 if (ril == NULL)
1110 return;
1111
1112 is_zero = g_atomic_int_dec_and_test(&ril->ref_count);
1113
1114 if (is_zero == FALSE)
1115 return;
1116
1117 ril_unref(ril->parent);
1118
1119 g_free(ril);
1120}
1121
1122gboolean g_ril_set_debug(GRil *ril,
1123 GRilDebugFunc func, gpointer user_data)
1124{
1125
1126 if (ril == NULL || ril->group != 0)
1127 return FALSE;
1128
1129 return ril_set_debug(ril->parent, func, user_data);
1130}
1131
1132guint g_ril_register(GRil *ril, const int req,
1133 GRilNotifyFunc func, gpointer user_data)
1134{
1135 if (ril == NULL)
1136 return 0;
1137
1138 return ril_register(ril->parent, ril->group, req,
1139 func, user_data);
1140}
1141
1142gboolean g_ril_unregister(GRil *ril, guint id)
1143{
1144 if (ril == NULL)
1145 return FALSE;
1146
1147 return ril_unregister(ril->parent, ril->parent->in_notify,
1148 ril->group, id);
1149}
1150
1151gboolean g_ril_unregister_all(GRil *ril)
1152{
1153 if (ril == NULL)
1154 return FALSE;
1155
1156 return ril_unregister_all(ril->parent,
1157 ril->parent->in_notify,
1158 node_compare_by_group,
1159 GUINT_TO_POINTER(ril->group));
1160}
01161
=== added file 'gril/gril.h'
--- gril/gril.h 1970-01-01 00:00:00 +0000
+++ gril/gril.h 2013-04-09 20:01:20 +0000
@@ -0,0 +1,102 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef __GRIL_H
24#define __GRIL_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#include "grilresponse.h"
31#include "grilutil.h"
32#include "grilio.h"
33#include "ril_constants.h"
34
35struct _GRil;
36
37typedef struct _GRil GRil;
38
39/*
40 * This struct represents an entire RIL message read
41 * from the command socket. It can hold responses or
42 * unsolicited requests from RILD.
43 */
44struct ril_msg {
45 gchar *buf;
46 gsize buf_len;
47 gboolean unsolicited;
48 int req;
49 int serial_no;
50 int error;
51};
52
53typedef void (*GRilResponseFunc)(struct ril_msg *message, gpointer user_data);
54
55typedef void (*GRilNotifyFunc)(struct ril_msg *message, gpointer user_data);
56
57GRil *g_ril_new();
58
59GIOChannel *g_ril_get_channel(GRil *ril);
60GRilIO *g_ril_get_io(GRil *ril);
61
62GRil *g_ril_ref(GRil *ril);
63void g_ril_unref(GRil *ril);
64
65GRil *g_ril_clone(GRil *ril);
66
67void g_ril_suspend(GRil *ril);
68void g_ril_resume(GRil *ril);
69
70gboolean g_ril_set_disconnect_function(GRil *ril, GRilDisconnectFunc disconnect,
71 gpointer user_data);
72
73/*!
74 * If the function is not NULL, then on every read/write from the GIOChannel
75 * provided to GRil the logging function will be called with the
76 * input/output string and user data
77 */
78gboolean g_ril_set_debug(GRil *ril, GRilDebugFunc func, gpointer user_data);
79
80/*!
81 * Queue an RIL request for execution. The request contents are given
82 * in data. Once the command executes, the callback function given by
83 * func is called with user provided data in user_data.
84 *
85 * Returns an id of the queued command which can be canceled using
86 * g_ril_cancel. If an error occurred, an id of 0 is returned.
87 *
88 */
89guint g_ril_send(GRil *ril, const guint req, const char *data, const gsize data_len,
90 GRilResponseFunc func, gpointer user_data, GDestroyNotify notify);
91
92guint g_ril_register(GRil *ril, const int req,
93 GRilNotifyFunc func, gpointer user_data);
94
95gboolean g_ril_unregister(GRil *ril, guint id);
96gboolean g_ril_unregister_all(GRil *ril);
97
98#ifdef __cplusplus
99}
100#endif
101
102#endif /* __GRIL_H */
0103
=== added file 'gril/grilio.c'
--- gril/grilio.c 1970-01-01 00:00:00 +0000
+++ gril/grilio.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,396 @@
1/*
2 *
3 * RIL chat library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdio.h>
28#include <unistd.h>
29#include <string.h>
30#include <assert.h>
31#include <ctype.h>
32#include <errno.h>
33
34#include <glib.h>
35
36#include "ringbuffer.h"
37#include "grilio.h"
38#include "grilutil.h"
39
40struct _GRilIO {
41 gint ref_count; /* Ref count */
42 guint read_watch; /* GSource read id, 0 if no */
43 guint write_watch; /* GSource write id, 0 if no */
44 GIOChannel *channel; /* comms channel */
45 GRilDisconnectFunc user_disconnect; /* user disconnect func */
46 gpointer user_disconnect_data; /* user disconnect data */
47 struct ring_buffer *buf; /* Current read buffer */
48 guint max_read_attempts; /* max reads / select */
49 GRilIOReadFunc read_handler; /* Read callback */
50 gpointer read_data; /* Read callback userdata */
51 gboolean use_write_watch; /* Use write select */
52 GRilIOWriteFunc write_handler; /* Write callback */
53 gpointer write_data; /* Write callback userdata */
54 GRilDebugFunc debugf; /* debugging output function */
55 gpointer debug_data; /* Data to pass to debug func */
56 GRilDisconnectFunc write_done_func; /* tx empty notifier */
57 gpointer write_done_data; /* tx empty data */
58 gboolean destroyed; /* Re-entrancy guard */
59};
60
61static void read_watcher_destroy_notify(gpointer user_data)
62{
63 GRilIO *io = user_data;
64
65 ring_buffer_free(io->buf);
66 io->buf = NULL;
67
68 io->debugf = NULL;
69 io->debug_data = NULL;
70
71 io->read_watch = 0;
72 io->read_handler = NULL;
73 io->read_data = NULL;
74
75 io->channel = NULL;
76
77 if (io->destroyed)
78 g_free(io);
79 else if (io->user_disconnect)
80 io->user_disconnect(io->user_disconnect_data);
81}
82
83static gboolean received_data(GIOChannel *channel, GIOCondition cond,
84 gpointer data)
85{
86 unsigned char *buf;
87 GRilIO *io = data;
88 GIOStatus status;
89 gsize rbytes;
90 gsize toread;
91 gsize total_read = 0;
92 guint read_count = 0;
93
94 if (cond & G_IO_NVAL)
95 return FALSE;
96
97 /* Regardless of condition, try to read all the data available */
98 do {
99 toread = ring_buffer_avail_no_wrap(io->buf);
100
101 if (toread == 0)
102 break;
103
104 rbytes = 0;
105 buf = ring_buffer_write_ptr(io->buf, 0);
106
107 status = g_io_channel_read_chars(channel, (char *) buf,
108 toread, &rbytes, NULL);
109
110 g_ril_util_debug_hexdump(TRUE, (char *)buf, rbytes,
111 io->debugf, io->debug_data);
112
113 read_count++;
114
115 total_read += rbytes;
116
117 if (rbytes > 0)
118 ring_buffer_write_advance(io->buf, rbytes);
119
120 } while (status == G_IO_STATUS_NORMAL && rbytes > 0 &&
121 read_count < io->max_read_attempts);
122
123 if (total_read > 0 && io->read_handler)
124 io->read_handler(io->buf, io->read_data);
125
126 if (cond & (G_IO_HUP | G_IO_ERR))
127 return FALSE;
128
129 if (read_count > 0 && rbytes == 0 && status != G_IO_STATUS_AGAIN)
130 return FALSE;
131
132 /* We're overflowing the buffer, shutdown the socket */
133 if (ring_buffer_avail(io->buf) == 0)
134 return FALSE;
135
136 return TRUE;
137}
138
139gsize g_ril_io_write(GRilIO *io, const gchar *data, gsize count)
140{
141 GIOStatus status;
142 gsize bytes_written;
143
144 status = g_io_channel_write_chars(io->channel, data,
145 count, &bytes_written, NULL);
146
147 if (status != G_IO_STATUS_NORMAL) {
148 g_source_remove(io->read_watch);
149 return 0;
150 }
151
152 g_ril_util_debug_hexdump(FALSE, data, bytes_written,
153 io->debugf, io->debug_data);
154
155 return bytes_written;
156}
157
158static void write_watcher_destroy_notify(gpointer user_data)
159{
160 GRilIO *io = user_data;
161
162 io->write_watch = 0;
163 io->write_handler = NULL;
164 io->write_data = NULL;
165
166 if (io->write_done_func) {
167 io->write_done_func(io->write_done_data);
168 io->write_done_func = NULL;
169 io->write_done_data = NULL;
170 }
171}
172
173static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
174 gpointer data)
175{
176 GRilIO *io = data;
177
178 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
179 return FALSE;
180
181 if (io->write_handler == NULL)
182 return FALSE;
183
184 return io->write_handler(io->write_data);
185}
186
187static GRilIO *create_io(GIOChannel *channel, GIOFlags flags)
188{
189 GRilIO *io;
190
191 if (channel == NULL)
192 return NULL;
193
194 io = g_try_new0(GRilIO, 1);
195 if (io == NULL)
196 return io;
197
198 io->ref_count = 1;
199 io->debugf = NULL;
200
201 if (flags & G_IO_FLAG_NONBLOCK) {
202 io->max_read_attempts = 3;
203 io->use_write_watch = TRUE;
204 } else {
205 io->max_read_attempts = 1;
206 io->use_write_watch = FALSE;
207 }
208
209 io->buf = ring_buffer_new(8192);
210
211 if (!io->buf)
212 goto error;
213
214 if (!g_ril_util_setup_io(channel, flags))
215 goto error;
216
217 io->channel = channel;
218 io->read_watch = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
219 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
220 received_data, io,
221 read_watcher_destroy_notify);
222
223 return io;
224
225error:
226 if (io->buf)
227 ring_buffer_free(io->buf);
228
229 g_free(io);
230
231 return NULL;
232}
233
234GRilIO *g_ril_io_new(GIOChannel *channel)
235{
236 return create_io(channel, G_IO_FLAG_NONBLOCK);
237}
238
239GRilIO *g_ril_io_new_blocking(GIOChannel *channel)
240{
241 return create_io(channel, 0);
242}
243
244GIOChannel *g_ril_io_get_channel(GRilIO *io)
245{
246 if (io == NULL)
247 return NULL;
248
249 return io->channel;
250}
251
252gboolean g_ril_io_set_read_handler(GRilIO *io, GRilIOReadFunc read_handler,
253 gpointer user_data)
254{
255 if (io == NULL)
256 return FALSE;
257
258 io->read_handler = read_handler;
259 io->read_data = user_data;
260
261 if (read_handler && ring_buffer_len(io->buf) > 0)
262 read_handler(io->buf, user_data);
263
264 return TRUE;
265}
266
267static gboolean call_blocking_read(gpointer user_data)
268{
269 GRilIO *io = user_data;
270
271 while (can_write_data(io->channel, G_IO_OUT, io) == TRUE);
272 write_watcher_destroy_notify(io);
273
274 return FALSE;
275}
276
277gboolean g_ril_io_set_write_handler(GRilIO *io, GRilIOWriteFunc write_handler,
278 gpointer user_data)
279{
280 if (io == NULL)
281 return FALSE;
282
283 if (io->write_watch > 0) {
284 if (write_handler == NULL) {
285 g_source_remove(io->write_watch);
286 return TRUE;
287 }
288
289 return FALSE;
290 }
291
292 if (write_handler == NULL)
293 return FALSE;
294
295 io->write_handler = write_handler;
296 io->write_data = user_data;
297
298 if (io->use_write_watch == TRUE)
299 io->write_watch = g_io_add_watch_full(io->channel,
300 G_PRIORITY_HIGH,
301 G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
302 can_write_data, io,
303 write_watcher_destroy_notify);
304 else
305 io->write_watch = g_idle_add(call_blocking_read, io);
306
307 return TRUE;
308}
309
310GRilIO *g_ril_io_ref(GRilIO *io)
311{
312 if (io == NULL)
313 return NULL;
314
315 g_atomic_int_inc(&io->ref_count);
316
317 return io;
318}
319
320static gboolean io_shutdown(GRilIO *io)
321{
322 /* Don't trigger user disconnect on shutdown */
323 io->user_disconnect = NULL;
324 io->user_disconnect_data = NULL;
325
326 if (io->read_watch > 0)
327 g_source_remove(io->read_watch);
328
329 if (io->write_watch > 0)
330 g_source_remove(io->write_watch);
331
332 return TRUE;
333}
334
335void g_ril_io_unref(GRilIO *io)
336{
337 gboolean is_zero;
338
339 if (io == NULL)
340 return;
341
342 is_zero = g_atomic_int_dec_and_test(&io->ref_count);
343
344 if (is_zero == FALSE)
345 return;
346
347 io_shutdown(io);
348
349 /* glib delays the destruction of the watcher until it exits, this
350 * means we can't free the data just yet, even though we've been
351 * destroyed already. We have to wait until the read_watcher
352 * destroy function gets called
353 */
354 if (io->read_watch > 0)
355 io->destroyed = TRUE;
356 else
357 g_free(io);
358}
359
360gboolean g_ril_io_set_disconnect_function(GRilIO *io,
361 GRilDisconnectFunc disconnect, gpointer user_data)
362{
363 if (io == NULL)
364 return FALSE;
365
366 io->user_disconnect = disconnect;
367 io->user_disconnect_data = user_data;
368
369 return TRUE;
370}
371
372gboolean g_ril_io_set_debug(GRilIO *io, GRilDebugFunc func, gpointer user_data)
373{
374 if (io == NULL)
375 return FALSE;
376
377 io->debugf = func;
378 io->debug_data = user_data;
379
380 return TRUE;
381}
382
383void g_ril_io_set_write_done(GRilIO *io, GRilDisconnectFunc func,
384 gpointer user_data)
385{
386 if (io == NULL)
387 return;
388
389 io->write_done_func = func;
390 io->write_done_data = user_data;
391}
392
393void g_ril_io_drain_ring_buffer(GRilIO *io, guint len)
394{
395 ring_buffer_drain(io->buf, len);
396}
0397
=== added file 'gril/grilio.h'
--- gril/grilio.h 1970-01-01 00:00:00 +0000
+++ gril/grilio.h 2013-04-09 20:01:20 +0000
@@ -0,0 +1,69 @@
1/*
2 *
3 * RIL chat library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef __GRILIO_H
24#define __GRILIO_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#include "gfunc.h"
31
32struct _GRilIO;
33
34typedef struct _GRilIO GRilIO;
35
36struct ring_buffer;
37
38typedef void (*GRilIOReadFunc)(struct ring_buffer *buffer, gpointer user_data);
39typedef gboolean (*GRilIOWriteFunc)(gpointer user_data);
40
41GRilIO *g_ril_io_new(GIOChannel *channel);
42GRilIO *g_ril_io_new_blocking(GIOChannel *channel);
43
44GIOChannel *g_ril_io_get_channel(GRilIO *io);
45
46GRilIO *g_ril_io_ref(GRilIO *io);
47void g_ril_io_unref(GRilIO *io);
48
49gboolean g_ril_io_set_read_handler(GRilIO *io, GRilIOReadFunc read_handler,
50 gpointer user_data);
51gboolean g_ril_io_set_write_handler(GRilIO *io, GRilIOWriteFunc write_handler,
52 gpointer user_data);
53void g_ril_io_set_write_done(GRilIO *io, GRilDisconnectFunc func,
54 gpointer user_data);
55
56void g_ril_io_drain_ring_buffer(GRilIO *io, guint len);
57
58gsize g_ril_io_write(GRilIO *io, const gchar *data, gsize count);
59
60gboolean g_ril_io_set_disconnect_function(GRilIO *io,
61 GRilDisconnectFunc disconnect, gpointer user_data);
62
63gboolean g_ril_io_set_debug(GRilIO *io, GRilDebugFunc func, gpointer user_data);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif /* __GRILIO_H */
070
=== added file 'gril/grilresponse.h'
--- gril/grilresponse.h 1970-01-01 00:00:00 +0000
+++ gril/grilresponse.h 2013-04-09 20:01:20 +0000
@@ -0,0 +1,46 @@
1/*
2 *
3 * RIL chat library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef __GRIL_RESPONSE_H
24#define __GRIL_RESPONSE_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30struct _GRilResponse {
31 GSList *lines;
32 char *final_or_pdu;
33};
34
35typedef struct _GRilResponse GRilResponse;
36
37#define G_RIL_RESPONSE_LINE_LENGTH_MAX 2048
38
39const char *g_ril_final_response(GRilResponse *response);
40const char *g_ril_response_pdu(GRilResponse *response);
41
42#ifdef __cplusplus
43}
44#endif
45
46#endif /* __GRIL_RESPONSE_H */
047
=== added file 'gril/grilutil.c'
--- gril/grilutil.c 1970-01-01 00:00:00 +0000
+++ gril/grilutil.c 2013-04-09 20:01:20 +0000
@@ -0,0 +1,499 @@
1/*
2 *
3 * RIL library with GLib integration
4 *
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6 * Copyright (C) 2012 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdio.h>
28#include <ctype.h>
29#include <string.h>
30
31#include <glib.h>
32
33#include "grilutil.h"
34#include "ril_constants.h"
35
36const char *ril_appstate_to_string(int app_state)
37{
38 switch (app_state) {
39 case RIL_APPSTATE_UNKNOWN:
40 return "UNKNOWN";
41 case RIL_APPSTATE_DETECTED:
42 return "DETECTED";
43 case RIL_APPSTATE_PIN:
44 return "PIN";
45 case RIL_APPSTATE_PUK:
46 return "PUK";
47 case RIL_APPSTATE_SUBSCRIPTION_PERSO:
48 return "";
49 case RIL_APPSTATE_READY:
50 return "READY";
51 default:
52 return "<INVALID>";
53 }
54}
55
56const char *ril_apptype_to_string(int app_type)
57{
58
59 switch (app_type) {
60 case RIL_APPTYPE_UNKNOWN:
61 return "UNKNOWN";
62 case RIL_APPTYPE_SIM:
63 return "SIM";
64 case RIL_APPTYPE_USIM:
65 return "USIM";
66 case RIL_APPTYPE_RUIM:
67 return "RUIM";
68 case RIL_APPTYPE_CSIM:
69 return "CSIM";
70 case RIL_APPTYPE_ISIM:
71 return "ISIM";
72 default:
73 return "<INVALID>";
74 }
75}
76
77const char *ril_cardstate_to_string(int card_state)
78{
79 switch (card_state) {
80 case RIL_CARDSTATE_ABSENT:
81 return "ABSENT";
82 case RIL_CARDSTATE_PRESENT:
83 return "PRESENT";
84 case RIL_CARDSTATE_ERROR:
85 return "ERROR";
86 default:
87 return "<INVALID>";
88 }
89}
90
91const char *ril_pinstate_to_string(int pin_state)
92{
93 switch (pin_state) {
94 case RIL_PINSTATE_UNKNOWN:
95 return "UNKNOWN";
96 case RIL_PINSTATE_ENABLED_NOT_VERIFIED:
97 return "ENABLED_NOT_VERIFIED";
98 case RIL_PINSTATE_ENABLED_VERIFIED:
99 return "ENABLED_VERIFIED";
100 case RIL_PINSTATE_DISABLED:
101 return "DISABLED";
102 case RIL_PINSTATE_ENABLED_BLOCKED:
103 return "ENABLED_BLOCKED";
104 case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
105 return "ENABLED_PERM_BLOCKED";
106 default:
107 return "<INVALID>";
108 }
109}
110
111const char *ril_request_id_to_string(int req)
112{
113 switch (req) {
114 case RIL_REQUEST_GET_SIM_STATUS:
115 return "RIL_REQUEST_GET_SIM_STATUS";
116 case RIL_REQUEST_ENTER_SIM_PIN:
117 return "RIL_REQUEST_ENTER_SIM_PIN";
118 case RIL_REQUEST_ENTER_SIM_PUK:
119 return "RIL_REQUEST_ENTER_SIM_PUK";
120 case RIL_REQUEST_ENTER_SIM_PIN2:
121 return "RIL_REQUEST_ENTER_SIM_PIN2";
122 case RIL_REQUEST_ENTER_SIM_PUK2:
123 return "RIL_REQUEST_ENTER_SIM_PUK2";
124 case RIL_REQUEST_CHANGE_SIM_PIN:
125 return "RIL_REQUEST_CHANGE_SIM_PIN";
126 case RIL_REQUEST_CHANGE_SIM_PIN2:
127 return "RIL_REQUEST_CHANGE_SIM_PIN2";
128 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
129 return "RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION";
130 case RIL_REQUEST_GET_CURRENT_CALLS:
131 return "RIL_REQUEST_GET_CURRENT_CALLS";
132 case RIL_REQUEST_DIAL:
133 return "RIL_REQUEST_DIAL";
134 case RIL_REQUEST_GET_IMSI:
135 return "RIL_REQUEST_GET_IMSI";
136 case RIL_REQUEST_HANGUP:
137 return "RIL_REQUEST_HANGUP";
138 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
139 return "RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND";
140 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
141 return "RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND";
142 case RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE:
143 return "RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE";
144 case RIL_REQUEST_CONFERENCE:
145 return "RIL_REQUEST_CONFERENCE";
146 case RIL_REQUEST_UDUB:
147 return "RIL_REQUEST_UDUB";
148 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
149 return "RIL_REQUEST_LAST_CALL_FAIL_CAUSE";
150 case RIL_REQUEST_SIGNAL_STRENGTH:
151 return "RIL_REQUEST_SIGNAL_STRENGTH";
152 case RIL_REQUEST_VOICE_REGISTRATION_STATE:
153 return "RIL_REQUEST_VOICE_REGISTRATION_STATE";
154 case RIL_REQUEST_DATA_REGISTRATION_STATE:
155 return "RIL_REQUEST_DATA_REGISTRATION_STATE";
156 case RIL_REQUEST_OPERATOR:
157 return "RIL_REQUEST_OPERATOR";
158 case RIL_REQUEST_RADIO_POWER:
159 return "RIL_REQUEST_RADIO_POWER";
160 case RIL_REQUEST_DTMF:
161 return "RIL_REQUEST_DTMF";
162 case RIL_REQUEST_SEND_SMS:
163 return "RIL_REQUEST_SEND_SMS";
164 case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
165 return "RIL_REQUEST_SEND_SMS_EXPECT_MORE";
166 case RIL_REQUEST_SETUP_DATA_CALL:
167 return "RIL_REQUEST_SETUP_DATA_CALL";
168 case RIL_REQUEST_SIM_IO:
169 return "RIL_REQUEST_SIM_IO";
170 case RIL_REQUEST_SEND_USSD:
171 return "RIL_REQUEST_SEND_USSD";
172 case RIL_REQUEST_CANCEL_USSD:
173 return "RIL_REQUEST_CANCEL_USSD";
174 case RIL_REQUEST_GET_CLIR:
175 return "RIL_REQUEST_GET_CLIR";
176 case RIL_REQUEST_SET_CLIR:
177 return "RIL_REQUEST_SET_CLIR";
178 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
179 return "RIL_REQUEST_QUERY_CALL_FORWARD_STATUS";
180 case RIL_REQUEST_SET_CALL_FORWARD:
181 return "RIL_REQUEST_SET_CALL_FORWARD";
182 case RIL_REQUEST_QUERY_CALL_WAITING:
183 return "RIL_REQUEST_QUERY_CALL_WAITING";
184 case RIL_REQUEST_SET_CALL_WAITING:
185 return "RIL_REQUEST_SET_CALL_WAITING";
186 case RIL_REQUEST_SMS_ACKNOWLEDGE :
187 return "RIL_REQUEST_SMS_ACKNOWLEDGE ";
188 case RIL_REQUEST_GET_IMEI:
189 return "RIL_REQUEST_GET_IMEI";
190 case RIL_REQUEST_GET_IMEISV:
191 return "RIL_REQUEST_GET_IMEISV";
192 case RIL_REQUEST_ANSWER:
193 return "RIL_REQUEST_ANSWER";
194 case RIL_REQUEST_DEACTIVATE_DATA_CALL:
195 return "RIL_REQUEST_DEACTIVATE_DATA_CALL";
196 case RIL_REQUEST_QUERY_FACILITY_LOCK:
197 return "RIL_REQUEST_QUERY_FACILITY_LOCK";
198 case RIL_REQUEST_SET_FACILITY_LOCK:
199 return "RIL_REQUEST_SET_FACILITY_LOCK";
200 case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
201 return "RIL_REQUEST_CHANGE_BARRING_PASSWORD";
202 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
203 return "RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE";
204 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
205 return "RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC";
206 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
207 return "RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL";
208 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
209 return "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS";
210 case RIL_REQUEST_DTMF_START:
211 return "RIL_REQUEST_DTMF_START";
212 case RIL_REQUEST_DTMF_STOP:
213 return "RIL_REQUEST_DTMF_STOP";
214 case RIL_REQUEST_BASEBAND_VERSION:
215 return "RIL_REQUEST_BASEBAND_VERSION";
216 case RIL_REQUEST_SEPARATE_CONNECTION:
217 return "RIL_REQUEST_SEPARATE_CONNECTION";
218 case RIL_REQUEST_SET_MUTE:
219 return "RIL_REQUEST_SET_MUTE";
220 case RIL_REQUEST_GET_MUTE:
221 return "RIL_REQUEST_GET_MUTE";
222 case RIL_REQUEST_QUERY_CLIP:
223 return "RIL_REQUEST_QUERY_CLIP";
224 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
225 return "RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE";
226 case RIL_REQUEST_DATA_CALL_LIST:
227 return "RIL_REQUEST_DATA_CALL_LIST";
228 case RIL_REQUEST_RESET_RADIO:
229 return "RIL_REQUEST_RESET_RADIO";
230 case RIL_REQUEST_OEM_HOOK_RAW:
231 return "RIL_REQUEST_OEM_HOOK_RAW";
232 case RIL_REQUEST_OEM_HOOK_STRINGS:
233 return "RIL_REQUEST_OEM_HOOK_STRINGS";
234 case RIL_REQUEST_SCREEN_STATE:
235 return "RIL_REQUEST_SCREEN_STATE";
236 case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
237 return "RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION";
238 case RIL_REQUEST_WRITE_SMS_TO_SIM:
239 return "RIL_REQUEST_WRITE_SMS_TO_SIM";
240 case RIL_REQUEST_DELETE_SMS_ON_SIM:
241 return "RIL_REQUEST_DELETE_SMS_ON_SIM";
242 case RIL_REQUEST_SET_BAND_MODE:
243 return "RIL_REQUEST_SET_BAND_MODE";
244 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
245 return "RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE";
246 case RIL_REQUEST_STK_GET_PROFILE:
247 return "RIL_REQUEST_STK_GET_PROFILE";
248 case RIL_REQUEST_STK_SET_PROFILE:
249 return "RIL_REQUEST_STK_SET_PROFILE";
250 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
251 return "RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND";
252 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
253 return "RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE";
254 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
255 return "RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
256 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER:
257 return "RIL_REQUEST_EXPLICIT_CALL_TRANSFER";
258 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
259 return "RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE";
260 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
261 return "RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE";
262 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
263 return "RIL_REQUEST_GET_NEIGHBORING_CELL_IDS";
264 case RIL_REQUEST_SET_LOCATION_UPDATES:
265 return "RIL_REQUEST_SET_LOCATION_UPDATES";
266 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
267 return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
268 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
269 return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
270 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
271 return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
272 case RIL_REQUEST_SET_TTY_MODE:
273 return "RIL_REQUEST_SET_TTY_MODE";
274 case RIL_REQUEST_QUERY_TTY_MODE:
275 return "RIL_REQUEST_QUERY_TTY_MODE";
276 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
277 return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
278 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
279 return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
280 case RIL_REQUEST_CDMA_FLASH:
281 return "RIL_REQUEST_CDMA_FLASH";
282 case RIL_REQUEST_CDMA_BURST_DTMF:
283 return "RIL_REQUEST_CDMA_BURST_DTMF";
284 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY:
285 return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
286 case RIL_REQUEST_CDMA_SEND_SMS:
287 return "RIL_REQUEST_CDMA_SEND_SMS";
288 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:
289 return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
290 case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:
291 return "RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG";
292 case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:
293 return "RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG";
294 case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION:
295 return "RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION";
296 case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:
297 return "RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG";
298 case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:
299 return "RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG";
300 case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:
301 return "RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION";
302 case RIL_REQUEST_CDMA_SUBSCRIPTION:
303 return "RIL_REQUEST_CDMA_SUBSCRIPTION";
304 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM:
305 return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
306 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM:
307 return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
308 case RIL_REQUEST_DEVICE_IDENTITY:
309 return "RIL_REQUEST_DEVICE_IDENTITY";
310 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
311 return "RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
312 case RIL_REQUEST_GET_SMSC_ADDRESS:
313 return "RIL_REQUEST_GET_SMSC_ADDRESS";
314 case RIL_REQUEST_SET_SMSC_ADDRESS:
315 return "RIL_REQUEST_SET_SMSC_ADDRESS";
316 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
317 return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
318 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
319 return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
320 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
321 return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
322 case RIL_REQUEST_ISIM_AUTHENTICATION:
323 return "RIL_REQUEST_ISIM_AUTHENTICATION";
324 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU:
325 return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
326 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS:
327 return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
328 default:
329 return "<INVALID>";
330 }
331}
332
333void g_ril_util_debug_chat(gboolean in, const char *str, gsize len,
334 GRilDebugFunc debugf, gpointer user_data)
335{
336 char type = in ? '<' : '>';
337 gsize escaped = 2; /* Enough for '<', ' ' */
338 char *escaped_str;
339 const char *esc = "<ESC>";
340 gsize esc_size = strlen(esc);
341 const char *ctrlz = "<CtrlZ>";
342 gsize ctrlz_size = strlen(ctrlz);
343 gsize i;
344
345 if (debugf == NULL || !len)
346 return;
347
348 for (i = 0; i < len; i++) {
349 char c = str[i];
350
351 if (g_ascii_isprint(c))
352 escaped += 1;
353 else if (c == '\r' || c == '\t' || c == '\n')
354 escaped += 2;
355 else if (c == 26)
356 escaped += ctrlz_size;
357 else if (c == 25)
358 escaped += esc_size;
359 else
360 escaped += 4;
361 }
362
363 escaped_str = g_try_malloc(escaped + 1);
364 if (escaped_str == NULL)
365 return;
366
367 escaped_str[0] = type;
368 escaped_str[1] = ' ';
369 escaped_str[2] = '\0';
370 escaped_str[escaped] = '\0';
371
372 for (escaped = 2, i = 0; i < len; i++) {
373 unsigned char c = str[i];
374
375 switch (c) {
376 case '\r':
377 escaped_str[escaped++] = '\\';
378 escaped_str[escaped++] = 'r';
379 break;
380 case '\t':
381 escaped_str[escaped++] = '\\';
382 escaped_str[escaped++] = 't';
383 break;
384 case '\n':
385 escaped_str[escaped++] = '\\';
386 escaped_str[escaped++] = 'n';
387 break;
388 case 26:
389 strncpy(&escaped_str[escaped], ctrlz, ctrlz_size);
390 escaped += ctrlz_size;
391 break;
392 case 25:
393 strncpy(&escaped_str[escaped], esc, esc_size);
394 escaped += esc_size;
395 break;
396 default:
397 if (g_ascii_isprint(c))
398 escaped_str[escaped++] = c;
399 else {
400 escaped_str[escaped++] = '\\';
401 escaped_str[escaped++] = '0' + ((c >> 6) & 07);
402 escaped_str[escaped++] = '0' + ((c >> 3) & 07);
403 escaped_str[escaped++] = '0' + (c & 07);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches