Main Page | Data Structures | File List | Data Fields | Globals

timer-retu.c

Go to the documentation of this file.
00001 /**
00002  * This file is part of alarmd
00003  *
00004  * Contact Person: David Weinehall <david.weinehall@nokia.com>
00005  *
00006  * Copyright (C) 2006 Nokia Corporation
00007  * alarmd and libalarm are free software; you can redistribute them
00008  * and/or modify them under the terms of the GNU Lesser General Public
00009  * License version 2.1 as published by the Free Software Foundation.
00010  *
00011  * alarmd and libalarm are distributed in the hope that they will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this software; if not, write to the Free
00018  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00019  * 02110-1301 USA
00020  */
00021 
00022 #include <glib/gmain.h>
00023 #include <glib/gtypes.h>
00024 #include <dbus/dbus.h>
00025 #include <time.h>
00026 #include <osso-log.h>
00027 #include <string.h>
00028 #include <glib/gfileutils.h>
00029 #include "rpc-retutime.h"
00030 #include "include/timer-interface.h"
00031 #include "debug.h"
00032 
00033 #define RETUTIME_DBUS_SIGNAL_RULE "type='signal',interface='org.kernel.kevent',path='/org/kernel/bus/platform/drivers/retu_rtc/alarm_expired'"
00034 /* 23:59 */
00035 #define RETUTIME_MAX_TIME 86340
00036 
00037 static gboolean retu_set_event(TimerPlugin *plugin, time_t wanted_time, TimerCallback cb, TimerCancel cancel, gpointer user_data);
00038 static gboolean retu_remove_event(TimerPlugin *plugin);
00039 static time_t retu_get_time(TimerPlugin *plugin);
00040 static void retu_time_changed(TimerPlugin *plugin);
00041 static void retu_plugin_deinit(TimerPlugin *plugin);
00042 static void _clock_set_alarm(time_t alarm_time);
00043 
00044 static gboolean _retu_event_fire(gpointer event);
00045 static gboolean _retu_idle_event_fire(gpointer event);
00046 
00047 typedef struct _RetuTimerEvent RetuTimerEvent;
00048 struct _RetuTimerEvent {
00049         guint timer_id;
00050         time_t timer_time;
00051         TimerCallback cb;
00052         TimerCancel cancel;
00053         gpointer cb_data;
00054 
00055         TimerPlugin *plugin;
00056 };
00057 
00058 typedef struct _RetuIdleEvent RetuIdleEvent;
00059 struct _RetuIdleEvent {
00060         TimerCallback cb;
00061         gpointer cb_data;
00062         gboolean delayed;
00063 };
00064 
00065 
00066 gboolean plugin_initialize(TimerPlugin *plugin)
00067 {
00068         ENTER_FUNC;
00069 
00070         plugin->set_event = retu_set_event;
00071         plugin->remove_event = retu_remove_event;
00072         plugin->get_time = retu_get_time;
00073         plugin->plugin_deinit = retu_plugin_deinit;
00074         plugin->time_changed = retu_time_changed;
00075 
00076         if (!g_file_test("/mnt/initfs/usr/bin/retutime", G_FILE_TEST_IS_REGULAR)) {
00077                 DEBUG("No retutime found.");
00078                 LEAVE_FUNC;
00079                 return FALSE;
00080         }
00081 
00082         plugin->can_power_up = TRUE;
00083         plugin->priority = 5;
00084         plugin->plugin_data = NULL;
00085 
00086         LEAVE_FUNC;
00087         return TRUE;
00088 }
00089 
00090 static gboolean _retu_idle_event_fire(gpointer event) {
00091         RetuIdleEvent *ev = event;
00092         ENTER_FUNC;
00093 
00094         if (ev->cb) {
00095                 ev->cb(ev->cb_data, ev->delayed);
00096         }
00097 
00098         g_free(event);
00099 
00100         LEAVE_FUNC;
00101         return FALSE;
00102 }
00103 
00104 static gboolean _retu_event_fire(gpointer event) {
00105         RetuTimerEvent *ev = (RetuTimerEvent *)event;
00106         ENTER_FUNC;
00107 
00108         ev->plugin->plugin_data = NULL;
00109 
00110         if (ev->cb) {
00111                 ev->cb(ev->cb_data, FALSE);
00112         }
00113 
00114         g_free(event);
00115 
00116         if (retutime_query_alarm()) {
00117                 retutime_ack_alarm();
00118         } else {
00119                 retutime_disable_alarm();
00120         }
00121 
00122         LEAVE_FUNC;
00123         return FALSE;
00124 }
00125 
00126 static gboolean retu_set_event(TimerPlugin *plugin, time_t wanted_time, TimerCallback cb, TimerCancel cancel, gpointer user_data)
00127 {
00128         RetuTimerEvent *event = NULL;
00129         time_t time_now = time(NULL);
00130 
00131         ENTER_FUNC;
00132 
00133         if (plugin == NULL || cb == NULL) {
00134                 DEBUG("plugin == NULL || cb == NULL");
00135                 LEAVE_FUNC;
00136                 return FALSE;
00137         }
00138 
00139         plugin->remove_event(plugin);
00140 
00141         if (time_now > wanted_time) {
00142                 RetuIdleEvent *ev = g_new0(RetuIdleEvent, 1);
00143                 ev->cb = cb;
00144                 ev->cb_data = user_data;
00145                 ev->delayed = time_now > wanted_time + 
00146                         (plugin->is_startup ? 120 : 10) ? TRUE : FALSE;
00147                 g_idle_add(_retu_idle_event_fire, ev);
00148 
00149                 LEAVE_FUNC;
00150                 return TRUE;
00151         }
00152         
00153         event = g_new0(RetuTimerEvent, 1);
00154 
00155         event->timer_id = g_timeout_add((wanted_time - time_now) * 1000, _retu_event_fire, event);
00156 
00157         if (event->timer_id == 0) {
00158                 ULOG_WARN_F("Adding timeout failed.");
00159                 g_free(event);
00160 
00161                 LEAVE_FUNC;
00162                 return FALSE;
00163         }
00164         
00165         event->timer_time = wanted_time;
00166         event->cb = cb;
00167         event->cb_data = user_data;
00168         event->cancel = cancel;
00169         event->plugin = plugin;
00170 
00171         plugin->plugin_data = (gpointer)event;
00172 
00173         _clock_set_alarm(wanted_time);
00174 
00175         LEAVE_FUNC;
00176         return TRUE;
00177 }
00178 
00179 static gboolean retu_remove_event(TimerPlugin *plugin)
00180 {
00181         ENTER_FUNC;
00182 
00183         if (plugin && plugin->plugin_data) {
00184                 RetuTimerEvent *event = (RetuTimerEvent *)plugin->plugin_data;
00185 
00186                 g_source_remove(event->timer_id);
00187 
00188                 if (event->cancel) {
00189                         event->cancel(event->cb_data);
00190                 }
00191 
00192                 plugin->plugin_data = NULL;
00193 
00194                 g_free(event);
00195 
00196                 retutime_disable_alarm();
00197 
00198                 LEAVE_FUNC;
00199                 return TRUE;
00200         }
00201         
00202         LEAVE_FUNC;
00203         return FALSE;
00204 }
00205 
00206 static time_t retu_get_time(TimerPlugin *plugin)
00207 {
00208         ENTER_FUNC;
00209         if (plugin && plugin->plugin_data) {
00210                 RetuTimerEvent *event = (RetuTimerEvent *)plugin->plugin_data;
00211 
00212                 LEAVE_FUNC;
00213                 return event->timer_time;
00214         }
00215 
00216         LEAVE_FUNC;
00217         return 0;
00218 }
00219 
00220 static void retu_plugin_deinit(TimerPlugin *plugin)
00221 {
00222         ENTER_FUNC;
00223         if (plugin && plugin->plugin_data) {
00224                 RetuTimerEvent *event = (RetuTimerEvent *)plugin->plugin_data;
00225 
00226                 g_source_remove(event->timer_id);
00227 
00228                 if (event->cancel) {
00229                         event->cancel(event->cb_data);
00230                 }
00231 
00232                 plugin->plugin_data = NULL;
00233 
00234                 g_free(event);
00235         }
00236         LEAVE_FUNC;
00237 }
00238 
00239 static void retu_time_changed(TimerPlugin *plugin)
00240 {
00241         ENTER_FUNC;
00242         if (plugin && plugin->plugin_data) {
00243                 RetuTimerEvent *event = (RetuTimerEvent *)plugin->plugin_data;
00244                 time_t now = time(NULL);
00245                 g_source_remove(event->timer_id);
00246                 if (now > event->timer_time) {
00247                         plugin->plugin_data = NULL;
00248 
00249                         if (event->cb) {
00250                                 event->cb(event->cb_data, TRUE);
00251                         }
00252 
00253                         g_free(event);
00254                 } else {
00255                         event->timer_id = g_timeout_add((event->timer_time - now) * 1000, _retu_event_fire, event);
00256                 }
00257         }
00258         LEAVE_FUNC;
00259 }
00260 
00261 static void _clock_set_alarm(time_t alarm_time)
00262 {
00263         time_t now = time(NULL);
00264         ENTER_FUNC;
00265 
00266         if (alarm_time - now > RETUTIME_MAX_TIME) {
00267                 retutime_set_alarm_time(now + RETUTIME_MAX_TIME);
00268         } else {
00269                 if (!retutime_set_alarm_time(alarm_time)) {
00270                         retutime_set_alarm_time(alarm_time + 60);
00271                 }
00272         }
00273 
00274         LEAVE_FUNC;
00275 }

Generated on Thu Dec 21 18:23:30 2006 for Alarmd by  doxygen 1.4.2