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));
111 printf("ERROR; Memory allocation fails\n");
115 memcpy(midnight, current, sizeof(struct tm));
117 midnight->tm_hour = 0;
118 midnight->tm_min = 0;
119 midnight->tm_sec = 0;
122 // Seconds from midnight.
123 delayed_time = current_time - mktime(midnight);
124 delayed_time = getRelativeSecondsOfDayofweek(current->tm_wday, tp->tm_wday) - delayed_time;
125 delayed_time = delayed_time + getSeconds(tp);
132 long int getSecondsFromAbsTime(struct tm* tp)
135 time_t delayed_time = 0;
138 localtime(¤t_time);
140 delayed_time = mktime(tp) - current_time;
145 time_t registerTimer(const time_t seconds, int *id, void *cb)
159 // get the current time
162 for (idx = 0; idx < TIMEOUTS; ++idx)
163 if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED))
166 if (TIMEOUTS == idx) // reach to end of timer list
169 // idx th timeout will be used.
170 // Reset and set state of the timer
171 timeout_list[idx].timeout_state = 0;
172 timeout_list[idx].timeout_state |= TIMEOUT_USED;
174 // calculate when the timeout should fire
176 timespec_add(&then, seconds);
178 timeout_list[idx].timeout_time = then;
179 timeout_list[idx].timeout_seconds = seconds;
181 // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
182 timeout_list[idx].cb = cb;
183 // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
185 // How long till the next timeout?
187 for (i = 0; i < TIMEOUTS; i++)
189 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED)
191 const time_t secs = timespec_diff(timeout_list[i].timeout_time, now);
193 if (secs >= 0 && secs < next)
199 /* Return the timeout number. */
200 return timeout_list[idx].timeout_time;
203 void unregisterTimer(int idx)
205 if( 0 <= idx && idx < TIMEOUTS)
206 timeout_list[idx].timeout_state = TIMEOUT_UNUSED;
216 /* Check all timeouts that are used and armed, but not passed yet. */
217 for (i = 0; i < TIMEOUTS; i++)
219 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED)
221 const time_t seconds = timespec_diff(timeout_list[i].timeout_time, now);
225 /* timeout [i] fires! */
226 timeout_list[i].timeout_state = TIMEOUT_UNUSED;
227 if (timeout_list[i].cb)
229 timeout_list[i].cb();
236 void *loop(void *threadid)
252 res = pthread_create(&thread_id, NULL, loop, (void *) t);
256 printf("ERROR; return code from pthread_create() is %d\n", res);
262 #else // WITH_ARDUINO
263 time_t timeToSecondsFromNow(tmElements_t *t_then)
268 then = makeTime((*t_then));
270 return (time_t) (then - t);
273 time_t registerTimer(const time_t seconds, int *id, void (*cb)())
282 // get the current time
285 for (idx = 0; idx < TIMEOUTS; ++idx)
286 if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED))
289 if (TIMEOUTS == idx)// reach to end of timer list
292 // idx th timeout will be used.
293 // Reset and set state of the timer
294 timeout_list[idx].timeout_state = 0;
295 timeout_list[idx].timeout_state |= TIMEOUT_USED;
297 // calculate when the timeout should fire
299 timespec_add(&then, seconds);
301 timeout_list[idx].timeout_time = then;
302 timeout_list[idx].timeout_seconds = seconds;
304 // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
305 timeout_list[idx].cb = cb;
306 // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb);
308 // How long till the next timeout?
310 for (i = 0; i < TIMEOUTS; i++)
312 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED))
315 const time_t secs = timespec_diff(timeout_list[i].timeout_time,
318 if (secs >= 0 && secs < next)
324 /* Return the timeout number. */
325 return timeout_list[idx].timeout_time;
328 void unregisterTimer(int idx)
330 if( 0 <= idx && idx < TIMEOUTS)
331 timeout_list[idx].timeout_state = TIMEOUT_UNUSED;
341 /* Check all timeouts that are used and armed, but not passed yet. */
342 for (i = 0; i < TIMEOUTS; i++)
344 if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED))
347 const time_t seconds = timespec_diff(timeout_list[i].timeout_time,
352 /* timeout [i] fires! */
353 timeout_list[i].timeout_state = TIMEOUT_UNUSED;
354 if (timeout_list[i].cb)
356 timeout_list[i].cb();