1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/net/ccn_lite/ccn-lite-relay.c

438 lines
14 KiB
C
Raw Normal View History

2013-10-28 10:25:17 +01:00
/*
* @f ccn-lite-relay.c
* @b CCN relay
*
* Copyright (C) 2011-13, Christian Tschudin, University of Basel
* Copyright (C) 2013, Christian Mehlis, Freie Universität Berlin
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* File history:
* 2011-11-22 created
*/
#include <inttypes.h>
#define RIOT_CCNL_POPULATE (1)
#include "ccnl-includes.h"
#include "ccnx.h"
#include "ccnl.h"
#include "ccnl-core.h"
#include "ccnl-ext.h"
#include "ccnl-platform.h"
#include "ccnl-core.h"
#include "ccnl-pdu.h"
#include "msg.h"
#include "thread.h"
#include "transceiver.h"
2014-04-18 18:41:00 +02:00
#include "vtimer.h"
2013-10-28 10:25:17 +01:00
#include "ccnl-riot-compat.h"
#include "ccn_lite/test_data/text.txt.ccnb.h"
2013-10-28 10:25:17 +01:00
/** The size of the message queue between router daemon and transceiver AND clients */
#define RELAY_MSG_BUFFER_SIZE (64)
/** message buffer */
msg_t msg_buffer_relay[RELAY_MSG_BUFFER_SIZE];
2014-04-19 20:47:20 +02:00
struct ccnl_relay_s *theRelay = NULL;
2013-10-28 10:25:17 +01:00
struct timeval *
ccnl_run_events(void)
{
static struct timeval now;
long usec;
ccnl_get_timeval(&now);
2013-12-03 23:30:23 +01:00
//DEBUGMSG(1, "ccnl_run_events now: %ld:%ld\n", now.tv_sec, now.tv_usec);
2013-10-28 10:25:17 +01:00
while (eventqueue) {
struct ccnl_timer_s *t = eventqueue;
usec = timevaldelta(&(t->timeout), &now);
if (usec >= 0) {
2013-12-03 23:30:23 +01:00
//DEBUGMSG(1, "ccnl_run_events nothing to do: %ld:%ld\n", now.tv_sec, now.tv_usec);
2013-10-28 10:25:17 +01:00
now.tv_sec = usec / 1000000;
now.tv_usec = usec % 1000000;
return &now;
}
2013-12-03 23:30:23 +01:00
//DEBUGMSG(1, "ccnl_run_events run event handler: %ld:%ld\n", now.tv_sec, now.tv_usec);
2013-10-28 10:25:17 +01:00
if (t->fct) {
(t->fct)(t->node, t->intarg);
}
else if (t->fct2) {
(t->fct2)(t->aux1, t->aux2);
}
eventqueue = t->next;
ccnl_free(t);
}
return NULL;
}
// ----------------------------------------------------------------------
int ccnl_open_riotmsgdev(void)
{
/*
* nothing to do here, msg system just needs a buffer, and this is
* generated staticly
*/
return RIOT_MSG_DEV; /* sock id */
}
int ccnl_open_riottransdev(void)
{
2014-04-10 22:36:58 +02:00
transceiver_init(TRANSCEIVER);
2013-10-28 10:25:17 +01:00
transceiver_start();
/** register for transceiver events */
2014-04-10 22:36:58 +02:00
transceiver_register(TRANSCEIVER, thread_getpid());
2013-10-28 10:25:17 +01:00
return RIOT_TRANS_DEV; /* sock id */
}
void ccnl_ll_TX(struct ccnl_relay_s *ccnl, struct ccnl_if_s *ifc,
sockunion *dest, struct ccnl_buf_s *buf)
{
(void) ccnl; /* unused */
ifc->sendfunc(buf->data, (uint16_t) buf->datalen, (uint16_t) dest->id);
2013-10-28 10:25:17 +01:00
}
// ----------------------------------------------------------------------
void ccnl_ageing(void *relay, void *aux)
{
ccnl_do_ageing(relay, aux);
2014-02-10 21:45:22 +01:00
ccnl_set_timer(TIMEOUT_TO_US(CCNL_CHECK_TIMEOUT_SEC, CCNL_CHECK_TIMEOUT_USEC), ccnl_ageing, relay, 0);
}
void ccnl_retransmit(void *relay, void *aux)
{
ccnl_do_retransmit(relay, aux);
2014-02-10 21:45:22 +01:00
ccnl_set_timer(TIMEOUT_TO_US(CCNL_CHECK_RETRANSMIT_SEC, CCNL_CHECK_RETRANSMIT_USEC), ccnl_retransmit, relay, 0);
2013-10-28 10:25:17 +01:00
}
2014-02-10 21:46:17 +01:00
void ccnl_nonce_timeout(void *relay, void *aux)
{
ccnl_do_nonce_timeout(relay, aux);
ccnl_set_timer(TIMEOUT_TO_US(CCNL_NONCE_TIMEOUT_SEC, CCNL_NONCE_TIMEOUT_USEC), ccnl_nonce_timeout, relay, 0);
}
2013-10-28 10:25:17 +01:00
// ----------------------------------------------------------------------
2013-11-29 22:42:56 +01:00
void ccnl_relay_config(struct ccnl_relay_s *relay, int max_cache_entries, int fib_threshold_prefix, int fib_threshold_aggregate)
2013-10-28 10:25:17 +01:00
{
struct ccnl_if_s *i;
DEBUGMSG(99, "ccnl_relay_config\n");
relay->max_cache_entries = max_cache_entries;
2013-11-29 22:42:56 +01:00
relay->fib_threshold_prefix = fib_threshold_prefix;
relay->fib_threshold_aggregate = fib_threshold_aggregate;
2013-10-28 10:25:17 +01:00
if (RIOT_MSG_IDX != relay->ifcount) {
DEBUGMSG(1, "sorry, idx did not match: riot msg device\n");
}
i = &relay->ifs[relay->ifcount];
i->sock = ccnl_open_riotmsgdev();
i->sendfunc = &riot_send_msg;
i->mtu = 4000;
i->reflect = 0;
i->fwdalli = 0;
if (i->sock >= 0) {
relay->ifcount++;
if (relay->defaultInterfaceScheduler) {
i->sched = relay->defaultInterfaceScheduler(relay,
ccnl_interface_CTS);
}
}
else {
DEBUGMSG(1, "sorry, could not open riot msg device\n");
}
if (RIOT_TRANS_IDX != relay->ifcount) {
DEBUGMSG(1, "sorry, idx did not match: riot trans device\n");
}
i = &relay->ifs[relay->ifcount];
i->sock = ccnl_open_riottransdev();
i->sendfunc = &riot_send_transceiver;
#ifdef USE_FRAG
i->mtu = 120;
#else
i->mtu = 1500;
#endif
i->reflect = 0;
i->fwdalli = 0;
if (i->sock >= 0) {
relay->ifcount++;
if (relay->defaultInterfaceScheduler) {
i->sched = relay->defaultInterfaceScheduler(relay,
ccnl_interface_CTS);
}
}
else {
DEBUGMSG(1, "sorry, could not open riot trans device\n");
}
2013-11-27 23:41:06 +01:00
2013-11-29 22:42:56 +01:00
/* create default boardcast face on transceiver interface */
struct ccnl_face_s * f = ccnl_get_face_or_create(relay, RIOT_TRANS_IDX, RIOT_BROADCAST);
f->flags |= CCNL_FACE_FLAGS_STATIC;
i->broadcast_face = f;
2014-02-10 21:45:22 +01:00
ccnl_set_timer(TIMEOUT_TO_US(CCNL_CHECK_TIMEOUT_SEC, CCNL_CHECK_TIMEOUT_USEC), ccnl_ageing, relay, 0);
ccnl_set_timer(TIMEOUT_TO_US(CCNL_CHECK_RETRANSMIT_SEC, CCNL_CHECK_RETRANSMIT_USEC), ccnl_retransmit, relay, 0);
2014-02-10 21:46:17 +01:00
ccnl_set_timer(TIMEOUT_TO_US(CCNL_NONCE_TIMEOUT_SEC, CCNL_NONCE_TIMEOUT_USEC), ccnl_nonce_timeout, relay, 0);
2013-10-28 10:25:17 +01:00
}
#if RIOT_CCNL_POPULATE
void ccnl_populate_cache(struct ccnl_relay_s *ccnl, unsigned char *buf, int datalen)
{
if (buf[0] == 0x04 && buf[1] == 0x82) {
struct ccnl_prefix_s *prefix = 0;
struct ccnl_content_s *c = 0;
struct ccnl_buf_s *nonce = 0, *ppkd = 0, *pkt = 0;
unsigned char *content, *data = buf + 2;
int contlen;
datalen -= 2;
pkt = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, 0, 0,
0, 0, &prefix, &nonce, &ppkd, &content, &contlen);
if (!pkt) {
DEBUGMSG(6, " parsing error\n");
goto Done;
}
if (!prefix) {
DEBUGMSG(6, " no prefix error\n");
goto Done;
}
printf("populating: %s\n", ccnl_prefix_to_path(prefix));
c = ccnl_content_new(ccnl, &pkt, &prefix, &ppkd, content,
contlen);
if (!c) {
goto Done;
}
c->flags |= CCNL_CONTENT_FLAGS_STATIC;
2014-02-16 23:06:48 +01:00
if (!ccnl_content_add2cache(ccnl, c)) {
// content store error
free_content(c);
}
2013-10-28 10:25:17 +01:00
Done:
free_prefix(prefix);
ccnl_free(pkt);
ccnl_free(nonce);
ccnl_free(ppkd);
}
else {
DEBUGMSG(6, " not a content object\n");
}
}
2014-04-19 20:47:20 +02:00
void handle_populate_cache(struct ccnl_relay_s *ccnl)
2013-10-28 10:25:17 +01:00
{
DEBUGMSG(1, "ccnl_populate_cache with: text_txt_ccnb\n");
2014-04-19 20:47:20 +02:00
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_0, (int) text_txt_ccnb_0_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_1, (int) text_txt_ccnb_1_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_2, (int) text_txt_ccnb_2_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_3, (int) text_txt_ccnb_3_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_4, (int) text_txt_ccnb_4_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_5, (int) text_txt_ccnb_5_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_6, (int) text_txt_ccnb_6_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_7, (int) text_txt_ccnb_7_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_8, (int) text_txt_ccnb_8_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_9, (int) text_txt_ccnb_9_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_10, (int) text_txt_ccnb_10_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_11, (int) text_txt_ccnb_11_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_12, (int) text_txt_ccnb_12_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_13, (int) text_txt_ccnb_13_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_14, (int) text_txt_ccnb_14_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_15, (int) text_txt_ccnb_15_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_16, (int) text_txt_ccnb_16_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_17, (int) text_txt_ccnb_17_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_18, (int) text_txt_ccnb_18_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_19, (int) text_txt_ccnb_19_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_20, (int) text_txt_ccnb_20_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_21, (int) text_txt_ccnb_21_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_22, (int) text_txt_ccnb_22_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_23, (int) text_txt_ccnb_23_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_24, (int) text_txt_ccnb_24_len);
ccnl_populate_cache(ccnl, (unsigned char *) text_txt_ccnb_25, (int) text_txt_ccnb_25_len);
2013-10-28 10:25:17 +01:00
}
#endif
// ----------------------------------------------------------------------
int ccnl_io_loop(struct ccnl_relay_s *ccnl)
{
if (ccnl->ifcount == 0) {
DEBUGMSG(1, "no socket to work with, not good, quitting\n");
return -1;
}
DEBUGMSG(1, "starting main event and IO loop\n");
if (msg_init_queue(msg_buffer_relay, RELAY_MSG_BUFFER_SIZE) != 0) {
DEBUGMSG(1, "msg init queue failed...abording\n");
return -1;
}
msg_t in;
radio_packet_t *p;
riot_ccnl_msg_t *m;
while (!ccnl->halt_flag) {
2013-10-28 10:25:17 +01:00
msg_receive(&in);
2014-04-19 20:47:20 +02:00
mutex_lock(&ccnl->global_lock);
2013-10-28 10:25:17 +01:00
switch (in.type) {
case PKT_PENDING:
/* msg from transceiver */
2013-10-28 10:25:17 +01:00
p = (radio_packet_t *) in.content.ptr;
DEBUGMSG(1, "\tLength:\t%u\n", p->length);
DEBUGMSG(1, "\tSrc:\t%u\n", p->src);
DEBUGMSG(1, "\tDst:\t%u\n", p->dst);
// p->src must be > 0
if (!p->src) {
p->src = RIOT_BROADCAST;
}
ccnl_core_RX(ccnl, RIOT_TRANS_IDX, (unsigned char *) p->data, (int) p->length, p->src);
p->processing--;
break;
case (CCNL_RIOT_MSG):
/* msg from device local client */
2013-10-28 10:25:17 +01:00
m = (riot_ccnl_msg_t *) in.content.ptr;
DEBUGMSG(1, "\tLength:\t%u\n", m->size);
DEBUGMSG(1, "\tSrc:\t%u\n", in.sender_pid);
ccnl_core_RX(ccnl, RIOT_MSG_IDX, (unsigned char *) m->payload, m->size,
in.sender_pid);
break;
case (CCNL_RIOT_HALT):
/* cmd to stop the relay */
2013-10-28 10:25:17 +01:00
DEBUGMSG(1, "\tSrc:\t%u\n", in.sender_pid);
DEBUGMSG(1, "\tNumb:\t%" PRIu32 "\n", in.content.value);
ccnl->halt_flag = 1;
break;
2013-12-16 22:52:20 +01:00
2013-10-28 10:25:17 +01:00
#if RIOT_CCNL_POPULATE
case (CCNL_RIOT_POPULATE):
/* cmd to polulate the cache */
2013-10-28 10:25:17 +01:00
DEBUGMSG(1, "\tSrc:\t%u\n", in.sender_pid);
DEBUGMSG(1, "\tNumb:\t%" PRIu32 "\n", in.content.value);
2014-04-19 20:47:20 +02:00
handle_populate_cache(ccnl);
2013-10-28 10:25:17 +01:00
break;
#endif
2013-12-04 01:12:19 +01:00
case (CCNL_RIOT_PRINT_STAT):
/* cmd to print face statistics */
2013-12-04 01:12:19 +01:00
for (struct ccnl_face_s *f = ccnl->faces; f; f = f->next) {
ccnl_face_print_stat(f);
}
break;
case (ENOBUFFER):
/* transceiver has not enough buffer to store incoming packets, one packet is dropped */
DEBUGMSG(1, "transceiver: one packet is dropped because buffers are full\n");
break;
2013-10-28 10:25:17 +01:00
default:
DEBUGMSG(1, "%s Packet waiting\n", riot_ccnl_event_to_string(in.type));
DEBUGMSG(1, "\tSrc:\t%u\n", in.sender_pid);
DEBUGMSG(1, "\tdropping it...\n");
break;
}
2014-04-19 20:47:20 +02:00
mutex_unlock(&ccnl->global_lock);
2013-10-28 10:25:17 +01:00
}
return 0;
}
/**
* @brief initializing routing system
* @param pointer to count transceiver pids
*
*/
2013-11-29 22:42:56 +01:00
void ccnl_riot_relay_start(int max_cache_entries, int fib_threshold_prefix, int fib_threshold_aggregate)
2013-10-28 10:25:17 +01:00
{
2014-04-19 20:47:20 +02:00
theRelay = calloc(1, sizeof(struct ccnl_relay_s));
ccnl_get_timeval(&theRelay->startup_time);
theRelay->riot_pid = sched_active_pid;
mutex_init(&theRelay->global_lock);
2013-10-28 10:25:17 +01:00
2014-04-19 20:47:20 +02:00
DEBUGMSG(1, "This is ccn-lite-relay, starting at %lu:%lu\n", theRelay->startup_time.tv_sec, theRelay->startup_time.tv_usec);
2013-10-28 10:25:17 +01:00
DEBUGMSG(1, " compile time: %s %s\n", __DATE__, __TIME__);
2013-11-27 17:02:06 +01:00
DEBUGMSG(1, " max_cache_entries: %d\n", max_cache_entries);
2013-11-29 22:42:56 +01:00
DEBUGMSG(1, " threshold_prefix: %d\n", fib_threshold_prefix);
DEBUGMSG(1, " threshold_aggregate: %d\n", fib_threshold_aggregate);
2013-10-28 10:25:17 +01:00
2014-04-19 20:47:20 +02:00
ccnl_relay_config(theRelay, max_cache_entries, fib_threshold_prefix, fib_threshold_aggregate);
2013-10-28 10:25:17 +01:00
2014-04-19 20:47:20 +02:00
theRelay->riot_helper_pid = riot_start_helper_thread();
2014-04-19 20:47:20 +02:00
ccnl_io_loop(theRelay);
2013-10-28 10:25:17 +01:00
DEBUGMSG(1, "ioloop stopped\n");
while (eventqueue) {
ccnl_rem_timer(eventqueue);
}
2014-04-19 20:47:20 +02:00
ccnl_core_cleanup(theRelay);
ccnl_free(theRelay);
2013-10-28 10:25:17 +01:00
}
void ccnl_riot_relay_helper_start(void)
{
unsigned long us = CCNL_CHECK_RETRANSMIT_USEC;
2014-04-19 20:47:20 +02:00
while (!theRelay->halt_flag) {
2014-04-18 18:41:00 +02:00
vtimer_usleep(us);
2014-04-19 20:47:20 +02:00
mutex_lock(&theRelay->global_lock);
ccnl_run_events();
2014-04-19 20:47:20 +02:00
mutex_unlock(&theRelay->global_lock);
}
}
2013-10-28 10:25:17 +01:00
// eof