Merge lp:~phablet-team/ofono/pro5-support-and-more into lp:~phablet-team/ofono/ubuntu

Proposed by Alfonso Sanchez-Beato
Status: Merged
Approved by: Tony Espy
Approved revision: 6913
Merged at revision: 6912
Proposed branch: lp:~phablet-team/ofono/pro5-support-and-more
Merge into: lp:~phablet-team/ofono/ubuntu
Diff against target: 5052 lines (+2710/-971)
35 files modified
.gitignore (+3/-0)
Makefile.am (+39/-8)
configure.ac (+11/-0)
debian/changelog (+23/-0)
debian/control (+2/-1)
drivers/qcommsimmodem/radio-settings.c (+60/-45)
drivers/rilmodem/call-barring.c (+2/-2)
drivers/rilmodem/sim.c (+6/-0)
drivers/rilmodem/sms.c (+6/-8)
gril/gril.c (+20/-0)
gril/gril.h (+3/-0)
gril/grilreply.c (+11/-3)
gril/grilunsol.c (+24/-0)
gril/grilunsol.h (+2/-0)
gril/ril_constants.h (+2/-1)
include/log.h (+2/-0)
include/system-settings.h (+51/-0)
include/wakelock.h (+0/-100)
plugins/accounts-settings.c (+474/-0)
plugins/android-wakelock.c (+0/-212)
plugins/qcom-msim.c (+12/-0)
plugins/ril.c (+36/-27)
plugins/rildev.c (+10/-0)
plugins/upower.c (+36/-144)
src/emulator.c (+29/-11)
src/system-settings.c (+74/-0)
src/voicecall.c (+5/-3)
src/wakelock.c (+0/-151)
unit/rilmodem-test-server.c (+237/-0)
unit/rilmodem-test-server.h (+47/-0)
unit/test-grilreply.c (+2/-2)
unit/test-grilunsol.c (+157/-0)
unit/test-rilmodem-cb.c (+605/-0)
unit/test-rilmodem-cs.c (+123/-253)
unit/test-rilmodem-sms.c (+596/-0)
To merge this branch: bzr merge lp:~phablet-team/ofono/pro5-support-and-more
Reviewer Review Type Date Requested Status
Tony Espy Approve
Review via email: mp+288897@code.launchpad.net

Commit message

[ Tony Espy ]
* unit: new rilmodem tests for sms and call barring
* plugins: address upower plugin upstream comments
* unit: fix test-grilreply set_facility_lock test
* style fixes for wakelock support

[ Ratchanan Srirattanamet ]
* qcommsimmodem: fix setting 3G pref when one of the slots is empty

[ Alfonso Sanchez-Beato ]
* ril: set properly gril vendor
* support for system settings
* unit: make unit tests parallelizable

[ Vicamo Yang ]
* ril, gril: support for pro 5
* gril, rilmodem: set RIL version from CONNECTED event
* unit: fix warning

Description of the change

[ Tony Espy ]
* unit: new rilmodem tests for sms and call barring
* plugins: address upower plugin upstream comments
* unit: fix test-grilreply set_facility_lock test
* style fixes for wakelock support

[ Ratchanan Srirattanamet ]
* qcommsimmodem: fix setting 3G pref when one of the slots is empty

[ Alfonso Sanchez-Beato ]
* ril: set properly gril vendor
* support for system settings
* unit: make unit tests parallelizable

[ Vicamo Yang ]
* ril, gril: support for pro 5
* gril, rilmodem: set RIL version from CONNECTED event
* unit: fix warning

To post a comment you must log in.
6913. By Alfonso Sanchez-Beato

Add libsystemd dependency

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Basic tests performed on krillin, rc-proposed/bq-aquaris.en #279, all looked good.

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

