Merge lp:~awe/phablet-extras/ofono-nettime-plugin into lp:phablet-extras/ofono
- ofono-nettime-plugin
- Merge into ofono
Status: | Merged |
---|---|
Approved by: | Ricardo Salveti |
Approved revision: | 46 |
Merged at revision: | 45 |
Proposed branch: | lp:~awe/phablet-extras/ofono-nettime-plugin |
Merge into: | lp:phablet-extras/ofono |
Diff against target: |
442 lines (+371/-1) 7 files modified
Makefile.am (+5/-0) configure.ac (+5/-0) debian/changelog (+5/-1) include/dbus.h (+1/-0) plugins/nettime.c (+274/-0) test/get-network-time (+69/-0) test/monitor-ofono (+12/-0) |
To merge this branch: | bzr merge lp:~awe/phablet-extras/ofono-nettime-plugin |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ricardo Salveti (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+171344@code.launchpad.net |
Commit message
Added network time plugin which exposes RILD NITZ messages over DBus.
Description of the change
Add network time plugin.
This can be tested using a new test script get-network-time and modification to monitor-ofono.
Tony Espy (awe) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:43
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:44
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Ricardo Salveti (rsalveti) wrote : | # |
476 + for member in ["NetworkTimeRe
This should be NetworkTimeChanged instead.
Other than that, code looks good.
Tony Espy (awe) wrote : | # |
Nice catch... fixed.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:45
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:46
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'Makefile.am' |
2 | --- Makefile.am 2013-04-12 20:04:45 +0000 |
3 | +++ Makefile.am 2013-06-26 17:26:23 +0000 |
4 | @@ -466,6 +466,11 @@ |
5 | endif |
6 | endif |
7 | |
8 | +if NETTIME |
9 | +builtin_modules += nettime |
10 | +builtin_sources += plugins/nettime.c |
11 | +endif |
12 | + |
13 | if PROVISION |
14 | builtin_sources += plugins/mbpi.h plugins/mbpi.c |
15 | |
16 | |
17 | === modified file 'configure.ac' |
18 | --- configure.ac 2013-03-28 12:50:26 +0000 |
19 | +++ configure.ac 2013-06-26 17:26:23 +0000 |
20 | @@ -188,6 +188,11 @@ |
21 | AC_SUBST(BLUEZ_LIBS) |
22 | AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no") |
23 | |
24 | +AC_ARG_ENABLE(nettime, AC_HELP_STRING([--disable-nettime], |
25 | + [disable Nettime plugin]), |
26 | + [enable_nettime=${enableval}]) |
27 | +AM_CONDITIONAL(NETTIME, test "${enable_netttime}" != "no") |
28 | + |
29 | AC_ARG_WITH([provisiondb], AC_HELP_STRING([--with-provisiondb=FILE], |
30 | [location of provision database]), [path_provisiondb=${withval}]) |
31 | |
32 | |
33 | === modified file 'debian/changelog' |
34 | --- debian/changelog 2013-06-26 15:49:07 +0000 |
35 | +++ debian/changelog 2013-06-26 17:26:23 +0000 |
36 | @@ -1,7 +1,11 @@ |
37 | -ofono (1.12phablet7) UNRELEASED; urgency=low |
38 | +ofono (1.12phablet7) saucy; urgency=low |
39 | |
40 | + [ Tony Espy ] |
41 | * gril/gril.c: Exit on RILD socket failures. |
42 | |
43 | + [ Petri M. Gerdt <petri.gerdt@jollamobile.com> ] |
44 | + * plugins/nettime.c: Added nettime plugin. |
45 | + |
46 | -- Tony Espy <espy@canonical.com> Tue, 25 Jun 2013 15:14:13 -0400 |
47 | |
48 | ofono (1.12phablet6) saucy; urgency=low |
49 | |
50 | === modified file 'include/dbus.h' |
51 | --- include/dbus.h 2012-08-22 19:59:08 +0000 |
52 | +++ include/dbus.h 2013-06-26 17:26:23 +0000 |
53 | @@ -59,6 +59,7 @@ |
54 | #define OFONO_GNSS_INTERFACE "org.ofono.AssistedSatelliteNavigation" |
55 | #define OFONO_GNSS_POSR_AGENT_INTERFACE "org.ofono.PositioningRequestAgent" |
56 | #define OFONO_HANDSFREE_INTERFACE OFONO_SERVICE ".Handsfree" |
57 | +#define OFONO_NETWORK_TIME_INTERFACE OFONO_SERVICE ".NetworkTime" |
58 | |
59 | /* CDMA Interfaces */ |
60 | #define OFONO_CDMA_VOICECALL_MANAGER_INTERFACE "org.ofono.cdma.VoiceCallManager" |
61 | |
62 | === added file 'plugins/nettime.c' |
63 | --- plugins/nettime.c 1970-01-01 00:00:00 +0000 |
64 | +++ plugins/nettime.c 2013-06-26 17:26:23 +0000 |
65 | @@ -0,0 +1,274 @@ |
66 | +/* |
67 | + * |
68 | + * oFono - Open Source Telephony |
69 | + * |
70 | + * Copyright (C) 2012-2013 Jolla Ltd. |
71 | + * |
72 | + * This program is free software; you can redistribute it and/or modify |
73 | + * it under the terms of the GNU General Public License version 2 as |
74 | + * published by the Free Software Foundation. |
75 | + * |
76 | + * This program is distributed in the hope that it will be useful, |
77 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
78 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
79 | + * GNU General Public License for more details. |
80 | + * |
81 | + * You should have received a copy of the GNU General Public License |
82 | + * along with this program; if not, write to the Free Software |
83 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
84 | + * |
85 | + */ |
86 | + |
87 | +#ifdef HAVE_CONFIG_H |
88 | +#include <config.h> |
89 | +#endif |
90 | + |
91 | +#include <string.h> |
92 | +#include <glib.h> |
93 | +#include <gdbus.h> |
94 | + |
95 | +#define OFONO_API_SUBJECT_TO_CHANGE |
96 | +#include <ofono/plugin.h> |
97 | +#include <ofono/log.h> |
98 | +#include <ofono/nettime.h> |
99 | +#include <ofono/types.h> |
100 | + |
101 | +#include "ofono.h" |
102 | + |
103 | +#include "common.h" |
104 | + |
105 | +struct nt_data { |
106 | + gboolean time_available; |
107 | + gboolean time_pending; |
108 | + |
109 | + time_t nw_time_utc; |
110 | + time_t received; |
111 | + |
112 | + int dst; |
113 | + int time_zone; |
114 | + |
115 | + const char *mcc; |
116 | + const char *mnc; |
117 | + const char *path; |
118 | +}; |
119 | + |
120 | +static struct nt_data *ntd = NULL; |
121 | + |
122 | + |
123 | +static void init_time(void) |
124 | +{ |
125 | + ntd = g_new0(struct nt_data, 1); |
126 | + |
127 | + ntd->time_available = FALSE; |
128 | + ntd->time_pending = FALSE; |
129 | + ntd->dst = 0; |
130 | + ntd->time_zone = 0; |
131 | +} |
132 | + |
133 | +static gboolean encode_time_format(const struct ofono_network_time *time, |
134 | + struct tm *tm) |
135 | +{ |
136 | + if (time->year < 0) |
137 | + return FALSE; |
138 | + |
139 | + memset(tm, 0, sizeof(struct tm)); |
140 | + tm->tm_year = time->year - 1900; |
141 | + tm->tm_mon = time->mon - 1; |
142 | + tm->tm_mday = time->mday; |
143 | + tm->tm_hour = time->hour; |
144 | + tm->tm_min = time->min; |
145 | + tm->tm_sec = time->sec; |
146 | + tm->tm_gmtoff = time->utcoff; |
147 | + tm->tm_isdst = time->dst; |
148 | + |
149 | + return TRUE; |
150 | +} |
151 | + |
152 | +static time_t get_monotonic_time() |
153 | +{ |
154 | + struct timespec ts; |
155 | + clock_gettime(CLOCK_MONOTONIC, &ts); |
156 | + return ts.tv_sec; |
157 | +} |
158 | + |
159 | +static int fill_time_notification(DBusMessage *msg, |
160 | + struct nt_data *ntd) |
161 | +{ |
162 | + DBusMessageIter iter, iter_array; |
163 | + dbus_int64_t utc_long, received; |
164 | + dbus_int32_t dst, timezone; |
165 | + dbus_message_iter_init_append(msg, &iter); |
166 | + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, |
167 | + "{sv}", |
168 | + &iter_array); |
169 | + if (ntd->time_pending) { |
170 | + if (ntd->time_available) { |
171 | + utc_long = (dbus_int64_t) ntd->nw_time_utc; |
172 | + ofono_dbus_dict_append(&iter_array, |
173 | + "UTC", |
174 | + DBUS_TYPE_INT64, |
175 | + &utc_long); |
176 | + dst = (dbus_int32_t) ntd->dst; |
177 | + ofono_dbus_dict_append(&iter_array, |
178 | + "DST", |
179 | + DBUS_TYPE_UINT32, |
180 | + &dst); |
181 | + received = (dbus_int64_t) ntd->received; |
182 | + ofono_dbus_dict_append(&iter_array, |
183 | + "Received", |
184 | + DBUS_TYPE_INT64, |
185 | + &received); |
186 | + } |
187 | + |
188 | + timezone = (dbus_int32_t) ntd->time_zone; |
189 | + ofono_dbus_dict_append(&iter_array, |
190 | + "Timezone", |
191 | + DBUS_TYPE_INT32, |
192 | + &timezone); |
193 | + |
194 | + ofono_dbus_dict_append(&iter_array, |
195 | + "MobileCountryCode", |
196 | + DBUS_TYPE_STRING, |
197 | + &ntd->mcc); |
198 | + |
199 | + ofono_dbus_dict_append(&iter_array, |
200 | + "MobileNetworkCode", |
201 | + DBUS_TYPE_STRING, |
202 | + &ntd->mnc); |
203 | + } else { |
204 | + DBG("fill_time_notification: time not available"); |
205 | + } |
206 | + |
207 | + dbus_message_iter_close_container(&iter, &iter_array); |
208 | + return 0; |
209 | +} |
210 | + |
211 | +static DBusMessage *get_network_time(DBusConnection *conn, |
212 | + DBusMessage *msg, void *data) |
213 | +{ |
214 | + DBusMessage *reply; |
215 | + |
216 | + reply = dbus_message_new_method_return(msg); |
217 | + if (reply == NULL) |
218 | + return NULL; |
219 | + fill_time_notification(reply, ntd); |
220 | + return reply; |
221 | +} |
222 | + |
223 | +static const GDBusMethodTable nettime_methods[] = { |
224 | + { GDBUS_METHOD("GetNetworkTime", |
225 | + NULL, GDBUS_ARGS({ "time", "a{sv}" }), |
226 | + get_network_time) }, |
227 | + { } |
228 | +}; |
229 | + |
230 | +static const GDBusSignalTable nettime_signals[] = { |
231 | + { GDBUS_SIGNAL("NetworkTimeChanged", |
232 | + GDBUS_ARGS({ "time", "a{sv}" })) }, |
233 | + { } |
234 | +}; |
235 | + |
236 | +static int nettime_probe(struct ofono_nettime_context *context) |
237 | +{ |
238 | + DBusConnection *conn = ofono_dbus_get_connection(); |
239 | + const char *path = ofono_modem_get_path(context->modem); |
240 | + DBG("Network time probe for modem: %p (%s)", context->modem, path); |
241 | + init_time(); |
242 | + if (!g_dbus_register_interface(conn, path, |
243 | + OFONO_NETWORK_TIME_INTERFACE, // name |
244 | + nettime_methods, // methods |
245 | + nettime_signals, // signals |
246 | + NULL, // GDBusPropertyTable *properties |
247 | + NULL, // user data |
248 | + NULL)) { // GDBusDestroyFunction destroy |
249 | + ofono_error("Networkt time: Could not register interface %s, path %s", |
250 | + OFONO_NETWORK_TIME_INTERFACE, path); |
251 | + return 1; |
252 | + } else { |
253 | + ofono_info("Network time: Registered inteface %s, path %s", |
254 | + OFONO_NETWORK_TIME_INTERFACE, path); |
255 | + } |
256 | + |
257 | + ofono_modem_add_interface(context->modem, OFONO_NETWORK_TIME_INTERFACE); |
258 | + return 0; |
259 | +} |
260 | + |
261 | +static void nettime_remove(struct ofono_nettime_context *context) |
262 | +{ |
263 | + DBusConnection *conn = ofono_dbus_get_connection(); |
264 | + const char *path = ofono_modem_get_path(context->modem); |
265 | + DBG("Network time remove for modem: %p (%s)", context->modem, path); |
266 | + if (!g_dbus_unregister_interface(conn, path, OFONO_NETWORK_TIME_INTERFACE)) { |
267 | + ofono_error("Network time: could not unregister interface %s, path %s", |
268 | + OFONO_NETWORK_TIME_INTERFACE, path); |
269 | + } |
270 | + |
271 | + ofono_modem_remove_interface(context->modem, OFONO_NETWORK_TIME_INTERFACE); |
272 | + g_free(ntd); |
273 | +} |
274 | + |
275 | +static void send_signal(struct nt_data *ntd) |
276 | +{ |
277 | + DBusConnection *conn = ofono_dbus_get_connection(); |
278 | + DBusMessage *signal = dbus_message_new_signal(ntd->path, |
279 | + OFONO_NETWORK_TIME_INTERFACE, |
280 | + "NetworkTimeChanged"); |
281 | + fill_time_notification(signal, ntd); |
282 | + g_dbus_send_message(conn, signal); |
283 | +} |
284 | + |
285 | +static void nettime_info_received(struct ofono_nettime_context *context, |
286 | + struct ofono_network_time *info) |
287 | +{ |
288 | + struct ofono_netreg *netreg; |
289 | + struct tm t; |
290 | + |
291 | + if (info == NULL) |
292 | + return; |
293 | + |
294 | + netreg = __ofono_atom_get_data(__ofono_modem_find_atom( |
295 | + context->modem, OFONO_ATOM_TYPE_NETREG)); |
296 | + ntd->path = ofono_modem_get_path(context->modem); |
297 | + ntd->mcc = ofono_netreg_get_mcc(netreg); |
298 | + ntd->mnc = ofono_netreg_get_mnc(netreg); |
299 | + ntd->received = get_monotonic_time(); |
300 | + ntd->time_pending = TRUE; |
301 | + ntd->dst = info->dst; |
302 | + ntd->time_zone = info->utcoff; |
303 | + |
304 | + ntd->time_available = encode_time_format(info, &t); |
305 | + if (ntd->time_available == TRUE) |
306 | + ntd->nw_time_utc = timegm(&t); |
307 | + |
308 | + send_signal(ntd); |
309 | + DBG("modem: %p (%s)", context->modem, ofono_modem_get_path(context->modem)); |
310 | + DBG("time: %04d-%02d-%02d %02d:%02d:%02d%c%02d:%02d (DST=%d)", |
311 | + info->year, info->mon, info->mday, info->hour, |
312 | + info->min, info->sec, info->utcoff > 0 ? '+' : '-', |
313 | + abs(info->utcoff) / 3600, (abs(info->utcoff) % 3600) / 60, |
314 | + info->dst); |
315 | + DBG("UTC timestamp: %li, Received (monotonic time): %li", |
316 | + ntd->nw_time_utc, ntd->received); |
317 | + DBG("MCC: %s, MNC: %s", ntd->mcc, ntd->mnc); |
318 | +} |
319 | + |
320 | +static struct ofono_nettime_driver driver = { |
321 | + .name = "Network Time", |
322 | + .probe = nettime_probe, |
323 | + .remove = nettime_remove, |
324 | + .info_received = nettime_info_received, |
325 | +}; |
326 | + |
327 | +static int nettime_init(void) |
328 | +{ |
329 | + return ofono_nettime_driver_register(&driver); |
330 | +} |
331 | + |
332 | +static void nettime_exit(void) |
333 | +{ |
334 | + ofono_nettime_driver_unregister(&driver); |
335 | +} |
336 | + |
337 | +OFONO_PLUGIN_DEFINE(nettime, "Network Time Plugin", |
338 | + VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT, |
339 | + nettime_init, nettime_exit) |
340 | |
341 | === added file 'test/get-network-time' |
342 | --- test/get-network-time 1970-01-01 00:00:00 +0000 |
343 | +++ test/get-network-time 2013-06-26 17:26:23 +0000 |
344 | @@ -0,0 +1,69 @@ |
345 | +#!/usr/bin/python |
346 | + |
347 | +import dbus |
348 | +import sys |
349 | +_dbus2py = { |
350 | + dbus.String : unicode, |
351 | + dbus.UInt32 : int, |
352 | + dbus.Int32 : int, |
353 | + dbus.Int16 : int, |
354 | + dbus.UInt16 : int, |
355 | + dbus.UInt64 : int, |
356 | + dbus.Int64 : int, |
357 | + dbus.Byte : int, |
358 | + dbus.Boolean : bool, |
359 | + dbus.ByteArray : str, |
360 | + dbus.ObjectPath : str |
361 | + } |
362 | + |
363 | +def dbus2py(d): |
364 | + t = type(d) |
365 | + if t in _dbus2py: |
366 | + return _dbus2py[t](d) |
367 | + if t is dbus.Dictionary: |
368 | + return dict([(dbus2py(k), dbus2py(v)) for k, v in d.items()]) |
369 | + if t is dbus.Array and d.signature == "y": |
370 | + return "".join([chr(b) for b in d]) |
371 | + if t is dbus.Array or t is list: |
372 | + return [dbus2py(v) for v in d] |
373 | + if t is dbus.Struct or t is tuple: |
374 | + return tuple([dbus2py(v) for v in d]) |
375 | + return d |
376 | + |
377 | +def pretty(d): |
378 | + d = dbus2py(d) |
379 | + t = type(d) |
380 | + |
381 | + if t in (dict, tuple, list) and len(d) > 0: |
382 | + if t is dict: |
383 | + d = ", ".join(["%s = %s" % (k, pretty(v)) |
384 | + for k, v in d.items()]) |
385 | + return "{ %s }" % d |
386 | + |
387 | + d = " ".join([pretty(e) for e in d]) |
388 | + |
389 | + if t is tuple: |
390 | + return "( %s )" % d |
391 | + |
392 | + if t is str: |
393 | + return "%s" % d |
394 | + |
395 | + return str(d) |
396 | + |
397 | +bus = dbus.SystemBus() |
398 | + |
399 | +manager = dbus.Interface(bus.get_object("org.ofono", "/"), |
400 | + "org.ofono.Manager") |
401 | + |
402 | +modems = manager.GetModems() |
403 | + |
404 | +for path, properties in modems: |
405 | + if "org.ofono.NetworkTime" in properties["Interfaces"]: |
406 | + break |
407 | + |
408 | +net_time = dbus.Interface(bus.get_object('org.ofono', path), |
409 | + 'org.ofono.NetworkTime') |
410 | + |
411 | +time = net_time.GetNetworkTime() |
412 | + |
413 | +print pretty(time) |
414 | |
415 | === modified file 'test/monitor-ofono' |
416 | --- test/monitor-ofono 2013-01-28 16:25:32 +0000 |
417 | +++ test/monitor-ofono 2013-06-26 17:26:23 +0000 |
418 | @@ -74,6 +74,10 @@ |
419 | print "{%s} [%s] %s %s (%s)" % (iface, path, member, |
420 | msg, pretty(args)) |
421 | |
422 | +def network_time_changed(time, member, path, interface): |
423 | + iface = interface[interface.rfind(".") + 1:] |
424 | + print "{%s} [%s] %s %s" % (iface, path, member, pretty(time)) |
425 | + |
426 | def ussd(msg, member, path, interface): |
427 | iface = interface[interface.rfind(".") + 1:] |
428 | print "{%s} [%s] %s %s" % (iface, path, member, msg) |
429 | @@ -150,5 +154,13 @@ |
430 | path_keyword="path", |
431 | interface_keyword="interface") |
432 | |
433 | + for member in ["NetworkTimeChanged"]: |
434 | + bus.add_signal_receiver(network_time_changed, |
435 | + bus_name="org.ofono", |
436 | + signal_name = member, |
437 | + member_keyword="member", |
438 | + path_keyword="path", |
439 | + interface_keyword="interface") |
440 | + |
441 | mainloop = gobject.MainLoop() |
442 | mainloop.run() |
Note, as I'm going to have to re-merge once the IMEI MR lands, I'll deal with the changelog at the same time...