1 //******************************************************************
3 // Copyright 2014 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
41 #define TIMEOUT_USED 1
42 #define TIMEOUT_UNUSED 2
45 pthread_t thread_id = 0; // 0: initial thread id (meaningless)
51 time_t timeout_seconds;
54 } timeout_list[TIMEOUTS];
57 * Return the number of seconds between before and after, (after - before).
58 * This must be async-signal safe, so it cannot use difftime().
60 time_t timespec_diff(const time_t after, const time_t before)
62 return after - before;
66 * Add positive seconds to a timespec, nothing if seconds is negative.
68 void timespec_add(time_t * to, const time_t seconds)
70 if (to && seconds > 0)
78 long int getSeconds(struct tm* tp)
80 long int nInterval = 0;
82 nInterval = (tp->tm_hour * SECS_PER_HOUR);
83 nInterval += (tp->tm_min * SECS_PER_MIN);
84 nInterval += (tp->tm_sec * SECOND);
86 printf("%ld", nInterval);
91 long int getRelativeSecondsOfDayofweek(int ia, int ib)
94 return (((long int)(7 - (ib - ia))) * SECS_PER_DAY);
96 return (((long int)((ib - ia))) * SECS_PER_DAY);
99 long int getRelativeIntervalOfWeek(struct tm* tp)
102 struct tm* current, *midnight;
103 time_t delayed_time = 0;
106 current = localtime(¤t_time);
107 midnight = (struct tm* )malloc(sizeof(struct tm));
108 memcpy(midnight, current, sizeof(struct tm));
110 midnight->tm_hour = 0;
111 midnight->tm_min = 0;
112 midnight->tm_sec = 0;
115 // Seconds from midnight.
116 delayed_time = current_time - mktime(midnight);
117 delayed_time = getRelativeSecondsOfDayofweek(current->tm_wday, tp->tm_wday) - delayed_time;
118 delayed_time = delayed_time + getSeconds(tp);
123 long int getSecondsFromAbsTime(struct tm* tp)
126 time_t delayed_time = 0;
129 localtime(¤t_time);
131 delayed_time = mktime(tp) - current_time;
136 time_t registerTimer(const time_t seconds, int *id, void *cb)
150 // get the current time
153 for (idx = 0; idx < TIMEOUTS; ++idx)
154 if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED))
157 if (TIMEOUTS == idx) // reach to end of timer list
160 // idx th timeout will be used.
161 // Reset and set state of the timer
162 timeout_list[idx].timeout_state = 0;
163 timeout_list[idx].timeout_state |= TIMEOUT_USED;
165 // calculate when the timeout should fire
167 timespec_add(&then, seconds);
169 timeout_list[idx].timeout_time = then;
170 timeout_list[idx].timeout_seconds = seconds;
172 // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
173 timeout_list[idx].cb = cb;
174 // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
176 // How long till the next timeout?
178 for (i = 0; i < TIMEOUTS; i++)
180 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED)
182 const time_t secs = timespec_diff(timeout_list[i].timeout_time, now);
184 if (secs >= 0 && secs < next)
190 /* Return the timeout number. */
191 return timeout_list[idx].timeout_time;
194 void unregisterTimer(int idx)
196 if( 0 <= idx && idx <= TIMEOUTS)
197 timeout_list[idx].timeout_state = TIMEOUT_UNUSED;
207 /* Check all timeouts that are used and armed, but not passed yet. */
208 for (i = 0; i < TIMEOUTS; i++)
210 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED)
212 const time_t seconds = timespec_diff(timeout_list[i].timeout_time, now);
216 /* timeout [i] fires! */
217 timeout_list[i].timeout_state = TIMEOUT_UNUSED;
218 if (timeout_list[i].cb)
220 timeout_list[i].cb();
227 void *loop(void *threadid)
243 res = pthread_create(&thread_id, NULL, loop, (void *) t);
247 printf("ERROR; return code from pthread_create() is %d\n", res);
253 #else // WITH_ARDUINO
254 time_t timeToSecondsFromNow(tmElements_t *t_then)
259 then = makeTime((*t_then));
261 return (time_t) (then - t);
264 time_t registerTimer(const time_t seconds, int *id, void (*cb)())
273 // get the current time
276 for (idx = 0; idx < TIMEOUTS; ++idx)
277 if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED))
280 if (TIMEOUTS == idx)// reach to end of timer list
283 // idx th timeout will be used.
284 // Reset and set state of the timer
285 timeout_list[idx].timeout_state = 0;
286 timeout_list[idx].timeout_state |= TIMEOUT_USED;
288 // calculate when the timeout should fire
290 timespec_add(&then, seconds);
292 timeout_list[idx].timeout_time = then;
293 timeout_list[idx].timeout_seconds = seconds;
295 // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
296 timeout_list[idx].cb = cb;
297 // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
299 // How long till the next timeout?
301 for (i = 0; i < TIMEOUTS; i++)
303 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED))
306 const time_t secs = timespec_diff(timeout_list[i].timeout_time,
309 if (secs >= 0 && secs < next)
315 /* Return the timeout number. */
316 return timeout_list[idx].timeout_time;
319 void unregisterTimer(int idx)
321 if( 0 <= idx && idx <= TIMEOUTS)
322 timeout_list[idx].timeout_state = TIMEOUT_UNUSED;
332 /* Check all timeouts that are used and armed, but not passed yet. */
333 for (i = 0; i < TIMEOUTS; i++)
335 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED))
338 const time_t seconds = timespec_diff(timeout_list[i].timeout_time,
343 /* timeout [i] fires! */
344 timeout_list[i].timeout_state = TIMEOUT_UNUSED;
345 if (timeout_list[i].cb)
347 timeout_list[i].cb();