Skip to content

Commit

Permalink
WIP - Factor out timer code into a timer module
Browse files Browse the repository at this point in the history
  • Loading branch information
franc0is committed Sep 7, 2015
1 parent f0eb4e3 commit f8d2b79
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 212 deletions.
5 changes: 4 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ libcoap_@LIBCOAP_API_VERSION@_la_SOURCES = \
src/uri.c \
platform/@PLATFORM@/platform_address.c \
platform/@PLATFORM@/platform_io.c \
platform/@PLATFORM@/platform_time.c
platform/@PLATFORM@/platform_net.c \
platform/@PLATFORM@/platform_time.c \
platform/@PLATFORM@/platform_timer.c

## Define the list of public header files and their install location.
## The list defined here will be used within the include/Makefile.am
Expand All @@ -81,6 +83,7 @@ libcoap_include_HEADERS = \
include/coap/coap_context.h \
include/coap/coap_io.h \
include/coap/coap_time.h \
include/coap/coap_timer.h \
include/coap/debug.h \
include/coap/encode.h \
include/coap/hashkey.h \
Expand Down
10 changes: 3 additions & 7 deletions include/coap/coap_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "pdu.h"
#include "coap_time.h"
#include "coap_timer.h"

typedef struct coap_queue_t { // TODO create coap_queue.h
struct coap_queue_t *next;
Expand Down Expand Up @@ -60,15 +61,10 @@ typedef struct coap_context_t {

#ifdef WITH_CONTIKI
struct uip_udp_conn *conn; /**< uIP connection object */
struct etimer retransmit_timer; /**< fires when the next packet must be sent */
struct etimer notify_timer; /**< used to check resources periodically */
#endif /* WITH_CONTIKI */

#ifdef WITH_LWIP
uint8_t timer_configured; /**< Set to 1 when a retransmission is
* scheduled using lwIP timers for this
* context, otherwise 0. */
#endif /* WITH_LWIP */
coap_timer_t *retransmit_timer; /**< fires when the next packet must be sent */
coap_timer_t *notify_timer; /**< used to check resources periodically */

/**
* The last message id that was used is stored in this field. The initial
Expand Down
187 changes: 187 additions & 0 deletions include/coap/coap_timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#ifndef _COAP_TIMER_H_
#define _COAP_TIMER_H_

#include "coap_time.h"

struct coap_timer_t;
typedef struct coap_timer_t coap_timer_t;

void coap_timer_init(void);

typedef void (*CoapTimerCallback)(void *data);

coap_timer_t *coap_new_timer(CoapTimerCallback cb, void *data);

void coap_timer_set(coap_timer_t *timer, coap_tick_t num_ticks);

void coap_timer_is_set(coap_timer_t *timer);

void coap_timer_unset(coap_timer_t *timer);

#endif /* _COAP_TIMER_H_ */

#if 0

#ifdef WITH_LWIP
#include <lwip/timers.h>
#endif

#ifdef WITH_CONTIKI

PROCESS(coap_retransmit_process, "message retransmit process");

#ifdef WITH_CONTIKI
{ /* (re-)initialize retransmission timer */
process_post(&coap_retransmit_process, PROCESS_EVENT_MSG, context);
}
#endif /* WITH_CONTIKI */

#ifdef WITH_LWIP

#include <lwip/memp.h>

static void coap_retransmittimer_execute(void *arg);
static void coap_retransmittimer_restart(coap_context_t *ctx);

#endif /* WITH_LWIP */




/*---------------------------------------------------------------------------*/
/* CoAP message retransmission */
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(coap_retransmit_process, ev, data)
{
coap_tick_t now;
coap_queue_t *nextpdu;
coap_context_t *context = NULL;

PROCESS_BEGIN();

debug("Started retransmit process\r\n");

while(1) {
PROCESS_YIELD();

if (ev == PROCESS_EVENT_MSG) {
context = data;
} else if (ev == PROCESS_EVENT_TIMER) {
#ifndef WITHOUT_OBSERVE
if (etimer_expired(&context->notify_timer)) {
coap_check_notify(context);
etimer_reset(context->notify_timer);
}
if (!etimer_expired(&context->retransmit_timer)) {
continue;
}
#endif /* WITHOUT_OBSERVE */
assert(etimer_expired(&context->retransmit_timer));
} else {
// Toss out events we're not interested in
continue;
}

nextpdu = coap_peek_next(context);

coap_ticks(&now);
while (nextpdu && nextpdu->t <= now) {
coap_retransmit(context, coap_pop_next(context));
nextpdu = coap_peek_next(context);
}

/* need to set timer to some value even if no nextpdu is available */
etimer_set(&context->retransmit_timer,
nextpdu ? nextpdu->t - now : 0xFFFF);
}

PROCESS_END();
}
/*---------------------------------------------------------------------------*/

#endif /* WITH_CONTIKI */

#ifdef WITH_LWIP
/* FIXME: retransmits that are not required any more due to incoming packages
* do *not* get cleared at the moment, the wakeup when the transmission is due
* is silently accepted. this is mainly due to the fact that the required
* checks are similar in two places in the code (when receiving ACK and RST)
* and that they cause more than one patch chunk, as it must be first checked
* whether the sendqueue item to be dropped is the next one pending, and later
* the restart function has to be called. nothing insurmountable, but it can
* also be implemented when things have stabilized, and the performance
* penality is minimal
*
* also, this completely ignores COAP_RESOURCE_CHECK_TIME.
* */

static void coap_retransmittimer_execute(void *arg)
{
coap_context_t *ctx = (coap_context_t*)arg;
coap_tick_t now;
coap_tick_t elapsed;
coap_queue_t *nextinqueue;

ctx->timer_configured = 0;

coap_ticks(&now);

elapsed = now - ctx->sendqueue_basetime; /* that's positive for sure, and unless we haven't been called for a complete wrapping cycle, did not wrap */

nextinqueue = coap_peek_next(ctx);
while (nextinqueue != NULL)
{
if (nextinqueue->t > elapsed) {
nextinqueue->t -= elapsed;
break;
} else {
elapsed -= nextinqueue->t;
coap_retransmit(ctx, coap_pop_next(ctx));
nextinqueue = coap_peek_next(ctx);
}
}

ctx->sendqueue_basetime = now;

coap_retransmittimer_restart(ctx);
}

static void coap_retransmittimer_restart(coap_context_t *ctx)
{
coap_tick_t now, elapsed, delay;

if (ctx->timer_configured)
{
printf("clearing\n");
sys_untimeout(coap_retransmittimer_execute, (void*)ctx);
ctx->timer_configured = 0;
}
if (ctx->sendqueue != NULL)
{
coap_ticks(&now);
elapsed = now - ctx->sendqueue_basetime;
if (ctx->sendqueue->t >= elapsed) {
delay = ctx->sendqueue->t - elapsed;
} else {
/* a strange situation, but not completely impossible.
*
* this happens, for example, right after
* coap_retransmittimer_execute, when a retransmission
* was *just not yet* due, and the clock ticked before
* our coap_ticks was called.
*
* not trying to retransmit anything now, as it might
* cause uncontrollable recursion; let's just try again
* with the next main loop run.
* */
delay = 0;
}

printf("scheduling for %d ticks\n", delay);
sys_timeout(delay, coap_retransmittimer_execute, (void*)ctx);
ctx->timer_configured = 1;
}
}
#endif

#endif
7 changes: 7 additions & 0 deletions platform/lwip/platform_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ coap_free_endpoint(coap_endpoint_t *ep) {
}
}


ssize_t
coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) {
// TODO not implemented
return -1;
}