Looks good to me...

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.gitignore'
2--- .gitignore 2015-07-31 12:46:34 +0000
3+++ .gitignore 2016-03-14 09:03:03 +0000
4@@ -52,6 +52,9 @@
5 unit/test-mtkreply
6 unit/test-mtkrequest
7 unit/test-mtkunsol
8+unit/test-rilmodem-cs
9+unit/test-rilmodem-sms
10+unit/test-rilmodem-cb
11 unit/test-*.log
12 unit/test-*.trs
13
14
15=== modified file 'Makefile.am'
16--- Makefile.am 2016-01-15 16:03:09 +0000
17+++ Makefile.am 2016-03-14 09:03:03 +0000
18@@ -23,7 +23,8 @@
19 include/cdma-provision.h include/handsfree.h \
20 include/handsfree-audio.h include/siri.h \
21 include/sim-mnclength.h include/spn-table.h \
22- include/dns-client.h include/wakelock.h
23+ include/dns-client.h include/wakelock.h \
24+ include/system-settings.h
25
26 nodist_pkginclude_HEADERS = include/version.h
27
28@@ -621,6 +622,14 @@
29 builtin_sources += plugins/android-wakelock.c
30 endif
31
32+if ACCOUNTSSETTINGS
33+builtin_modules += accounts_settings
34+builtin_sources += plugins/accounts-settings.c
35+
36+builtin_cflags += @SYSTEMD_CFLAGS@
37+builtin_libadd += @SYSTEMD_LIBS@
38+endif
39+
40 sbin_PROGRAMS = src/ofonod
41
42 src_ofonod_SOURCES = $(builtin_sources) src/ofono.ver \
43@@ -650,7 +659,8 @@
44 src/handsfree-audio.c src/bluetooth.h \
45 src/hfp.h src/siri.c \
46 src/sim-mnclength.c src/spn-table.c \
47- src/dns-client.c src/wakelock.c
48+ src/dns-client.c src/wakelock.c \
49+ src/system-settings.c
50
51 src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
52 @GLIB_LIBS@ @DBUS_LIBS@ -ldl
53@@ -817,7 +827,9 @@
54 unit/test-mtkrequest \
55 unit/test-mtkreply \
56 unit/test-mtkunsol \
57- unit/test-rilmodem-cs
58+ unit/test-rilmodem-cs \
59+ unit/test-rilmodem-sms \
60+ unit/test-rilmodem-cb
61
62 noinst_PROGRAMS = $(unit_tests) \
63 unit/test-sms-root unit/test-mux unit/test-caif
64@@ -913,14 +925,33 @@
65 unit_test_mnclength_LDADD = @GLIB_LIBS@ -ldl
66 unit_objects += $(unit_test_mnclength_OBJECTS)
67
68-unit_test_rilmodem_cs_SOURCES = unit/test-rilmodem-cs.c $(gril_sources) \
69- src/log.c src/common.c src/util.c \
70- drivers/rilmodem/call-settings.c \
71- src/simutil.c gatchat/ringbuffer.c
72+test_rilmodem_sources = $(gril_sources) src/log.c src/common.c src/util.c \
73+ gatchat/ringbuffer.h gatchat/ringbuffer.c \
74+ unit/rilmodem-test-server.h \
75+ unit/rilmodem-test-server.c \
76+ src/simutil.c
77+
78+unit_test_rilmodem_cs_SOURCES = $(test_rilmodem_sources) \
79+ unit/test-rilmodem-cs.c \
80+ drivers/rilmodem/call-settings.c
81 unit_test_rilmodem_cs_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
82- @GLIB_LIBS@ @DBUS_LIBS@ -ldl
83+ @GLIB_LIBS@ @DBUS_LIBS@ -ldl
84 unit_objects += $(unit_test_rilmodem_cs_OBJECTS)
85
86+unit_test_rilmodem_sms_SOURCES = $(test_rilmodem_sources) \
87+ unit/test-rilmodem-sms.c \
88+ drivers/rilmodem/sms.c
89+unit_test_rilmodem_sms_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
90+ @GLIB_LIBS@ @DBUS_LIBS@ -ldl
91+unit_objects += $(unit_test_rilmodem_sms_OBJECTS)
92+
93+unit_test_rilmodem_cb_SOURCES = $(test_rilmodem_sources) \
94+ unit/test-rilmodem-cb.c \
95+ drivers/rilmodem/call-barring.c
96+unit_test_rilmodem_cb_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
97+ @GLIB_LIBS@ @DBUS_LIBS@ -ldl
98+unit_objects += $(unit_test_rilmodem_cb_OBJECTS)
99+
100 TESTS = $(unit_tests)
101
102 if TOOLS
103
104=== modified file 'configure.ac'
105--- configure.ac 2016-01-15 16:03:09 +0000
106+++ configure.ac 2016-03-14 09:03:03 +0000
107@@ -200,6 +200,17 @@
108 AC_SUBST(CARES_LIBS)
109 AM_CONDITIONAL(CARES, test "${enable_cares}" != "no")
110
111+AC_ARG_ENABLE(accounts-settings, AC_HELP_STRING([--disable-accounts-settings],
112+ [disable using accounts service for system settings]),
113+ [enable_accounts_settings=${enableval}])
114+if (test "${enable_accounts_settings=$}" != "no"); then
115+ PKG_CHECK_MODULES(SYSTEMD, libsystemd, dummy=yes,
116+ AC_MSG_ERROR(libsystemd is required))
117+fi
118+AC_SUBST(SYSTEMD_CFLAGS)
119+AC_SUBST(SYSTEMD_LIBS)
120+AM_CONDITIONAL(ACCOUNTSSETTINGS, test "${enable_accounts_settings=$}" != "no")
121+
122 AC_ARG_ENABLE(nettime, AC_HELP_STRING([--disable-nettime],
123 [disable Nettime plugin]),
124 [enable_nettime=${enableval}])
125
126=== modified file 'debian/changelog'
127--- debian/changelog 2016-01-15 17:37:10 +0000
128+++ debian/changelog 2016-03-14 09:03:03 +0000
129@@ -1,3 +1,26 @@
130+ofono (1.17.bzr6912+16.04.20160314.1-0ubuntu1) UNRELEASED; urgency=medium
131+
132+ [ Tony Espy ]
133+ * unit: new rilmodem tests for sms and call barring
134+ * plugins: address upower plugin upstream comments
135+ * unit: fix test-grilreply set_facility_lock test
136+ * style fixes for wakelock support
137+
138+ [ Ratchanan Srirattanamet ]
139+ * qcommsimmodem: fix setting 3G pref when one of the slots is empty
140+
141+ [ Alfonso Sanchez-Beato ]
142+ * ril: set properly gril vendor
143+ * support for system settings
144+ * unit: make tests parallelizable
145+
146+ [ Vicamo Yang ]
147+ * ril, gril: support for pro 5
148+ * gril, rilmodem: set RIL version from CONNECTED event
149+ * unit: fix warning
150+
151+ -- Alfonso Sanchez-Beato (email Canonical) <alfonso.sanchez-beato@canonical.com> Mon, 14 Mar 2016 09:07:47 +0100
152+
153 ofono (1.17.bzr6910+16.04.20160115.3-0ubuntu1) xenial; urgency=medium
154
155 [ Simon Fels ]
156
157=== modified file 'debian/control'
158--- debian/control 2015-07-01 07:00:40 +0000
159+++ debian/control 2016-03-14 09:03:03 +0000
160@@ -14,7 +14,8 @@
161 udev,
162 libbluetooth-dev (>= 4.30),
163 mobile-broadband-provider-info,
164- libc-ares-dev
165+ libc-ares-dev,
166+ libsystemd-dev
167 Standards-Version: 3.9.4
168 Homepage: http://www.ofono.org/
169 # If you aren't a member of ~phablet-team but need to upload
170
171=== modified file 'drivers/qcommsimmodem/radio-settings.c'
172--- drivers/qcommsimmodem/radio-settings.c 2015-07-31 13:44:26 +0000
173+++ drivers/qcommsimmodem/radio-settings.c 2016-03-14 09:03:03 +0000
174@@ -31,10 +31,12 @@
175 #include <errno.h>
176
177 #include <glib.h>
178+#include <ofono.h>
179
180 #include <ofono/log.h>
181 #include <ofono/modem.h>
182 #include <ofono/radio-settings.h>
183+#include <ofono/sim.h>
184
185 #include "gril.h"
186 #include "grilrequest.h"
187@@ -58,7 +60,6 @@
188 };
189
190 static struct ofono_radio_settings *multisim_rs[QCOMMSIM_NUM_SLOTS_MAX];
191-static int multisim_num_slots;
192
193 static void qcom_msim_set_rat_cb(struct ril_msg *message, gpointer user_data)
194 {
195@@ -76,6 +77,24 @@
196 }
197 }
198
199+static void qcom_msim_do_set_rat_mode(struct ofono_radio_settings *rs, int pref,
200+ struct cb_data *cbd)
201+{
202+ struct radio_data *rd = ofono_radio_settings_get_data(rs);
203+ struct parcel rilp;
204+ ofono_radio_settings_rat_mode_set_cb_t cb;
205+
206+ g_ril_request_set_preferred_network_type(rd->ril, pref, &rilp);
207+
208+ if (g_ril_send(rd->ril, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE,
209+ &rilp, qcom_msim_set_rat_cb, cbd, g_free) == 0) {
210+ ofono_error("%s: unable to set rat mode", __func__);
211+ cb = cbd->cb;
212+ CALLBACK_WITH_FAILURE(cb, cbd->data);
213+ g_free(cbd);
214+ }
215+}
216+
217 static void qcom_msim_set_2g_rat_cb(struct ril_msg *message,
218 gpointer user_data)
219 {
220@@ -84,7 +103,6 @@
221 struct qcom_msim_pending_pref_setting *pps = set_2g_rat_data->pps;
222 struct radio_data *rd = ofono_radio_settings_get_data(rs);
223 ofono_radio_settings_rat_mode_set_cb_t cb;
224- struct parcel rilp;
225
226 pps->pending_gsm_pref_remaining -= 1;
227
228@@ -104,23 +122,8 @@
229 }
230
231 if (pps->pending_gsm_pref_remaining == 0) {
232- if (pps->cbd != NULL) {
233- struct radio_data *pps_rd =
234- ofono_radio_settings_get_data(pps->rs);
235- g_ril_request_set_preferred_network_type(pps_rd->ril,
236- pps->pref, &rilp);
237-
238- if (g_ril_send(pps_rd->ril,
239- RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE,
240- &rilp, qcom_msim_set_rat_cb, pps->cbd,
241- g_free) == 0) {
242- ofono_error("%s: unable to set rat mode",
243- __func__);
244- cb = pps->cbd->cb;
245- CALLBACK_WITH_FAILURE(cb, pps->cbd->data);
246- g_free(pps->cbd);
247- }
248- }
249+ if (pps->cbd != NULL)
250+ qcom_msim_do_set_rat_mode(pps->rs, pps->pref, pps->cbd);
251
252 g_free(pps);
253 }
254@@ -131,10 +134,10 @@
255 ofono_radio_settings_rat_mode_set_cb_t cb,
256 void *data)
257 {
258- struct radio_data *rd = ofono_radio_settings_get_data(rs);
259 struct cb_data *cbd = cb_data_new(cb, data, rs);
260 struct parcel rilp;
261 int pref = PREF_NET_TYPE_GSM_WCDMA;
262+ struct qcom_msim_pending_pref_setting *pps = NULL;
263
264 switch (mode) {
265 case OFONO_RADIO_ACCESS_MODE_ANY:
266@@ -151,24 +154,43 @@
267 break;
268 }
269
270- if (pref != PREF_NET_TYPE_GSM_ONLY && multisim_num_slots > 1) {
271- struct qcom_msim_pending_pref_setting *pps =
272- g_try_new0(struct qcom_msim_pending_pref_setting, 1);
273+ if (pref != PREF_NET_TYPE_GSM_ONLY) {
274 int i;
275-
276- pps->rs = rs;
277- pps->pref = pref;
278- pps->cbd = cbd;
279- pps->pending_gsm_pref_remaining = 0;
280-
281 for (i = 0; i < QCOMMSIM_NUM_SLOTS_MAX; i++) {
282 struct radio_data *temp_rd;
283 struct qcom_msim_set_2g_rat *set_2g_rat_data;
284+ struct ofono_atom *sim_atom;
285+ struct ofono_sim *sim;
286
287 if (multisim_rs[i] == rs || multisim_rs[i] == NULL)
288 continue;
289
290 temp_rd = ofono_radio_settings_get_data(multisim_rs[i]);
291+ sim_atom = __ofono_modem_find_atom(temp_rd->modem,
292+ OFONO_ATOM_TYPE_SIM);
293+ if (sim_atom == NULL) {
294+ if (pps != NULL)
295+ pps->cbd = NULL;
296+ g_free(cbd);
297+ CALLBACK_WITH_FAILURE(cb, data);
298+ break;
299+ }
300+
301+ sim = __ofono_atom_get_data(sim_atom);
302+ if (ofono_sim_get_state(sim) ==
303+ OFONO_SIM_STATE_NOT_PRESENT)
304+ continue;
305+
306+ if (pps == NULL) {
307+ pps = g_try_new0(
308+ struct qcom_msim_pending_pref_setting,
309+ 1);
310+ pps->rs = rs;
311+ pps->pref = pref;
312+ pps->cbd = cbd;
313+ pps->pending_gsm_pref_remaining = 0;
314+ }
315+
316 set_2g_rat_data =
317 g_try_new0(struct qcom_msim_set_2g_rat, 1);
318 set_2g_rat_data->pps = pps;
319@@ -192,20 +214,15 @@
320 pps->pending_gsm_pref_remaining += 1;
321 }
322 }
323-
324- if (pps->pending_gsm_pref_remaining == 0)
325- g_free(pps);
326- } else {
327- g_ril_request_set_preferred_network_type(rd->ril, pref, &rilp);
328-
329- if (g_ril_send(rd->ril, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE,
330- &rilp, qcom_msim_set_rat_cb, cbd,
331- g_free) == 0) {
332- ofono_error("%s: unable to set rat mode", __func__);
333- g_free(cbd);
334- CALLBACK_WITH_FAILURE(cb, data);
335- }
336- }
337+ }
338+
339+ if (pps && pps->pending_gsm_pref_remaining == 0) {
340+ g_free(pps);
341+ pps = NULL;
342+ }
343+
344+ if (pps == NULL)
345+ qcom_msim_do_set_rat_mode(rs, pref, cbd);
346 }
347
348 static int qcom_msim_radio_settings_probe(struct ofono_radio_settings *rs,
349@@ -229,7 +246,6 @@
350
351 slot_id = ofono_modem_get_integer(rsd->modem, "Slot");
352 multisim_rs[slot_id] = rs;
353- multisim_num_slots += 1;
354
355 return 0;
356 }
357@@ -240,7 +256,6 @@
358 int slot_id = ofono_modem_get_integer(rd->modem, "Slot");
359
360 multisim_rs[slot_id] = NULL;
361- multisim_num_slots -= 1;
362
363 ofono_radio_settings_set_data(rs, NULL);
364
365
366=== modified file 'drivers/rilmodem/call-barring.c'
367--- drivers/rilmodem/call-barring.c 2014-04-21 07:56:17 +0000
368+++ drivers/rilmodem/call-barring.c 2016-03-14 09:03:03 +0000
369@@ -105,8 +105,8 @@
370 goto error;
371 }
372
373- /* Just for printing return value */
374- g_ril_reply_parse_set_facility_lock(bd->ril, message);
375+ if (g_ril_reply_parse_set_facility_lock(bd->ril, message) < 0)
376+ goto error;
377
378 CALLBACK_WITH_SUCCESS(cb, cbd->data);
379 return;
380
381=== modified file 'drivers/rilmodem/sim.c'
382--- drivers/rilmodem/sim.c 2015-10-07 07:14:11 +0000
383+++ drivers/rilmodem/sim.c 2016-03-14 09:03:03 +0000
384@@ -733,6 +733,12 @@
385 struct reply_sim_status *status;
386 guint search_index;
387
388+ if (message->error != RIL_E_SUCCESS) {
389+ ofono_error("%s: RIL error %s", __func__,
390+ ril_error_to_string(message->error));
391+ return;
392+ }
393+
394 status = g_ril_reply_parse_sim_status(sd->ril, message);
395 if (status == NULL) {
396 ofono_error("%s: Cannot parse SIM status reply", __func__);
397
398=== modified file 'drivers/rilmodem/sms.c'
399--- drivers/rilmodem/sms.c 2014-04-15 23:42:56 +0000
400+++ drivers/rilmodem/sms.c 2016-03-14 09:03:03 +0000
401@@ -127,19 +127,17 @@
402 static void ril_submit_sms_cb(struct ril_msg *message, gpointer user_data)
403 {
404 struct cb_data *cbd = user_data;
405- struct ofono_error error;
406 ofono_sms_submit_cb_t cb = cbd->cb;
407 struct sms_data *sd = cbd->user;
408- int mr = 0;
409+ int mr;
410
411- if (message->error == RIL_E_SUCCESS) {
412- decode_ril_error(&error, "OK");
413- mr = g_ril_reply_parse_sms_response(sd->ril, message);
414- } else {
415- decode_ril_error(&error, "FAIL");
416+ if (message->error != RIL_E_SUCCESS) {
417+ CALLBACK_WITH_FAILURE(cb, 0, cbd->data);
418+ return;
419 }
420
421- cb(&error, mr, cbd->data);
422+ mr = g_ril_reply_parse_sms_response(sd->ril, message);
423+ CALLBACK_WITH_SUCCESS(cb, mr, cbd->data);
424 }
425
426 static void ril_cmgs(struct ofono_sms *sms, const unsigned char *pdu,
427
428=== modified file 'gril/gril.c'
429--- gril/gril.c 2015-11-10 09:17:36 +0000
430+++ gril/gril.c 2016-03-14 09:03:03 +0000
431@@ -104,6 +104,7 @@
432 int slot;
433 GRilMsgIdToStrFunc req_to_string;
434 GRilMsgIdToStrFunc unsol_to_string;
435+ int version;
436 };
437
438 struct _GRil {
439@@ -1066,6 +1067,7 @@
440 ril->ref_count = 1;
441
442 ril->parent->vendor = vendor;
443+ ril->parent->version = RIL_VERSION_UNSPECIFIED;
444
445 return ril;
446 }
447@@ -1207,6 +1209,24 @@
448 return ril->parent->slot;
449 }
450
451+gboolean g_ril_set_version(GRil *ril, int version)
452+{
453+ if (ril == NULL || ril->parent == NULL ||
454+ ril->parent->version != RIL_VERSION_UNSPECIFIED)
455+ return FALSE;
456+
457+ ril->parent->version = version;
458+ return TRUE;
459+}
460+
461+int g_ril_get_version(GRil *ril)
462+{
463+ if (ril == NULL)
464+ return RIL_VERSION_UNSPECIFIED;
465+
466+ return ril->parent->version;
467+}
468+
469 gboolean g_ril_set_debugf(GRil *ril,
470 GRilDebugFunc func, gpointer user_data)
471 {
472
473=== modified file 'gril/gril.h'
474--- gril/gril.h 2014-07-31 06:45:32 +0000
475+++ gril/gril.h 2016-03-14 09:03:03 +0000
476@@ -129,6 +129,9 @@
477 int g_ril_get_slot(GRil *ril);
478 gboolean g_ril_set_slot(GRil *ril, int slot);
479
480+int g_ril_get_version(GRil *ril);
481+gboolean g_ril_set_version(GRil *ril, int version);
482+
483 /*!
484 * If the function is not NULL, then on every read/write from the GIOChannel
485 * provided to GRil the logging function will be called with the
486
487=== modified file 'gril/grilreply.c'
488--- gril/grilreply.c 2015-10-23 07:09:51 +0000
489+++ gril/grilreply.c 2016-03-14 09:03:03 +0000
490@@ -1258,8 +1258,10 @@
491 g_ril_init_parcel(message, &rilp);
492
493 /* mako reply has no payload for call barring */
494- if (parcel_data_avail(&rilp) == 0)
495- goto end;
496+ if (parcel_data_avail(&rilp) == 0) {
497+ retries = 0;
498+ goto done;
499+ }
500
501 numint = parcel_r_int32(&rilp);
502 if (numint != 1) {
503@@ -1271,13 +1273,19 @@
504
505 if (rilp.malformed) {
506 ofono_error("%s: malformed parcel", __func__);
507+ retries = -1;
508 goto end;
509 }
510
511-end:
512+done:
513 g_ril_append_print_buf(gril, "{%d}", retries);
514 g_ril_print_response(gril, message);
515
516+ /* -1 indicates unknown; reset to 0 so as to not trigger failure */
517+ if (retries == -1)
518+ retries = 0;
519+
520+end:
521 return retries;
522 }
523
524
525=== modified file 'gril/grilunsol.c'
526--- gril/grilunsol.c 2015-09-29 08:47:19 +0000
527+++ gril/grilunsol.c 2016-03-14 09:03:03 +0000
528@@ -48,6 +48,30 @@
529 */
530 #define MIN_NITZ_SIZE 17
531
532+int g_ril_unsol_parse_connected(GRil *gril, const struct ril_msg *message)
533+{
534+ struct parcel rilp;
535+ int size;
536+ int version;
537+
538+ DBG("");
539+
540+ g_ril_init_parcel(message, &rilp);
541+
542+ size = parcel_r_int32(&rilp);
543+ version = parcel_r_int32(&rilp);
544+
545+ if (rilp.malformed) {
546+ ofono_error("%s: malformed parcel", __func__);
547+ version = RIL_VERSION_UNSPECIFIED;
548+ }
549+
550+ g_ril_append_print_buf(gril, "{size:%d, [%d, ...]}", size, version);
551+ g_ril_print_unsol(gril, message);
552+
553+ return version;
554+}
555+
556 static gint data_call_compare(gconstpointer a, gconstpointer b)
557 {
558 const struct ril_data_call *ca = a;
559
560=== modified file 'gril/grilunsol.h'
561--- gril/grilunsol.h 2014-08-11 12:41:11 +0000
562+++ gril/grilunsol.h 2016-03-14 09:03:03 +0000
563@@ -64,6 +64,8 @@
564 char *message;
565 };
566
567+int g_ril_unsol_parse_connected(GRil *gril, const struct ril_msg *message);
568+
569 void g_ril_unsol_free_data_call_list(struct ril_data_call_list *data_call_list);
570
571
572
573=== modified file 'gril/ril_constants.h'
574--- gril/ril_constants.h 2015-02-18 13:54:39 +0000
575+++ gril/ril_constants.h 2016-03-14 09:03:03 +0000
576@@ -23,7 +23,8 @@
577
578 #ifndef __RIL_CONSTANTS_H
579 #define __RIL_CONSTANTS_H 1
580-#define RIL_VERSION 7
581+
582+#define RIL_VERSION_UNSPECIFIED 0
583
584 /* Error Codes */
585 #define RIL_E_SUCCESS 0
586
587=== modified file 'include/log.h'
588--- include/log.h 2011-10-10 20:39:42 +0000
589+++ include/log.h 2016-03-14 09:03:03 +0000
590@@ -67,6 +67,8 @@
591 __FILE__, __FUNCTION__ , ## arg); \
592 } while (0)
593
594+#define PRINTABLE_STR(s) ((s) ? (s) : "(null)")
595+
596 #ifdef __cplusplus
597 }
598 #endif
599
600=== added file 'include/system-settings.h'
601--- include/system-settings.h 1970-01-01 00:00:00 +0000
602+++ include/system-settings.h 2016-03-14 09:03:03 +0000
603@@ -0,0 +1,51 @@
604+/*
605+ *
606+ * oFono - Open Telephony stack for Linux
607+ *
608+ * Copyright (C) 2016 Canonical Ltd.
609+ *
610+ * This program is free software; you can redistribute it and/or modify
611+ * it under the terms of the GNU General Public License version 2 as
612+ * published by the Free Software Foundation.
613+ *
614+ * This program is distributed in the hope that it will be useful,
615+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
617+ * GNU General Public License for more details.
618+ *
619+ * You should have received a copy of the GNU General Public License
620+ * along with this program; if not, write to the Free Software
621+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
622+ *
623+ */
624+
625+#ifndef OFONO_SYSTEM_SETTINGS_H
626+#define OFONO_SYSTEM_SETTINGS_H
627+
628+#ifdef __cplusplus
629+extern "C" {
630+#endif
631+
632+/* Settings names */
633+#define PREFERRED_VOICE_MODEM "PreferredVoiceModem"
634+
635+struct ofono_system_settings_driver {
636+ const char *name;
637+ /* The user must free the returned string */
638+ char *(*get_string_value)(const char *name);
639+};
640+
641+/* The user must free the returned string */
642+char *__ofono_system_settings_get_string_value(const char *name);
643+
644+int ofono_system_settings_driver_register(
645+ struct ofono_system_settings_driver *driver);
646+
647+void ofono_system_settings_driver_unregister(
648+ const struct ofono_system_settings_driver *driver);
649+
650+#ifdef __cplusplus
651+}
652+#endif
653+
654+#endif /* OFONO_SYSTEM_SETTINGS_H */
655
656=== added file 'include/wakelock.h'
657--- include/wakelock.h 1970-01-01 00:00:00 +0000
658+++ include/wakelock.h 2016-03-14 09:03:03 +0000
659@@ -0,0 +1,100 @@
660+/*
661+ *
662+ * oFono - Open Source Telephony
663+ *
664+ * Copyright (C) 2015 Jolla Ltd. All rights reserved.
665+ * Contact: Hannu Mallat <hannu.mallat@jollamobile.com>
666+ *
667+ * This program is free software; you can redistribute it and/or modify
668+ * it under the terms of the GNU General Public License as published by
669+ * the Free Software Foundation; either version 2 of the License, or
670+ * (at your option) any later version.
671+ *
672+ * This program is distributed in the hope that it will be useful,
673+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
674+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
675+ * GNU General Public License for more details.
676+ *
677+ * You should have received a copy of the GNU General Public License
678+ * along with this program; if not, write to the Free Software
679+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
680+ *
681+ */
682+
683+#ifndef __OFONO_WAKELOCK_H_
684+#define __OFONO_WAKELOCK_H_
685+
686+#include <ofono/types.h>
687+
688+/* Wakelock interface
689+ *
690+ * Wakelocks ensure system does not suspend/enter power save mode
691+ * before an ongoing operation completes. This header declares a
692+ * wakelock API that can be implemented by a OS-specific plugin.
693+ */
694+
695+struct wakelock; /* Opaque */
696+
697+struct wakelock_table {
698+ int (*create)(const char *name, struct wakelock **);
699+ int (*free)(struct wakelock *);
700+ int (*acquire)(struct wakelock *);
701+ int (*release)(struct wakelock *);
702+ ofono_bool_t (*is_locked)(struct wakelock *);
703+};
704+
705+
706+/*** Functions for wakelock users ***/
707+
708+/*
709+ * This will create a wakelock which will be held for a short duration
710+ * and then automatically freed. If this is called multiple times the
711+ * timeout will be restarted on every call.
712+ */
713+void wakelock_system_lock(void);
714+
715+/*
716+ * Create a wakelock. Multiple wakelocks can be created; if any one of
717+ * them is activated, system will be prevented from going to suspend.
718+ * This makes it possible to overlap locks to hand over from subsystem
719+ * to subsystem, each with their own wakelock-guarded sections,
720+ * without falling to suspend in between.
721+ */
722+int wakelock_create(const char *name, struct wakelock **wakelock);
723+
724+/*
725+ * Free a wakelock, releasing all acquisitions at the same time
726+ * and deallocating the lock.
727+ */
728+int wakelock_free(struct wakelock *wakelock);
729+
730+/*
731+ * Acquire a wakelock. Multiple acquisitions are possible, meaning
732+ * that the wakelock needs to be released the same number of times
733+ * until it is actually deactivated.
734+ */
735+int wakelock_acquire(struct wakelock *wakelock);
736+
737+/*
738+ * Release a wakelock, deactivating it if all acquisitions are
739+ * released, letting system suspend.
740+ */
741+int wakelock_release(struct wakelock *wakelock);
742+
743+/*
744+ * Check if a wakelock is currently locked or not.
745+ */
746+ofono_bool_t wakelock_is_locked(struct wakelock *wakelock);
747+
748+/*** Functions for wakelock implementors ***/
749+
750+/*
751+ * Register a wakelock implementation. Only one implementation may be
752+ * registered at a time. In the absence of an implementation, all
753+ * wakelock functions are no-ops.
754+ */
755+int wakelock_plugin_register(const char *name, struct wakelock_table *fns);
756+
757+int wakelock_plugin_unregister(void);
758+
759+#endif
760
761=== removed file 'include/wakelock.h'
762--- include/wakelock.h 2016-01-15 16:03:09 +0000
763+++ include/wakelock.h 1970-01-01 00:00:00 +0000
764@@ -1,100 +0,0 @@
765-/*
766- *
767- * oFono - Open Source Telephony
768- *
769- * Copyright (C) 2015 Jolla Ltd. All rights reserved.
770- * Contact: Hannu Mallat <hannu.mallat@jollamobile.com>
771- *
772- * This program is free software; you can redistribute it and/or modify
773- * it under the terms of the GNU General Public License as published by
774- * the Free Software Foundation; either version 2 of the License, or
775- * (at your option) any later version.
776- *
777- * This program is distributed in the hope that it will be useful,
778- * but WITHOUT ANY WARRANTY; without even the implied warranty of
779- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
780- * GNU General Public License for more details.
781- *
782- * You should have received a copy of the GNU General Public License
783- * along with this program; if not, write to the Free Software
784- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
785- *
786- */
787-
788-#ifndef __OFONO_WAKELOCK_H_
789-#define __OFONO_WAKELOCK_H_
790-
791-#include <ofono/types.h>
792-
793-/* Wakelock interface
794- *
795- * Wakelocks ensure system does not suspend/enter power save mode
796- * before an ongoing operation completes. This header declares a
797- * wakelock API that can be implemented by a OS-specific plugin.
798- */
799-
800-struct wakelock; /* Opaque */
801-
802-struct wakelock_table {
803- int (*create)(const char *name, struct wakelock **);
804- int (*free)(struct wakelock *);
805- int (*acquire)(struct wakelock *);
806- int (*release)(struct wakelock *);
807- ofono_bool_t (*is_locked)(struct wakelock *);
808-};
809-
810-
811-/*** Functions for wakelock users ***/
812-
813-/*
814- * This will create a wakelock which will be held for a short duration
815- * and then automatically freed. If this is called multiple times the
816- * timeout will be restarted on every call.
817- */
818-void wakelock_system_lock(void);
819-
820-/*
821- * Create a wakelock. Multiple wakelocks can be created; if any one of
822- * them is activated, system will be prevented from going to suspend.
823- * This makes it possible to overlap locks to hand over from subsystem
824- * to subsystem, each with their own wakelock-guarded sections,
825- * without falling to suspend in between.
826- */
827-int wakelock_create(const char *name, struct wakelock **wakelock);
828-
829-/*
830- * Free a wakelock, releasing all acquisitions at the same time
831- * and deallocating the lock.
832- */
833-int wakelock_free(struct wakelock *wakelock);
834-
835-/*
836- * Acquire a wakelock. Multiple acquisitions are possible, meaning
837- * that the wakelock needs to be released the same number of times
838- * until it is actually deactivated.
839- */
840-int wakelock_acquire(struct wakelock *wakelock);
841-
842-/*
843- * Release a wakelock, deactivating it if all acquisitions are
844- * released, letting system suspend.
845- */
846-int wakelock_release(struct wakelock *wakelock);
847-
848-/*
849- * Check if a wakelock is currently locked or not.
850- */
851-ofono_bool_t wakelock_is_locked(struct wakelock *wakelock);
852-
853-/*** Functions for wakelock implementors ***/
854-
855-/*
856- * Register a wakelock implementation. Only one implementation may be
857- * registered at a time. In the absence of an implementation, all
858- * wakelock functions are no-ops.
859- */
860-int wakelock_plugin_register(const char *name, struct wakelock_table *fns);
861-
862-int wakelock_plugin_unregister(void);
863-
864-#endif
865
866=== added file 'plugins/accounts-settings.c'
867--- plugins/accounts-settings.c 1970-01-01 00:00:00 +0000
868+++ plugins/accounts-settings.c 2016-03-14 09:03:03 +0000
869@@ -0,0 +1,474 @@
870+/*
871+ *
872+ * oFono - Open Source Telephony
873+ *
874+ * Copyright (C) 2016 Canonical Ltd.
875+ *
876+ * This program is free software; you can redistribute it and/or modify
877+ * it under the terms of the GNU General Public License version 2 as
878+ * published by the Free Software Foundation.
879+ *
880+ * This program is distributed in the hope that it will be useful,
881+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
882+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
883+ * GNU General Public License for more details.
884+ *
885+ * You should have received a copy of the GNU General Public License
886+ * along with this program; if not, write to the Free Software
887+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
888+ *
889+ */
890+
891+#ifdef HAVE_CONFIG_H
892+#include <config.h>
893+#endif
894+
895+#include <stdlib.h>
896+#include <string.h>
897+#include <stdio.h>
898+
899+#include <sys/types.h>
900+#include <pwd.h>
901+#include <errno.h>
902+#include <unistd.h>
903+
904+#include <glib.h>
905+#include <gdbus.h>
906+#include <systemd/sd-login.h>
907+
908+#include <ofono.h>
909+
910+#define OFONO_API_SUBJECT_TO_CHANGE
911+#include <ofono/types.h>
912+#include <ofono/log.h>
913+#include <ofono/plugin.h>
914+#include <ofono/system-settings.h>
915+
916+#define ACCOUNTS_SERVICE "org.freedesktop.Accounts"
917+#define ACCOUNTS_PATH "/org/freedesktop/Accounts/User"
918+#define ACCOUNTS_PHONE_INTERFACE "com.ubuntu.touch.AccountsService.Phone"
919+#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
920+
921+struct setting {
922+ char* ofono_name;
923+ char* property_name;
924+};
925+
926+static const struct setting setting_names[] = {
927+ { PREFERRED_VOICE_MODEM, "DefaultSimForCalls" }
928+};
929+
930+#define NUM_SETTINGS G_N_ELEMENTS(setting_names)
931+
932+struct accounts_data {
933+ sd_login_monitor *login_monitor;
934+ guint login_watch;
935+ char *property_values[NUM_SETTINGS];
936+ uid_t current_uid;
937+ guint prop_change_watch;
938+ char uid_path[sizeof(ACCOUNTS_PATH) + 32];
939+};
940+
941+static struct accounts_data g_accounts;
942+
943+static int translate_name(const char *name)
944+{
945+ size_t i;
946+
947+ for (i = 0; i < NUM_SETTINGS; ++i) {
948+ if (g_strcmp0(setting_names[i].ofono_name, name) != 0)
949+ continue;
950+
951+ return i;
952+ }
953+
954+ return -1;
955+}
956+
957+static char *accounts_settings_get_string_value(const char *name)
958+{
959+ int id;
960+
961+ id = translate_name(name);
962+ if (id < 0)
963+ return NULL;
964+
965+ return g_strdup(g_accounts.property_values[id]);
966+}
967+
968+static struct ofono_system_settings_driver accounts_settings_driver = {
969+ .name = "Accounts Service System Settings",
970+ .get_string_value = accounts_settings_get_string_value
971+};
972+
973+static int get_id_from_name(const char *name)
974+{
975+ size_t i;
976+
977+ for (i = 0; i < NUM_SETTINGS; ++i) {
978+ if (g_strcmp0(setting_names[i].property_name, name) != 0)
979+ continue;
980+
981+ return i;
982+ }
983+
984+ return -1;
985+}
986+
987+static char *get_property_value(DBusMessage *reply)
988+{
989+ DBusMessageIter iter, val;
990+ const char *ptr;
991+ char *property = NULL;
992+
993+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
994+ ofono_error("%s: ERROR reply to Get", __func__);
995+ goto done;
996+ }
997+
998+ if (dbus_message_iter_init(reply, &iter) == FALSE) {
999+ ofono_error("%s: error initializing array iter", __func__);
1000+ goto done;
1001+ }
1002+
1003+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
1004+ ofono_error("%s: type != VARIANT!", __func__);
1005+ goto done;
1006+ }
1007+
1008+ dbus_message_iter_recurse(&iter, &val);
1009+
1010+ if (dbus_message_iter_get_arg_type(&val) != DBUS_TYPE_STRING) {
1011+ ofono_error("%s: type != STRING!", __func__);
1012+ goto done;
1013+ }
1014+
1015+ dbus_message_iter_get_basic(&val, &ptr);
1016+
1017+ property = g_strdup(ptr);
1018+
1019+done:
1020+ return property;
1021+}
1022+
1023+struct get_property_data {
1024+ struct accounts_data *accounts;
1025+ int prop_id;
1026+};
1027+
1028+static void get_property_reply(DBusPendingCall *call, void *user_data)
1029+{
1030+ DBusMessage *reply;
1031+ struct get_property_data *gpd = user_data;
1032+ char **values = gpd->accounts->property_values;
1033+ int id = gpd->prop_id;
1034+
1035+ reply = dbus_pending_call_steal_reply(call);
1036+ if (reply == NULL) {
1037+ ofono_error("%s: failed to get reply", __func__);
1038+ goto done;
1039+ }
1040+
1041+ g_free(values[id]);
1042+ values[id] = get_property_value(reply);
1043+ dbus_message_unref(reply);
1044+
1045+ DBG("property %s has value %s",
1046+ setting_names[id].property_name, PRINTABLE_STR(values[id]));
1047+
1048+done:
1049+ dbus_pending_call_unref(call);
1050+ g_free(gpd);
1051+}
1052+
1053+static void get_property(struct accounts_data *accounts, int id)
1054+{
1055+ DBusMessageIter iter;
1056+ DBusMessage *msg;
1057+ const char *iface = ACCOUNTS_PHONE_INTERFACE;
1058+ DBusConnection *conn = ofono_dbus_get_connection();
1059+ DBusPendingCall *call;
1060+ struct get_property_data *gpd;
1061+
1062+ msg = dbus_message_new_method_call(ACCOUNTS_SERVICE, accounts->uid_path,
1063+ DBUS_PROPERTIES_INTERFACE,
1064+ "Get");
1065+ if (msg == NULL) {
1066+ ofono_error("%s: dbus_message_new_method failed", __func__);
1067+ return;
1068+ }
1069+
1070+ dbus_message_iter_init_append(msg, &iter);
1071+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface);
1072+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1073+ &setting_names[id].property_name);
1074+
1075+ if (!dbus_connection_send_with_reply(conn, msg, &call, -1)) {
1076+ ofono_error("%s: Sending Get failed", __func__);
1077+ goto done;
1078+ }
1079+
1080+ gpd = g_malloc0(sizeof(*gpd));
1081+ gpd->accounts = accounts;
1082+ gpd->prop_id = id;
1083+ dbus_pending_call_set_notify(call, get_property_reply, gpd, NULL);
1084+
1085+done:
1086+ dbus_message_unref(msg);
1087+}
1088+
1089+static gboolean property_changed(DBusConnection *conn,
1090+ DBusMessage *msg, void *user_data)
1091+{
1092+ struct accounts_data *accounts = user_data;
1093+ const char *iface;
1094+ DBusMessageIter iter, dict, inv_it;
1095+
1096+ dbus_message_iter_init(msg, &iter);
1097+
1098+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
1099+ ofono_error("%s: iface != TYPE_STRING!", __func__);
1100+ goto done;
1101+ }
1102+
1103+ dbus_message_iter_get_basic(&iter, &iface);
1104+
1105+ /* We can receive notifications from other AccountsService interfaces */
1106+ if (g_str_equal(iface, ACCOUNTS_PHONE_INTERFACE) != TRUE)
1107+ goto done;
1108+
1109+ if (!dbus_message_iter_next(&iter)) {
1110+ ofono_error("%s: advance iter failed!", __func__);
1111+ goto done;
1112+ }
1113+
1114+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1115+ ofono_error("%s: type != ARRAY!", __func__);
1116+ goto done;
1117+ }
1118+
1119+ dbus_message_iter_recurse(&iter, &dict);
1120+
1121+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
1122+ DBusMessageIter entry, val;
1123+ const char *key, *str_val;
1124+ int id;
1125+
1126+ dbus_message_iter_recurse(&dict, &entry);
1127+
1128+ if (dbus_message_iter_get_arg_type(&entry) !=
1129+ DBUS_TYPE_STRING) {
1130+ ofono_error("%s: key type != STRING!", __func__);
1131+ goto done;
1132+ }
1133+
1134+ dbus_message_iter_get_basic(&entry, &key);
1135+
1136+ dbus_message_iter_next(&entry);
1137+
1138+ if (dbus_message_iter_get_arg_type(&entry) !=
1139+ DBUS_TYPE_VARIANT) {
1140+ ofono_error("%s: val != VARIANT", __func__);
1141+ goto done;
1142+ }
1143+
1144+ dbus_message_iter_recurse(&entry, &val);
1145+
1146+ if (dbus_message_iter_get_arg_type(&val) != DBUS_TYPE_STRING) {
1147+ ofono_error("%s: *val != STRING", __func__);
1148+ goto done;
1149+ }
1150+
1151+ dbus_message_iter_get_basic(&val, &str_val);
1152+
1153+ DBG("property %s changed to %s", key, PRINTABLE_STR(str_val));
1154+
1155+ id = get_id_from_name(key);
1156+ if (id >= 0)
1157+ accounts->property_values[id] = g_strdup(str_val);
1158+
1159+ dbus_message_iter_next(&dict);
1160+ }
1161+
1162+ /* Check invalidated properties */
1163+ if (!dbus_message_iter_next(&iter)) {
1164+ ofono_error("%s: advance iter failed!", __func__);
1165+ goto done;
1166+ }
1167+
1168+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1169+ ofono_error("%s: type != ARRAY!", __func__);
1170+ goto done;
1171+ }
1172+
1173+ dbus_message_iter_recurse(&iter, &inv_it);
1174+
1175+ while (dbus_message_iter_get_arg_type(&inv_it) == DBUS_TYPE_STRING) {
1176+ const char *inv_name;
1177+ int id;
1178+
1179+ dbus_message_iter_get_basic(&inv_it, &inv_name);
1180+
1181+ DBG("property %s invalidated", inv_name);
1182+
1183+ id = get_id_from_name(inv_name);
1184+ if (id >= 0)
1185+ get_property(accounts, id);
1186+
1187+ dbus_message_iter_next(&inv_it);
1188+ }
1189+
1190+done:
1191+ return TRUE;
1192+}
1193+
1194+static void get_user_settings(struct accounts_data *accounts)
1195+{
1196+ DBusConnection *conn = ofono_dbus_get_connection();
1197+ size_t i;
1198+
1199+ snprintf(accounts->uid_path, sizeof(accounts->uid_path),
1200+ ACCOUNTS_PATH"%u", (unsigned) accounts->current_uid);
1201+
1202+ /*
1203+ * Register for property changes. Note that AccountsService is D-Bus,
1204+ * initiated, so there is no risk for race conditions on start.
1205+ */
1206+ accounts->prop_change_watch =
1207+ g_dbus_add_signal_watch(conn, ACCOUNTS_SERVICE,
1208+ accounts->uid_path,
1209+ DBUS_INTERFACE_PROPERTIES,
1210+ "PropertiesChanged",
1211+ property_changed,
1212+ accounts, NULL);
1213+
1214+ /* Retrieve AccountService properties */
1215+ for (i = 0; i < NUM_SETTINGS; ++i)
1216+ get_property(accounts, i);
1217+}
1218+
1219+static void release_accounts_data(struct accounts_data *accounts)
1220+{
1221+ DBusConnection *conn = ofono_dbus_get_connection();
1222+ size_t i;
1223+
1224+ g_dbus_remove_watch(conn, accounts->prop_change_watch);
1225+
1226+ for (i = 0; i < NUM_SETTINGS; ++i) {
1227+ g_free(accounts->property_values[i]);
1228+ accounts->property_values[i] = NULL;
1229+ }
1230+}
1231+
1232+static uid_t get_active_seat_uid(void)
1233+{
1234+ char **seats, **iter;
1235+ int res;
1236+ gboolean found = FALSE;
1237+ uid_t uid;
1238+
1239+ res = sd_get_seats(&seats);
1240+ if (res < 0) {
1241+ ofono_error("Error retrieving seats: %s (%d)",
1242+ strerror(-res), -res);
1243+ goto end;
1244+ } else if (res == 0) {
1245+ ofono_info("No seats found");
1246+ goto end;
1247+ }
1248+
1249+ for (iter = seats; *iter; ++iter) {
1250+
1251+ if (!found && sd_seat_get_active(*iter, NULL, &uid) >= 0) {
1252+ DBG("seat %s with uid %d", *iter, uid);
1253+ found = TRUE;
1254+ }
1255+
1256+ free(*iter);
1257+ }
1258+
1259+ free(seats);
1260+
1261+end:
1262+ if (!found)
1263+ uid = geteuid();
1264+
1265+ return uid;
1266+}
1267+
1268+static gboolean sd_changed(GIOChannel *stream, GIOCondition condition,
1269+ gpointer user_data)
1270+{
1271+ struct accounts_data *accounts = user_data;
1272+ uid_t new_uid;
1273+
1274+ sd_login_monitor_flush(accounts->login_monitor);
1275+
1276+ new_uid = get_active_seat_uid();
1277+ if (new_uid != accounts->current_uid) {
1278+ /* User in seat changed, resetting data */
1279+ release_accounts_data(accounts);
1280+
1281+ accounts->current_uid = new_uid;
1282+ get_user_settings(accounts);
1283+ }
1284+
1285+ return TRUE;
1286+}
1287+
1288+static void sd_init(struct accounts_data *accounts)
1289+{
1290+ int status;
1291+ GIOChannel *stream;
1292+ int fd;
1293+
1294+ status = sd_login_monitor_new(NULL, &accounts->login_monitor);
1295+ if (status < 0) {
1296+ ofono_error("Error creating systemd login monitor: %d", status);
1297+ accounts->login_monitor = NULL;
1298+ return;
1299+ }
1300+
1301+ fd = sd_login_monitor_get_fd(accounts->login_monitor);
1302+ stream = g_io_channel_unix_new(fd);
1303+ accounts->login_watch =
1304+ g_io_add_watch(stream, G_IO_IN, sd_changed, accounts);
1305+
1306+ g_io_channel_unref(stream);
1307+}
1308+
1309+static void sd_finalize(struct accounts_data *accounts)
1310+{
1311+ if (accounts->login_monitor == NULL)
1312+ return;
1313+
1314+ g_source_remove(accounts->login_watch);
1315+ sd_login_monitor_unref(accounts->login_monitor);
1316+}
1317+
1318+static int accounts_settings_init(void)
1319+{
1320+ g_accounts.current_uid = get_active_seat_uid();
1321+
1322+ /* Register for login changes */
1323+ sd_init(&g_accounts);
1324+
1325+ /* Get property values for current user */
1326+ get_user_settings(&g_accounts);
1327+
1328+ return ofono_system_settings_driver_register(&accounts_settings_driver);
1329+}
1330+
1331+static void accounts_settings_exit(void)
1332+{
1333+ ofono_system_settings_driver_unregister(&accounts_settings_driver);
1334+
1335+ sd_finalize(&g_accounts);
1336+
1337+ release_accounts_data(&g_accounts);
1338+}
1339+
1340+OFONO_PLUGIN_DEFINE(accounts_settings,
1341+ "Accounts Service System Settings Plugin",
1342+ VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
1343+ accounts_settings_init, accounts_settings_exit)
1344
1345=== added file 'plugins/android-wakelock.c'
1346--- plugins/android-wakelock.c 1970-01-01 00:00:00 +0000
1347+++ plugins/android-wakelock.c 2016-03-14 09:03:03 +0000
1348@@ -0,0 +1,212 @@
1349+/*
1350+ *
1351+ * oFono - Open Source Telephony - Android based wakelocks
1352+ *
1353+ * Copyright (C) 2016 Canonical Ltd.
1354+ *
1355+ * This program is free software; you can redistribute it and/or modify
1356+ * it under the terms of the GNU General Public License as published by
1357+ * the Free Software Foundation; either version 2 of the License, or
1358+ * (at your option) any later version.
1359+ *
1360+ * This program is distributed in the hope that it will be useful,
1361+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1362+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1363+ * GNU General Public License for more details.
1364+ *
1365+ * You should have received a copy of the GNU General Public License
1366+ * along with this program; if not, write to the Free Software
1367+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1368+ *
1369+ */
1370+
1371+#ifdef HAVE_CONFIG_H
1372+#include <config.h>
1373+#endif
1374+
1375+#include <sys/types.h>
1376+#include <sys/stat.h>
1377+#include <fcntl.h>
1378+#include <unistd.h>
1379+#include <string.h>
1380+#include <errno.h>
1381+#include <glib.h>
1382+#include <dlfcn.h>
1383+
1384+#include <glib.h>
1385+
1386+#define OFONO_API_SUBJECT_TO_CHANGE
1387+
1388+#include "plugin.h"
1389+#include "log.h"
1390+#include "wakelock.h"
1391+
1392+#define ANDROID_WAKELOCK_LOCK_PATH "/sys/power/wake_lock"
1393+#define ANDROID_WAKELOCK_UNLOCK_PATH "/sys/power/wake_unlock"
1394+
1395+struct wakelock {
1396+ char *name;
1397+ unsigned int acquisitions;
1398+};
1399+
1400+GSList *locks = NULL;
1401+
1402+static int file_exists(char const *filename)
1403+{
1404+ struct stat st;
1405+
1406+ return stat(filename, &st) == 0;
1407+}
1408+
1409+static int write_file(const char *file, const char *content)
1410+{
1411+ int fd;
1412+ unsigned int r = 0;
1413+
1414+ fd = open(file, O_WRONLY);
1415+
1416+ if (fd == -1)
1417+ return -EIO;
1418+
1419+ r = write(fd, content, strlen(content));
1420+
1421+ close(fd);
1422+
1423+ if (r != strlen(content))
1424+ return -EIO;
1425+
1426+ return 0;
1427+}
1428+
1429+static int wakelock_lock(const char *name)
1430+{
1431+ return write_file(ANDROID_WAKELOCK_LOCK_PATH, name);
1432+}
1433+
1434+static int wakelock_unlock(const char *name)
1435+{
1436+ return write_file(ANDROID_WAKELOCK_UNLOCK_PATH, name);
1437+}
1438+
1439+static int android_wakelock_acquire(struct wakelock *lock)
1440+{
1441+ if (lock == NULL)
1442+ return -EINVAL;
1443+
1444+ if (lock->acquisitions > 0) {
1445+ lock->acquisitions++;
1446+ return 0;
1447+ }
1448+
1449+ if (wakelock_lock(lock->name) < 0)
1450+ return -EIO;
1451+
1452+ lock->acquisitions++;
1453+
1454+ return 0;
1455+}
1456+
1457+static int android_wakelock_release(struct wakelock *lock)
1458+{
1459+ if (lock == NULL)
1460+ return -EINVAL;
1461+
1462+ DBG("lock %p name %s acquisitions %d",
1463+ lock, lock->name, lock->acquisitions);
1464+
1465+ if (!lock->acquisitions) {
1466+ ofono_warn("Attempted to release already released lock %s", lock->name);
1467+ return -EINVAL;
1468+ }
1469+
1470+ if (lock->acquisitions > 1) {
1471+ lock->acquisitions--;
1472+ DBG("lock %s released acquisitions %d", lock->name, lock->acquisitions);
1473+ return 0;
1474+ }
1475+
1476+ if (wakelock_unlock(lock->name) < 0)
1477+ return -EIO;
1478+
1479+ lock->acquisitions = 0;
1480+
1481+ DBG("lock %s was released", lock->name);
1482+
1483+ return 0;
1484+}
1485+
1486+static int android_wakelock_create(const char *name, struct wakelock **lock)
1487+{
1488+ if (lock == NULL)
1489+ return -EINVAL;
1490+
1491+ *lock = g_new0(struct wakelock, 1);
1492+ (*lock)->name = g_strdup(name);
1493+ (*lock)->acquisitions = 0;
1494+
1495+ locks = g_slist_prepend(locks, *lock);
1496+
1497+ DBG("wakelock %s create", name);
1498+
1499+ return 0;
1500+}
1501+
1502+static int android_wakelock_free(struct wakelock *lock)
1503+{
1504+ if (lock == NULL)
1505+ return -EINVAL;
1506+
1507+ if (lock->acquisitions) {
1508+ /* Need to force releasing the lock here */
1509+ lock->acquisitions = 1;
1510+ android_wakelock_release(lock);
1511+ }
1512+
1513+ locks = g_slist_remove(locks, lock);
1514+
1515+ DBG("Freeing lock %s", lock->name);
1516+
1517+ g_free(lock->name);
1518+ g_free(lock);
1519+
1520+ return 0;
1521+}
1522+
1523+static ofono_bool_t android_wakelock_is_locked(struct wakelock *lock)
1524+{
1525+ if (lock == NULL)
1526+ return FALSE;
1527+
1528+ return lock->acquisitions > 0;
1529+}
1530+
1531+struct wakelock_table driver = {
1532+ .create = android_wakelock_create,
1533+ .free = android_wakelock_free,
1534+ .acquire = android_wakelock_acquire,
1535+ .release = android_wakelock_release,
1536+ .is_locked = android_wakelock_is_locked
1537+};
1538+
1539+static int android_wakelock_init(void)
1540+{
1541+ if (!file_exists(ANDROID_WAKELOCK_LOCK_PATH)) {
1542+ ofono_warn("System does not support Android wakelocks.");
1543+ return 0;
1544+ }
1545+
1546+ if (wakelock_plugin_register("android-wakelock", &driver) < 0) {
1547+ ofono_error("Failed to register wakelock driver");
1548+ return -EIO;
1549+ }
1550+
1551+ return 0;
1552+}
1553+
1554+static void android_wakelock_exit(void)
1555+{
1556+ wakelock_plugin_unregister();
1557+}
1558+
1559+OFONO_PLUGIN_DEFINE(android_wakelock, "Android Wakelock driver", VERSION,
1560+ OFONO_PLUGIN_PRIORITY_DEFAULT, android_wakelock_init, android_wakelock_exit)
1561
1562=== removed file 'plugins/android-wakelock.c'
1563--- plugins/android-wakelock.c 2016-01-15 16:03:09 +0000
1564+++ plugins/android-wakelock.c 1970-01-01 00:00:00 +0000
1565@@ -1,212 +0,0 @@
1566-/*
1567- *
1568- * oFono - Open Source Telephony - Android based wakelocks
1569- *
1570- * Copyright (C) 2016 Canonical Ltd.
1571- *
1572- * This program is free software; you can redistribute it and/or modify
1573- * it under the terms of the GNU General Public License as published by
1574- * the Free Software Foundation; either version 2 of the License, or
1575- * (at your option) any later version.
1576- *
1577- * This program is distributed in the hope that it will be useful,
1578- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1579- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1580- * GNU General Public License for more details.
1581- *
1582- * You should have received a copy of the GNU General Public License
1583- * along with this program; if not, write to the Free Software
1584- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1585- *
1586- */
1587-
1588-#ifdef HAVE_CONFIG_H
1589-#include <config.h>
1590-#endif
1591-
1592-#include <sys/types.h>
1593-#include <sys/stat.h>
1594-#include <fcntl.h>
1595-#include <unistd.h>
1596-#include <string.h>
1597-#include <errno.h>
1598-#include <glib.h>
1599-#include <dlfcn.h>
1600-
1601-#include <glib.h>
1602-
1603-#define OFONO_API_SUBJECT_TO_CHANGE
1604-
1605-#include "plugin.h"
1606-#include "log.h"
1607-#include "wakelock.h"
1608-
1609-#define ANDROID_WAKELOCK_LOCK_PATH "/sys/power/wake_lock"
1610-#define ANDROID_WAKELOCK_UNLOCK_PATH "/sys/power/wake_unlock"
1611-
1612-struct wakelock {
1613- char *name;
1614- unsigned int acquisitions;
1615-};
1616-
1617-GSList *locks = NULL;
1618-
1619-static int file_exists(char const *filename)
1620-{
1621- struct stat st;
1622-
1623- return stat(filename, &st) == 0;
1624-}
1625-
1626-static int write_file(const char *file, const char *content)
1627-{
1628- int fd;
1629- unsigned int r = 0;
1630-
1631- fd = open(file, O_WRONLY);
1632-
1633- if (fd == -1)
1634- return -EIO;
1635-
1636- r = write(fd, content, strlen(content));
1637-
1638- close(fd);
1639-
1640- if (r != strlen(content))
1641- return -EIO;
1642-
1643- return 0;
1644-}
1645-
1646-static int wakelock_lock(const char *name)
1647-{
1648- return write_file(ANDROID_WAKELOCK_LOCK_PATH, name);
1649-}
1650-
1651-static int wakelock_unlock(const char *name)
1652-{
1653- return write_file(ANDROID_WAKELOCK_UNLOCK_PATH, name);
1654-}
1655-
1656-static int android_wakelock_acquire(struct wakelock *lock)
1657-{
1658- if (!lock)
1659- return -EINVAL;
1660-
1661- if (lock->acquisitions > 0) {
1662- lock->acquisitions++;
1663- return 0;
1664- }
1665-
1666- if (wakelock_lock(lock->name) < 0)
1667- return -EIO;
1668-
1669- lock->acquisitions++;
1670-
1671- return 0;
1672-}
1673-
1674-static int android_wakelock_release(struct wakelock *lock)
1675-{
1676- if (!lock)
1677- return -EINVAL;
1678-
1679- DBG("lock %p name %s acquisitions %d",
1680- lock, lock->name, lock->acquisitions);
1681-
1682- if (!lock->acquisitions) {
1683- ofono_warn("Attempted to release already released lock %s", lock->name);
1684- return -EINVAL;
1685- }
1686-
1687- if (lock->acquisitions > 1) {
1688- lock->acquisitions--;
1689- DBG("lock %s released acquisitions %d", lock->name, lock->acquisitions);
1690- return 0;
1691- }
1692-
1693- if (wakelock_unlock(lock->name) < 0)
1694- return -EIO;
1695-
1696- lock->acquisitions = 0;
1697-
1698- DBG("lock %s was released", lock->name);
1699-
1700- return 0;
1701-}
1702-
1703-static int android_wakelock_create(const char *name, struct wakelock **lock)
1704-{
1705- if (!lock)
1706- return -EINVAL;
1707-
1708- *lock = g_new0(struct wakelock, 1);
1709- (*lock)->name = g_strdup(name);
1710- (*lock)->acquisitions = 0;
1711-
1712- locks = g_slist_prepend(locks, *lock);
1713-
1714- DBG("wakelock %s create", name);
1715-
1716- return 0;
1717-}
1718-
1719-static int android_wakelock_free(struct wakelock *lock)
1720-{
1721- if (!lock)
1722- return -EINVAL;
1723-
1724- if (lock->acquisitions) {
1725- /* Need to force releasing the lock here */
1726- lock->acquisitions = 1;
1727- android_wakelock_release(lock);
1728- }
1729-
1730- locks = g_slist_remove(locks, lock);
1731-
1732- DBG("Freeing lock %s", lock->name);
1733-
1734- g_free(lock->name);
1735- g_free(lock);
1736-
1737- return 0;
1738-}
1739-
1740-static ofono_bool_t android_wakelock_is_locked(struct wakelock *lock)
1741-{
1742- if (!lock)
1743- return FALSE;
1744-
1745- return lock->acquisitions > 0;
1746-}
1747-
1748-struct wakelock_table driver = {
1749- .create = android_wakelock_create,
1750- .free = android_wakelock_free,
1751- .acquire = android_wakelock_acquire,
1752- .release = android_wakelock_release,
1753- .is_locked = android_wakelock_is_locked
1754-};
1755-
1756-static int android_wakelock_init(void)
1757-{
1758- if (!file_exists(ANDROID_WAKELOCK_LOCK_PATH)) {
1759- ofono_warn("System does not support Android wakelocks.");
1760- return 0;
1761- }
1762-
1763- if (wakelock_plugin_register("android-wakelock", &driver) < 0) {
1764- ofono_error("Failed to register wakelock driver");
1765- return -EIO;
1766- }
1767-
1768- return 0;
1769-}
1770-
1771-static void android_wakelock_exit(void)
1772-{
1773- wakelock_plugin_unregister();
1774-}
1775-
1776-OFONO_PLUGIN_DEFINE(android_wakelock, "Android Wakelock driver", VERSION,
1777- OFONO_PLUGIN_PRIORITY_DEFAULT, android_wakelock_init, android_wakelock_exit)
1778
1779=== modified file 'plugins/qcom-msim.c'
1780--- plugins/qcom-msim.c 2015-04-23 13:08:30 +0000
1781+++ plugins/qcom-msim.c 2016-03-14 09:03:03 +0000
1782@@ -36,6 +36,18 @@
1783
1784 static int qcom_msim_probe(struct ofono_modem *modem)
1785 {
1786+ int slot_id = ofono_modem_get_integer(modem, "Slot");
1787+
1788+ /* qcom_msim has socket path "rild", "rild1", ... */
1789+ if (slot_id != 0) {
1790+ char *socket;
1791+
1792+ socket = g_strdup_printf("/dev/socket/rild%d", slot_id);
1793+ ofono_modem_set_string(modem, "Socket", socket);
1794+
1795+ g_free(socket);
1796+ }
1797+
1798 return ril_create(modem, OFONO_RIL_VENDOR_QCOM_MSIM);
1799 }
1800
1801
1802=== modified file 'plugins/ril.c'
1803--- plugins/ril.c 2015-10-07 07:14:11 +0000
1804+++ plugins/ril.c 2016-03-14 09:03:03 +0000
1805@@ -73,9 +73,6 @@
1806 #define RILD_MAX_CONNECT_RETRIES 5
1807 #define RILD_CONNECT_RETRY_TIME_S 5
1808
1809-char *RILD_CMD_SOCKET[] = {"/dev/socket/rild", "/dev/socket/rild1"};
1810-char *GRIL_HEX_PREFIX[] = {"Device 0: ", "Device 1: "};
1811-
1812 struct ril_data {
1813 GRil *ril;
1814 enum ofono_ril_vendor vendor;
1815@@ -90,9 +87,9 @@
1816
1817 static void ril_debug(const char *str, void *user_data)
1818 {
1819- const char *prefix = user_data;
1820+ struct ril_data *rd = user_data;
1821
1822- ofono_info("%s%s", prefix, str);
1823+ ofono_info("Device %d: %s", g_ril_get_slot(rd->ril), str);
1824 }
1825
1826 static void ril_radio_state_changed(struct ril_msg *message, gpointer user_data)
1827@@ -169,7 +166,7 @@
1828
1829 rd->vendor = vendor;
1830 rd->ofono_online = FALSE;
1831- rd->radio_state = RADIO_STATE_OFF;
1832+ rd->radio_state = RADIO_STATE_UNAVAILABLE;
1833
1834 lte_cap = getenv("OFONO_RIL_RAT_LTE") ? TRUE : FALSE;
1835 ofono_modem_set_boolean(modem, MODEM_PROP_LTE_CAPABLE, lte_cap);
1836@@ -284,7 +281,9 @@
1837 struct ril_data *rd = cbd->user;
1838 ofono_modem_online_cb_t cb = cbd->cb;
1839
1840- if (message->error == RIL_E_SUCCESS) {
1841+ if (message != NULL && message->error == RIL_E_SUCCESS) {
1842+ g_ril_print_response_no_args(rd->ril, message);
1843+
1844 DBG("%s: set_online OK: rd->ofono_online: %d", __func__,
1845 rd->ofono_online);
1846 CALLBACK_WITH_SUCCESS(cb, cbd->data);
1847@@ -293,31 +292,24 @@
1848 rd->ofono_online);
1849 CALLBACK_WITH_FAILURE(cb, cbd->data);
1850 }
1851+
1852+ g_free(cbd);
1853 }
1854
1855 static void ril_send_power(struct ril_data *rd, ofono_bool_t online,
1856 GRilResponseFunc func,
1857 gpointer user_data)
1858 {
1859- struct cb_data *cbd = user_data;
1860- ofono_modem_online_cb_t cb;
1861- GDestroyNotify notify = NULL;
1862 struct parcel rilp;
1863
1864- if (cbd != NULL) {
1865- notify = g_free;
1866- cb = cbd->cb;
1867- }
1868-
1869 DBG("(online = 1, offline = 0)): %i", online);
1870
1871 g_ril_request_power(rd->ril, (const gboolean) online, &rilp);
1872
1873 if (g_ril_send(rd->ril, RIL_REQUEST_RADIO_POWER, &rilp,
1874- func, cbd, notify) == 0 && cbd != NULL) {
1875+ func, user_data, NULL) == 0 && func != NULL) {
1876
1877- CALLBACK_WITH_FAILURE(cb, cbd->data);
1878- g_free(cbd);
1879+ func(NULL, user_data);
1880 }
1881 }
1882
1883@@ -334,30 +326,47 @@
1884 ril_send_power(rd, online, ril_set_online_cb, cbd);
1885 }
1886
1887+static void ril_set_powered_off_cb(struct ril_msg *message, gpointer user_data)
1888+{
1889+ struct ofono_modem *modem = user_data;
1890+ struct ril_data *rd = ofono_modem_get_data(modem);
1891+
1892+ if (message != NULL && message->error == RIL_E_SUCCESS)
1893+ g_ril_print_response_no_args(rd->ril, message);
1894+
1895+ DBG("calling set_powered(TRUE)");
1896+
1897+ ofono_modem_set_powered(modem, TRUE);
1898+}
1899+
1900 static void ril_connected(struct ril_msg *message, gpointer user_data)
1901 {
1902 struct ofono_modem *modem = (struct ofono_modem *) user_data;
1903 struct ril_data *rd = ofono_modem_get_data(modem);
1904-
1905- ofono_info("[%d,UNSOL]< %s", g_ril_get_slot(rd->ril),
1906- g_ril_unsol_request_to_string(rd->ril, message->req));
1907+ int version;
1908+
1909+ version = g_ril_unsol_parse_connected(rd->ril, message);
1910+ g_ril_set_version(rd->ril, version);
1911+
1912+ ofono_info("[%d,UNSOL]< %s, version %d", g_ril_get_slot(rd->ril),
1913+ g_ril_unsol_request_to_string(rd->ril, message->req), version);
1914
1915 /* TODO: need a disconnect function to restart things! */
1916 rd->connected = TRUE;
1917
1918- DBG("calling set_powered(TRUE)");
1919+ DBG("calling set_powered(FALSE) on connected");
1920
1921- ofono_modem_set_powered(modem, TRUE);
1922+ ril_send_power(rd, FALSE, ril_set_powered_off_cb, modem);
1923 }
1924
1925 static int create_gril(struct ofono_modem *modem)
1926 {
1927 struct ril_data *rd = ofono_modem_get_data(modem);
1928 int slot_id = ofono_modem_get_integer(modem, "Slot");
1929+ const gchar *socket = ofono_modem_get_string(modem, "Socket");
1930
1931- ofono_info("Using %s as socket for slot %d.",
1932- RILD_CMD_SOCKET[slot_id], slot_id);
1933- rd->ril = g_ril_new(RILD_CMD_SOCKET[slot_id], OFONO_RIL_VENDOR_AOSP);
1934+ ofono_info("Using %s as socket for slot %d.", socket, slot_id);
1935+ rd->ril = g_ril_new(socket, rd->vendor);
1936
1937 /* NOTE: Since AT modems open a tty, and then call
1938 * g_at_chat_new(), they're able to return -EIO if
1939@@ -377,7 +386,7 @@
1940 g_ril_set_trace(rd->ril, TRUE);
1941
1942 if (getenv("OFONO_RIL_HEX_TRACE"))
1943- g_ril_set_debugf(rd->ril, ril_debug, GRIL_HEX_PREFIX[slot_id]);
1944+ g_ril_set_debugf(rd->ril, ril_debug, rd);
1945
1946 g_ril_register(rd->ril, RIL_UNSOL_RIL_CONNECTED,
1947 ril_connected, modem);
1948
1949=== modified file 'plugins/rildev.c'
1950--- plugins/rildev.c 2015-11-10 09:13:46 +0000
1951+++ plugins/rildev.c 2016-03-14 09:03:03 +0000
1952@@ -43,6 +43,7 @@
1953 {
1954 struct ofono_modem *modem;
1955 char dev_name[64];
1956+ char *socket;
1957 int retval;
1958
1959 snprintf(dev_name, sizeof(dev_name), "ril_%d", slot);
1960@@ -58,6 +59,15 @@
1961
1962 ofono_modem_set_integer(modem, "Slot", slot);
1963
1964+ /* AOSP has socket path "rild", "rild2"..., while others may differ */
1965+ if (slot != 0)
1966+ socket = g_strdup_printf("/dev/socket/rild%d", slot + 1);
1967+ else
1968+ socket = g_strdup("/dev/socket/rild");
1969+
1970+ ofono_modem_set_string(modem, "Socket", socket);
1971+ g_free(socket);
1972+
1973 /* This causes driver->probe() to be called... */
1974 retval = ofono_modem_register(modem);
1975 if (retval != 0) {
1976
1977=== modified file 'plugins/upower.c'
1978--- plugins/upower.c 2015-11-02 09:18:14 +0000
1979+++ plugins/upower.c 2016-03-14 09:03:03 +0000
1980@@ -40,11 +40,8 @@
1981 #define UPOWER_DEVICE_INTERFACE UPOWER_SERVICE ".Device"
1982
1983 static guint modem_watch;
1984-static guint upower_battery_watch;
1985 static guint upower_daemon_watch;
1986 static DBusConnection *connection;
1987-static GHashTable *modem_hfp_watches;
1988-static GList *modems;
1989 static int last_battery_level;
1990 static char *battery_device_path;
1991
1992@@ -56,9 +53,17 @@
1993 ofono_emulator_set_indicator(atom, OFONO_EMULATOR_IND_BATTERY, val);
1994 }
1995
1996+static void update_modem_battery_indicator(struct ofono_modem *modem,
1997+ void *data)
1998+{
1999+ __ofono_modem_foreach_registered_atom(modem,
2000+ OFONO_ATOM_TYPE_EMULATOR_HFP,
2001+ emulator_battery_cb,
2002+ data);
2003+}
2004+
2005 static void update_battery_level(double percentage_val)
2006 {
2007- GList *list;
2008 int battery_level;
2009
2010 if (percentage_val <= 1.00) {
2011@@ -69,27 +74,19 @@
2012 ofono_error("%s: Invalid value for battery level: %f",
2013 __func__,
2014 percentage_val);
2015- goto done;
2016+ return;
2017 }
2018
2019 DBG("last_battery_level: %d battery_level: %d (%f)", last_battery_level,
2020 battery_level, percentage_val);
2021
2022 if (last_battery_level == battery_level)
2023- goto done;
2024+ return;
2025
2026 last_battery_level = battery_level;
2027
2028- for (list = modems; list; list = list->next) {
2029- struct ofono_modem *modem = list->data;
2030-
2031- __ofono_modem_foreach_registered_atom(modem,
2032- OFONO_ATOM_TYPE_EMULATOR_HFP,
2033- emulator_battery_cb,
2034+ __ofono_modem_foreach(update_modem_battery_indicator,
2035 GINT_TO_POINTER(battery_level));
2036- }
2037-done:
2038- ;
2039 }
2040
2041 static gboolean battery_props_changed(DBusConnection *conn, DBusMessage *msg,
2042@@ -102,6 +99,8 @@
2043 gboolean percentage_found = FALSE;
2044 gboolean retval = FALSE;
2045
2046+ DBG("");
2047+
2048 dbus_message_iter_init(msg, &iter);
2049
2050 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
2051@@ -179,117 +178,19 @@
2052 return retval;
2053 }
2054
2055-static void get_property_reply(DBusPendingCall *call, void *user_data)
2056-{
2057- double percentage_val;
2058- DBusMessageIter iter, val;
2059- DBusMessage *reply;
2060-
2061- DBG("");
2062-
2063- reply = dbus_pending_call_steal_reply(call);
2064- if (reply == NULL) {
2065- ofono_error("%s: dbus_message_new_method failed", __func__);
2066- goto done;
2067- }
2068-
2069- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
2070- ofono_error("%s: ERROR reply to Get('Percentage')", __func__);
2071- goto done;
2072- }
2073-
2074- if (dbus_message_iter_init(reply, &iter) == FALSE) {
2075- ofono_error("%s: error initializing array iter", __func__);
2076- goto done;
2077- }
2078-
2079- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
2080- ofono_error("%s: type != VARIANT!", __func__);
2081- goto done;
2082- }
2083-
2084- dbus_message_iter_recurse(&iter, &val);
2085-
2086- if (dbus_message_iter_get_arg_type(&val) != DBUS_TYPE_DOUBLE) {
2087- ofono_error("%s: type != DOUBLE!", __func__);
2088- goto done;
2089- }
2090-
2091- dbus_message_iter_get_basic(&val, &percentage_val);
2092-
2093- update_battery_level(percentage_val);
2094-
2095-done:
2096- if (reply)
2097- dbus_message_unref(reply);
2098-
2099- dbus_pending_call_unref(call);
2100-}
2101-
2102 static void emulator_hfp_watch(struct ofono_atom *atom,
2103 enum ofono_atom_watch_condition cond,
2104 void *data)
2105 {
2106- struct ofono_modem *modem = data;
2107- DBusMessageIter iter;
2108- DBusPendingCall *call;
2109- DBusMessage *msg;
2110- const char *iface = UPOWER_DEVICE_INTERFACE;
2111- const char *property = "Percentage";
2112-
2113- if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
2114- DBG("UNREGISTERED");
2115-
2116- modems = g_list_remove(modems, modem);
2117- if (modems != NULL)
2118- return;
2119-
2120- if (upower_battery_watch) {
2121- g_dbus_remove_watch(connection, upower_battery_watch);
2122- upower_battery_watch = 0;
2123- }
2124-
2125- return;
2126- }
2127-
2128- DBG("REGISTERED");
2129-
2130- /* TODO: handle removable batteries */
2131-
2132- modems = g_list_append(modems, modem);
2133-
2134- if (modems->next != NULL)
2135- return;
2136-
2137- upower_battery_watch = g_dbus_add_signal_watch(connection,
2138- UPOWER_SERVICE,
2139- battery_device_path,
2140- DBUS_INTERFACE_PROPERTIES,
2141- "PropertiesChanged",
2142- battery_props_changed,
2143- NULL, NULL);
2144-
2145- /* Query current battery value */
2146- msg = dbus_message_new_method_call(UPOWER_SERVICE, battery_device_path,
2147- DBUS_PROPERTIES_INTERFACE,
2148- "Get");
2149- if (msg == NULL) {
2150- ofono_error("%s: dbus_message_new_method failed", __func__);
2151- return;
2152- }
2153-
2154- dbus_message_iter_init_append(msg, &iter);
2155- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface);
2156- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
2157-
2158- if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
2159- ofono_error("%s: Sending EnumerateDevices failed", __func__);
2160- goto done;
2161- }
2162-
2163- dbus_pending_call_set_notify(call, get_property_reply, NULL, NULL);
2164-done:
2165- dbus_message_unref(msg);
2166+ if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
2167+ DBG("REGISTERED; calling set_indicator: %d", last_battery_level);
2168+
2169+ ofono_emulator_set_indicator(atom, OFONO_EMULATOR_IND_BATTERY,
2170+ last_battery_level);
2171+ return;
2172+ }
2173+
2174+ DBG("UNREGISTERED");
2175 }
2176
2177 static void modemwatch(struct ofono_modem *modem, gboolean added, void *user)
2178@@ -299,24 +200,10 @@
2179
2180 DBG("modem: %s, added: %d", path, added);
2181
2182- if (added) {
2183- guint watch_id;
2184-
2185- watch_id = __ofono_modem_add_atom_watch(modem,
2186+ if (added)
2187+ __ofono_modem_add_atom_watch(modem,
2188 OFONO_ATOM_TYPE_EMULATOR_HFP,
2189- emulator_hfp_watch, modem, NULL);
2190-
2191- g_hash_table_insert(modem_hfp_watches, g_strdup(path),
2192- GINT_TO_POINTER(watch_id));
2193-
2194- } else {
2195- guint *watch_id = g_hash_table_lookup(modem_hfp_watches, path);
2196-
2197- if (watch_id != NULL) {
2198- __ofono_modem_remove_atom_watch(modem, *watch_id);
2199- g_hash_table_remove(modem_hfp_watches, path);
2200- }
2201- }
2202+ emulator_hfp_watch, NULL, NULL);
2203 }
2204
2205 static void call_modemwatch(struct ofono_modem *modem, void *user)
2206@@ -383,13 +270,23 @@
2207
2208 DBG("parse_devices_reply OK");
2209
2210+ /* TODO: handle removable batteries */
2211+
2212 if (battery_device_path == NULL) {
2213 ofono_error("%s: no battery detected", __func__);
2214 goto done;
2215 }
2216
2217+ /* Always listen to PropertiesChanged for battery */
2218+ g_dbus_add_signal_watch(connection, UPOWER_SERVICE, battery_device_path,
2219+ DBUS_INTERFACE_PROPERTIES,
2220+ "PropertiesChanged",
2221+ battery_props_changed,
2222+ NULL, NULL);
2223+
2224 modem_watch = __ofono_modemwatch_add(modemwatch, NULL, NULL);
2225 __ofono_modem_foreach(call_modemwatch, NULL);
2226+
2227 done:
2228 if (reply)
2229 dbus_message_unref(reply);
2230@@ -449,9 +346,6 @@
2231 upower_disconnect,
2232 NULL, NULL);
2233
2234- modem_hfp_watches = g_hash_table_new_full(g_str_hash, g_str_equal,
2235- g_free, NULL);
2236-
2237 return 0;
2238 }
2239
2240@@ -465,8 +359,6 @@
2241
2242 if (battery_device_path)
2243 g_free(battery_device_path);
2244-
2245- g_hash_table_destroy(modem_hfp_watches);
2246 }
2247
2248 OFONO_PLUGIN_DEFINE(upower, "upower battery monitor", VERSION,
2249
2250=== modified file 'src/emulator.c'
2251--- src/emulator.c 2015-11-27 16:53:45 +0000
2252+++ src/emulator.c 2016-03-14 09:03:03 +0000
2253@@ -37,6 +37,7 @@
2254 #include "gatserver.h"
2255 #include "gatppp.h"
2256 #include "handsfree-audio.h"
2257+#include "system-settings.h"
2258
2259 #define RING_TIMEOUT 3
2260
2261@@ -1448,14 +1449,35 @@
2262
2263 static struct ofono_atom *get_preferred_atom(struct ofono_emulator *em)
2264 {
2265+ char *path;
2266+ GSList *l;
2267+ struct ofono_atom *preferred = em->atoms->data;
2268+
2269+ path = __ofono_system_settings_get_string_value(PREFERRED_VOICE_MODEM);
2270+ if (path == NULL)
2271+ goto end;
2272+
2273+ for (l = em->atoms; l; l = l->next) {
2274+ struct ofono_atom *atom = l->data;
2275+
2276+ if (g_strcmp0(__ofono_atom_get_path(atom), path) == 0) {
2277+ preferred = atom;
2278+ break;
2279+ }
2280+ }
2281+
2282+ g_free(path);
2283+
2284+end:
2285+ return preferred;
2286+}
2287+
2288+static struct ofono_atom *get_active_atom(struct ofono_emulator *em)
2289+{
2290 if (em->active_atom)
2291 return em->active_atom;
2292
2293- /*
2294- * TODO For the moment we just take the first on the list, we need to
2295- * ask the modem and have something configurable from settings.
2296- */
2297- return em->atoms->data;
2298+ return get_preferred_atom(em);
2299 }
2300
2301 static struct atom_callback *find_atom_callback(GSList *prefix_cbs,
2302@@ -1494,7 +1516,7 @@
2303 struct ofono_emulator_request req;
2304 struct ofono_atom *atom;
2305
2306- atom = get_preferred_atom(h->em);
2307+ atom = get_active_atom(h->em);
2308 prefix_cbs = g_hash_table_lookup(h->em->prefixes, h->prefix);
2309 atom_cb = find_atom_callback(prefix_cbs, atom);
2310 if (atom_cb == NULL) {
2311@@ -1689,11 +1711,7 @@
2312 }
2313
2314 /* Return FALSE if the modem is not the preferred one */
2315- /*
2316- * TODO For the moment we just take the first on the list, we need to
2317- * ask the modem and have some configurable from settings.
2318- */
2319- preferred = em->atoms->data;
2320+ preferred = get_preferred_atom(em);
2321 if (preferred == atom)
2322 return TRUE;
2323 else
2324
2325=== added file 'src/system-settings.c'
2326--- src/system-settings.c 1970-01-01 00:00:00 +0000
2327+++ src/system-settings.c 2016-03-14 09:03:03 +0000
2328@@ -0,0 +1,74 @@
2329+/*
2330+ *
2331+ * oFono - Open Source Telephony
2332+ *
2333+ * Copyright (C) 2016 Canonical Ltd.
2334+ *
2335+ * This program is free software; you can redistribute it and/or modify
2336+ * it under the terms of the GNU General Public License version 2 as
2337+ * published by the Free Software Foundation.
2338+ *
2339+ * This program is distributed in the hope that it will be useful,
2340+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2341+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2342+ * GNU General Public License for more details.
2343+ *
2344+ * You should have received a copy of the GNU General Public License
2345+ * along with this program; if not, write to the Free Software
2346+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2347+ *
2348+ */
2349+
2350+#ifdef HAVE_CONFIG_H
2351+#include <config.h>
2352+#endif
2353+
2354+#include <errno.h>
2355+#include <string.h>
2356+#include <glib.h>
2357+#include "ofono.h"
2358+#include "system-settings.h"
2359+
2360+static GSList *g_drivers = NULL;
2361+
2362+char *__ofono_system_settings_get_string_value(const char *name)
2363+{
2364+ GSList *d;
2365+ char *value = NULL;
2366+
2367+ for (d = g_drivers; d != NULL; d = d->next) {
2368+ const struct ofono_system_settings_driver *driver = d->data;
2369+
2370+ if (driver->get_string_value == NULL)
2371+ continue;
2372+
2373+ DBG("Calling system settings plugin '%s'", driver->name);
2374+
2375+ value = driver->get_string_value(name);
2376+ if (value == NULL)
2377+ continue;
2378+
2379+ DBG("property %s value %s", name, value);
2380+
2381+ return value;
2382+ }
2383+
2384+ return value;
2385+}
2386+
2387+int ofono_system_settings_driver_register(
2388+ struct ofono_system_settings_driver *driver)
2389+{
2390+ DBG("driver: %p name: %s", driver, driver->name);
2391+
2392+ g_drivers = g_slist_prepend(g_drivers, driver);
2393+ return 0;
2394+}
2395+
2396+void ofono_system_settings_driver_unregister(
2397+ const struct ofono_system_settings_driver *driver)
2398+{
2399+ DBG("driver: %p name: %s", driver, driver->name);
2400+
2401+ g_drivers = g_slist_remove(g_drivers, driver);
2402+}
2403
2404=== modified file 'src/voicecall.c'
2405--- src/voicecall.c 2016-01-15 16:03:09 +0000
2406+++ src/voicecall.c 2016-03-14 09:03:03 +0000
2407@@ -3463,9 +3463,11 @@
2408 char number[OFONO_MAX_PHONE_NUMBER_LENGTH + 1];
2409 struct ofono_error result;
2410
2411- /* Make sure we keep the system awake if we get woken up
2412- * shortly for processing the incoming request from the
2413- * HFP HF. */
2414+ /*
2415+ * If the device supports wakelocks, acquire one to
2416+ * ensure the device is kept awake after being woken
2417+ * by an incoming request from the HFP HF.
2418+ */
2419 wakelock_system_lock();
2420
2421 switch (ofono_emulator_request_get_type(req)) {
2422
2423=== added file 'src/wakelock.c'
2424--- src/wakelock.c 1970-01-01 00:00:00 +0000
2425+++ src/wakelock.c 2016-03-14 09:03:03 +0000
2426@@ -0,0 +1,152 @@
2427+/*
2428+ *
2429+ * oFono - Open Source Telephony
2430+ *
2431+ * Copyright (C) 2015 Jolla Ltd. All rights reserved.
2432+ * Contact: Hannu Mallat <hannu.mallat@jollamobile.com>
2433+ *
2434+ * This program is free software; you can redistribute it and/or modify
2435+ * it under the terms of the GNU General Public License as published by
2436+ * the Free Software Foundation; either version 2 of the License, or
2437+ * (at your option) any later version.
2438+ *
2439+ * This program is distributed in the hope that it will be useful,
2440+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2441+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2442+ * GNU General Public License for more details.
2443+ *
2444+ * You should have received a copy of the GNU General Public License
2445+ * along with this program; if not, write to the Free Software
2446+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2447+ *
2448+ */
2449+
2450+#ifdef HAVE_CONFIG_H
2451+#include <config.h>
2452+#endif
2453+
2454+#include <errno.h>
2455+#include <string.h>
2456+#include <glib.h>
2457+
2458+#include "log.h"
2459+#include "wakelock.h"
2460+#include "ofono.h"
2461+
2462+#define SYSTEM_WAKELOCK_NAME "ofono-system"
2463+#define SYSTEM_WAKELOCK_DURATION 30
2464+
2465+static char *impl = NULL;
2466+static struct wakelock_table table;
2467+
2468+static struct wakelock *system_wakelock = NULL;
2469+static guint system_wakelock_source = 0;
2470+
2471+static gboolean system_wakelock_put(gpointer user_data)
2472+{
2473+ DBG("Releasing system wakelock");
2474+ wakelock_release(system_wakelock);
2475+ system_wakelock_source = 0;
2476+ return FALSE;
2477+}
2478+
2479+void wakelock_system_lock(void)
2480+{
2481+ guint old_source;
2482+
2483+ if (impl == NULL)
2484+ return;
2485+
2486+ DBG("Acquiring system wakelock");
2487+
2488+ old_source = system_wakelock_source;
2489+
2490+ system_wakelock_source = g_timeout_add_seconds(SYSTEM_WAKELOCK_DURATION,
2491+ system_wakelock_put,
2492+ NULL);
2493+
2494+ if (system_wakelock_source)
2495+ wakelock_acquire(system_wakelock);
2496+
2497+ if (old_source) {
2498+ g_source_remove(old_source);
2499+ wakelock_release(system_wakelock);
2500+ }
2501+}
2502+
2503+int wakelock_create(const char *name, struct wakelock **wakelock)
2504+{
2505+ if (impl == NULL) {
2506+ *wakelock = NULL;
2507+ return -EINVAL;
2508+ }
2509+
2510+ return (table.create)(name, wakelock);
2511+}
2512+
2513+int wakelock_free(struct wakelock *wakelock)
2514+{
2515+ if (impl == NULL)
2516+ return -EINVAL;
2517+
2518+ return table.free(wakelock);
2519+}
2520+
2521+int wakelock_acquire(struct wakelock *wakelock)
2522+{
2523+ if (impl == NULL)
2524+ return -EINVAL;
2525+
2526+ return table.acquire(wakelock);
2527+}
2528+
2529+int wakelock_release(struct wakelock *wakelock)
2530+{
2531+ if (impl == NULL)
2532+ return -EINVAL;
2533+
2534+ return table.release(wakelock);
2535+}
2536+
2537+ofono_bool_t wakelock_is_locked(struct wakelock *wakelock) {
2538+ if (impl == NULL)
2539+ return -EINVAL;
2540+
2541+ return table.is_locked(wakelock);
2542+}
2543+
2544+int wakelock_plugin_register(const char *name, struct wakelock_table *fns)
2545+{
2546+ if (impl)
2547+ return -EALREADY;
2548+
2549+ impl = g_strdup(name);
2550+ memcpy(&table, fns, sizeof(struct wakelock_table));
2551+ return 0;
2552+}
2553+
2554+int wakelock_plugin_unregister(void)
2555+{
2556+ if (impl == NULL)
2557+ return -ENOENT;
2558+
2559+ memset(&table, 0, sizeof(struct wakelock_table));
2560+ g_free(impl);
2561+ impl = NULL;
2562+
2563+ return 0;
2564+}
2565+
2566+int __ofono_wakelock_init(void)
2567+{
2568+ if (wakelock_create(SYSTEM_WAKELOCK_NAME, &system_wakelock) < 0)
2569+ ofono_warn("Failed to create system keep alive wakelock");
2570+
2571+ return 0;
2572+}
2573+
2574+void __ofono_wakelock_cleanup(void)
2575+{
2576+ if (system_wakelock)
2577+ wakelock_free(system_wakelock);
2578+}
2579
2580=== removed file 'src/wakelock.c'
2581--- src/wakelock.c 2016-01-15 16:03:09 +0000
2582+++ src/wakelock.c 1970-01-01 00:00:00 +0000
2583@@ -1,151 +0,0 @@
2584-/*
2585- *
2586- * oFono - Open Source Telephony
2587- *
2588- * Copyright (C) 2015 Jolla Ltd. All rights reserved.
2589- * Contact: Hannu Mallat <hannu.mallat@jollamobile.com>
2590- *
2591- * This program is free software; you can redistribute it and/or modify
2592- * it under the terms of the GNU General Public License as published by
2593- * the Free Software Foundation; either version 2 of the License, or
2594- * (at your option) any later version.
2595- *
2596- * This program is distributed in the hope that it will be useful,
2597- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2598- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2599- * GNU General Public License for more details.
2600- *
2601- * You should have received a copy of the GNU General Public License
2602- * along with this program; if not, write to the Free Software
2603- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2604- *
2605- */
2606-
2607-#ifdef HAVE_CONFIG_H
2608-#include <config.h>
2609-#endif
2610-
2611-#include <errno.h>
2612-#include <string.h>
2613-#include <glib.h>
2614-
2615-#include "log.h"
2616-#include "wakelock.h"
2617-#include "ofono.h"
2618-
2619-#define SYSTEM_WAKELOCK_NAME "ofono-system"
2620-#define SYSTEM_WAKELOCK_DURATION 30
2621-
2622-static char *impl = NULL;
2623-static struct wakelock_table table;
2624-
2625-static struct wakelock *system_wakelock = NULL;
2626-static guint system_wakelock_source = 0;
2627-
2628-static gboolean system_wakelock_put(gpointer user_data)
2629-{
2630- DBG("Releasing system wakelock");
2631- wakelock_release(system_wakelock);
2632- system_wakelock_source = 0;
2633- return FALSE;
2634-}
2635-
2636-void wakelock_system_lock(void)
2637-{
2638- guint old_source;
2639-
2640- if (!impl)
2641- return;
2642-
2643- DBG("Acquiring system wakelock");
2644-
2645- old_source = system_wakelock_source;
2646-
2647- system_wakelock_source = g_timeout_add_seconds(SYSTEM_WAKELOCK_DURATION,
2648- system_wakelock_put,
2649- NULL);
2650- if (system_wakelock_source)
2651- wakelock_acquire(system_wakelock);
2652-
2653- if (old_source) {
2654- g_source_remove(old_source);
2655- wakelock_release(system_wakelock);
2656- }
2657-}
2658-
2659-int wakelock_create(const char *name, struct wakelock **wakelock)
2660-{
2661- if (!impl) {
2662- *wakelock = NULL;
2663- return -EINVAL;
2664- }
2665-
2666- return (table.create)(name, wakelock);
2667-}
2668-
2669-int wakelock_free(struct wakelock *wakelock)
2670-{
2671- if (!impl)
2672- return -EINVAL;
2673-
2674- return table.free(wakelock);
2675-}
2676-
2677-int wakelock_acquire(struct wakelock *wakelock)
2678-{
2679- if (!impl)
2680- return -EINVAL;
2681-
2682- return table.acquire(wakelock);
2683-}
2684-
2685-int wakelock_release(struct wakelock *wakelock)
2686-{
2687- if (!impl)
2688- return -EINVAL;
2689-
2690- return table.release(wakelock);
2691-}
2692-
2693-ofono_bool_t wakelock_is_locked(struct wakelock *wakelock) {
2694- if (!impl)
2695- return -EINVAL;
2696-
2697- return table.is_locked(wakelock);
2698-}
2699-
2700-int wakelock_plugin_register(const char *name, struct wakelock_table *fns)
2701-{
2702- if (impl)
2703- return -EALREADY;
2704-
2705- impl = g_strdup(name);
2706- memcpy(&table, fns, sizeof(struct wakelock_table));
2707- return 0;
2708-}
2709-
2710-int wakelock_plugin_unregister(void)
2711-{
2712- if (!impl)
2713- return -ENOENT;
2714-
2715- memset(&table, 0, sizeof(struct wakelock_table));
2716- g_free(impl);
2717- impl = NULL;
2718-
2719- return 0;
2720-}
2721-
2722-int __ofono_wakelock_init(void)
2723-{
2724- if (wakelock_create(SYSTEM_WAKELOCK_NAME, &system_wakelock) < 0)
2725- ofono_warn("Failed to create system keep alive wakelock");
2726-
2727- return 0;
2728-}
2729-
2730-void __ofono_wakelock_cleanup(void)
2731-{
2732- if (system_wakelock)
2733- wakelock_free(system_wakelock);
2734-}
2735
2736=== added file 'unit/rilmodem-test-server.c'
2737--- unit/rilmodem-test-server.c 1970-01-01 00:00:00 +0000
2738+++ unit/rilmodem-test-server.c 2016-03-14 09:03:03 +0000
2739@@ -0,0 +1,237 @@
2740+/*
2741+ *
2742+ * oFono - Open Source Telephony
2743+ *
2744+ * Copyright (C) 2015 Canonical Ltd.
2745+ *
2746+ * This program is free software; you can redistribute it and/or modify
2747+ * it under the terms of the GNU General Public License version 2 as
2748+ * published by the Free Software Foundation.
2749+ *
2750+ * This program is distributed in the hope that it will be useful,
2751+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2752+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2753+ * GNU General Public License for more details.
2754+ *
2755+ * You should have received a copy of the GNU General Public License
2756+ * along with this program; if not, write to the Free Software
2757+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2758+ *
2759+ */
2760+
2761+#ifdef HAVE_CONFIG_H
2762+#include <config.h>
2763+#endif
2764+
2765+#define _GNU_SOURCE
2766+#include <stdio.h>
2767+#include <netinet/in.h>
2768+#include <sys/socket.h>
2769+#include <sys/un.h>
2770+#include <unistd.h>
2771+
2772+#include <ofono/types.h>
2773+
2774+#include <gril.h>
2775+
2776+#include "rilmodem-test-server.h"
2777+
2778+#define MAX_REQUEST_SIZE 4096
2779+#define RIL_SERVER_SOCK_PATH "/tmp/unittestril"
2780+
2781+struct server_data {
2782+ int server_sk;
2783+ ConnectFunc connect_func;
2784+ GIOChannel *server_io;
2785+ char *sock_name;
2786+ const struct rilmodem_test_data *rtd;
2787+ void *user_data;
2788+};
2789+
2790+/* Warning: length is stored in network order */
2791+struct rsp_hdr {
2792+ uint32_t length;
2793+ uint32_t unsolicited;
2794+ uint32_t serial;
2795+ uint32_t error;
2796+};
2797+
2798+static gboolean read_server(gpointer data)
2799+{
2800+ struct server_data *sd = data;
2801+ GIOStatus status;
2802+ gsize offset, rbytes, wbytes;
2803+ gchar *buf, *bufp;
2804+ uint32_t req_serial;
2805+ struct rsp_hdr rsp;
2806+
2807+ buf = g_malloc0(MAX_REQUEST_SIZE);
2808+
2809+ status = g_io_channel_read_chars(sd->server_io, buf, MAX_REQUEST_SIZE,
2810+ &rbytes, NULL);
2811+ g_assert(status == G_IO_STATUS_NORMAL);
2812+ g_assert(rbytes == sd->rtd->req_size);
2813+
2814+ /* validate len, and request_id */
2815+ g_assert(!memcmp(buf, sd->rtd->req_data, (sizeof(uint32_t) * 2)));
2816+
2817+ /*
2818+ * header: size (uint32), reqid (uin32), serial (uint32)
2819+ * header size == 16 ( excludes sizeof(size) )
2820+ */
2821+
2822+ /* advance past request_no */
2823+ bufp = buf + (sizeof(uint32_t) * 2);
2824+
2825+ req_serial = (uint32_t) *bufp;
2826+
2827+ /* advance past serial_no */
2828+ bufp += sizeof(uint32_t);
2829+
2830+ /* validate the rest of the parcel... */
2831+ offset = (sizeof(uint32_t) * 3);
2832+ g_assert(!memcmp(bufp, sd->rtd->req_data + offset,
2833+ sd->rtd->req_size - offset));
2834+
2835+ /* Length does not include the length field. Network order. */
2836+ rsp.length = htonl(sizeof(rsp) - sizeof(rsp.length) +
2837+ sd->rtd->rsp_size);
2838+ rsp.unsolicited = 0;
2839+ rsp.serial = req_serial;
2840+ rsp.error = sd->rtd->rsp_error;
2841+
2842+ /* copy header */
2843+ memcpy(buf, &rsp, sizeof(rsp));
2844+
2845+ if (sd->rtd->rsp_size) {
2846+ bufp = buf + sizeof(rsp);
2847+
2848+ memcpy(bufp, sd->rtd->rsp_data, sd->rtd->rsp_size);
2849+ }
2850+
2851+ status = g_io_channel_write_chars(sd->server_io,
2852+ buf,
2853+ sizeof(rsp) + sd->rtd->rsp_size,
2854+ &wbytes, NULL);
2855+
2856+ /* FIXME: assert wbytes is correct */
2857+
2858+ g_assert(status == G_IO_STATUS_NORMAL);
2859+
2860+ g_free(buf);
2861+ g_io_channel_unref(sd->server_io);
2862+
2863+ return FALSE;
2864+}
2865+
2866+static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
2867+ gpointer data)
2868+{
2869+ struct server_data *sd = data;
2870+ struct sockaddr saddr;
2871+ unsigned int len = sizeof(saddr);
2872+ int fd;
2873+ GIOStatus status;
2874+
2875+ g_assert(cond == G_IO_IN);
2876+
2877+ fd = accept(sd->server_sk, &saddr, &len);
2878+ g_assert(fd != -1);
2879+
2880+ sd->server_io = g_io_channel_unix_new(fd);
2881+ g_assert(sd->server_io != NULL);
2882+
2883+ status = g_io_channel_set_encoding(sd->server_io, NULL, NULL);
2884+ g_assert(status == G_IO_STATUS_NORMAL);
2885+
2886+ g_io_channel_set_buffered(sd->server_io, FALSE);
2887+ g_io_channel_set_close_on_unref(sd->server_io, TRUE);
2888+
2889+ if (sd->connect_func)
2890+ sd->connect_func(sd->user_data);
2891+
2892+ if (sd->rtd->unsol_test == FALSE)
2893+ g_idle_add(read_server, sd);
2894+
2895+ return FALSE;
2896+}
2897+
2898+void rilmodem_test_server_close(struct server_data *sd)
2899+{
2900+ g_assert(sd->server_sk);
2901+ close(sd->server_sk);
2902+ remove(sd->sock_name);
2903+ g_free(sd->sock_name);
2904+ g_free(sd);
2905+}
2906+
2907+struct server_data *rilmodem_test_server_create(ConnectFunc connect,
2908+ const struct rilmodem_test_data *test_data,
2909+ void *data)
2910+{
2911+ GIOChannel *io;
2912+ struct sockaddr_un addr;
2913+ int retval;
2914+ struct server_data *sd;
2915+
2916+ sd = g_new0(struct server_data, 1);
2917+
2918+ sd->connect_func = connect;
2919+ sd->user_data = data;
2920+ sd->rtd = test_data;
2921+
2922+ sd->server_sk = socket(AF_UNIX, SOCK_STREAM, 0);
2923+ g_assert(sd->server_sk);
2924+
2925+ sd->sock_name =
2926+ g_strdup_printf(RIL_SERVER_SOCK_PATH"%u", (unsigned) getpid());
2927+
2928+ memset(&addr, 0, sizeof(addr));
2929+ addr.sun_family = AF_UNIX;
2930+ strncpy(addr.sun_path, sd->sock_name, sizeof(addr.sun_path) - 1);
2931+
2932+ /* Unlink any existing socket for this session */
2933+ unlink(addr.sun_path);
2934+
2935+ retval = bind(sd->server_sk, (struct sockaddr *) &addr, sizeof(addr));
2936+ g_assert(retval >= 0);
2937+
2938+ retval = listen(sd->server_sk, 0);
2939+ g_assert(retval >= 0);
2940+
2941+ io = g_io_channel_unix_new(sd->server_sk);
2942+ g_assert(io != NULL);
2943+
2944+ g_io_channel_set_close_on_unref(io, TRUE);
2945+ g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
2946+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
2947+ on_socket_connected, sd, NULL);
2948+
2949+ g_io_channel_unref(io);
2950+
2951+ return sd;
2952+}
2953+
2954+void rilmodem_test_server_write(struct server_data *sd,
2955+ const unsigned char *buf,
2956+ const size_t buf_len)
2957+{
2958+ GIOStatus status;
2959+ gsize wbytes;
2960+
2961+ status = g_io_channel_write_chars(sd->server_io,
2962+ (const char *) buf,
2963+ buf_len,
2964+ &wbytes, NULL);
2965+
2966+ g_assert(status == G_IO_STATUS_NORMAL);
2967+
2968+ status = g_io_channel_flush(sd->server_io, NULL);
2969+
2970+ g_assert(status == G_IO_STATUS_NORMAL);
2971+}
2972+
2973+const char *rilmodem_test_get_socket_name(struct server_data *sd)
2974+{
2975+ return sd->sock_name;
2976+}
2977
2978=== added file 'unit/rilmodem-test-server.h'
2979--- unit/rilmodem-test-server.h 1970-01-01 00:00:00 +0000
2980+++ unit/rilmodem-test-server.h 2016-03-14 09:03:03 +0000
2981@@ -0,0 +1,47 @@
2982+/*
2983+ *
2984+ * oFono - Open Source Telephony
2985+ *
2986+ * Copyright (C) 2015 Canonical Ltd.
2987+ *
2988+ * This program is free software; you can redistribute it and/or modify
2989+ * it under the terms of the GNU General Public License version 2 as
2990+ * published by the Free Software Foundation.
2991+ *
2992+ * This program is distributed in the hope that it will be useful,
2993+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2994+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2995+ * GNU General Public License for more details.
2996+ *
2997+ * You should have received a copy of the GNU General Public License
2998+ * along with this program; if not, write to the Free Software
2999+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3000+ *
3001+ */
3002+
3003+struct server_data;
3004+
3005+struct rilmodem_test_data {
3006+ const unsigned char *req_data;
3007+
3008+ const size_t req_size;
3009+
3010+ uint32_t rsp_error;
3011+ const unsigned char *rsp_data;
3012+ const size_t rsp_size;
3013+ gboolean unsol_test;
3014+};
3015+
3016+typedef void (*ConnectFunc)(void *data);
3017+
3018+void rilmodem_test_server_close(struct server_data *sd);
3019+
3020+struct server_data *rilmodem_test_server_create(ConnectFunc connect,
3021+ const struct rilmodem_test_data *test_data,
3022+ void *data);
3023+
3024+void rilmodem_test_server_write(struct server_data *sd,
3025+ const unsigned char *buf,
3026+ const size_t buf_len);
3027+
3028+const char *rilmodem_test_get_socket_name(struct server_data *sd);
3029
3030=== modified file 'unit/test-grilreply.c'
3031--- unit/test-grilreply.c 2015-10-07 07:14:11 +0000
3032+++ unit/test-grilreply.c 2016-03-14 09:03:03 +0000
3033@@ -1420,7 +1420,7 @@
3034 * RIL_REQUEST_SET_FACILITY_LOCK reply with no parameters.
3035 */
3036 static const struct set_facility_lock_test reply_set_facility_lock_valid_1 = {
3037- .retries = -1,
3038+ .retries = 0,
3039 .msg = {
3040 .buf = NULL,
3041 .buf_len = 0,
3042@@ -1686,7 +1686,7 @@
3043
3044 reason = g_ril_reply_parse_call_fail_cause(NULL, data);
3045
3046- g_assert(reason >= 0);
3047+ g_assert(reason == OFONO_DISCONNECT_REASON_REMOTE_HANGUP);
3048 }
3049
3050 static void test_reply_get_mute_off(gconstpointer data)
3051
3052=== modified file 'unit/test-grilunsol.c'
3053--- unit/test-grilunsol.c 2014-08-19 16:29:51 +0000
3054+++ unit/test-grilunsol.c 2016-03-14 09:03:03 +0000
3055@@ -525,6 +525,115 @@
3056 .error = 0,
3057 };
3058
3059+/*
3060+ * The following hexadecimal data represents a serialized Binder parcel
3061+ * instance containing a valid RIL_UNSOL_RIL_CONNECTED message with the
3062+ * following parameters:
3063+ *
3064+ * [1, 10]
3065+ */
3066+static const guchar unsol_on_ril_connected_valid_parcel1[] = {
3067+ 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00
3068+};
3069+
3070+static const struct ril_msg unsol_on_ril_connected_valid_1 = {
3071+ .buf = (gchar *) &unsol_on_ril_connected_valid_parcel1,
3072+ .buf_len = sizeof(unsol_on_ril_connected_valid_parcel1),
3073+ .unsolicited = TRUE,
3074+ .req = RIL_UNSOL_RIL_CONNECTED,
3075+ .serial_no = 0,
3076+ .error = 0,
3077+};
3078+
3079+/*
3080+ * The following hexadecimal data represents a serialized Binder parcel
3081+ * instance containing a valid RIL_UNSOL_RIL_CONNECTED message with the
3082+ * following parameters:
3083+ *
3084+ * [2, 10, 11]
3085+ */
3086+static const guchar unsol_on_ril_connected_valid_parcel2[] = {
3087+ 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00
3088+};
3089+
3090+static const struct ril_msg unsol_on_ril_connected_valid_2 = {
3091+ .buf = (gchar *) &unsol_on_ril_connected_valid_parcel2,
3092+ .buf_len = sizeof(unsol_on_ril_connected_valid_parcel2),
3093+ .unsolicited = TRUE,
3094+ .req = RIL_UNSOL_RIL_CONNECTED,
3095+ .serial_no = 0,
3096+ .error = 0,
3097+};
3098+
3099+/*
3100+ * The following hexadecimal data represents a serialized Binder parcel
3101+ * instance containing a valid RIL_UNSOL_RIL_CONNECTED message with the
3102+ * following parameters:
3103+ *
3104+ * [1, 10, 11]
3105+ */
3106+static const guchar unsol_on_ril_connected_valid_parcel3[] = {
3107+ 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00
3108+};
3109+
3110+static const struct ril_msg unsol_on_ril_connected_valid_3 = {
3111+ .buf = (gchar *) &unsol_on_ril_connected_valid_parcel3,
3112+ .buf_len = sizeof(unsol_on_ril_connected_valid_parcel3),
3113+ .unsolicited = TRUE,
3114+ .req = RIL_UNSOL_RIL_CONNECTED,
3115+ .serial_no = 0,
3116+ .error = 0,
3117+};
3118+
3119+static const struct ril_msg unsol_on_ril_connected_invalid_1 = {
3120+ .buf = "",
3121+ .buf_len = 0,
3122+ .unsolicited = TRUE,
3123+ .req = RIL_UNSOL_RIL_CONNECTED,
3124+ .serial_no = 0,
3125+ .error = 0,
3126+};
3127+
3128+/*
3129+ * The following hexadecimal data represents a serialized Binder parcel
3130+ * instance containing an invalid RIL_UNSOL_RIL_CONNECTED message with the
3131+ * following parameters:
3132+ *
3133+ * [0]
3134+ */
3135+static const guchar unsol_on_ril_connected_invalid_parcel2[] = {
3136+ 0x00, 0x00, 0x00, 0x00
3137+};
3138+
3139+static const struct ril_msg unsol_on_ril_connected_invalid_2 = {
3140+ .buf = (gchar *) &unsol_on_ril_connected_invalid_parcel2,
3141+ .buf_len = sizeof(unsol_on_ril_connected_invalid_parcel2),
3142+ .unsolicited = TRUE,
3143+ .req = RIL_UNSOL_RIL_CONNECTED,
3144+ .serial_no = 0,
3145+ .error = 0,
3146+};
3147+
3148+/*
3149+ * The following hexadecimal data represents a serialized Binder parcel
3150+ * instance containing an invalid RIL_UNSOL_RIL_CONNECTED message with the
3151+ * following parameters:
3152+ *
3153+ * [1]
3154+ */
3155+static const guchar unsol_on_ril_connected_invalid_parcel3[] = {
3156+ 0x01, 0x00, 0x00, 0x00
3157+};
3158+
3159+static const struct ril_msg unsol_on_ril_connected_invalid_3 = {
3160+ .buf = (gchar *) &unsol_on_ril_connected_invalid_parcel3,
3161+ .buf_len = sizeof(unsol_on_ril_connected_invalid_parcel3),
3162+ .unsolicited = TRUE,
3163+ .req = RIL_UNSOL_RIL_CONNECTED,
3164+ .serial_no = 0,
3165+ .error = 0,
3166+};
3167+
3168 static void test_reply_data_call_invalid(gconstpointer data)
3169 {
3170 struct ril_data_call_list *call_list;
3171@@ -599,6 +708,24 @@
3172 g_assert(unsol != NULL);
3173 g_ril_unsol_free_ussd(unsol);
3174 }
3175+
3176+static void test_unsol_on_ril_connected_valid(gconstpointer data)
3177+{
3178+ int version;
3179+
3180+ version = g_ril_unsol_parse_connected(NULL, (struct ril_msg *) data);
3181+
3182+ g_assert(version == 10);
3183+}
3184+
3185+static void test_unsol_on_ril_connected_invalid(gconstpointer data)
3186+{
3187+ int version;
3188+
3189+ version = g_ril_unsol_parse_connected(NULL, (struct ril_msg *) data);
3190+
3191+ g_assert(version == RIL_VERSION_UNSPECIFIED);
3192+}
3193 #endif
3194
3195 int main(int argc, char **argv)
3196@@ -693,6 +820,36 @@
3197 &unsol_on_ussd_valid_1,
3198 test_unsol_on_ussd_valid);
3199
3200+ g_test_add_data_func("/testgrilunsol/ril-connected: "
3201+ "valid RIL_CONNECTED Test 1",
3202+ &unsol_on_ril_connected_valid_1,
3203+ test_unsol_on_ril_connected_valid);
3204+
3205+ g_test_add_data_func("/testgrilunsol/ril-connected: "
3206+ "valid RIL_CONNECTED Test 2",
3207+ &unsol_on_ril_connected_valid_2,
3208+ test_unsol_on_ril_connected_valid);
3209+
3210+ g_test_add_data_func("/testgrilunsol/ril-connected: "
3211+ "valid RIL_CONNECTED Test 3",
3212+ &unsol_on_ril_connected_valid_3,
3213+ test_unsol_on_ril_connected_valid);
3214+
3215+ g_test_add_data_func("/testgrilunsol/ril-connected: "
3216+ "invalid RIL_CONNECTED Test 1",
3217+ &unsol_on_ril_connected_invalid_1,
3218+ test_unsol_on_ril_connected_invalid);
3219+
3220+ g_test_add_data_func("/testgrilunsol/ril-connected: "
3221+ "invalid RIL_CONNECTED Test 2",
3222+ &unsol_on_ril_connected_invalid_2,
3223+ test_unsol_on_ril_connected_invalid);
3224+
3225+ g_test_add_data_func("/testgrilunsol/ril-connected: "
3226+ "invalid RIL_CONNECTED Test 3",
3227+ &unsol_on_ril_connected_invalid_3,
3228+ test_unsol_on_ril_connected_invalid);
3229+
3230 #endif
3231 return g_test_run();
3232 }
3233
3234=== added file 'unit/test-rilmodem-cb.c'
3235--- unit/test-rilmodem-cb.c 1970-01-01 00:00:00 +0000
3236+++ unit/test-rilmodem-cb.c 2016-03-14 09:03:03 +0000
3237@@ -0,0 +1,605 @@
3238+/*
3239+ *
3240+ * oFono - Open Source Telephony
3241+ *
3242+ * Copyright (C) 2015 Canonical Ltd.
3243+ *
3244+ * This program is free software; you can redistribute it and/or modify
3245+ * it under the terms of the GNU General Public License version 2 as
3246+ * published by the Free Software Foundation.
3247+ *
3248+ * This program is distributed in the hope that it will be useful,
3249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3251+ * GNU General Public License for more details.
3252+ *
3253+ * You should have received a copy of the GNU General Public License
3254+ * along with this program; if not, write to the Free Software
3255+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3256+ *
3257+ */
3258+
3259+#ifdef HAVE_CONFIG_H
3260+#include <config.h>
3261+#endif
3262+
3263+#define _GNU_SOURCE
3264+#include <assert.h>
3265+#include <errno.h>
3266+#include <glib.h>
3267+#include <stdio.h>
3268+#include <netinet/in.h>
3269+#include <sys/socket.h>
3270+#include <sys/un.h>
3271+#include <unistd.h>
3272+
3273+#include <ofono/modem.h>
3274+#include <ofono/types.h>
3275+#include <ofono/call-barring.h>
3276+#include <gril.h>
3277+
3278+#include "common.h"
3279+#include "ril_constants.h"
3280+#include "rilmodem-test-server.h"
3281+
3282+static GMainLoop *mainloop;
3283+
3284+static const struct ofono_call_barring_driver *cbdriver;
3285+
3286+struct rilmodem_cb_data {
3287+ GRil *ril;
3288+ struct ofono_modem *modem;
3289+ gconstpointer test_data;
3290+ struct ofono_call_barring *cb;
3291+ struct server_data *serverd;
3292+};
3293+
3294+typedef gboolean (*StartFunc)(gpointer data);
3295+
3296+struct cb_data {
3297+ StartFunc start_func;
3298+
3299+ const char *lock;
3300+ int enable;
3301+ const char *passwd;
3302+ const char *new_passwd;
3303+ int cls;
3304+
3305+ struct rilmodem_test_data rtd;
3306+ enum ofono_error_type error_type;
3307+
3308+ int status;
3309+};
3310+
3311+static void query_callback(const struct ofono_error *error, int status,
3312+ gpointer data)
3313+{
3314+ struct rilmodem_cb_data *rsd = data;
3315+ const struct cb_data *cbd = rsd->test_data;
3316+
3317+ g_assert(error->type == cbd->error_type);
3318+
3319+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
3320+ g_assert(status == cbd->status);
3321+
3322+ g_main_loop_quit(mainloop);
3323+}
3324+
3325+static gboolean trigger_query(gpointer data)
3326+{
3327+ struct rilmodem_cb_data *rsd = data;
3328+ const struct cb_data *cbd = rsd->test_data;
3329+
3330+ g_assert(cbdriver->query != NULL);
3331+ cbdriver->query(rsd->cb, cbd->lock, cbd->cls, query_callback, rsd);
3332+
3333+ return FALSE;
3334+}
3335+
3336+static void set_callback(const struct ofono_error *error, gpointer data)
3337+{
3338+ struct rilmodem_cb_data *rsd = data;
3339+ const struct cb_data *cbd = rsd->test_data;
3340+
3341+ g_assert(error->type == cbd->error_type);
3342+
3343+ g_main_loop_quit(mainloop);
3344+}
3345+
3346+static gboolean trigger_set(gpointer data)
3347+{
3348+ struct rilmodem_cb_data *rsd = data;
3349+ const struct cb_data *cbd = rsd->test_data;
3350+
3351+ g_assert(cbdriver->set != NULL);
3352+ cbdriver->set(rsd->cb, cbd->lock, cbd->enable, cbd->passwd, cbd->cls,
3353+ set_callback, rsd);
3354+
3355+ return FALSE;
3356+}
3357+
3358+static void set_passwd_callback(const struct ofono_error *error, gpointer data)
3359+{
3360+ struct rilmodem_cb_data *rsd = data;
3361+ const struct cb_data *cbd = rsd->test_data;
3362+
3363+ g_assert(error->type == cbd->error_type);
3364+
3365+ g_main_loop_quit(mainloop);
3366+}
3367+
3368+static gboolean trigger_set_passwd(gpointer data)
3369+{
3370+ struct rilmodem_cb_data *rsd = data;
3371+ const struct cb_data *cbd = rsd->test_data;
3372+
3373+ g_assert(cbdriver->set_passwd != NULL);
3374+ cbdriver->set_passwd(rsd->cb, cbd->lock, cbd->passwd, cbd->new_passwd,
3375+ set_passwd_callback, rsd);
3376+
3377+ return FALSE;
3378+}
3379+
3380+/* RIL_REQUEST_GET_FACILITY_LOCK witht the following parameters:
3381+ *
3382+ * facility="OI" (outgoing international calls)
3383+ * service class=1 ( VOICE )
3384+ */
3385+static const guchar req_get_facility_lock_parcel_1[] = {
3386+ 0x00, 0x00, 0x00, 0x2c, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3387+ 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x49, 0x00,
3388+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3389+ 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
3390+};
3391+
3392+/*
3393+ * The following structure contains test data for a valid
3394+ * RIL_REQUEST_GET_FACILITY_LOCK reply with parameter {1}
3395+ * which indicates that call-barring is activated for the
3396+ * previously specified facility for the VOICE class.
3397+ */
3398+static const guchar reply_get_facility_lock_data_valid_1[] = {
3399+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
3400+};
3401+
3402+static const struct cb_data testdata_query_valid_1 = {
3403+ .start_func = trigger_query,
3404+ .lock = "OI",
3405+ .cls = BEARER_CLASS_VOICE,
3406+ .rtd = {
3407+ .req_data = req_get_facility_lock_parcel_1,
3408+ .req_size = sizeof(req_get_facility_lock_parcel_1),
3409+ .rsp_data = reply_get_facility_lock_data_valid_1,
3410+ .rsp_size = sizeof(reply_get_facility_lock_data_valid_1),
3411+ },
3412+ .status = BEARER_CLASS_VOICE,
3413+};
3414+
3415+/* GENERIC_FAILURE returned in RIL reply */
3416+static const struct cb_data testdata_query_invalid_1 = {
3417+ .start_func = trigger_query,
3418+ .lock = "OI",
3419+ .cls = BEARER_CLASS_VOICE,
3420+ .rtd = {
3421+ .req_data = req_get_facility_lock_parcel_1,
3422+ .req_size = sizeof(req_get_facility_lock_parcel_1),
3423+ .rsp_data = reply_get_facility_lock_data_valid_1,
3424+ .rsp_size = sizeof(reply_get_facility_lock_data_valid_1),
3425+ .rsp_error = RIL_E_GENERIC_FAILURE,
3426+ },
3427+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3428+};
3429+
3430+/*
3431+ * The following structure contains test data for a valid
3432+ * RIL_REQUEST_GET_FACILITY_LOCK reply with invalid number
3433+ * of parameters {0} specified.
3434+ */
3435+static const guchar reply_get_facility_lock_data_invalid_2[] = {
3436+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
3437+};
3438+
3439+static const struct cb_data testdata_query_invalid_2 = {
3440+ .start_func = trigger_query,
3441+ .lock = "OI",
3442+ .cls = BEARER_CLASS_VOICE,
3443+ .rtd = {
3444+ .req_data = req_get_facility_lock_parcel_1,
3445+ .req_size = sizeof(req_get_facility_lock_parcel_1),
3446+ .rsp_data = reply_get_facility_lock_data_invalid_2,
3447+ .rsp_size = sizeof(reply_get_facility_lock_data_invalid_2),
3448+ },
3449+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3450+};
3451+
3452+/*
3453+ * The following structure contains test data for an invalid
3454+ * RIL_REQUEST_GET_FACILITY_LOCK reply with an invalid class
3455+ * mask (-255).
3456+ */
3457+static const guchar reply_get_facility_lock_data_invalid_3[] = {
3458+ 0x01, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff
3459+};
3460+
3461+static const struct cb_data testdata_query_invalid_3 = {
3462+ .start_func = trigger_query,
3463+ .lock = "OI",
3464+ .cls = BEARER_CLASS_VOICE,
3465+ .rtd = {
3466+ .req_data = req_get_facility_lock_parcel_1,
3467+ .req_size = sizeof(req_get_facility_lock_parcel_1),
3468+ .rsp_data = reply_get_facility_lock_data_invalid_3,
3469+ .rsp_size = sizeof(reply_get_facility_lock_data_invalid_3),
3470+ },
3471+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3472+};
3473+
3474+/*
3475+ * The following structure contains test data for a
3476+ * RIL_REQUEST_GET_FACILITY_LOCK reply with an incomplete
3477+ * integer parameter, which will trigger a malformed parcel
3478+ * error.
3479+ */
3480+static const guchar reply_get_facility_lock_data_invalid_4[] = {
3481+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
3482+};
3483+
3484+static const struct cb_data testdata_query_invalid_4 = {
3485+ .start_func = trigger_query,
3486+ .lock = "OI",
3487+ .cls = BEARER_CLASS_VOICE,
3488+ .rtd = {
3489+ .req_data = req_get_facility_lock_parcel_1,
3490+ .req_size = sizeof(req_get_facility_lock_parcel_1),
3491+ .rsp_data = reply_get_facility_lock_data_invalid_4,
3492+ .rsp_size = sizeof(reply_get_facility_lock_data_invalid_4),
3493+ },
3494+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3495+};
3496+
3497+/* RIL_REQUEST_SET_FACILITY_LOCK witht the following parameters:
3498+ *
3499+ * facility="OI" (outgoing international calls)
3500+ * unlock (0)
3501+ * passwd="0000"
3502+ * service class=1 ( VOICE )
3503+ */
3504+static const guchar req_set_facility_lock_parcel_1[] = {
3505+ 0x00, 0x00, 0x00, 0x3c, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3506+ 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x49, 0x00,
3507+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
3508+ 0x04, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00,
3509+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
3510+ 0xff, 0xff, 0xff, 0xff
3511+};
3512+
3513+/*
3514+ * This test doesn't specify any data for RIL_REQUEST_SET_FACILITY_LOCK reply
3515+ * to simulate a reply generated by mako.
3516+ */
3517+static const struct cb_data testdata_set_valid_1 = {
3518+ .start_func = trigger_set,
3519+ .lock = "OI",
3520+ .passwd = "0000",
3521+ .cls = BEARER_CLASS_VOICE,
3522+ .rtd = {
3523+ .req_data = req_set_facility_lock_parcel_1,
3524+ .req_size = sizeof(req_set_facility_lock_parcel_1),
3525+ },
3526+};
3527+
3528+/* RIL_REQUEST_SET_FACILITY_LOCK witht the following parameters:
3529+ *
3530+ * facility="OI" (outgoing international calls)
3531+ * unlock (1)
3532+ * passwd="0000"
3533+ * service class=0 ( NONE )
3534+ */
3535+static const guchar req_set_facility_lock_parcel_2[] = {
3536+ 0x00, 0x00, 0x00, 0x3c, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3537+ 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x49, 0x00,
3538+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
3539+ 0x04, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00,
3540+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
3541+ 0xff, 0xff, 0xff, 0xff
3542+};
3543+
3544+/*
3545+ * The following structure contains test data for a valid
3546+ * RIL_REQUEST_SET_FACILITY_LOCK reply with parameter {1}
3547+ */
3548+static const guchar reply_set_facility_lock_data_valid_2[] = {
3549+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
3550+};
3551+
3552+static const struct cb_data testdata_set_valid_2 = {
3553+ .start_func = trigger_set,
3554+ .lock = "OI",
3555+ .enable = 1,
3556+ .passwd = "0000",
3557+ .cls = BEARER_CLASS_DEFAULT, /* updated to NONE in outgoing parcel */
3558+ .rtd = {
3559+ .req_data = req_set_facility_lock_parcel_2,
3560+ .req_size = sizeof(req_set_facility_lock_parcel_2),
3561+ .rsp_data = reply_set_facility_lock_data_valid_2,
3562+ .rsp_size = sizeof(reply_set_facility_lock_data_valid_2),
3563+ },
3564+};
3565+
3566+/* GENERIC_FAILURE returned in RIL reply */
3567+static const struct cb_data testdata_set_invalid_1 = {
3568+ .start_func = trigger_set,
3569+ .lock = "OI",
3570+ .enable = 1,
3571+ .passwd = "0000",
3572+ .cls = BEARER_CLASS_DEFAULT,
3573+ .rtd = {
3574+ .req_data = req_set_facility_lock_parcel_2,
3575+ .req_size = sizeof(req_set_facility_lock_parcel_2),
3576+ .rsp_error = RIL_E_GENERIC_FAILURE,
3577+ },
3578+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3579+};
3580+
3581+
3582+/*
3583+ * The following structure contains test data for a
3584+ * RIL_REQUEST_SET_FACILITY_LOCK reply with an invalid
3585+ * number of parameters {2}
3586+ */
3587+static const guchar reply_set_facility_lock_data_invalid_2[] = {
3588+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
3589+};
3590+
3591+static const struct cb_data testdata_set_invalid_2 = {
3592+ .start_func = trigger_set,
3593+ .lock = "OI",
3594+ .enable = 1,
3595+ .passwd = "0000",
3596+ .cls = BEARER_CLASS_DEFAULT,
3597+ .rtd = {
3598+ .req_data = req_set_facility_lock_parcel_2,
3599+ .req_size = sizeof(req_set_facility_lock_parcel_2),
3600+ .rsp_data = reply_set_facility_lock_data_invalid_2,
3601+ .rsp_size = sizeof(reply_set_facility_lock_data_invalid_2),
3602+ },
3603+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3604+};
3605+
3606+/*
3607+ * The following structure contains test data for a
3608+ * RIL_REQUEST_SET_FACILITY_LOCK reply with an incomplete
3609+ * integer parameter, which will trigger a malformed parcel
3610+ * error.
3611+ */
3612+static const guchar reply_set_facility_lock_data_invalid_3[] = {
3613+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
3614+};
3615+
3616+static const struct cb_data testdata_set_invalid_3 = {
3617+ .start_func = trigger_set,
3618+ .lock = "OI",
3619+ .enable = 1,
3620+ .passwd = "0000",
3621+ .cls = BEARER_CLASS_DEFAULT,
3622+ .rtd = {
3623+ .req_data = req_set_facility_lock_parcel_2,
3624+ .req_size = sizeof(req_set_facility_lock_parcel_2),
3625+ .rsp_data = reply_set_facility_lock_data_invalid_3,
3626+ .rsp_size = sizeof(reply_set_facility_lock_data_invalid_3),
3627+ },
3628+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3629+};
3630+
3631+/* RIL_REQUEST_CHANGE_BARRING_PASSWORD with the following parameters:
3632+ *
3633+ * facility="OI" (outgoing international calls)
3634+ * old passwd="1111"
3635+ * new_passwd="0000"
3636+ */
3637+static const guchar req_change_barring_passwd_parcel_1[] = {
3638+ 0x00, 0x00, 0x00, 0x38, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3639+ 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x49, 0x00,
3640+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x31, 0x00,
3641+ 0x31, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
3642+ 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00
3643+};
3644+
3645+/*
3646+ * This test doesn't specify any data for RIL_REQUEST_SET_FACILITY_LOCK reply
3647+ * to simulate a reply generated by mako.
3648+ */
3649+static const struct cb_data testdata_set_passwd_valid_1 = {
3650+ .start_func = trigger_set_passwd,
3651+ .lock = "OI",
3652+ .passwd = "1111",
3653+ .new_passwd = "0000",
3654+ .rtd = {
3655+ .req_data = req_change_barring_passwd_parcel_1,
3656+ .req_size = sizeof(req_change_barring_passwd_parcel_1),
3657+ },
3658+};
3659+
3660+/* GENERIC_FAILURE returned in RIL reply */
3661+static const struct cb_data testdata_set_passwd_invalid_1 = {
3662+ .start_func = trigger_set_passwd,
3663+ .lock = "OI",
3664+ .passwd = "1111",
3665+ .new_passwd = "0000",
3666+ .rtd = {
3667+ .req_data = req_change_barring_passwd_parcel_1,
3668+ .req_size = sizeof(req_change_barring_passwd_parcel_1),
3669+ .rsp_error = RIL_E_GENERIC_FAILURE,
3670+ },
3671+ .error_type = OFONO_ERROR_TYPE_FAILURE,
3672+};
3673+
3674+/* Declarations && Re-implementations of core functions. */
3675+void ril_call_barring_exit(void);
3676+void ril_call_barring_init(void);
3677+
3678+struct ofono_call_barring {
3679+ void *driver_data;
3680+ const struct cb_data *cbd;
3681+};
3682+
3683+struct ofono_call_barring *ofono_call_barring_create(struct ofono_modem *modem,
3684+ unsigned int vendor,
3685+ const char *driver,
3686+ void *data)
3687+{
3688+ struct rilmodem_cb_data *rsd = data;
3689+ struct ofono_call_barring *cb = g_new0(struct ofono_call_barring, 1);
3690+ int retval;
3691+
3692+ retval = cbdriver->probe(cb, OFONO_RIL_VENDOR_AOSP, rsd->ril);
3693+ g_assert(retval == 0);
3694+
3695+ return cb;
3696+}
3697+
3698+int ofono_call_barring_driver_register(const struct ofono_call_barring_driver *d)
3699+{
3700+ if (cbdriver == NULL)
3701+ cbdriver = d;
3702+
3703+ return 0;
3704+}
3705+
3706+void ofono_call_barring_set_data(struct ofono_call_barring *cb, void *data)
3707+{
3708+ cb->driver_data = data;
3709+}
3710+
3711+void *ofono_call_barring_get_data(struct ofono_call_barring *cb)
3712+{
3713+ return cb->driver_data;
3714+}
3715+
3716+void ofono_call_barring_register(struct ofono_call_barring *cb)
3717+{
3718+}
3719+
3720+void ofono_call_barring_driver_unregister(const struct ofono_call_barring_driver *d)
3721+{
3722+}
3723+
3724+/*
3725+ * As all our architectures are little-endian except for
3726+ * PowerPC, and the Binder wire-format differs slightly
3727+ * depending on endian-ness, the following guards against test
3728+ * failures when run on PowerPC.
3729+ */
3730+#if BYTE_ORDER == LITTLE_ENDIAN
3731+
3732+static void server_connect_cb(gpointer data)
3733+{
3734+ struct rilmodem_cb_data *rsd = data;
3735+ const struct cb_data *cbd = rsd->test_data;
3736+
3737+ /* This causes local impl of _create() to call driver's probe func. */
3738+ rsd->cb = ofono_call_barring_create(NULL, OFONO_RIL_VENDOR_AOSP,
3739+ "rilmodem", rsd);
3740+ rsd->cb->cbd = cbd;
3741+
3742+ /* add_idle doesn't work, read blocks main loop!!! */
3743+
3744+ if (cbd->rtd.unsol_test)
3745+ g_idle_add(cbd->start_func, (void *) rsd);
3746+ else
3747+ g_assert(cbd->start_func(rsd) == FALSE);
3748+}
3749+
3750+/*
3751+ * This unit test:
3752+ * - does some test data setup
3753+ * - configures a dummy server socket
3754+ * - creates a new gril client instance
3755+ * - triggers a connect to the dummy
3756+ * server socket
3757+ * - starts a mainloop
3758+ */
3759+static void test_call_barring_func(gconstpointer data)
3760+{
3761+ const struct cb_data *sd = data;
3762+ struct rilmodem_cb_data *rsd;
3763+
3764+ ril_call_barring_init();
3765+
3766+ rsd = g_new0(struct rilmodem_cb_data, 1);
3767+
3768+ rsd->test_data = sd;
3769+
3770+ rsd->serverd = rilmodem_test_server_create(&server_connect_cb,
3771+ &sd->rtd, rsd);
3772+
3773+ rsd->ril = g_ril_new(rilmodem_test_get_socket_name(rsd->serverd),
3774+ OFONO_RIL_VENDOR_AOSP);
3775+ g_assert(rsd->ril != NULL);
3776+
3777+ mainloop = g_main_loop_new(NULL, FALSE);
3778+
3779+ g_main_loop_run(mainloop);
3780+ g_main_loop_unref(mainloop);
3781+
3782+ cbdriver->remove(rsd->cb);
3783+ g_ril_unref(rsd->ril);
3784+ g_free(rsd);
3785+
3786+ rilmodem_test_server_close(rsd->serverd);
3787+
3788+ ril_call_barring_exit();
3789+}
3790+
3791+#endif
3792+
3793+int main(int argc, char **argv)
3794+{
3795+ g_test_init(&argc, &argv, NULL);
3796+
3797+/*
3798+ * As all our architectures are little-endian except for
3799+ * PowerPC, and the Binder wire-format differs slightly
3800+ * depending on endian-ness, the following guards against test
3801+ * failures when run on PowerPC.
3802+ */
3803+#if BYTE_ORDER == LITTLE_ENDIAN
3804+ g_test_add_data_func("/testrilmodemcallbarring/query/valid/1",
3805+ &testdata_query_valid_1,
3806+ test_call_barring_func);
3807+ g_test_add_data_func("/testrilmodemcallbarring/query/invalid/1",
3808+ &testdata_query_invalid_1,
3809+ test_call_barring_func);
3810+ g_test_add_data_func("/testrilmodemcallbarring/query/invalid/2",
3811+ &testdata_query_invalid_2,
3812+ test_call_barring_func);
3813+ g_test_add_data_func("/testrilmodemcallbarring/query/invalid/3",
3814+ &testdata_query_invalid_3,
3815+ test_call_barring_func);
3816+ g_test_add_data_func("/testrilmodemcallbarring/query/invalid/4",
3817+ &testdata_query_invalid_3,
3818+ test_call_barring_func);
3819+ g_test_add_data_func("/testrilmodemcallbarring/set/valid/1",
3820+ &testdata_set_valid_1,
3821+ test_call_barring_func);
3822+ g_test_add_data_func("/testrilmodemcallbarring/set/valid/2",
3823+ &testdata_set_valid_2,
3824+ test_call_barring_func);
3825+ g_test_add_data_func("/testrilmodemcallbarring/set/invalid/1",
3826+ &testdata_set_invalid_1,
3827+ test_call_barring_func);
3828+ g_test_add_data_func("/testrilmodemcallbarring/set/invalid/2",
3829+ &testdata_set_invalid_2,
3830+ test_call_barring_func);
3831+ g_test_add_data_func("/testrilmodemcallbarring/set/invalid/3",
3832+ &testdata_set_invalid_3,
3833+ test_call_barring_func);
3834+ g_test_add_data_func("/testrilmodemcallbarring/set_passwd/valid/1",
3835+ &testdata_set_passwd_valid_1,
3836+ test_call_barring_func);
3837+ g_test_add_data_func("/testrilmodemcallbarring/set_passwd/invalid/1",
3838+ &testdata_set_passwd_invalid_1,
3839+ test_call_barring_func);
3840+#endif
3841+ return g_test_run();
3842+}
3843
3844=== modified file 'unit/test-rilmodem-cs.c'
3845--- unit/test-rilmodem-cs.c 2015-11-05 21:28:06 +0000
3846+++ unit/test-rilmodem-cs.c 2016-03-14 09:03:03 +0000
3847@@ -40,29 +40,18 @@
3848
3849 #include "common.h"
3850 #include "ril_constants.h"
3851-
3852-#define MAX_REQUEST_SIZE 4096
3853+#include "rilmodem-test-server.h"
3854
3855 static GMainLoop *mainloop;
3856
3857 static const struct ofono_call_settings_driver *csdriver;
3858
3859-struct rilmodemcs_data {
3860+struct rilmodem_cs_data {
3861 GRil *ril;
3862- int sk;
3863- gint server_watch;
3864- GIOChannel *server_io;
3865 struct ofono_modem *modem;
3866 gconstpointer test_data;
3867 struct ofono_call_settings *cs;
3868-};
3869-
3870-/* Warning: length is stored in network order */
3871-struct rsp_hdr {
3872- uint32_t length;
3873- uint32_t unsolicited;
3874- uint32_t serial;
3875- uint32_t error;
3876+ struct server_data *serverd;
3877 };
3878
3879 typedef gboolean (*StartFunc)(gpointer data);
3880@@ -72,13 +61,7 @@
3881 gint param_int1;
3882 gint param_int2;
3883
3884- const guchar *parcel_data;
3885-
3886- const gsize parcel_size;
3887-
3888- uint32_t rsp_error;
3889- const guchar *rsp_data;
3890- const gsize rsp_size;
3891+ struct rilmodem_test_data rtd;
3892 enum ofono_error_type error_type;
3893 gint cb_int1;
3894 gint cb_int2;
3895@@ -87,8 +70,8 @@
3896 static void status_query_callback(const struct ofono_error *error, int status,
3897 gpointer data)
3898 {
3899- struct rilmodemcs_data *rcsd = data;
3900- const struct cs_data *csd = rcsd->test_data;
3901+ struct rilmodem_cs_data *rcd = data;
3902+ const struct cs_data *csd = rcd->test_data;
3903
3904 g_assert(error->type == csd->error_type);
3905
3906@@ -101,8 +84,8 @@
3907 static void clir_query_callback(const struct ofono_error *error, int override,
3908 int network, gpointer data)
3909 {
3910- struct rilmodemcs_data *rcsd = data;
3911- const struct cs_data *csd = rcsd->test_data;
3912+ struct rilmodem_cs_data *rcd = data;
3913+ const struct cs_data *csd = rcd->test_data;
3914
3915 g_assert(error->type == csd->error_type);
3916
3917@@ -116,8 +99,8 @@
3918
3919 static void set_callback(const struct ofono_error *error, gpointer data)
3920 {
3921- struct rilmodemcs_data *rcsd = data;
3922- const struct cs_data *csd = rcsd->test_data;
3923+ struct rilmodem_cs_data *rcd = data;
3924+ const struct cs_data *csd = rcd->test_data;
3925
3926 g_assert(error->type == csd->error_type);
3927
3928@@ -126,56 +109,56 @@
3929
3930 static gboolean trigger_clip_query(gpointer data)
3931 {
3932- struct rilmodemcs_data *rcsd = data;
3933+ struct rilmodem_cs_data *rcd = data;
3934
3935 g_assert(csdriver->clip_query != NULL);
3936- csdriver->clip_query(rcsd->cs, status_query_callback, rcsd);
3937+ csdriver->clip_query(rcd->cs, status_query_callback, rcd);
3938
3939 return FALSE;
3940 }
3941
3942 static gboolean trigger_cw_query(gpointer data)
3943 {
3944- struct rilmodemcs_data *rcsd = data;
3945+ struct rilmodem_cs_data *rcd = data;
3946
3947 g_assert(csdriver->cw_query != NULL);
3948
3949 /* cls is explicitly ignored by rilmodem; just use 0 */
3950- csdriver->cw_query(rcsd->cs, 0, status_query_callback, rcsd);
3951+ csdriver->cw_query(rcd->cs, 0, status_query_callback, rcd);
3952
3953 return FALSE;
3954 }
3955
3956 static gboolean trigger_cw_set(gpointer data)
3957 {
3958- struct rilmodemcs_data *rcsd = data;
3959- const struct cs_data *csd = rcsd->test_data;
3960+ struct rilmodem_cs_data *rcd = data;
3961+ const struct cs_data *csd = rcd->test_data;
3962
3963 g_assert(csdriver->cw_set != NULL);
3964
3965- csdriver->cw_set(rcsd->cs, csd->param_int1, csd->param_int2,
3966- set_callback, rcsd);
3967+ csdriver->cw_set(rcd->cs, csd->param_int1, csd->param_int2,
3968+ set_callback, rcd);
3969
3970 return FALSE;
3971 }
3972
3973 static gboolean trigger_clir_query(gpointer data)
3974 {
3975- struct rilmodemcs_data *rcsd = data;
3976+ struct rilmodem_cs_data *rcd = data;
3977
3978 g_assert(csdriver->clir_query != NULL);
3979- csdriver->clir_query(rcsd->cs, clir_query_callback, rcsd);
3980+ csdriver->clir_query(rcd->cs, clir_query_callback, rcd);
3981
3982 return FALSE;
3983 }
3984
3985 static gboolean trigger_clir_set(gpointer data)
3986 {
3987- struct rilmodemcs_data *rcsd = data;
3988- const struct cs_data *csd = rcsd->test_data;
3989+ struct rilmodem_cs_data *rcd = data;
3990+ const struct cs_data *csd = rcd->test_data;
3991
3992 g_assert(csdriver->clir_set != NULL);
3993- csdriver->clir_set(rcsd->cs, csd->param_int1, set_callback, rcsd);
3994+ csdriver->clir_set(rcd->cs, csd->param_int1, set_callback, rcd);
3995
3996 return FALSE;
3997 }
3998@@ -192,11 +175,13 @@
3999
4000 static const struct cs_data testdata_clip_query_valid_1 = {
4001 .start_func = trigger_clip_query,
4002- .parcel_data = req_clip_query_parcel_1,
4003- .parcel_size = sizeof(req_clip_query_parcel_1),
4004- .rsp_data = rsp_clip_query_data_1,
4005- .rsp_size = sizeof(rsp_clip_query_data_1),
4006- .rsp_error = RIL_E_SUCCESS,
4007+ .rtd = {
4008+ .req_data = req_clip_query_parcel_1,
4009+ .req_size = sizeof(req_clip_query_parcel_1),
4010+ .rsp_data = rsp_clip_query_data_1,
4011+ .rsp_size = sizeof(rsp_clip_query_data_1),
4012+ .rsp_error = RIL_E_SUCCESS,
4013+ },
4014 .cb_int1 = 1,
4015 .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4016 };
4017@@ -209,21 +194,25 @@
4018 /* reply parse error causes status to be returned as -1 */
4019 static const struct cs_data testdata_clip_query_invalid_1 = {
4020 .start_func = trigger_clip_query,
4021- .parcel_data = req_clip_query_parcel_1,
4022- .parcel_size = sizeof(req_clip_query_parcel_1),
4023- .rsp_data = rsp_clip_query_data_2,
4024- .rsp_size = sizeof(rsp_clip_query_data_2),
4025+ .rtd = {
4026+ .req_data = req_clip_query_parcel_1,
4027+ .req_size = sizeof(req_clip_query_parcel_1),
4028+ .rsp_data = rsp_clip_query_data_2,
4029+ .rsp_size = sizeof(rsp_clip_query_data_2),
4030+ .rsp_error = RIL_E_SUCCESS,
4031+ },
4032 .cb_int1 = -1,
4033- .rsp_error = RIL_E_SUCCESS,
4034 .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4035 };
4036
4037 /* error triggered by RIL reply error */
4038 static const struct cs_data testdata_clip_query_invalid_2 = {
4039 .start_func = trigger_clip_query,
4040- .parcel_data = req_clip_query_parcel_1,
4041- .parcel_size = sizeof(req_clip_query_parcel_1),
4042- .rsp_error = RIL_E_GENERIC_FAILURE,
4043+ .rtd = {
4044+ .req_data = req_clip_query_parcel_1,
4045+ .req_size = sizeof(req_clip_query_parcel_1),
4046+ .rsp_error = RIL_E_GENERIC_FAILURE,
4047+ },
4048 .error_type = OFONO_ERROR_TYPE_FAILURE,
4049 };
4050
4051@@ -240,11 +229,13 @@
4052
4053 static const struct cs_data testdata_cw_query_valid_1 = {
4054 .start_func = trigger_cw_query,
4055- .parcel_data = req_cw_query_parcel_1,
4056- .parcel_size = sizeof(req_cw_query_parcel_1),
4057- .rsp_data = rsp_cw_query_data_1,
4058- .rsp_size = sizeof(rsp_cw_query_data_1),
4059- .rsp_error = RIL_E_SUCCESS,
4060+ .rtd = {
4061+ .req_data = req_cw_query_parcel_1,
4062+ .req_size = sizeof(req_cw_query_parcel_1),
4063+ .rsp_data = rsp_cw_query_data_1,
4064+ .rsp_size = sizeof(rsp_cw_query_data_1),
4065+ .rsp_error = RIL_E_SUCCESS,
4066+ },
4067 .cb_int1 = 3,
4068 .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4069 };
4070@@ -257,24 +248,28 @@
4071 /* reply parse error causes status to be returned as -1 */
4072 static const struct cs_data testdata_cw_query_invalid_1 = {
4073 .start_func = trigger_cw_query,
4074- .parcel_data = req_cw_query_parcel_1,
4075- .parcel_size = sizeof(req_cw_query_parcel_1),
4076- .rsp_data = rsp_cw_query_data_2,
4077- .rsp_size = sizeof(rsp_cw_query_data_2),
4078+ .rtd = {
4079+ .req_data = req_cw_query_parcel_1,
4080+ .req_size = sizeof(req_cw_query_parcel_1),
4081+ .rsp_data = rsp_cw_query_data_2,
4082+ .rsp_size = sizeof(rsp_cw_query_data_2),
4083+ .rsp_error = RIL_E_SUCCESS,
4084+ },
4085 .cb_int1 = -1,
4086- .rsp_error = RIL_E_SUCCESS,
4087 .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4088 };
4089
4090 /* GENERIC_FAILURE returned in RIL reply */
4091 static const struct cs_data testdata_cw_query_invalid_2 = {
4092 .start_func = trigger_cw_query,
4093- .parcel_data = req_cw_query_parcel_1,
4094- .parcel_size = sizeof(req_cw_query_parcel_1),
4095- .rsp_data = rsp_cw_query_data_2,
4096- .rsp_size = sizeof(rsp_cw_query_data_2),
4097+ .rtd = {
4098+ .req_data = req_cw_query_parcel_1,
4099+ .req_size = sizeof(req_cw_query_parcel_1),
4100+ .rsp_data = rsp_cw_query_data_2,
4101+ .rsp_size = sizeof(rsp_cw_query_data_2),
4102+ .rsp_error = RIL_E_GENERIC_FAILURE,
4103+ },
4104 .cb_int1 = -1,
4105- .rsp_error = RIL_E_GENERIC_FAILURE,
4106 .error_type = OFONO_ERROR_TYPE_FAILURE,
4107 };
4108
4109@@ -289,9 +284,11 @@
4110 .start_func = trigger_cw_set,
4111 .param_int1 = 1,
4112 .param_int2 = BEARER_CLASS_DEFAULT,
4113- .parcel_data = req_cw_set_enabled_parcel_1,
4114- .parcel_size = sizeof(req_cw_set_enabled_parcel_1),
4115- .rsp_error = RIL_E_SUCCESS,
4116+ .rtd = {
4117+ .req_data = req_cw_set_enabled_parcel_1,
4118+ .req_size = sizeof(req_cw_set_enabled_parcel_1),
4119+ .rsp_error = RIL_E_SUCCESS,
4120+ },
4121 .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4122 };
4123
4124@@ -306,9 +303,11 @@
4125 .start_func = trigger_cw_set,
4126 .param_int1 = 0,
4127 .param_int2 = 0,
4128- .parcel_data = req_cw_set_disabled_parcel_2,
4129- .parcel_size = sizeof(req_cw_set_disabled_parcel_2),
4130- .rsp_error = RIL_E_GENERIC_FAILURE,
4131+ .rtd = {
4132+ .req_data = req_cw_set_disabled_parcel_2,
4133+ .req_size = sizeof(req_cw_set_disabled_parcel_2),
4134+ .rsp_error = RIL_E_GENERIC_FAILURE,
4135+ },
4136 .error_type = OFONO_ERROR_TYPE_FAILURE,
4137 };
4138
4139@@ -324,13 +323,15 @@
4140
4141 static const struct cs_data testdata_clir_query_valid_1 = {
4142 .start_func = trigger_clir_query,
4143- .parcel_data = req_clir_query_parcel_1,
4144- .parcel_size = sizeof(req_clir_query_parcel_1),
4145- .rsp_data = rsp_clir_query_data_1,
4146- .rsp_size = sizeof(rsp_clir_query_data_1),
4147+ .rtd = {
4148+ .req_data = req_clir_query_parcel_1,
4149+ .req_size = sizeof(req_clir_query_parcel_1),
4150+ .rsp_data = rsp_clir_query_data_1,
4151+ .rsp_size = sizeof(rsp_clir_query_data_1),
4152+ .rsp_error = RIL_E_SUCCESS,
4153+ },
4154 .cb_int1 = 2,
4155 .cb_int2 = 4,
4156- .rsp_error = RIL_E_SUCCESS,
4157 .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4158 };
4159
4160@@ -340,11 +341,13 @@
4161 };
4162 static const struct cs_data testdata_clir_query_invalid_1 = {
4163 .start_func = trigger_clir_query,
4164- .parcel_data = req_clir_query_parcel_1,
4165- .parcel_size = sizeof(req_clir_query_parcel_1),
4166- .rsp_data = rsp_clir_query_data_2,
4167- .rsp_size = sizeof(rsp_clir_query_data_2),
4168- .rsp_error = RIL_E_SUCCESS,
4169+ .rtd = {
4170+ .req_data = req_clir_query_parcel_1,
4171+ .req_size = sizeof(req_clir_query_parcel_1),
4172+ .rsp_data = rsp_clir_query_data_2,
4173+ .rsp_size = sizeof(rsp_clir_query_data_2),
4174+ .rsp_error = RIL_E_SUCCESS,
4175+ },
4176 .error_type = OFONO_ERROR_TYPE_FAILURE,
4177 };
4178
4179@@ -357,9 +360,11 @@
4180 static const struct cs_data testdata_clir_set_valid_1 = {
4181 .start_func = trigger_clir_set,
4182 .param_int1 = OFONO_CLIR_OPTION_DEFAULT,
4183- .parcel_data = req_clir_set_mode0_parcel_1,
4184- .parcel_size = sizeof(req_clir_set_mode0_parcel_1),
4185- .rsp_error = RIL_E_SUCCESS,
4186+ .rtd = {
4187+ .req_data = req_clir_set_mode0_parcel_1,
4188+ .req_size = sizeof(req_clir_set_mode0_parcel_1),
4189+ .rsp_error = RIL_E_SUCCESS,
4190+ },
4191 .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4192 };
4193
4194@@ -373,9 +378,12 @@
4195 static const struct cs_data testdata_clir_set_invalid_1 = {
4196 .start_func = trigger_clir_set,
4197 .param_int1 = OFONO_CLIR_OPTION_INVOCATION,
4198- .parcel_data = req_clir_set_mode0_parcel_2,
4199- .parcel_size = sizeof(req_clir_set_mode0_parcel_2),
4200- .rsp_error = RIL_E_GENERIC_FAILURE,
4201+
4202+ .rtd = {
4203+ .req_data = req_clir_set_mode0_parcel_2,
4204+ .req_size = sizeof(req_clir_set_mode0_parcel_2),
4205+ .rsp_error = RIL_E_GENERIC_FAILURE,
4206+ },
4207 .error_type = OFONO_ERROR_TYPE_FAILURE,
4208 };
4209
4210@@ -392,11 +400,11 @@
4211 const char *driver,
4212 void *data)
4213 {
4214- struct rilmodemcs_data *rcsd = data;
4215+ struct rilmodem_cs_data *rcd = data;
4216 struct ofono_call_settings *cs = g_new0(struct ofono_call_settings, 1);
4217 int retval;
4218
4219- retval = csdriver->probe(cs, OFONO_RIL_VENDOR_AOSP, rcsd->ril);
4220+ retval = csdriver->probe(cs, OFONO_RIL_VENDOR_AOSP, rcd->ril);
4221 g_assert(retval == 0);
4222
4223 return cs;
4224@@ -422,12 +430,10 @@
4225
4226 void ofono_call_settings_register(struct ofono_call_settings *cs)
4227 {
4228- ;
4229 }
4230
4231 void ofono_call_settings_driver_unregister(const struct ofono_call_settings_driver *d)
4232 {
4233- ;
4234 }
4235
4236 /*
4237@@ -438,163 +444,23 @@
4238 */
4239 #if BYTE_ORDER == LITTLE_ENDIAN
4240
4241-static gboolean read_server(gpointer data)
4242-{
4243- GIOStatus status;
4244- struct rilmodemcs_data *rcsd = data;
4245- gsize offset, rbytes, wbytes;
4246- gchar *buf, *bufp;
4247- uint32_t req_serial;
4248- struct rsp_hdr rsp;
4249-
4250- /*
4251- * FIXME: separate out verification from here, so read_server doesn't
4252- * need to know about cs_data.
4253- */
4254- const struct cs_data *csd = rcsd->test_data;
4255-
4256- buf = g_malloc0(MAX_REQUEST_SIZE);
4257-
4258- status = g_io_channel_read_chars(rcsd->server_io, buf, MAX_REQUEST_SIZE,
4259- &rbytes, NULL);
4260- g_assert(status == G_IO_STATUS_NORMAL);
4261- g_assert(rbytes == csd->parcel_size);
4262-
4263- /* validate len, and request_id */
4264- g_assert(!memcmp(buf, csd->parcel_data, (sizeof(uint32_t) * 2)));
4265-
4266- /*
4267- * header: size (uint32), reqid (uin32), serial (uint32)
4268- * header size == 16 ( excludes sizeof(size) )
4269- */
4270-
4271- /* advance past request_no */
4272- bufp = buf + (sizeof(uint32_t) * 2);
4273-
4274- req_serial = (uint32_t) *bufp;
4275-
4276- /* advance past serial_no */
4277- bufp += sizeof(uint32_t);
4278-
4279- /* validate the rest of the parcel... */
4280- offset = (sizeof(uint32_t) * 3);
4281- g_assert(!memcmp(bufp, csd->parcel_data + offset,
4282- csd->parcel_size - offset));
4283-
4284- /* Length does not include the length field. Network order. */
4285- rsp.length = htonl(sizeof(rsp) - sizeof(rsp.length) + csd->rsp_size);
4286- rsp.unsolicited = 0;
4287- rsp.serial = req_serial;
4288- rsp.error = csd->rsp_error;
4289-
4290- /* copy header */
4291- memcpy(buf, &rsp, sizeof(rsp));
4292-
4293- if (csd->rsp_size) {
4294- bufp = buf + sizeof(rsp);
4295-
4296- memcpy(bufp, csd->rsp_data, csd->rsp_size);
4297- }
4298-
4299-
4300- status = g_io_channel_write_chars(rcsd->server_io,
4301- buf,
4302- sizeof(rsp) + csd->rsp_size,
4303- &wbytes, NULL);
4304-
4305- /* FIXME: assert wbytes is correct */
4306-
4307- g_assert(status == G_IO_STATUS_NORMAL);
4308-
4309- g_free(buf);
4310- g_io_channel_unref(rcsd->server_io);
4311-
4312- return FALSE;
4313-}
4314-
4315-static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
4316- gpointer data)
4317-{
4318- struct rilmodemcs_data *rcsd = data;
4319- const struct cs_data *csd = rcsd->test_data;
4320- struct sockaddr saddr;
4321- unsigned int len = sizeof(saddr);
4322- int fd;
4323- GIOChannel *server_io = NULL;
4324- GIOStatus status;
4325-
4326- g_assert(cond == G_IO_IN);
4327-
4328- fd = accept(rcsd->sk, &saddr, &len);
4329- g_assert(fd != -1);
4330-
4331- server_io = g_io_channel_unix_new(fd);
4332- g_assert(server_io != NULL);
4333+static void server_connect_cb(gpointer data)
4334+{
4335+ struct rilmodem_cs_data *rcd = data;
4336+ const struct cs_data *csd = rcd->test_data;
4337
4338 /* This causes local impl of _create() to call driver's probe func. */
4339- rcsd->cs = ofono_call_settings_create(NULL, OFONO_RIL_VENDOR_AOSP,
4340- "rilmodem", rcsd);
4341+ rcd->cs = ofono_call_settings_create(NULL, OFONO_RIL_VENDOR_AOSP,
4342+ "rilmodem", rcd);
4343
4344 /* add_idle doesn't work, read blocks main loop!!! */
4345- g_assert(csd->start_func(rcsd) == FALSE);
4346-
4347- status = g_io_channel_set_encoding(server_io, NULL, NULL);
4348- g_assert(status == G_IO_STATUS_NORMAL);
4349-
4350- g_io_channel_set_buffered(server_io, FALSE);
4351- g_io_channel_set_close_on_unref(server_io, TRUE);
4352-
4353- rcsd->server_io = server_io;
4354-
4355- g_idle_add(read_server, rcsd);
4356-
4357- /* single-shot callback */
4358- return FALSE;
4359-}
4360-
4361-static void create_server_socket(const char *sock_path,
4362- struct rilmodemcs_data *rcsd)
4363-{
4364- GIOChannel *io;
4365- struct sockaddr_un addr;
4366- int retval;
4367-
4368- rcsd->sk = socket(AF_UNIX, SOCK_STREAM, 0);
4369- g_assert(rcsd->sk);
4370-
4371- memset(&addr, 0, sizeof(addr));
4372- addr.sun_family = AF_UNIX;
4373- strncpy(addr.sun_path, sock_path, sizeof(addr.sun_path) - 1);
4374-
4375- /* Unlink any existing socket for this session */
4376- unlink(addr.sun_path);
4377-
4378- retval = bind(rcsd->sk, (struct sockaddr *) &addr, sizeof(addr));
4379- g_assert(retval >= 0);
4380-
4381- retval = listen(rcsd->sk, 0);
4382- g_assert(retval >= 0);
4383-
4384- io = g_io_channel_unix_new(rcsd->sk);
4385- g_assert(io != NULL);
4386-
4387- g_io_channel_set_close_on_unref(io, TRUE);
4388- g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
4389-
4390- rcsd->server_watch = g_io_add_watch_full(io,
4391- G_PRIORITY_DEFAULT,
4392- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4393- on_socket_connected, rcsd, NULL);
4394-
4395- g_io_channel_unref(io);
4396+ g_assert(csd->start_func(rcd) == FALSE);
4397 }
4398
4399 /*
4400 * This unit test:
4401 * - does some test data setup
4402 * - configures a dummy server socket
4403- * - on_socket_connected: callback for
4404- * incoming socket connects
4405 * - creates a new gril client instance
4406 * - triggers a connect to the dummy
4407 * server socket
4408@@ -603,27 +469,31 @@
4409 static void test_cs_func(gconstpointer data)
4410 {
4411 const struct cs_data *csd = data;
4412- struct rilmodemcs_data *rcsd;
4413+ struct rilmodem_cs_data *rcd;
4414
4415 ril_call_settings_init();
4416
4417- rcsd = g_new0(struct rilmodemcs_data, 1);
4418-
4419- rcsd->test_data = csd;
4420-
4421- create_server_socket("/tmp/unittestril", rcsd);
4422-
4423- rcsd->ril = g_ril_new("/tmp/unittestril", OFONO_RIL_VENDOR_AOSP);
4424- g_assert(rcsd->ril != NULL);
4425+ rcd = g_new0(struct rilmodem_cs_data, 1);
4426+
4427+ rcd->test_data = csd;
4428+
4429+ rcd->serverd = rilmodem_test_server_create(&server_connect_cb,
4430+ &csd->rtd, rcd);
4431+
4432+ rcd->ril = g_ril_new(rilmodem_test_get_socket_name(rcd->serverd),
4433+ OFONO_RIL_VENDOR_AOSP);
4434+ g_assert(rcd->ril != NULL);
4435
4436 mainloop = g_main_loop_new(NULL, FALSE);
4437
4438 g_main_loop_run(mainloop);
4439 g_main_loop_unref(mainloop);
4440
4441- csdriver->remove(rcsd->cs);
4442- g_ril_unref(rcsd->ril);
4443- g_free(rcsd);
4444+ csdriver->remove(rcd->cs);
4445+ g_ril_unref(rcd->ril);
4446+ g_free(rcd);
4447+
4448+ rilmodem_test_server_close(rcd->serverd);
4449
4450 ril_call_settings_exit();
4451 }
4452
4453=== added file 'unit/test-rilmodem-sms.c'
4454--- unit/test-rilmodem-sms.c 1970-01-01 00:00:00 +0000
4455+++ unit/test-rilmodem-sms.c 2016-03-14 09:03:03 +0000
4456@@ -0,0 +1,596 @@
4457+/*
4458+ *
4459+ * oFono - Open Source Telephony
4460+ *
4461+ * Copyright (C) 2015 Canonical Ltd.
4462+ *
4463+ * This program is free software; you can redistribute it and/or modify
4464+ * it under the terms of the GNU General Public License version 2 as
4465+ * published by the Free Software Foundation.
4466+ *
4467+ * This program is distributed in the hope that it will be useful,
4468+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4469+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4470+ * GNU General Public License for more details.
4471+ *
4472+ * You should have received a copy of the GNU General Public License
4473+ * along with this program; if not, write to the Free Software
4474+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4475+ *
4476+ */
4477+
4478+#ifdef HAVE_CONFIG_H
4479+#include <config.h>
4480+#endif
4481+
4482+#define _GNU_SOURCE
4483+#include <assert.h>
4484+#include <errno.h>
4485+#include <glib.h>
4486+#include <stdio.h>
4487+#include <netinet/in.h>
4488+#include <sys/socket.h>
4489+#include <sys/un.h>
4490+#include <unistd.h>
4491+
4492+#include <ofono/modem.h>
4493+#include <ofono/types.h>
4494+#include <ofono/sms.h>
4495+#include <gril.h>
4496+
4497+#include "common.h"
4498+#include "ril_constants.h"
4499+#include "rilmodem-test-server.h"
4500+
4501+static GMainLoop *mainloop;
4502+
4503+static const struct ofono_sms_driver *smsdriver;
4504+
4505+struct rilmodem_sms_data {
4506+ GRil *ril;
4507+ struct ofono_modem *modem;
4508+ gconstpointer test_data;
4509+ struct ofono_sms *sms;
4510+ struct server_data *serverd;
4511+};
4512+
4513+typedef gboolean (*StartFunc)(gpointer data);
4514+
4515+struct sms_data {
4516+ StartFunc start_func;
4517+
4518+ const unsigned char *pdu;
4519+ gint pdu_len;
4520+ gint tpdu_len;
4521+ gint mms;
4522+
4523+ struct rilmodem_test_data rtd;
4524+ enum ofono_error_type error_type;
4525+
4526+ const struct ofono_phone_number ph;
4527+ gint mr;
4528+};
4529+
4530+static void sca_query_callback(const struct ofono_error *error,
4531+ const struct ofono_phone_number *ph,
4532+ gpointer data)
4533+{
4534+ struct rilmodem_sms_data *rsd = data;
4535+ const struct sms_data *sd = rsd->test_data;
4536+
4537+ g_assert(error->type == sd->error_type);
4538+
4539+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
4540+ g_assert(ph->type == sd->ph.type);
4541+ g_assert(strcmp(ph->number, sd->ph.number) == 0);
4542+ }
4543+
4544+ g_main_loop_quit(mainloop);
4545+}
4546+
4547+static void sca_set_callback(const struct ofono_error *error, gpointer data)
4548+{
4549+ struct rilmodem_sms_data *rsd = data;
4550+ const struct sms_data *sd = rsd->test_data;
4551+
4552+ g_assert(error->type == sd->error_type);
4553+
4554+ g_main_loop_quit(mainloop);
4555+}
4556+
4557+static void submit_callback(const struct ofono_error *error, int mr,
4558+ gpointer data)
4559+{
4560+ struct rilmodem_sms_data *rsd = data;
4561+ const struct sms_data *sd = rsd->test_data;
4562+
4563+ g_assert(error->type == sd->error_type);
4564+ g_assert(mr == sd->mr);
4565+
4566+ g_main_loop_quit(mainloop);
4567+}
4568+
4569+static gboolean trigger_sca_query(gpointer data)
4570+{
4571+ struct rilmodem_sms_data *rsd = data;
4572+
4573+ g_assert(smsdriver->sca_query != NULL);
4574+ smsdriver->sca_query(rsd->sms, sca_query_callback, rsd);
4575+
4576+ return FALSE;
4577+}
4578+
4579+static gboolean trigger_sca_set(gpointer data)
4580+{
4581+ struct rilmodem_sms_data *rsd = data;
4582+ const struct sms_data *sd = rsd->test_data;
4583+
4584+ g_assert(smsdriver->sca_set != NULL);
4585+ smsdriver->sca_set(rsd->sms, &sd->ph, sca_set_callback, rsd);
4586+
4587+ return FALSE;
4588+}
4589+
4590+static gboolean trigger_submit(gpointer data)
4591+{
4592+ struct rilmodem_sms_data *rsd = data;
4593+ const struct sms_data *sd = rsd->test_data;
4594+
4595+ g_assert(smsdriver->submit != NULL);
4596+
4597+ smsdriver->submit(rsd->sms, sd->pdu, sd->pdu_len, sd->tpdu_len,
4598+ sd->mms, submit_callback, rsd);
4599+
4600+ return FALSE;
4601+}
4602+
4603+static gboolean trigger_new_sms(gpointer data)
4604+{
4605+ struct rilmodem_sms_data *rsd = data;
4606+ const struct sms_data *sd = rsd->test_data;
4607+
4608+ rilmodem_test_server_write(rsd->serverd, sd->rtd.req_data,
4609+ sd->rtd.req_size);
4610+
4611+ return FALSE;
4612+}
4613+
4614+/* RIL_REQUEST_GET_SMSC_ADDRESS */
4615+static const guchar req_get_smsc_address_parcel_1[] = {
4616+ 0x00, 0x00, 0x00, 0x08, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4617+};
4618+
4619+
4620+/*
4621+ * RIL_REQUEST_GET_SMSC_ADDRESS reply with the following data:
4622+ *
4623+ * {number="+34607003110"}
4624+ */
4625+static const guchar rsp_get_smsc_address_data_1[] = {
4626+ 0x0d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x2b, 0x00, 0x33, 0x00, 0x34, 0x00,
4627+ 0x36, 0x00, 0x30, 0x00, 0x37, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00,
4628+ 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00
4629+};
4630+
4631+static const struct sms_data testdata_sca_query_valid_1 = {
4632+ .start_func = trigger_sca_query,
4633+ .rtd = {
4634+ .req_data = req_get_smsc_address_parcel_1,
4635+ .req_size = sizeof(req_get_smsc_address_parcel_1),
4636+ .rsp_data = rsp_get_smsc_address_data_1,
4637+ .rsp_size = sizeof(rsp_get_smsc_address_data_1),
4638+ .rsp_error = RIL_E_SUCCESS,
4639+ },
4640+ .ph = { .number = "34607003110", .type = 145 },
4641+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4642+};
4643+
4644+/*
4645+ * RIL_REQUEST_GET_SMSC_ADDRESS reply with no data, which should
4646+ * trigger a callback failure.
4647+ */
4648+static const struct sms_data testdata_sca_query_invalid_1 = {
4649+ .start_func = trigger_sca_query,
4650+ .rtd = {
4651+ .req_data = req_get_smsc_address_parcel_1,
4652+ .req_size = sizeof(req_get_smsc_address_parcel_1),
4653+ .rsp_error = RIL_E_SUCCESS,
4654+ },
4655+ .error_type = OFONO_ERROR_TYPE_FAILURE,
4656+};
4657+
4658+/*
4659+ * RIL_REQUEST_GET_SMSC_ADDRESS reply with no quotes found which
4660+ * should trigger a callback failure.
4661+ */
4662+static const guchar rsp_get_smsc_address_data_3[] = {
4663+ 0x02, 0x00, 0x00, 0x00, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00
4664+};
4665+
4666+static const struct sms_data testdata_sca_query_invalid_2 = {
4667+ .start_func = trigger_sca_query,
4668+ .ph = { .number = "34607003110", .type = 145 },
4669+ .rtd = {
4670+ .req_data = req_get_smsc_address_parcel_1,
4671+ .req_size = sizeof(req_get_smsc_address_parcel_1),
4672+ .rsp_data = rsp_get_smsc_address_data_3,
4673+ .rsp_size = sizeof(rsp_get_smsc_address_data_3),
4674+ .rsp_error = RIL_E_SUCCESS,
4675+ },
4676+ .error_type = OFONO_ERROR_TYPE_FAILURE,
4677+};
4678+
4679+/* GENERIC_FAILURE returned in RIL reply */
4680+static const struct sms_data testdata_sca_query_invalid_3 = {
4681+ .start_func = trigger_sca_query,
4682+ .rtd = {
4683+ .req_data = req_get_smsc_address_parcel_1,
4684+ .req_size = sizeof(req_get_smsc_address_parcel_1),
4685+ .rsp_error = RIL_E_GENERIC_FAILURE,
4686+ },
4687+ .error_type = OFONO_ERROR_TYPE_FAILURE,
4688+};
4689+
4690+/*
4691+ * RIL_REQUEST_SET_SMSC_ADDRESS with the following data:
4692+ *
4693+ * {number="+34607003110"}
4694+ */
4695+static const guchar req_set_smsc_address_parcel_1[] = {
4696+ +0x00, 0x00, 0x00, 0x2C, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4697+ +0x0e, 0x00, 0x00, 0x00, 0x22, 0x00, 0x2b, 0x00, 0x33, 0x00, 0x34, 0x00,
4698+ +0x36, 0x00, 0x30, 0x00, 0x37, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00,
4699+ +0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00
4700+};
4701+
4702+static const struct sms_data testdata_sca_set_valid_1 = {
4703+ .start_func = trigger_sca_set,
4704+ .ph = { .number = "34607003110", .type = 145 },
4705+ .rtd = {
4706+ .req_data = req_set_smsc_address_parcel_1,
4707+ .req_size = sizeof(req_set_smsc_address_parcel_1),
4708+ .rsp_error = RIL_E_SUCCESS,
4709+ },
4710+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4711+};
4712+
4713+/* GENERIC_FAILURE returned in RIL reply */
4714+static const struct sms_data testdata_sca_set_invalid_1 = {
4715+ .start_func = trigger_sca_set,
4716+ .ph = { .number = "34607003110", .type = 145 },
4717+ .rtd = {
4718+ .req_data = req_set_smsc_address_parcel_1,
4719+ .req_size = sizeof(req_set_smsc_address_parcel_1),
4720+ .rsp_error = RIL_E_GENERIC_FAILURE,
4721+ },
4722+ .error_type = OFONO_ERROR_TYPE_FAILURE,
4723+};
4724+
4725+static const unsigned char req_send_sms_pdu_valid_1[] = {
4726+ 0x00, 0x11, 0x00, 0x09, 0x81, 0x36, 0x54, 0x39, 0x80, 0xf5, 0x00, 0x00,
4727+ 0xa7, 0x0a, 0xc8, 0x37, 0x3b, 0x0c, 0x6a, 0xd7, 0xdd, 0xe4, 0x37
4728+};
4729+
4730+static const guchar req_send_sms_parcel_1[] = {
4731+ 0x00, 0x00, 0x00, 0x70, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4732+ 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00,
4733+ 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x39, 0x00,
4734+ 0x38, 0x00, 0x31, 0x00, 0x33, 0x00, 0x36, 0x00, 0x35, 0x00, 0x34, 0x00,
4735+ 0x33, 0x00, 0x39, 0x00, 0x38, 0x00, 0x30, 0x00, 0x46, 0x00, 0x35, 0x00,
4736+ 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x41, 0x00, 0x37, 0x00,
4737+ 0x30, 0x00, 0x41, 0x00, 0x43, 0x00, 0x38, 0x00, 0x33, 0x00, 0x37, 0x00,
4738+ 0x33, 0x00, 0x42, 0x00, 0x30, 0x00, 0x43, 0x00, 0x36, 0x00, 0x41, 0x00,
4739+ 0x44, 0x00, 0x37, 0x00, 0x44, 0x00, 0x44, 0x00, 0x45, 0x00, 0x34, 0x00,
4740+ 0x33, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00
4741+};
4742+
4743+/*
4744+ * SEND_SMS reply with the following data:
4745+ *
4746+ * messageRef=1
4747+ * ackPDU=NULL
4748+ * errorCode=0
4749+ */
4750+static const guchar rsp_send_sms_valid_1[] = {
4751+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4752+};
4753+
4754+static const struct sms_data testdata_submit_valid_1 = {
4755+ .start_func = trigger_submit,
4756+ .pdu = req_send_sms_pdu_valid_1,
4757+ .pdu_len = sizeof(req_send_sms_pdu_valid_1),
4758+ .tpdu_len = sizeof(req_send_sms_pdu_valid_1) - 1,
4759+ .mms = 0,
4760+ .rtd = {
4761+ .req_data = req_send_sms_parcel_1,
4762+ .req_size = sizeof(req_send_sms_parcel_1),
4763+ .rsp_data = rsp_send_sms_valid_1,
4764+ .rsp_size = sizeof(rsp_send_sms_valid_1),
4765+ .rsp_error = RIL_E_SUCCESS,
4766+ },
4767+ .mr = 1,
4768+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
4769+};
4770+
4771+/*
4772+ * SEND_SMS reply with failure indicated
4773+ */
4774+static const struct sms_data testdata_submit_invalid_1 = {
4775+ .start_func = trigger_submit,
4776+ .pdu = req_send_sms_pdu_valid_1,
4777+ .pdu_len = sizeof(req_send_sms_pdu_valid_1),
4778+ .tpdu_len = sizeof(req_send_sms_pdu_valid_1) - 1,
4779+ .mms = 0,
4780+ .rtd = {
4781+ .req_data = req_send_sms_parcel_1,
4782+ .req_size = sizeof(req_send_sms_parcel_1),
4783+ .rsp_error = RIL_E_GENERIC_FAILURE,
4784+ },
4785+ .error_type = OFONO_ERROR_TYPE_FAILURE,
4786+};
4787+
4788+/*
4789+ * The following hexadecimal data represents a serialized Binder parcel
4790+ * instance containing a valid RIL_UNSOL_RESPONSE_NEW_SMS message
4791+ * with the following parameter (SMSC address length is 7):
4792+ *
4793+ * {07914306073011F0040B914336543980F50000310113212002400AC8373B0C6AD7DDE437}
4794+ * {069143060730F0040B914336543980F50000310113212002400AC8373B0C6AD7DDE437}
4795+ */
4796+static const guchar unsol_response_new_sms_parcel_1[] = {
4797+ 0x00, 0x00, 0x00, 0xA0, 0x01, 0x00, 0x00, 0x00, 0xEB, 0x03, 0x00, 0x00,
4798+ 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x37, 0x00, 0x39, 0x00, 0x31, 0x00,
4799+ 0x34, 0x00, 0x33, 0x00, 0x30, 0x00, 0x36, 0x00, 0x30, 0x00, 0x37, 0x00,
4800+ 0x33, 0x00, 0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 0x46, 0x00, 0x30, 0x00,
4801+ 0x30, 0x00, 0x34, 0x00, 0x30, 0x00, 0x42, 0x00, 0x39, 0x00, 0x31, 0x00,
4802+ 0x34, 0x00, 0x33, 0x00, 0x33, 0x00, 0x36, 0x00, 0x35, 0x00, 0x34, 0x00,
4803+ 0x33, 0x00, 0x39, 0x00, 0x38, 0x00, 0x30, 0x00, 0x46, 0x00, 0x35, 0x00,
4804+ 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x31, 0x00,
4805+ 0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 0x33, 0x00, 0x32, 0x00, 0x31, 0x00,
4806+ 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32, 0x00, 0x34, 0x00, 0x30, 0x00,
4807+ 0x30, 0x00, 0x41, 0x00, 0x43, 0x00, 0x38, 0x00, 0x33, 0x00, 0x37, 0x00,
4808+ 0x33, 0x00, 0x42, 0x00, 0x30, 0x00, 0x43, 0x00, 0x36, 0x00, 0x41, 0x00,
4809+ 0x44, 0x00, 0x37, 0x00, 0x44, 0x00, 0x44, 0x00, 0x45, 0x00, 0x34, 0x00,
4810+ 0x33, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00
4811+};
4812+
4813+const unsigned char new_sms_pdu_valid_1[] = {
4814+ 0x07, 0x91, 0x43, 0x06, 0x07, 0x30, 0x11, 0xf0, 0x04, 0x0b, 0x91, 0x43,
4815+ 0x36, 0x54, 0x39, 0x80, 0xf5, 0x00, 0x00, 0x31, 0x01, 0x13, 0x21, 0x20,
4816+ 0x02, 0x40, 0x0a, 0xc8, 0x37, 0x3b, 0x0c, 0x6a, 0xd7, 0xdd, 0xe4, 0x37
4817+};
4818+
4819+static const struct sms_data testdata_new_sms_valid_1 = {
4820+ .start_func = trigger_new_sms,
4821+ .rtd = {
4822+ .req_data = unsol_response_new_sms_parcel_1,
4823+ .req_size = sizeof(unsol_response_new_sms_parcel_1),
4824+ .unsol_test = TRUE,
4825+ },
4826+ .pdu = new_sms_pdu_valid_1,
4827+ .pdu_len = sizeof(new_sms_pdu_valid_1),
4828+ .tpdu_len = 28,
4829+};
4830+
4831+/*
4832+ * The following hexadecimal data represents a serialized Binder parcel
4833+ * instance containing a valid UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT message
4834+ * with the following parameter (SMSC address length is 6):
4835+ *
4836+ * {069143060730F0040B914336543980F50000310113212002400AC8373B0C6AD7DDE437}
4837+ */
4838+static const guchar unsol_response_new_sms_parcel_2[] = {
4839+ 0x00, 0x00, 0x00, 0x9C, 0x01, 0x00, 0x00, 0x00, 0xEC, 0x03, 0x00, 0x00,
4840+ 0x46, 0x00, 0x00, 0x00, 0x30, 0x00, 0x36, 0x00, 0x39, 0x00, 0x31, 0x00,
4841+ 0x34, 0x00, 0x33, 0x00, 0x30, 0x00, 0x36, 0x00, 0x30, 0x00, 0x37, 0x00,
4842+ 0x33, 0x00, 0x30, 0x00, 0x46, 0x00, 0x30, 0x00, 0x30, 0x00, 0x34, 0x00,
4843+ 0x30, 0x00, 0x42, 0x00, 0x39, 0x00, 0x31, 0x00, 0x34, 0x00, 0x33, 0x00,
4844+ 0x33, 0x00, 0x36, 0x00, 0x35, 0x00, 0x34, 0x00, 0x33, 0x00, 0x39, 0x00,
4845+ 0x38, 0x00, 0x30, 0x00, 0x46, 0x00, 0x35, 0x00, 0x30, 0x00, 0x30, 0x00,
4846+ 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x31, 0x00, 0x30, 0x00, 0x31, 0x00,
4847+ 0x31, 0x00, 0x33, 0x00, 0x32, 0x00, 0x31, 0x00, 0x32, 0x00, 0x30, 0x00,
4848+ 0x30, 0x00, 0x32, 0x00, 0x34, 0x00, 0x30, 0x00, 0x30, 0x00, 0x41, 0x00,
4849+ 0x43, 0x00, 0x38, 0x00, 0x33, 0x00, 0x37, 0x00, 0x33, 0x00, 0x42, 0x00,
4850+ 0x30, 0x00, 0x43, 0x00, 0x36, 0x00, 0x41, 0x00, 0x44, 0x00, 0x37, 0x00,
4851+ 0x44, 0x00, 0x44, 0x00, 0x45, 0x00, 0x34, 0x00, 0x33, 0x00, 0x37, 0x00,
4852+ 0x00, 0x00, 0x00, 0x00
4853+};
4854+
4855+const unsigned char new_sms_pdu_valid_2[] = {
4856+ 0x06, 0x91, 0x43, 0x06, 0x07, 0x30, 0xf0, 0x04, 0x0b, 0x91, 0x43, 0x36,
4857+ 0x54, 0x39, 0x80, 0xf5, 0x00, 0x00, 0x31, 0x01, 0x13, 0x21, 0x20, 0x02,
4858+ 0x40, 0x0a, 0xc8, 0x37, 0x3b, 0x0c, 0x6a, 0xd7, 0xdd, 0xe4, 0x37
4859+};
4860+
4861+static const struct sms_data testdata_new_sms_valid_2 = {
4862+ .start_func = trigger_new_sms,
4863+ .rtd = {
4864+ .req_data = unsol_response_new_sms_parcel_2,
4865+ .req_size = sizeof(unsol_response_new_sms_parcel_2),
4866+ .unsol_test = TRUE,
4867+ },
4868+ .pdu = new_sms_pdu_valid_2,
4869+ .pdu_len = sizeof(new_sms_pdu_valid_2),
4870+ .tpdu_len = 28,
4871+};
4872+
4873+/* Declarations && Re-implementations of core functions. */
4874+void ril_sms_exit(void);
4875+void ril_sms_init(void);
4876+
4877+struct ofono_sms {
4878+ void *driver_data;
4879+ const struct sms_data *sd;
4880+};
4881+
4882+struct ofono_sms *ofono_sms_create(struct ofono_modem *modem,
4883+ unsigned int vendor,
4884+ const char *driver,
4885+ void *data)
4886+{
4887+ struct rilmodem_sms_data *rsd = data;
4888+ struct ofono_sms *sms = g_new0(struct ofono_sms, 1);
4889+ int retval;
4890+
4891+ retval = smsdriver->probe(sms, OFONO_RIL_VENDOR_AOSP, rsd->ril);
4892+ g_assert(retval == 0);
4893+
4894+ return sms;
4895+}
4896+
4897+int ofono_sms_driver_register(const struct ofono_sms_driver *d)
4898+{
4899+ if (smsdriver == NULL)
4900+ smsdriver = d;
4901+
4902+ return 0;
4903+}
4904+
4905+void ofono_sms_set_data(struct ofono_sms *sms, void *data)
4906+{
4907+ sms->driver_data = data;
4908+}
4909+
4910+void *ofono_sms_get_data(struct ofono_sms *sms)
4911+{
4912+ return sms->driver_data;
4913+}
4914+
4915+void ofono_sms_register(struct ofono_sms *sms)
4916+{
4917+}
4918+
4919+void ofono_sms_driver_unregister(const struct ofono_sms_driver *d)
4920+{
4921+}
4922+
4923+void ofono_sms_deliver_notify(struct ofono_sms *sms, const unsigned char *pdu,
4924+ int len, int tpdu_len)
4925+{
4926+ g_assert(sms->sd->pdu_len == len);
4927+ g_assert(sms->sd->tpdu_len == tpdu_len);
4928+ g_assert(!memcmp(pdu, sms->sd->pdu, len));
4929+
4930+ g_main_loop_quit(mainloop);
4931+}
4932+
4933+void ofono_sms_status_notify(struct ofono_sms *sms, const unsigned char *pdu,
4934+ int len, int tpdu_len)
4935+{
4936+ ofono_sms_deliver_notify(sms, pdu, len, tpdu_len);
4937+}
4938+
4939+/*
4940+ * As all our architectures are little-endian except for
4941+ * PowerPC, and the Binder wire-format differs slightly
4942+ * depending on endian-ness, the following guards against test
4943+ * failures when run on PowerPC.
4944+ */
4945+#if BYTE_ORDER == LITTLE_ENDIAN
4946+
4947+static void server_connect_cb(gpointer data)
4948+{
4949+ struct rilmodem_sms_data *rsd = data;
4950+ const struct sms_data *sd = rsd->test_data;
4951+
4952+ /* This causes local impl of _create() to call driver's probe func. */
4953+ rsd->sms = ofono_sms_create(NULL, OFONO_RIL_VENDOR_AOSP,
4954+ "rilmodem", rsd);
4955+ rsd->sms->sd = sd;
4956+
4957+ /* add_idle doesn't work, read blocks main loop!!! */
4958+
4959+ if (sd->rtd.unsol_test)
4960+ g_idle_add(sd->start_func, (void *) rsd);
4961+ else
4962+ g_assert(sd->start_func(rsd) == FALSE);
4963+}
4964+
4965+/*
4966+ * This unit test:
4967+ * - does some test data setup
4968+ * - configures a dummy server socket
4969+ * - creates a new gril client instance
4970+ * - triggers a connect to the dummy
4971+ * server socket
4972+ * - starts a mainloop
4973+ */
4974+static void test_sms_func(gconstpointer data)
4975+{
4976+ const struct sms_data *sd = data;
4977+ struct rilmodem_sms_data *rsd;
4978+
4979+ ril_sms_init();
4980+
4981+ rsd = g_new0(struct rilmodem_sms_data, 1);
4982+
4983+ rsd->test_data = sd;
4984+
4985+ rsd->serverd = rilmodem_test_server_create(&server_connect_cb,
4986+ &sd->rtd, rsd);
4987+
4988+ rsd->ril = g_ril_new(rilmodem_test_get_socket_name(rsd->serverd),
4989+ OFONO_RIL_VENDOR_AOSP);
4990+ g_assert(rsd->ril != NULL);
4991+
4992+ mainloop = g_main_loop_new(NULL, FALSE);
4993+
4994+ g_main_loop_run(mainloop);
4995+ g_main_loop_unref(mainloop);
4996+
4997+ smsdriver->remove(rsd->sms);
4998+ g_ril_unref(rsd->ril);
4999+ g_free(rsd);
5000+
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: