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);
110 printf("ERROR; Getting local time fails\n");
114 midnight = (struct tm* )malloc(sizeof(struct tm));
118 printf("ERROR; Memory allocation fails\n");
122 memcpy(midnight, current, sizeof(struct tm));
124 midnight->tm_hour = 0;
125 midnight->tm_min = 0;
126 midnight->tm_sec = 0;
129 // Seconds from midnight.
130 delayed_time = current_time - mktime(midnight);
131 delayed_time = getRelativeSecondsOfDayofweek(current->tm_wday, tp->tm_wday) - delayed_time;
132 delayed_time = delayed_time + getSeconds(tp);
139 long int getSecondsFromAbsTime(struct tm* tp)
142 time_t delayed_time = 0;
145 localtime(¤t_time);
147 delayed_time = mktime(tp) - current_time;
152 time_t registerTimer(const time_t seconds, int *id, void *cb)
166 // get the current time
169 for (idx = 0; idx < TIMEOUTS; ++idx)
170 if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED))
173 if (TIMEOUTS == idx) // reach to end of timer list
176 // idx th timeout will be used.
177 // Reset and set state of the timer
178 timeout_list[idx].timeout_state = 0;
179 timeout_list[idx].timeout_state |= TIMEOUT_USED;
181 // calculate when the timeout should fire
183 timespec_add(&then, seconds);
185 timeout_list[idx].timeout_time = then;
186 timeout_list[idx].timeout_seconds = seconds;
188 // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
189 timeout_list[idx].cb = cb;
190 // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
192 // How long till the next timeout?
194 for (i = 0; i < TIMEOUTS; i++)
196 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED)
198 const time_t secs = timespec_diff(timeout_list[i].timeout_time, now);
200 if (secs >= 0 && secs < next)
206 /* Return the timeout number. */
207 return timeout_list[idx].timeout_time;
210 void unregisterTimer(int idx)
212 if( 0 <= idx && idx < TIMEOUTS)
213 timeout_list[idx].timeout_state = TIMEOUT_UNUSED;
223 /* Check all timeouts that are used and armed, but not passed yet. */
224 for (i = 0; i < TIMEOUTS; i++)
226 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED)
228 const time_t seconds = timespec_diff(timeout_list[i].timeout_time, now);
232 /* timeout [i] fires! */
233 timeout_list[i].timeout_state = TIMEOUT_UNUSED;
234 if (timeout_list[i].cb)
236 timeout_list[i].cb();
243 void *loop(void *threadid)
259 res = pthread_create(&thread_id, NULL, loop, (void *) t);
263 printf("ERROR; return code from pthread_create() is %d\n", res);
269 #else // WITH_ARDUINO
270 time_t timeToSecondsFromNow(tmElements_t *t_then)
275 then = makeTime((*t_then));
277 return (time_t) (then - t);
280 time_t registerTimer(const time_t seconds, int *id, void (*cb)())
289 // get the current time
292 for (idx = 0; idx < TIMEOUTS; ++idx)
293 if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED))
296 if (TIMEOUTS == idx)// reach to end of timer list
299 // idx th timeout will be used.
300 // Reset and set state of the timer
301 timeout_list[idx].timeout_state = 0;
302 timeout_list[idx].timeout_state |= TIMEOUT_USED;
304 // calculate when the timeout should fire
306 timespec_add(&then, seconds);
308 timeout_list[idx].timeout_time = then;
309 timeout_list[idx].timeout_seconds = seconds;
311 // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
312 timeout_list[idx].cb = cb;
313 // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
315 // How long till the next timeout?
317 for (i = 0; i < TIMEOUTS; i++)
319 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED))
322 const time_t secs = timespec_diff(timeout_list[i].timeout_time,
325 if (secs >= 0 && secs < next)
331 /* Return the timeout number. */
332 return timeout_list[idx].timeout_time;
335 void unregisterTimer(int idx)
337 if( 0 <= idx && idx < TIMEOUTS)
338 timeout_list[idx].timeout_state = TIMEOUT_UNUSED;
348 /* Check all timeouts that are used and armed, but not passed yet. */
349 for (i = 0; i < TIMEOUTS; i++)
351 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED))
354 const time_t seconds = timespec_diff(timeout_list[i].timeout_time,
359 /* timeout [i] fires! */
360 timeout_list[i].timeout_state = TIMEOUT_UNUSED;
361 if (timeout_list[i].cb)
363 timeout_list[i].cb();