ssize_t
coap_network_send(struct coap_context_t *context UNUSED_PARAM,
const coap_endpoint_t *local_interface,
Expand Down
2 changes: 2 additions & 0 deletions platform/posix/platform_net.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "net.h"

#include <limits.h>

void coap_transaction_id(const coap_address_t *peer,
const coap_pdu_t *pdu,
coap_tid_t *id) {
Expand Down
27 changes: 27 additions & 0 deletions platform/posix/platform_timer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "coap_timer.h"

struct coap_timer_t {
int time;
};

void coap_timer_init(void) {

}

coap_timer_t *coap_new_timer(CoapTimerCallback cb, void *data) {
return NULL;
}

void coap_timer_set(coap_timer_t *timer, coap_tick_t num_ticks) {
return;
}

void coap_timer_is_set(coap_timer_t *timer) {
return;
}

void coap_timer_unset(coap_timer_t *timer) {
return;
}


22 changes: 7 additions & 15 deletions src/coap_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
#include <arpa/inet.h>
#endif

#ifdef WITH_LWIP
#include <lwip/timers.h>
#endif

#include "debug.h"
#include "mem.h"
#include "str.h"
Expand All @@ -35,6 +31,7 @@
#include "encode.h"
#include "block.h"
#include "net.h"
#include "coap_timer.h"

#if defined(WITH_POSIX)

Expand Down Expand Up @@ -127,22 +124,17 @@ coap_new_context(
c->sockfd = c->endpoint->handle.fd;
#endif /* WITH_POSIX */

#if defined(WITH_POSIX) || defined(WITH_CONTIKI)
c->network_send = coap_network_send;
c->network_read = coap_network_read;
#endif /* WITH_POSIX or WITH_CONTIKI */

#ifdef WITH_CONTIKI
process_start(&coap_retransmit_process, (char *)c);

PROCESS_CONTEXT_BEGIN(&coap_retransmit_process);
#ifndef WITHOUT_OBSERVE
etimer_set(&c->notify_timer, COAP_RESOURCE_CHECK_TIME * COAP_TICKS_PER_SECOND);
# ifndef WITHOUT_OBSERVE
c->notify_timer = coap_new_timer(NULL, c); //FIXME
coap_timer_set(c->notify_timer, COAP_RESOURCE_CHECK_TIME * COAP_TICKS_PER_SECOND);
#endif /* WITHOUT_OBSERVE */

/* the retransmit timer must be initialized to some large value */
etimer_set(&the_coap_context.retransmit_timer, 0xFFFF);
PROCESS_CONTEXT_END(&coap_retransmit_process);
#endif /* WITH_CONTIKI */
c->retransmit_timer = coap_new_timer(NULL, c); //FIXME
coap_timer_set(c->retransmit_timer, 0xFFFF);

return c;

Expand Down
Loading

0 comments on commit f8d2b79

Please sign in to comment.