+Wed Jul 11 17:10:11 EEST 2007 Pekka Riikonen <priikone@silcnet.org>
+
+ * Added SILC Timer API to lib/silcutil/silctimer.[ch],
+ silctimer_i.h, tests/test_silctimer.c.
+
Tue Jul 10 20:02:04 EEST 2007 Pekka Riikonen <priikone@silcnet.org>
* Added queue entry free list to thread pool instead of
lib/silcclient, The Client Library
==================================
+ o UDP SILC connection support to SILC server
+
o Giving WHOIS for nick that doesn't exist should remove any same
named entries from the client cache.
o Structured log messages to Log API. Allows machine readable log
messages. Would allow sending of any kind of data in a log message.
- o Base64 to an own API
+ o Base64 to an own API (***DONE)
- o Timer API
+ o Timer API (***DONE)
o Add builtin SOCKS and HTTP Proxy support, well the SOCKS at least.
SILC currently supports SOCKS4 and SOCKS5 but it needs to be compiled
o Library must have support for SERVICE command.
+ o Both UDP and TCP support for incoming connecetions. Maintaining long
+ term UDP sessions.
+
o The server must be able to run behind NAT device. This means that
Server ID must be based on public IP instead of private IP.
/* More SILC util library includes */
#include "silctime.h"
+#include "silctimer.h"
#include "silccond.h"
#include "silcthread.h"
#include "silcschedule.h"
silcfsm.c \
silcasync.c \
silctime.c \
+ silctimer.c \
silcmime.c \
silcstack.c \
silcsnprintf.c \
silcfsm.h \
silcfsm_i.h \
silctime.h \
+ silctimer.h \
+ silctimer_i.h \
silcmime.h \
silcmime_i.h \
silcasync.h \
--- /dev/null
+/*
+
+ silctimer.c
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2007 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+#include "silc.h"
+
+/* Start timer */
+
+void silc_timer_start(SilcTimer timer)
+{
+ struct timeval curtime;
+
+ memset(timer, 0, sizeof(timer));
+
+ silc_gettimeofday(&curtime);
+ timer->start_sec = curtime.tv_sec;
+ timer->start_usec = curtime.tv_usec;
+
+ timer->running = TRUE;
+}
+
+/* Stop timer */
+
+void silc_timer_stop(SilcTimer timer)
+{
+ struct timeval curtime;
+
+ silc_gettimeofday(&curtime);
+
+ if (curtime.tv_usec < timer->start_usec) {
+ curtime.tv_sec--;
+ curtime.tv_usec += 1000000L;
+ }
+ timer->timer_sec = curtime.tv_sec - timer->start_sec;
+ timer->timer_usec = curtime.tv_usec - timer->start_usec;
+
+ timer->running = FALSE;
+}
+
+/* Continue stopped timer */
+
+void silc_timer_continue(SilcTimer timer)
+{
+ struct timeval curtime;
+
+ if (timer->running)
+ return;
+
+ silc_gettimeofday(&curtime);
+
+ if (curtime.tv_usec < timer->timer_usec) {
+ curtime.tv_sec--;
+ curtime.tv_usec += 1000000L;
+ }
+ timer->start_sec = curtime.tv_sec - timer->timer_sec;
+ timer->start_usec = curtime.tv_usec - timer->timer_usec;
+
+ timer->running = TRUE;
+}
+
+/* Return timer value */
+
+void silc_timer_value(SilcTimer timer,
+ SilcUInt64 *elapsed_time_seconds,
+ SilcUInt32 *elapsed_time_microseconds)
+{
+ if (timer->running) {
+ struct timeval curtime;
+
+ silc_gettimeofday(&curtime);
+
+ if (curtime.tv_usec < timer->start_usec) {
+ curtime.tv_sec--;
+ curtime.tv_usec += 1000000L;
+ }
+ timer->timer_sec = curtime.tv_sec - timer->start_sec;
+ timer->timer_usec = curtime.tv_usec - timer->start_usec;
+ }
+
+ if (elapsed_time_seconds)
+ *elapsed_time_seconds = timer->timer_sec;
+ if (elapsed_time_microseconds)
+ *elapsed_time_microseconds = timer->timer_usec;
+}
+
+/* Return timer value */
+
+void silc_timer_value_time(SilcTimer timer, SilcTime ret_time)
+{
+ SilcUInt64 sec;
+ SilcUInt32 usec;
+
+ silc_timer_value(timer, &sec, &usec);
+ sec = ((timer->start_sec + sec) * (SilcUInt64)1000);
+ sec += ((timer->start_usec + usec) / 1000);
+ silc_time_value(sec, ret_time);
+}
+
+/* Return start time */
+
+void silc_timer_start_time(SilcTimer timer, SilcTime ret_start_time)
+{
+ silc_time_value(((timer->start_sec * (SilcUInt64)1000) +
+ (timer->start_usec / 1000)), ret_start_time);
+}
+
+/* Return TRUE if timer is running */
+
+SilcBool silc_timer_is_running(SilcTimer timer)
+{
+ return timer->running;
+}
--- /dev/null
+/*
+
+ silctimer.h
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2007 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+/****h* silcutil/SILC Timer Interface
+ *
+ * SILC Timer interface provides a simple way to measure time intervals.
+ * The SILC Timer works with microsecond resolution, depending on platform.
+ *
+ ***/
+
+#ifndef SILCTIMER_H
+#define SILCTIMER_H
+
+/****s* silcutil/SilcTimerAPI/SilcTimer
+ *
+ * NAME
+ *
+ * typedef struct SilcTimerObject *SilcTimer, SilcTimerStruct;
+ *
+ * DESCRIPTION
+ *
+ * The timer context. The context is given as argument to all
+ * silc_timer_* functions.
+ *
+ ***/
+typedef struct SilcTimerObject *SilcTimer, SilcTimerStruct;
+
+/****f* silcutil/SilcTimerAPI/silc_timer_start
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_timer_start(SilcTimer timer);
+ *
+ * DESCRIPTION
+ *
+ * Starts the timer. If the timer is already running this will reset
+ * the timer and continue.
+ *
+ * EXAMPLE
+ *
+ * SilcTimerStruct timer;
+ *
+ * silc_timer_start(&timer);
+ * ... time passes ...
+ * silc_timer_stop(&timer);
+ * silc_timer_value(&timer, &elapsed_sec, &elapsed_usec);
+ *
+ ***/
+void silc_timer_start(SilcTimer timer);
+
+/****f* silcutil/SilcTimerAPI/silc_timer_stop
+ *
+ * SYNOPSIS
+ *
+ * void silc_timer_stop(SilcTimer timer);
+ *
+ * DESCRIPTION
+ *
+ * Stop the timer. The elapsed time can be retrieved by calling the
+ * silc_timer_value function.
+ *
+ ***/
+void silc_timer_stop(SilcTimer timer);
+
+/****f* silcutil/SilcTimerAPI/silc_timer_continue
+ *
+ * SYNOPSIS
+ *
+ * void silc_timer_continue(SilcTimer timer);
+ *
+ * DESCRIPTION
+ *
+ * Continue stopped timer. If timer is running already this does nothing.
+ *
+ ***/
+void silc_timer_continue(SilcTimer timer);
+
+/****f* silcutil/SilcTimerAPI/silc_timer_value
+ *
+ * SYNOPSIS
+ *
+ * void silc_timer_value(SilcTimer timer,
+ * SilcUInt64 *elapsed_time_seconds,
+ * SilcUInt32 *elapsed_time_microseconds);
+ *
+ * DESCRIPTION
+ *
+ * Returns either the current value or the end value of the timer. If the
+ * timer is currently running this returns the currently elapsed time. If
+ * the timer is stopped this returns the cumulative elapsed time.
+ *
+ ***/
+void silc_timer_value(SilcTimer timer,
+ SilcUInt64 *elapsed_time_seconds,
+ SilcUInt32 *elapsed_time_microseconds);
+
+/****f* silcutil/SilcTimerAPI/silc_timer_value_time
+ *
+ * SYNOPSIS
+ *
+ * void silc_timer_value_time(SilcTimer timer, SilcTime ret_time);
+ *
+ * DESCRIPTION
+ *
+ * Same as silc_timer_value but returns the elapsed time to `ret_time'
+ * SilcTime structure as absolute date and time. This is useful if the
+ * returned time needs to be converted into some other format such as
+ * time and date strings.
+ *
+ ***/
+void silc_timer_value_time(SilcTimer timer, SilcTime ret_time);
+
+/****f* silcutil/SilcTimerAPI/silc_timer_start_time
+ *
+ * SYNOPSIS
+ *
+ * void silc_timer_start_time(SilcTimer timer, SilcTime ret_start_time);
+ *
+ * DESCRIPTION
+ *
+ * Returns the timer's start time into `ret_start_time' SilcTime structure.
+ *
+ ***/
+void silc_timer_start_time(SilcTimer timer, SilcTime ret_start_time);
+
+/****f* silcutil/SilcTimerAPI/silc_timer_is_running
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_timer_is_running(SilcTimer timer);
+ *
+ * DESCRIPTION
+ *
+ * Returns TRUE if the timer is currently running, FALSE otherwise.
+ *
+ ***/
+SilcBool silc_timer_is_running(SilcTimer timer);
+
+#include "silctimer_i.h"
+
+#endif /* SILCTIMER_H */
--- /dev/null
+/*
+
+ silctimer_i.h
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2007 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+#ifndef SILCTIMER_I_H
+#define SILCTIMER_I_H
+
+#ifndef SILCTIMER_H
+#error "Do not include this header directly"
+#endif
+
+struct SilcTimerObject {
+ SilcUInt64 start_sec; /* Start seconds */
+ SilcUInt32 start_usec; /* Start microseconds */
+ SilcUInt64 timer_sec; /* Timer seconds */
+ SilcUInt32 timer_usec; /* Timer microseconds */
+ unsigned int running : 1; /* Set when timer is running */
+};
+
+#endif /* SILCTIMER_I_H */
test_silclist test_silcfsm test_silcasync test_silcschedule \
test_silcnet test_silcstack test_silcmime test_silcfdstream \
test_silcatomic test_silcmutex test_silctime test_silcthread \
- test_silcdll test_silcenv
+ test_silcdll test_silcenv test_silctimer
test_silcstrutil_SOURCES = test_silcstrutil.c
test_silcstringprep_SOURCES = test_silcstringprep.c
test_silcthread_SOURCES = test_silcthread.c
test_silcdll_SOURCES = test_silcdll.c
test_silcenv_SOURCES = test_silcenv.c
+test_silctimer_SOURCES = test_silctimer.c
LIBS = $(SILC_COMMON_LIBS)
LDADD = -L.. -L../.. -lsilc
{
SilcBool success = FALSE;
SilcTimeStruct curtime;
+ unsigned char ts[32];
if (argc > 1 && !strcmp(argv[1], "-d")) {
silc_log_debug(TRUE);
SILC_LOG_DEBUG(("utc_east : %d", curtime.utc_east));
SILC_LOG_DEBUG(("dst : %d", curtime.dst));
+ silc_time_universal_string(&curtime, ts, sizeof(ts));
+ SILC_LOG_DEBUG(("Universal: %s", ts));
+ silc_time_generalized_string(&curtime, ts, sizeof(ts));
+ SILC_LOG_DEBUG(("Generaliz: %s", ts));
+
success = TRUE;
err:
--- /dev/null
+/* SilcTimer tests */
+
+#include "silc.h"
+
+SilcSchedule schedule;
+SilcTimerStruct timer;
+SilcBool success = FALSE;
+
+SILC_TASK_CALLBACK(check);
+
+SILC_TASK_CALLBACK(restart)
+{
+ SILC_LOG_DEBUG(("Timer is %s", silc_timer_is_running(&timer) ?
+ "running" : "stopped"));
+ SILC_LOG_DEBUG(("Restart timer"));
+ silc_timer_continue(&timer);
+ silc_schedule_task_add_timeout(schedule, check, NULL, 1, 0);
+}
+
+SILC_TASK_CALLBACK(check)
+{
+ SilcUInt64 sec;
+ SilcUInt32 usec;
+ SilcTimeStruct t, st;
+ char ts[32];
+
+ SILC_LOG_DEBUG(("Timer is %s", silc_timer_is_running(&timer) ?
+ "running" : "stopped"));
+
+ silc_timer_value(&timer, &sec, &usec);
+ SILC_LOG_DEBUG(("Timer elapsed: %llu secs, %lu usec", sec, usec));
+
+ if (sec == 5) {
+ SILC_LOG_DEBUG(("Stop timer"));
+ silc_timer_stop(&timer);
+
+ silc_timer_value(&timer, &sec, &usec);
+ SILC_LOG_DEBUG(("Timer elapsed: %llu secs, %lu usec", sec, usec));
+
+ silc_timer_start_time(&timer, &st);
+ silc_timer_value_time(&timer, &t);
+ silc_time_universal_string(&st, ts, sizeof(ts));
+ SILC_LOG_DEBUG(("Start time: %s", ts));
+ silc_time_universal_string(&t, ts, sizeof(ts));
+ SILC_LOG_DEBUG(("End time: %s", ts));
+
+ success = TRUE;
+ silc_schedule_stop(schedule);
+ return;
+ }
+
+ if (sec == 2) {
+ SILC_LOG_DEBUG(("Stopping timer, sleep 3 seconds"));
+ silc_timer_stop(&timer);
+ silc_schedule_task_add_timeout(schedule, restart, NULL, 3, 0);
+ return;
+ }
+
+ silc_schedule_task_add_timeout(schedule, check, NULL, 0, 500000);
+}
+
+
+int main(int argc, char **argv)
+{
+ if (argc > 1 && !strcmp(argv[1], "-d")) {
+ silc_log_debug(TRUE);
+ silc_log_quick(TRUE);
+ silc_log_debug_hexdump(TRUE);
+ silc_log_set_debug_string("*timer*");
+ }
+
+ schedule = silc_schedule_init(0, NULL, NULL);
+ if (!schedule)
+ goto err;
+
+ SILC_LOG_DEBUG(("Start timer"));
+ silc_timer_start(&timer);
+
+ silc_schedule_task_add_timeout(schedule, check, NULL, 1, 0);
+
+ silc_schedule(schedule);
+
+ silc_schedule_uninit(schedule);
+
+ err:
+ SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
+ fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");
+
+ return success;
+}