00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <time.h>
00036 #include <unistd.h>
00037 #include <sys/wait.h>
00038 #include <sys/ioctl.h>
00039 #include <linux/rtc.h>
00040 #include <fcntl.h>
00041 #include <gtk/gtk.h>
00042
00043 #include <liberregxml/erregapi.h>
00044 #include <libermanifest/ermanifest.h>
00045
00046 #include "contentListerLog.h"
00047 #include "system.h"
00048 #include "gtkPincodeScreen.h"
00049 #include "erConnect.h"
00050 #include "control.h"
00051 #include "button.h"
00052 #include "displayUpdate.h"
00053 #include "timedids.h"
00054
00055 #define SECONDS_OF_DAY 86400
00056
00057
00058 static regTimedIds_t *g_timedids_settings = NULL;
00059 static timedids_connect_reason g_connect_reason = connect_undefined;
00060 static guint g_timeout_source_id = 0;
00061 static int g_current_tzoffset = 0;
00062
00063
00064 static void handle_wakeup();
00065 static void handle_normal_startup();
00066 static regTimedIds_t* read_timedids_settings();
00067 static void create_timedids_trigger();
00068 static int get_current_tz_offset();
00069
00070 regTimedIds_t* read_timedids_settings()
00071 {
00072 CL_LOGPRINTF("entry");
00073
00074 regTimedIds_t* theTimedIds = NULL;
00075
00076 theTimedIds = erRegGetTimedIds();
00077 if (theTimedIds == NULL)
00078 {
00079 CL_ERRORPRINTF("erRegGetTimedIds returns NULL");
00080 }
00081
00082 return theTimedIds;
00083 }
00084
00085 void timed_ids_init()
00086 {
00087 CL_LOGPRINTF("entry");
00088
00089
00090
00091 if ((g_timedids_settings = read_timedids_settings()) == NULL)
00092 {
00093 CL_ERRORPRINTF("Can NOT read timed-iDS connection settings");
00094 return;
00095 }
00096
00097
00098 g_current_tzoffset = get_current_tz_offset();
00099
00100 if (!g_timedids_settings->enable)
00101 {
00102
00103 return;
00104 }
00105
00106 time_t utc_second = time(NULL);
00107 struct tm* tm_local = localtime(&utc_second);
00108 int local_second = tm_local->tm_hour * 3600 + tm_local->tm_min * 60 + tm_local->tm_sec;
00109
00110 gboolean wakeup_by_alarm = FALSE;
00111 int i;
00112 for (i=0; i<g_timedids_settings->timeCnt; i++)
00113 {
00114
00115
00116 if (local_second > g_timedids_settings->timeSet[i] &&
00117 local_second - g_timedids_settings->timeSet[i] <= 90)
00118 {
00119 wakeup_by_alarm = TRUE;
00120 break;
00121 }
00122 }
00123
00124 if (wakeup_by_alarm)
00125 {
00126
00127 handle_wakeup();
00128 }
00129 else
00130 {
00131
00132 handle_normal_startup();
00133 }
00134 }
00135
00136 void handle_wakeup()
00137 {
00138 CL_LOGPRINTF("entry");
00139
00140
00141 button_block_all_keys(TRUE);
00142
00143 g_connect_reason = connect_after_wakeup;
00144 }
00145
00146 gboolean on_timedids_connect_after_wakeup(gpointer p)
00147 {
00148 CL_LOGPRINTF("entry");
00149
00150
00151 ctrl_disconnect_wait();
00152 if (g_timedids_settings->swUpdate)
00153 {
00154 ctrl_connect(connectScrDownloadHistory, connect_timed_ids_with_sw);
00155 }
00156 else
00157 {
00158 ctrl_connect(connectScrDownloadHistory, connect_timed_ids_content_only);
00159 }
00160
00161 display_update_decrease_level(LISTER_EXPOSE_LEVEL);
00162
00163 return FALSE;
00164 }
00165
00166 void handle_normal_startup()
00167 {
00168 CL_LOGPRINTF("entry");
00169
00170 int rtc, ret;
00171
00172
00173 rtc = open ("/dev/rtc", O_RDWR);
00174 if (rtc == -1)
00175 {
00176 CL_ERRORPRINTF("Can NOT open /dev/rtc");
00177 return;
00178 }
00179
00180
00181 ret = ioctl(rtc, RTC_AIE_OFF, 0);
00182 if (ret == -1)
00183 {
00184 CL_ERRORPRINTF("Can NOT disable RTC alarm interrupt");
00185 return;
00186 }
00187
00188 close(rtc);
00189
00190
00191 create_timedids_trigger();
00192 }
00193
00194 void create_timedids_trigger()
00195 {
00196 time_t utc_second = time(NULL);
00197 int local_second = (utc_second + g_current_tzoffset) % SECONDS_OF_DAY;
00198
00199 int i, time_left = 0;
00200 for (i=0; i<g_timedids_settings->timeCnt; i++)
00201 {
00202 if (g_timedids_settings->timeSet[i] > local_second)
00203 {
00204 time_left = g_timedids_settings->timeSet[i] - local_second;
00205 break;
00206 }
00207 }
00208
00209 if (i == g_timedids_settings->timeCnt)
00210 {
00211 time_left = SECONDS_OF_DAY + g_timedids_settings->timeSet[0] - local_second;
00212 }
00213
00214 g_timeout_source_id = g_timeout_add(time_left*1000,
00215 on_idle_connect_start_background, (gpointer)connect_timed_ids_background);
00216 }
00217
00218 void timed_ids_handle_recreate_timer(gint interval)
00219 {
00220 if (g_timeout_source_id > 0)
00221 {
00222 g_source_remove(g_timeout_source_id);
00223 g_timeout_source_id = 0;
00224 }
00225
00226 g_timeout_source_id = g_timeout_add(interval * 60 * 1000,
00227 on_idle_connect_start_background, (gpointer)connect_timed_ids_background);
00228 }
00229
00230 void timed_ids_handle_connmgr_quit()
00231 {
00232 CL_LOGPRINTF("entry");
00233 switch (g_connect_reason)
00234 {
00235 case connect_after_wakeup:
00236 if (g_timedids_settings->switchOff)
00237 {
00238
00239 ctrl_shutdown();
00240 }
00241 else
00242 {
00243 create_timedids_trigger();
00244
00245 button_block_all_keys(FALSE);
00246 }
00247 break;
00248 case connect_when_running:
00249
00250 create_timedids_trigger();
00251 break;
00252 default:
00253 break;
00254 }
00255 }
00256
00257 void timed_ids_handle_reread_settings()
00258 {
00259 CL_LOGPRINTF("entry");
00260
00261
00262 regTimedIds_t* stored_timedids_settings = NULL;
00263 if ((stored_timedids_settings = read_timedids_settings()) == NULL)
00264 {
00265 CL_ERRORPRINTF("Can NOT read timed-iDS connection settings");
00266 return;
00267 }
00268
00269 int new_tzoffset = get_current_tz_offset();
00270 gboolean settings_changed = FALSE;
00271
00272 if (memcmp(stored_timedids_settings, g_timedids_settings, sizeof(regTimedIds_t)) != 0)
00273 {
00274
00275 *g_timedids_settings = *stored_timedids_settings;
00276 settings_changed = TRUE;
00277 }
00278 if (new_tzoffset != g_current_tzoffset)
00279 {
00280
00281 g_current_tzoffset = new_tzoffset;
00282 settings_changed = TRUE;
00283 }
00284
00285 if (settings_changed)
00286 {
00287
00288 if (g_timeout_source_id > 0)
00289 {
00290 g_source_remove(g_timeout_source_id);
00291 g_timeout_source_id = 0;
00292 }
00293
00294
00295 if (g_timedids_settings->enable)
00296 {
00297 create_timedids_trigger();
00298 }
00299 }
00300
00301 erRegFreeTimedIds(stored_timedids_settings);
00302 }
00303
00304 void timed_ids_final()
00305 {
00306 CL_LOGPRINTF("entry");
00307
00308 if (g_timedids_settings->enable)
00309 {
00310
00311 time_t utc_second = time(NULL);
00312 int local_second = (utc_second + g_current_tzoffset) % SECONDS_OF_DAY;
00313
00314 int i;
00315 for(i=0; i<g_timedids_settings->timeCnt; i++)
00316 {
00317 if (g_timedids_settings->timeSet[i] > local_second)
00318 {
00319 break;
00320 }
00321 }
00322
00323 if (i == g_timedids_settings->timeCnt)
00324 {
00325 i = 0;
00326 }
00327
00328 int utc_alarm = g_timedids_settings->timeSet[i] - g_current_tzoffset;
00329 if (utc_alarm < 0)
00330 {
00331 utc_alarm += SECONDS_OF_DAY;
00332 }
00333 else if (utc_alarm > SECONDS_OF_DAY)
00334 {
00335 utc_alarm -= SECONDS_OF_DAY;
00336 }
00337
00338 struct rtc_time rtc_tm;
00339 memset(&rtc_tm, 0, sizeof(struct rtc_time));
00340 rtc_tm.tm_hour = utc_alarm / 3600;
00341 rtc_tm.tm_min = utc_alarm / 60 % 60;
00342 rtc_tm.tm_sec = utc_alarm % 60;
00343
00344
00345 int rtc, ret;
00346 rtc = open ("/dev/rtc", O_RDWR);
00347 if (rtc == -1)
00348 {
00349 CL_ERRORPRINTF("Can NOT open /dev/rtc");
00350 return;
00351 }
00352
00353
00354 ret = ioctl(rtc, RTC_ALM_SET, &rtc_tm);
00355 if (ret == -1)
00356 {
00357 CL_ERRORPRINTF("Can NOT set RTC alarm");
00358 return;
00359 }
00360
00361 CL_WARNPRINTF("RTC Alarm is set to %02d:%02d:%02d\n", rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
00362
00363
00364 ret = ioctl(rtc, RTC_AIE_ON, 0);
00365 if (ret == -1)
00366 {
00367 CL_ERRORPRINTF("Can NOT enable RTC alarm interrupt");
00368 return;
00369 }
00370
00371 close(rtc);
00372 }
00373
00374 erRegFreeTimedIds(g_timedids_settings);
00375 }
00376
00377 int get_current_tz_offset()
00378 {
00379 FILE* fp = fopen(TZ_FILE, "rb");
00380
00381 if (NULL == fp)
00382 {
00383 CL_ERRORPRINTF("Can't open %s, use default timezone settings.", TZ_FILE);
00384 return 0;
00385 }
00386
00387 fseek(fp, sizeof(struct tzhead), SEEK_SET);
00388
00389 int offset;
00390 if (fread(&offset, sizeof(int), 1, fp) != 1)
00391 {
00392 CL_ERRORPRINTF("Error reading %s, use default timezone settings.", TZ_FILE);
00393 fclose(fp);
00394 return 0;
00395 }
00396
00397 fclose(fp);
00398
00399 return GINT32_FROM_BE(offset);
00400 }
00401
00402 timedids_connect_reason get_timedids_connect_reason()
00403 {
00404 return g_connect_reason;
00405 }
00406
00407 void set_timedids_connect_reason(timedids_connect_reason connReason)
00408 {
00409 g_connect_reason = connReason;
00410 }
00411