Merge branch 'master' of ssh://contiki.git.sourceforge.net/gitroot/contiki/contiki

This commit is contained in:
Joakim Eriksson 2011-09-05 11:40:22 +02:00
commit 7b50b87e12
65 changed files with 3156 additions and 825 deletions

View file

@ -55,7 +55,7 @@ NET = netstack.c uip-debug.c packetbuf.c queuebuf.c packetqueue.c
ifdef UIP_CONF_IPV6
CFLAGS += -DUIP_CONF_IPV6=1
UIP = uip6.c tcpip.c psock.c uip-udp-packet.c uip-split.c \
resolv.c tcpdump.c uiplib.c
resolv.c tcpdump.c uiplib.c simple-udp.c
NET += $(UIP) uip-icmp6.c uip-nd6.c uip-packetqueue.c \
sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c
include $(CONTIKI)/core/net/rpl/Makefile.rpl

View file

@ -86,6 +86,8 @@ PROCESS(servreg_hack_process, "Service regstry hack");
static struct etimer sendtimer;
static uint8_t started = 0;
/*---------------------------------------------------------------------------*/
/* Go through the list of registrations and remove those that are too
old. */
@ -117,15 +119,18 @@ purge_registrations(void)
void
servreg_hack_init(void)
{
list_init(others_services);
list_init(own_services);
memb_init(&registrations);
if(started == 0) {
list_init(others_services);
list_init(own_services);
memb_init(&registrations);
process_start(&servreg_hack_process, NULL);
process_start(&servreg_hack_process, NULL);
started = 1;
}
}
/*---------------------------------------------------------------------------*/
void
servreg_hack_register(servreg_hack_id_t id)
servreg_hack_register(servreg_hack_id_t id, const uip_ipaddr_t *addr)
{
servreg_hack_item_t *t;
struct servreg_hack_registration *r;
@ -134,6 +139,8 @@ servreg_hack_register(servreg_hack_id_t id)
list. If we cannot allocate a service registration, we reuse one
from the service registrations made by others. */
servreg_hack_init();
for(t = list_head(own_services);
t != NULL;
t = list_item_next(t)) {
@ -149,6 +156,7 @@ servreg_hack_register(servreg_hack_id_t id)
}
r->id = id;
r->seqno = 1;
uip_ipaddr_copy(&r->addr, addr);
timer_set(&r->timer, LIFETIME / 2);
list_push(own_services, r);
@ -183,6 +191,8 @@ servreg_hack_lookup(servreg_hack_id_t id)
{
servreg_hack_item_t *t;
servreg_hack_init();
purge_registrations();
for(t = servreg_hack_list_head(); t != NULL; t = list_item_next(t)) {
@ -212,8 +222,6 @@ handle_incoming_reg(const uip_ipaddr_t *owner, servreg_hack_id_t id, uint8_t seq
now - we might later choose to discard the oldest registration
that we have). */
/* printf("Handle incoming reg id %d seqno %d\n", id, seqno);*/
for(t = servreg_hack_list_head();
t != NULL;
t = list_item_next(t)) {
@ -276,34 +284,28 @@ send_udp_packet(struct uip_udp_conn *conn)
uint8_t buf[MAX_BUFSIZE];
int bufptr;
servreg_hack_item_t *t;
uip_ds6_addr_t *addr;
addr = uip_ds6_get_global(-1);
buf[MSG_FLAGS_OFFSET] = 0;
numregs = 0;
bufptr = MSG_ADDRS_OFFSET;
if(addr != NULL) {
for(t = list_head(own_services);
(bufptr + MSG_ADDRS_LEN <= MAX_BUFSIZE) && t != NULL;
t = list_item_next(t)) {
uip_ipaddr_copy((uip_ipaddr_t *)&buf[bufptr + MSG_IPADDR_SUBOFFSET],
&addr->ipaddr);
buf[bufptr + MSG_REGS_SUBOFFSET] =
servreg_hack_item_id(t);
buf[bufptr + MSG_REGS_SUBOFFSET + 1] =
buf[bufptr + MSG_REGS_SUBOFFSET + 2] = 0;
buf[bufptr + MSG_SEQNO_SUBOFFSET] = ((struct servreg_hack_registration *)t)->seqno;
bufptr += MSG_ADDRS_LEN;
++numregs;
}
}
for(t = list_head(own_services);
(bufptr + MSG_ADDRS_LEN <= MAX_BUFSIZE) && t != NULL;
t = list_item_next(t)) {
uip_ipaddr_copy((uip_ipaddr_t *)&buf[bufptr + MSG_IPADDR_SUBOFFSET],
servreg_hack_item_address(t));
buf[bufptr + MSG_REGS_SUBOFFSET] =
servreg_hack_item_id(t);
buf[bufptr + MSG_REGS_SUBOFFSET + 1] =
buf[bufptr + MSG_REGS_SUBOFFSET + 2] = 0;
buf[bufptr + MSG_SEQNO_SUBOFFSET] = ((struct servreg_hack_registration *)t)->seqno;
bufptr += MSG_ADDRS_LEN;
++numregs;
}
for(t = servreg_hack_list_head();
(bufptr + MSG_ADDRS_LEN <= MAX_BUFSIZE) && t != NULL;
t = list_item_next(t)) {
@ -338,7 +340,7 @@ parse_incoming_packet(const u8_t *buf, int len)
numregs = buf[MSG_NUMREGS_OFFSET];
flags = buf[MSG_FLAGS_OFFSET];
/* printf("Numregs %d flags %d\n", numregs, flags);*/
/* printf("parse_incoming_packet Numregs %d flags %d\n", numregs, flags);*/
bufptr = MSG_ADDRS_OFFSET;
for(i = 0; i < numregs; ++i) {

View file

@ -81,6 +81,7 @@ void servreg_hack_init(void);
/**
* \brief Register that this node provides a service
* \param service_id The 8-bit ID for the service
* \param addr The address associated with the service
*
* This function is used to register a
* service. Registering a service means that other nodes
@ -91,7 +92,7 @@ void servreg_hack_init(void);
* reached: this is up to the application that uses the
* servreg-hack application.
*/
void servreg_hack_register(servreg_hack_id_t service_id);
void servreg_hack_register(servreg_hack_id_t service_id, const uip_ipaddr_t *addr);
/**

View file

@ -58,7 +58,9 @@ PROCESS_THREAD(shell_ps_process, ev, data)
shell_output_str(&ps_command, "Processes:", "");
for(p = PROCESS_LIST(); p != NULL; p = p->next) {
shell_output_str(&ps_command, PROCESS_NAME_STRING(p), "");
char namebuf[30];
strncpy(namebuf, PROCESS_NAME_STRING(p), sizeof(namebuf));
shell_output_str(&ps_command, namebuf, "");
}
PROCESS_END();

View file

@ -1,2 +1,12 @@
webserver-nano_src = webserver-nogui.c httpd.c psock.c memb.c httpd-fs.c httpd-cgi.c
webserver-nano_dsc = webserver-dsc.c
#Run makefsdata to regenerate httpd-fsdata.c when web content has been edited. This requires PERL.
# Note: Deleting files or transferring pages from makefsdata.ignore will not trigger this rule
# when there is no change in modification dates.
$(CONTIKI)/apps/webserver-nano/httpd-fsdata.c : $(CONTIKI)/apps/webserver-nano/httpd-fs/*.*
$(CONTIKI)/tools/makefsdata -A HTTPD_STRING_ATTR -d $(CONTIKI)/apps/webserver-nano/httpd-fs -o $(CONTIKI)/apps/webserver-nano/httpd-fsdata.c
#Rebuild httpd-fs.c when makefsdata has changed httpd-fsdata.c
$(CONTIKI)/apps/webserver-nano/httpd-fs.c: $(CONTIKI)/apps/webserver-nano/httpd-fsdata.c
touch $(CONTIKI)/apps/webserver-nano/httpd-fs.c

View file

@ -88,9 +88,10 @@ static const char rtes_name[] HTTPD_STRING_ATTR = "routes";
#if WEBSERVER_CONF_TICTACTOE
static const char tictac_name[] HTTPD_STRING_ATTR = "tictac";
#endif
#endif
/*Process states for processes cgi*/
#endif
#if WEBSERVER_CONF_PROCESSES || WEBSERVER_CONF_TCPSTATS
static const char closed[] HTTPD_STRING_ATTR = "CLOSED";
static const char syn_rcvd[] HTTPD_STRING_ATTR = "SYN-RCVD";
@ -178,42 +179,58 @@ generate_header(void *arg)
{
unsigned short numprinted=0;
#if WEBSERVER_CONF_HEADER_W3C
#define _MSS1 100
static const char httpd_cgi_headerw[] HTTPD_STRING_ATTR = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerw);
#endif
#if WEBSERVER_CONF_HEADER_ICON
#define _MSS2 105
static const char httpd_cgi_header1[] HTTPD_STRING_ATTR = "<html><head><title>Contiki-nano</title><link rel=\"icon\" href=\"favicon.gif\" type=\"image/gif\"></head><body>";
#else
#define _MSS2 52
static const char httpd_cgi_header1[] HTTPD_STRING_ATTR = "<html><head><title>Contiki-nano</title></head><body>";
#endif
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_header1);
#if WEBSERVER_CONF_HEADER_MENU
#define _MSS3 32
static const char httpd_cgi_headerm1[] HTTPD_STRING_ATTR = "<pre><a href=\"/\">Front page</a>";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm1);
#if WEBSERVER_CONF_SENSORS
#define _MSS4 34
static const char httpd_cgi_headerm2[] HTTPD_STRING_ATTR = "|<a href=\"status.shtml\">Status</a>";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm2);
#endif
#if WEBSERVER_CONF_TCPSTATS
#define _MSS5 44
static const char httpd_cgi_headerm3[] HTTPD_STRING_ATTR = "|<a href=\"tcp.shtml\">Network connections</a>";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm3);
#endif
#if WEBSERVER_CONF_PROCESSES
#define _MSS6 46
static const char httpd_cgi_headerm4[] HTTPD_STRING_ATTR = "|<a href=\"processes.shtml\">System processes</a>";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm4);
#endif
#if WEBSERVER_CONF_FILESTATS
#define _MSS7 45
static const char httpd_cgi_headerm5[] HTTPD_STRING_ATTR = "|<a href=\"files.shtml\">File statistics</a>";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm5);
#endif
#if WEBSERVER_CONF_TICTACTOE
#define _MSS8 44
static const char httpd_cgi_headerm6[] HTTPD_STRING_ATTR = "|<a href=\"/ttt/ttt.shtml\">TicTacToe</a>";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm6);
#endif
static const char httpd_cgi_headerme[] HTTPD_STRING_ATTR = "</pre>";
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerme);
#endif /* WEBSERVER_CONF_MENU */
#if UIP_RECEIVE_WINDOW < _MSS1+_MSS2+_MSS3_+MSS4_+MSS5_MSS6+_MSS7+_MSS8
#warning ************************************************************
#warning UIP_RECEIVE_WINDOW not large enough for header cgi output.
#warning Web pages will not render properly!
#warning ************************************************************
#endif
return numprinted;
}
/*---------------------------------------------------------------------------*/
@ -546,6 +563,14 @@ generate_sensor_readings(void *arg)
m=s/60;
s=s-m*60;
numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor3, h,m,s);
/* TODO: some gcc's have a bug with %02d format that adds a zero byte and extra chars to the end of the string.
* Seen with arm-none-eabi-gcc.exe (Sourcery G++ Lite 2008q3-66) 4.3.2
* Quick cosmetic fix to strip that off: */
if (*(char *)(uip_appdata + numprinted-3)==0) {numprinted-=3;}
else if (*(char *)(uip_appdata + numprinted-2)==0) {numprinted-=2;}
else if (*(char *)(uip_appdata + numprinted-1)==0) {numprinted-=1;}
#if 0
if (sleepseconds) {
p1=100UL*sleepseconds/seconds;

View file

@ -43,8 +43,22 @@
* Firefox network.http.max-connections-per-server is set to a lower number.
* The RAM needed for each entry depends on script enabling and buffer sizes; see struct httpd_state below.
* Typical range is 100 - 200 bytes per connection
* cgi's that use PSOCK_GENERATOR_SEND will have truncated output if UIP_CONF_RECEIVE_WINDOW and UIP_CONF_TCP_MSS
* are not large enough. The header-menu cgi needs ~340 bytes if all options are enabled, while the file-stats * cgi
* can exceed any MSS if there are enough files to display (e.g. tic-tac-toe).
* The advertised MSS is easily seen in wireshark.
* Some example set a small MSS by default. rpl-border-router for example uses a receive window of 60.
*/
#ifndef WEBSERVER_CONF_NANO
#if CONTIKI_TARGET_SKY || CONTIKI_TARGET_STK500
#define WEBSERVER_CONF_NANO 1
#else
#define WEBSERVER_CONF_NANO 3
#endif
#endif
#if WEBSERVER_CONF_NANO==1
/* nano-size for constrained MCUs */
#define WEBSERVER_CONF_CONNS 2
#define WEBSERVER_CONF_NAMESIZE 16
#define WEBSERVER_CONF_BUFSIZE 40
@ -84,7 +98,12 @@ extern char httpd_query[WEBSERVER_CONF_PASSQUERY];
/* Include referrer in log */
#define WEBSERVER_CONF_REFERER 0
#else /* !sky */
#elif WEBSERVER_CONF_NANO==2
/* webserver-mini having more content */
#error webserver-micro not implemented
#elif WEBSERVER_CONF_NANO==3
/* webserver-mini having all content */
#define WEBSERVER_CONF_CONNS 6
#define WEBSERVER_CONF_NAMESIZE 20
#define WEBSERVER_CONF_BUFSIZE 40
@ -123,7 +142,10 @@ extern char httpd_query[WEBSERVER_CONF_PASSQUERY];
#define WEBSERVER_CONF_LOG 1
/* Include referrer in log */
#define WEBSERVER_CONF_REFERER 1
#endif
#else
#error Specified WEBSERVER_CONF_NANO configuration not supported.
#endif /* WEBSERVER_CONF_NANO */
/* Address printing used by cgi's and logging, but it can be turned off if desired */
#if WEBSERVER_CONF_LOG || WEBSERVER_CONF_ADDRESSES || WEBSERVER_CONF_NEIGHBORS || WEBSERVER_CONF_ROUTES

View file

@ -35,9 +35,7 @@
#include <stdio.h>
#include "contiki.h"
#include "sys/log.h"
//#include "http-strings.h"
#include "webserver-nogui.h"
#include "httpd.h"
@ -59,11 +57,11 @@ PROCESS_THREAD(webserver_nogui_process, ev, data)
PROCESS_END();
}
#if WEBSERVER_CONF_LOG
/*---------------------------------------------------------------------------*/
void
webserver_log_file(uip_ipaddr_t *requester, char *file)
{
#if LOG_CONF_ENABLED
/* Print out IP address of requesting host. */
#if UIP_CONF_IPV6
@ -81,14 +79,14 @@ webserver_log_file(uip_ipaddr_t *requester, char *file)
sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1],
requester->u8[2], requester->u8[3]);
#endif /* UIP_CONF_IPV6 */
log_message(buf, file);
#endif /* LOG_CONF_ENABLED */
//log_message(buf, file);
printf("%s%s\n", buf, file);
}
/*---------------------------------------------------------------------------*/
void
webserver_log(char *msg)
{
log_message(msg, "");
//log_message(msg, "");
printf("%s\n", msg);
}
/*---------------------------------------------------------------------------*/
#endif /* WEBSERVER_CONF_LOG */

View file

@ -44,6 +44,7 @@
#include "net/uip_arp.h"
#include "net/uiplib.h"
#include "net/uip-udp-packet.h"
#include "net/simple-udp.h"
#if UIP_CONF_IPV6
#include "net/uip-icmp6.h"

View file

@ -33,30 +33,25 @@
/**
* \file
* The Contiki power-saving MAC protocol (ContikiMAC)
* Implementation of the ContikiMAC power-saving radio duty cycling protocol
* \author
* Adam Dunkels <adam@sics.se>
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "net/netstack.h"
#include "contiki-conf.h"
#include "dev/leds.h"
#include "dev/radio.h"
#include "dev/watchdog.h"
#include "lib/random.h"
#include "net/mac/contikimac.h"
#include "net/netstack.h"
#include "net/rime.h"
#include "sys/compower.h"
#include "sys/pt.h"
#include "sys/rtimer.h"
/*#include "cooja-debug.h"*/
#include "contiki-conf.h"
#ifdef EXPERIMENT_SETUP
#include "experiment-setup.h"
#endif
#include <string.h>
@ -66,7 +61,9 @@
#ifndef WITH_STREAMING
#define WITH_STREAMING 0
#endif
#ifndef WITH_CONTIKIMAC_HEADER
#ifdef CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
#define WITH_CONTIKIMAC_HEADER CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
#else
#define WITH_CONTIKIMAC_HEADER 1
#endif
#ifndef WITH_FAST_SLEEP
@ -78,15 +75,6 @@
#define WITH_PHASE_OPTIMIZATION 0
#endif
struct announcement_data {
uint16_t id;
uint16_t value;
};
/* The maximum number of announcements in a single announcement
message - may need to be increased in the future. */
#define ANNOUNCEMENT_MAX 10
#if WITH_CONTIKIMAC_HEADER
#define CONTIKIMAC_ID 0x00
@ -96,20 +84,6 @@ struct hdr {
};
#endif /* WITH_CONTIKIMAC_HEADER */
/* The structure of the announcement messages. */
struct announcement_msg {
uint8_t announcement_magic[2];
uint16_t num;
struct announcement_data data[ANNOUNCEMENT_MAX];
};
#define ANNOUNCEMENT_MAGIC1 0xAD
#define ANNOUNCEMENT_MAGIC2 0xAD
/* The length of the header of the announcement message, i.e., the
"num" field in the struct. */
#define ANNOUNCEMENT_MSG_HEADERLEN (sizeof(uint16_t) * 2)
#ifdef CONTIKIMAC_CONF_CYCLE_TIME
#define CYCLE_TIME (CONTIKIMAC_CONF_CYCLE_TIME)
#else
@ -178,19 +152,6 @@ struct announcement_msg {
#define SHORTEST_PACKET_SIZE 43
/* The cycle time for announcements. */
#ifdef ANNOUNCEMENT_CONF_PERIOD
#define ANNOUNCEMENT_PERIOD ANNOUNCEMENT_CONF_PERIOD
#else /* ANNOUNCEMENT_CONF_PERIOD */
#define ANNOUNCEMENT_PERIOD 1 * CLOCK_SECOND
#endif /* ANNOUNCEMENT_CONF_PERIOD */
/* The time before sending an announcement within one announcement
cycle. */
#define ANNOUNCEMENT_TIME (random_rand() % (ANNOUNCEMENT_PERIOD))
#define ACK_LEN 3
#include <stdio.h>
@ -213,13 +174,6 @@ static volatile unsigned char radio_is_on = 0;
#define PRINTDEBUG(...)
#endif
#if CONTIKIMAC_CONF_ANNOUNCEMENTS
/* Timers for keeping track of when to send announcements. */
static struct ctimer announcement_cycle_ctimer, announcement_ctimer;
static int announcement_radio_txpower;
#endif /* CONTIKIMAC_CONF_ANNOUNCEMENTS */
/* Flag that is used to keep track of whether or not we are snooping
for announcements from neighbors. */
static volatile uint8_t is_snooping;
@ -232,6 +186,10 @@ static struct compower_activity current_packet;
#include "net/mac/phase.h"
#ifdef CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
#define MAX_PHASE_NEIGHBORS CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
#endif
#ifndef MAX_PHASE_NEIGHBORS
#define MAX_PHASE_NEIGHBORS 30
#endif
@ -281,8 +239,7 @@ static void
off(void)
{
if(contikimac_is_on && radio_is_on != 0 && /*is_streaming == 0 &&*/
contikimac_keep_radio_on == 0
/* && is_snooping == 0*/) {
contikimac_keep_radio_on == 0) {
radio_is_on = 0;
NETSTACK_RADIO.off();
}
@ -308,6 +265,7 @@ schedule_powercycle(struct rtimer *t, rtimer_clock_t time)
}
}
}
/*---------------------------------------------------------------------------*/
static void
schedule_powercycle_fixed(struct rtimer *t, rtimer_clock_t fixed_time)
{
@ -326,6 +284,7 @@ schedule_powercycle_fixed(struct rtimer *t, rtimer_clock_t fixed_time)
}
}
}
/*---------------------------------------------------------------------------*/
static void
powercycle_turn_radio_off(void)
{
@ -342,6 +301,7 @@ powercycle_turn_radio_off(void)
#endif /* CONTIKIMAC_CONF_COMPOWER */
}
}
/*---------------------------------------------------------------------------*/
static void
powercycle_turn_radio_on(void)
{
@ -349,6 +309,7 @@ powercycle_turn_radio_on(void)
on();
}
}
/*---------------------------------------------------------------------------*/
static char
powercycle(struct rtimer *t, void *ptr)
{
@ -378,10 +339,6 @@ powercycle(struct rtimer *t, void *ptr)
t0 = RTIMER_NOW();
if(we_are_sending == 0) {
powercycle_turn_radio_on();
// schedule_powercycle_fixed(t, t0 + CCA_CHECK_TIME);
#if 0
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME));
#endif /* 0 */
/* Check if a packet is seen in the air. If so, we keep the
radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to
be able to receive the packet. We also continuously check
@ -394,12 +351,10 @@ powercycle(struct rtimer *t, void *ptr)
}
powercycle_turn_radio_off();
}
// schedule_powercycle_fixed(t, t0 + CCA_CHECK_TIME + CCA_SLEEP_TIME);
schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME);
/* COOJA_DEBUG_STR("yield\n");*/
PT_YIELD(&pt);
}
if(packet_seen) {
static rtimer_clock_t start;
static uint8_t silence_periods, periods;
@ -458,10 +413,7 @@ powercycle(struct rtimer *t, void *ptr)
RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 8));
if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) {
/* schedule_powercycle(t, CYCLE_TIME - (RTIMER_NOW() - cycle_start));*/
schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
/* printf("cycle_start 0x%02x now 0x%02x wait 0x%02x\n",
cycle_start, RTIMER_NOW(), CYCLE_TIME - (RTIMER_NOW() - cycle_start));*/
PT_YIELD(&pt);
}
}
@ -469,77 +421,6 @@ powercycle(struct rtimer *t, void *ptr)
PT_END(&pt);
}
/*---------------------------------------------------------------------------*/
#if CONTIKIMAC_CONF_ANNOUNCEMENTS
static int
parse_announcements(void)
{
/* Parse incoming announcements */
struct announcement_msg adata;
const rimeaddr_t *from;
int i;
memcpy(&adata, packetbuf_dataptr(),
MIN(packetbuf_datalen(), sizeof(adata)));
from = packetbuf_addr(PACKETBUF_ADDR_SENDER);
/* printf("%d.%d: probe from %d.%d with %d announcements\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
from->u8[0], from->u8[1], adata.num); */
/* for(i = 0; i < packetbuf_datalen(); ++i) {
printf("%02x ", ((uint8_t *)packetbuf_dataptr())[i]);
}
printf("\n"); */
if(adata.num / sizeof(struct announcement_data) > sizeof(struct announcement_msg)) {
/* Sanity check. The number of announcements is too large -
corrupt packet has been received. */
return 0;
}
for(i = 0; i < adata.num; ++i) {
/* printf("%d.%d: announcement %d: %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
adata.data[i].id,
adata.data[i].value); */
announcement_heard(from, adata.data[i].id, adata.data[i].value);
}
return i;
}
/*---------------------------------------------------------------------------*/
static int
format_announcement(char *hdr)
{
struct announcement_msg adata;
struct announcement *a;
/* Construct the announcements */
/* adata = (struct announcement_msg *)hdr; */
adata.announcement_magic[0] = ANNOUNCEMENT_MAGIC1;
adata.announcement_magic[1] = ANNOUNCEMENT_MAGIC2;
adata.num = 0;
for(a = announcement_list();
a != NULL && adata.num < ANNOUNCEMENT_MAX;
a = a->next) {
if(a->has_value) {
adata.data[adata.num].id = a->id;
adata.data[adata.num].value = a->value;
adata.num++;
}
}
memcpy(hdr, &adata, sizeof(struct announcement_msg));
if(adata.num > 0) {
return ANNOUNCEMENT_MSG_HEADERLEN +
sizeof(struct announcement_data) * adata.num;
} else {
return 0;
}
}
#endif /* CONTIKIMAC_CONF_ANNOUNCEMENTS */
/*---------------------------------------------------------------------------*/
static int
broadcast_rate_drop(void)
{
@ -586,7 +467,6 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr)
return MAC_TX_ERR_FATAL;
}
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr);
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
is_broadcast = 1;
@ -671,12 +551,10 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr)
packet length. */
transmit_len = packetbuf_totlen();
if(transmit_len < SHORTEST_PACKET_SIZE) {
#if 0
/* Pad with zeroes */
uint8_t *ptr;
ptr = packetbuf_dataptr();
memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen());
#endif
PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen());
transmit_len = SHORTEST_PACKET_SIZE;
@ -884,7 +762,6 @@ qsend_packet(mac_callback_t sent, void *ptr)
{
int ret = send_packet(sent, ptr);
if(ret != MAC_TX_DEFERRED) {
// printf("contikimac qsend_packet %p\n", ptr);
mac_call_sent_callback(sent, ptr, ret, 1);
}
}
@ -921,18 +798,6 @@ input_packet(void)
/* This is a regular packet that is destined to us or to the
broadcast address. */
#if CONTIKIMAC_CONF_ANNOUNCEMENTS
{
struct announcement_msg *hdr = packetbuf_dataptr();
uint8_t magic[2];
memcpy(magic, hdr->announcement_magic, 2);
if(magic[0] == ANNOUNCEMENT_MAGIC1 &&
magic[1] == ANNOUNCEMENT_MAGIC2) {
parse_announcements();
}
}
#endif /* CONTIKIMAC_CONF_ANNOUNCEMENTS */
#if WITH_PHASE_OPTIMIZATION
/* If the sender has set its pending flag, it has its radio
turned on and we should drop the phase estimation that we
@ -989,120 +854,6 @@ input_packet(void)
}
}
/*---------------------------------------------------------------------------*/
#if CONTIKIMAC_CONF_ANNOUNCEMENTS
static void
send_announcement(void *ptr)
{
int announcement_len;
int transmit_len;
#if WITH_CONTIKIMAC_HEADER
struct hdr *chdr;
#endif /* WITH_CONTIKIMAC_HEADER */
/* Set up the probe header. */
packetbuf_clear();
announcement_len = format_announcement(packetbuf_dataptr());
if(announcement_len > 0) {
packetbuf_set_datalen(announcement_len);
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr);
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &rimeaddr_null);
packetbuf_set_attr(PACKETBUF_ATTR_RADIO_TXPOWER,
announcement_radio_txpower);
#if WITH_CONTIKIMAC_HEADER
transmit_len = packetbuf_totlen();
if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) {
/* Failed to allocate space for contikimac header */
PRINTF("contikimac: send announcement failed, too large header\n");
return;
}
chdr = packetbuf_hdrptr();
chdr->id = CONTIKIMAC_ID;
chdr->len = transmit_len;
#endif /* WITH_CONTIKIMAC_HEADER */
if(NETSTACK_FRAMER.create()) {
rtimer_clock_t t;
int i, collisions;
we_are_sending = 1;
/* Make sure that the packet is longer or equal to the shorest
packet length. */
transmit_len = packetbuf_totlen();
if(transmit_len < SHORTEST_PACKET_SIZE) {
#if 0
/* Pad with zeroes */
uint8_t *ptr;
ptr = packetbuf_dataptr();
memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - transmit_len);
#endif
PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen());
transmit_len = SHORTEST_PACKET_SIZE;
}
collisions = 0;
/* Check for collisions */
for(i = 0; i < CCA_COUNT_MAX; ++i) {
t = RTIMER_NOW();
on();
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t + CCA_CHECK_TIME));
if(NETSTACK_RADIO.channel_clear() == 0) {
collisions++;
off();
break;
}
off();
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t + CCA_SLEEP_TIME + CCA_CHECK_TIME)) { }
}
if(collisions == 0) {
NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len);
NETSTACK_RADIO.transmit(transmit_len);
t = RTIMER_NOW();
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t + INTER_PACKET_INTERVAL)) { }
NETSTACK_RADIO.transmit(transmit_len);
}
we_are_sending = 0;
}
}
}
/*---------------------------------------------------------------------------*/
static void
cycle_announcement(void *ptr)
{
ctimer_set(&announcement_ctimer, ANNOUNCEMENT_TIME,
send_announcement, NULL);
ctimer_set(&announcement_cycle_ctimer, ANNOUNCEMENT_PERIOD,
cycle_announcement, NULL);
if(is_snooping > 0) {
is_snooping--;
/* printf("is_snooping %d\n", is_snooping); */
}
}
/*---------------------------------------------------------------------------*/
static void
listen_callback(int periods)
{
printf("Snoop\n");
is_snooping = periods + 1;
}
#endif /* CONTIKIMAC_CONF_ANNOUNCEMENTS */
/*---------------------------------------------------------------------------*/
void
contikimac_set_announcement_radio_txpower(int txpower)
{
#if CONTIKIMAC_CONF_ANNOUNCEMENTS
announcement_radio_txpower = txpower;
#endif /* CONTIKIMAC_CONF_ANNOUNCEMENTS */
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
@ -1117,11 +868,6 @@ init(void)
phase_init(&phase_list);
#endif /* WITH_PHASE_OPTIMIZATION */
#if CONTIKIMAC_CONF_ANNOUNCEMENTS
announcement_register_listen_callback(listen_callback);
ctimer_set(&announcement_cycle_ctimer, ANNOUNCEMENT_TIME,
cycle_announcement, NULL);
#endif /* CONTIKIMAC_CONF_ANNOUNCEMENTS */
}
/*---------------------------------------------------------------------------*/
static int

View file

@ -33,13 +33,13 @@
/**
* \file
* The Contiki power-saving MAC protocol (ContikiMAC)
* Header file for the ContikiMAC radio duty cycling protocol
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __CONTIKIMAC_H__
#define __CONTIKIMAC_H__
#ifndef CONTIKIMAC_H
#define CONTIKIMAC_H
#include "sys/rtimer.h"
#include "net/mac/rdc.h"
@ -47,4 +47,4 @@
extern const struct rdc_driver contikimac_driver;
#endif /* __CONTIKIMAC_H__ */
#endif /* CONTIKIMAC_H */

View file

@ -165,6 +165,16 @@ void uip_log(char *msg);
/** \brief Size of the 802.15.4 payload (127byte - 25 for MAC header) */
#define MAC_MAX_PAYLOAD 102
/** \brief Some MAC layers need a minimum payload, which is
configurable through the SICSLOWPAN_CONF_MIN_MAC_PAYLOAD
option. */
#ifdef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD
#define COMPRESSION_THRESHOLD SICSLOWPAN_CONF_COMPRESSION_THRESHOLD
#else
#define COMPRESSION_THRESHOLD 0
#endif
/** \name General variables
* @{
*/
@ -433,7 +443,7 @@ compress_hdr_hc06(rimeaddr_t *rime_destaddr)
uint8_t tmp, iphc0, iphc1;
#if DEBUG
PRINTF("before compression: ");
for (tmp = 0; tmp < UIP_IP_BUF->len[1] + 40; tmp++) {
for(tmp = 0; tmp < UIP_IP_BUF->len[1] + 40; tmp++) {
uint8_t data = ((uint8_t *) (UIP_IP_BUF))[tmp];
PRINTF("%02x", data);
}
@ -1204,7 +1214,7 @@ uncompress_hdr_hc1(uint16_t ip_len)
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
/*--------------------------------------------------------------------*/
/** \name IPv6 dispatch "compression" function
* @{ */
@ -1232,9 +1242,6 @@ compress_hdr_ipv6(rimeaddr_t *rime_destaddr)
return;
}
/** @} */
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */
/*--------------------------------------------------------------------*/
/** \name Input/output functions common to all compression schemes
@ -1259,7 +1266,6 @@ packet_sent(void *ptr, int status, int transmissions)
static void
send_packet(rimeaddr_t *dest)
{
/* Set the link layer destination address for the packet as a
* packetbuf attribute. The MAC layer can access the destination
* address with the function packetbuf_addr(PACKETBUF_ADDR_RECEIVER).
@ -1270,7 +1276,7 @@ send_packet(rimeaddr_t *dest)
#if SICSLOWPAN_CONF_ACK_ALL
packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
#endif
/* Provide a callback function to receive the result of
a packet transmission. */
NETSTACK_MAC.send(&packet_sent, NULL);
@ -1279,7 +1285,7 @@ send_packet(rimeaddr_t *dest)
watchdog know that we are still alive. */
watchdog_periodic();
}
/*--------------------------------------------------------------------*/
/** \brief Take an IP packet and format it to be sent on an 802.15.4
* network using 6lowpan.
* \param localdest The MAC address of the destination
@ -1294,7 +1300,6 @@ output(uip_lladdr_t *localdest)
{
/* The MAC address of the destination of the packet */
rimeaddr_t dest;
/* init */
uncomp_hdr_len = 0;
@ -1334,19 +1339,23 @@ output(uip_lladdr_t *localdest)
}
PRINTFO("sicslowpan output: sending packet len %d\n", uip_len);
/* Try to compress the headers */
if(uip_len >= COMPRESSION_THRESHOLD) {
/* Try to compress the headers */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1
compress_hdr_hc1(&dest);
compress_hdr_hc1(&dest);
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
compress_hdr_ipv6(&dest);
compress_hdr_ipv6(&dest);
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
compress_hdr_hc06(&dest);
compress_hdr_hc06(&dest);
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */
} else {
compress_hdr_ipv6(&dest);
}
PRINTFO("sicslowpan output: header of len %d\n", rime_hdr_len);
if(uip_len - uncomp_hdr_len > MAC_MAX_PAYLOAD - rime_hdr_len) {
#if SICSLOWPAN_CONF_FRAG
struct queuebuf *q;
@ -1358,7 +1367,6 @@ output(uip_lladdr_t *localdest)
* The following fragments contain only the fragn dispatch.
*/
PRINTFO("Fragmentation sending packet len %d\n", uip_len);
/* Create 1st Fragment */

215
core/net/simple-udp.c Normal file
View file

@ -0,0 +1,215 @@
/**
* \addtogroup simple-udp
* @{
*/
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* \file
* Header file for the simple-udp module.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#include "contiki-net.h"
#include "net/simple-udp.h"
#include <string.h>
PROCESS(simple_udp_process, "Simple UDP process");
static uint8_t started = 0;
static uint8_t databuffer[UIP_BUFSIZE];
#define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
/*---------------------------------------------------------------------------*/
static void
init_simple_udp(void)
{
if(started == 0) {
process_start(&simple_udp_process, NULL);
started = 1;
}
}
/*---------------------------------------------------------------------------*/
/**
* \brief Send a UDP packet
* \param c A pointer to a struct simple_udp_connection
* \param data A pointer to the data to be sent
* \param datalen The length of the data
*
* This function sends a UDP packet. The packet will be
* sent to the IP address and with the UDP ports that were
* specified when the connection wa registered with
* simple_udp_register().
*
* \sa simple_udp_sendto()
*/
int
simple_udp_send(struct simple_udp_connection *c,
const void *data, uint16_t datalen)
{
if(c->udp_conn != NULL) {
uip_udp_packet_sendto(c->udp_conn, data, datalen,
&c->remote_addr, UIP_HTONS(c->remote_port));
}
return 0;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Send a UDP packet to a specified IP address
* \param c A pointer to a struct simple_udp_connection
* \param data A pointer to the data to be sent
* \param datalen The length of the data
* \param to The IP address of the receiver
*
* This function sends a UDP packet to a specified IP
* address. The packet will be sent with the UDP ports
* that were specified when the connection wa registered
* with simple_udp_register().
*
* \sa simple_udp_send()
*/
int
simple_udp_sendto(struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to)
{
if(c->udp_conn != NULL) {
uip_udp_packet_sendto(c->udp_conn, data, datalen,
to, UIP_HTONS(c->remote_port));
}
return 0;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Register a UDP connection
* \param c A pointer to a struct simple_udp_connection
* \param local_port The local UDP port in host byte order
* \param remote_addr The remote IP address
* \param remote_port The remote UDP port in host byte order
* \param receive_callback A pointer to a function to be called for incoming packets
* \retval 0 If no UDP connection could be allocated
* \retval 1 If the connection was successfully allocated
*
* This function registers a UDP connection and attaches a
* callback function to it. The callback function will be
* called for incoming packets. The local UDP port can be
* set to 0 to indicate that an ephemeral UDP port should
* be allocated. The remote IP address can be NULL, to
* indicate that packets from any IP address should be
* accepted.
*
*/
int
simple_udp_register(struct simple_udp_connection *c,
uint16_t local_port,
uip_ipaddr_t *remote_addr,
uint16_t remote_port,
simple_udp_callback receive_callback)
{
init_simple_udp();
c->local_port = local_port;
c->remote_port = remote_port;
if(remote_addr != NULL) {
uip_ipaddr_copy(&c->remote_addr, remote_addr);
}
c->receive_callback = receive_callback;
PROCESS_CONTEXT_BEGIN(&simple_udp_process);
c->udp_conn = udp_new(remote_addr, UIP_HTONS(remote_port), c);
if(c->udp_conn != NULL) {
udp_bind(c->udp_conn, UIP_HTONS(local_port));
}
PROCESS_CONTEXT_END();
if(c->udp_conn == NULL) {
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(simple_udp_process, ev, data)
{
struct simple_udp_connection *c;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
/* An appstate pointer is passed to use from the IP stack
through the 'data' pointer. We registered this appstate when
we did the udp_new() call in simple_udp_register() as the
struct simple_udp_connection pointer. So we extract this
pointer and use it when calling the reception callback. */
c = (struct simple_udp_connection *)data;
/* Defensive coding: although the appstate *should* be non-null
here, we make sure to avoid the program crashing on us. */
if(c != NULL) {
/* If we were called because of incoming data, we should call
the reception callback. */
if(uip_newdata()) {
/* Copy the data from the uIP data buffer into our own
buffer to avoid the uIP buffer being messed with by the
callee. */
memcpy(databuffer, uip_appdata, uip_datalen());
/* Call the client process. We use the PROCESS_CONTEXT
mechanism to temporarily switch process context to the
client process. */
if(c->receive_callback != NULL) {
PROCESS_CONTEXT_BEGIN(c->client_process);
c->receive_callback(c,
&(UIP_IP_BUF->srcipaddr),
UIP_HTONS(UIP_IP_BUF->srcport),
&(UIP_IP_BUF->destipaddr),
UIP_HTONS(UIP_IP_BUF->destport),
databuffer, uip_datalen());
PROCESS_CONTEXT_END();
}
}
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/** @} */

94
core/net/simple-udp.h Normal file
View file

@ -0,0 +1,94 @@
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup simple-udp
*
* The default Contiki UDP API is difficult to use. The simple-udp
* module provides a significantly simpler API.
*
* @{
*/
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* \file
* Header file for the simple-udp module.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef SIMPLE_UDP_H
#define SIMPLE_UDP_H
#include "net/uip.h"
struct simple_udp_connection;
typedef void (* simple_udp_callback)(struct simple_udp_connection *c,
const uip_ipaddr_t *source_addr,
uint16_t source_port,
const uip_ipaddr_t *dest_addr,
uint16_t dest_port,
const uint8_t *data, uint16_t datalen);
struct simple_udp_connection {
struct simple_udp_connection *next;
uip_ipaddr_t remote_addr;
uint16_t remote_port, local_port;
simple_udp_callback receive_callback;
struct uip_udp_conn *udp_conn;
struct process *client_process;
};
int simple_udp_register(struct simple_udp_connection *c,
uint16_t local_port,
uip_ipaddr_t *remote_addr,
uint16_t remote_port,
simple_udp_callback receive_callback);
int simple_udp_send(struct simple_udp_connection *c,
const void *data, uint16_t datalen);
int simple_udp_sendto(struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to);
void simple_udp_init(void);
#endif /* SIMPLE_UDP_H */
/** @} */
/** @} */

View file

@ -46,23 +46,25 @@ extern u16_t uip_slen;
#include <string.h>
/*---------------------------------------------------------------------------*/
void
uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
{
#if UIP_UDP
uip_udp_conn = c;
uip_slen = len;
memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, len > UIP_BUFSIZE? UIP_BUFSIZE: len);
uip_process(UIP_UDP_SEND_CONN);
#if UIP_CONF_IPV6 //math
tcpip_ipv6_output();
if(data != NULL) {
uip_udp_conn = c;
uip_slen = len;
memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data,
len > UIP_BUFSIZE? UIP_BUFSIZE: len);
uip_process(UIP_UDP_SEND_CONN);
#if UIP_CONF_IPV6
tcpip_ipv6_output();
#else
if(uip_len > 0) {
tcpip_output();
}
if(uip_len > 0) {
tcpip_output();
}
#endif
}
uip_slen = 0;
#endif /* UIP_UDP */
}
@ -74,18 +76,20 @@ uip_udp_packet_sendto(struct uip_udp_conn *c, const void *data, int len,
uip_ipaddr_t curaddr;
uint16_t curport;
/* Save current IP addr/port. */
uip_ipaddr_copy(&curaddr, &c->ripaddr);
curport = c->rport;
if(toaddr != NULL) {
/* Save current IP addr/port. */
uip_ipaddr_copy(&curaddr, &c->ripaddr);
curport = c->rport;
/* Load new IP addr/port */
uip_ipaddr_copy(&c->ripaddr, toaddr);
c->rport = toport;
/* Load new IP addr/port */
uip_ipaddr_copy(&c->ripaddr, toaddr);
c->rport = toport;
uip_udp_packet_send(c, data, len);
uip_udp_packet_send(c, data, len);
/* Restore old IP addr/port */
uip_ipaddr_copy(&c->ripaddr, &curaddr);
c->rport = curport;
/* Restore old IP addr/port */
uip_ipaddr_copy(&c->ripaddr, &curaddr);
c->rport = curport;
}
}
/*---------------------------------------------------------------------------*/

View file

@ -431,7 +431,6 @@ uip_init(void)
}
#endif /* UIP_UDP */
}
/*---------------------------------------------------------------------------*/
#if UIP_TCP && UIP_ACTIVE_OPEN
struct uip_conn *
@ -503,8 +502,6 @@ uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
return conn;
}
#endif /* UIP_TCP && UIP_ACTIVE_OPEN */
/*---------------------------------------------------------------------------*/
#if UIP_UDP
struct uip_udp_conn *
@ -526,7 +523,6 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport)
}
}
conn = 0;
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == 0) {
@ -551,8 +547,6 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport)
return conn;
}
#endif /* UIP_UDP */
/*---------------------------------------------------------------------------*/
#if UIP_TCP
void
@ -565,8 +559,6 @@ uip_unlisten(u16_t port)
}
}
}
/*---------------------------------------------------------------------------*/
void
uip_listen(u16_t port)
@ -581,7 +573,6 @@ uip_listen(u16_t port)
#endif
/*---------------------------------------------------------------------------*/
#if UIP_CONF_IPV6_REASSEMBLY
#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
@ -814,15 +805,16 @@ uip_add_rcv_nxt(u16_t n)
* \brief Process the options in Destination and Hop By Hop extension headers
*/
static u8_t
ext_hdr_options_process() {
ext_hdr_options_process(void)
{
/*
* Length field in the extension header: length of th eheader in units of
* Length field in the extension header: length of the header in units of
* 8 bytes, excluding the first 8 bytes
* length field in an option : the length of data in the option
*/
uip_ext_opt_offset = 2;
while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) {
switch (UIP_EXT_HDR_OPT_BUF->type) {
while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) {
switch(UIP_EXT_HDR_OPT_BUF->type) {
/*
* for now we do not support any options except padding ones
* PAD1 does not make sense as the header must be 8bytes aligned,

View file

@ -34,6 +34,10 @@ CONTIKI_TARGET_SOURCEFILES += $(USB)
//AVR = clock.c mtarch.c eeprom.c flash.c leds-arch.c watchdog.c rtimer-arch.c
endif
ifdef WITH_RPL
CFLAGS += -DUIP_CONF_IPV6_RPL=$(WITH_RPL)
endif
#For a coffee file system, the application makefile can define COFFEE_FILES=n
#to select the type and COFFEE_ADDRESS=0xaaaaaaaa as the starting byte address.
#If only one is define the other will use the (Raven webserver 1284p) defaults
@ -101,6 +105,7 @@ CC = avr-gcc
LD = avr-gcc
AS = avr-as
AR = avr-ar
ELF_SIZE = avr-size -C --mcu=$(MCU)
OBJCOPY = avr-objcopy
STRIP = avr-strip
CFLAGSNO = -Wall -mmcu=$(MCU) -gdwarf-2 -fno-strict-aliasing \

View file

@ -253,4 +253,4 @@ ISR( _VECTOR(76)) {while (1) x++;}
ISR( _VECTOR(77)) {while (1) x++;}
ISR( _VECTOR(78)) {while (1) x++;}
ISR( _VECTOR(79)) {while (1) x++;}
#endif
#endif

View file

@ -502,7 +502,9 @@ on(void)
#if defined(__AVR_ATmega128RFA1__)
rf230_interruptwait=1;
ENERGEST_ON(ENERGEST_TYPE_LED_RED);
#if RF230BB_CONF_LEDONPORTE1
// PORTE|=(1<<PE1); //ledon
#endif
hal_set_slptr_low();
while (rf230_interruptwait) {}
}
@ -550,7 +552,9 @@ off(void)
/* Sleep Radio */
hal_set_slptr_high();
ENERGEST_OFF(ENERGEST_TYPE_LED_RED);
#if RF230BB_CONF_LEDONPORTE1
// PORTE&=~(1<<PE1); //ledoff
#endif
// DEBUGFLOW('d');
#else
// DEBUGFLOW('e');
@ -834,7 +838,9 @@ rf230_transmit(unsigned short payload_len)
radiowason=0;
// DEBUGFLOW('j');
ENERGEST_ON(ENERGEST_TYPE_LED_RED);
#if RF230BB_CONF_LEDONPORTE1
// PORTE|=(1<<PE1); //ledon
#endif
rf230_interruptwait=1;
hal_set_slptr_low();
while (rf230_interruptwait) {}
@ -974,16 +980,18 @@ rf230_transmit(unsigned short payload_len)
RELEASE_LOCK();
if (tx_result==1) { //success, data pending from adressee
tx_result=0; //Just show success?
tx_result = RADIO_TX_OK; //Just show success?
} else if (tx_result==3) { //CSMA channel access failure
DEBUGFLOW('m');
RIMESTATS_ADD(contentiondrop);
PRINTF("rf230_transmit: Transmission never started\n");
tx_result = RADIO_TX_COLLISION;
} else if (tx_result==5) { //Expected ACK, none received
DEBUGFLOW('n');
// tx_result=0;
tx_result = RADIO_TX_NOACK;
} else if (tx_result==7) { //Invalid (Can't happen since waited for idle above?)
DEBUGFLOW('o');
tx_result = RADIO_TX_ERR;
}
return tx_result;
@ -1688,4 +1696,4 @@ void rf230_start_sneeze(void) {
// while (hal_register_read(0x0f)!=1) {continue;} //wait for pll lock-hangs
hal_register_write(0x02,0x02); //Set TRX_STATE to TX_START
}
#endif
#endif

View file

@ -9,6 +9,7 @@
* Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com
* David Kopf dak664@embarqmail.com
*
* All rights reserved.
*
@ -45,7 +46,6 @@
* \file
* \brief This file contains radio driver code.
*
* $Id: rf230bb.h,v 1.6 2010/12/15 16:50:44 dak664 Exp $
*/
#ifndef RADIO_H
@ -228,4 +228,4 @@ uint8_t rf230_get_raw_rssi(void);
#endif
/** @} */
/*EOF*/
/*EOF*/

View file

@ -77,11 +77,19 @@ rtimer_arch_schedule(rtimer_clock_t t)
volatile uint32_t now;
now = rtimer_arch_now();
PRINTF("rtimer_arch_schedule time %u; now is %u\n", t,now);
#if 1
/* If specified time is always in the future, counter can wrap without harm */
*CRM_RTC_TIMEOUT = t - now;
#else
/* Immediate interrupt if specified time is before current time. This may also
happen on counter overflow. */
if(now>t) {
*CRM_RTC_TIMEOUT = 1;
} else {
*CRM_RTC_TIMEOUT = t - now;
}
#endif
clear_rtc_wu_evt();
enable_rtc_wu();

View file

@ -53,7 +53,7 @@
#if USE_32KHZ_XTAL
#define RTIMER_ARCH_SECOND 32768
#else
#define RTIMER_ARCH_SECOND 2000 /* bogus value --- you should set xmac_config after calibration */
#define RTIMER_ARCH_SECOND 18778 /* close --- should get calibrated */
#endif
#define rtimer_arch_now() (*CRM_RTC_COUNT)

View file

@ -17,6 +17,11 @@ PROJECT_SOURCEFILES += slip-bridge.c
# WITH_WEBSERVER=webserver for /apps/webserver
# WITH_WEBSERVER=raven-webserver for /platform/avr-raven/apps/raven-webserver/
#make clean before changing webservers!
#Note /apps/webserver contains a 2500 byte style sheet which is a severe test
#of the slip connection. Large MSS together with low baud rates without flow
#control will overrun the transmit buffer when the style sheet is requested.
WITH_WEBSERVER=1
ifeq ($(WITH_WEBSERVER),1)
CFLAGS += -DWEBSERVER=1

View file

@ -26,7 +26,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: httpd-simple.h,v 1.1 2010/05/09 12:52:05 nifi Exp $
*/
/**
@ -43,8 +42,10 @@
#include "contiki-net.h"
/* The current internal border router webserver ignores the requested file name */
/* and needs no per-connection output buffer, so save some RAM */
#ifndef WEBSERVER_CONF_CFS_PATHLEN
#define HTTPD_PATHLEN 80
#define HTTPD_PATHLEN 2
#else /* WEBSERVER_CONF_CFS_CONNS */
#define HTTPD_PATHLEN WEBSERVER_CONF_CFS_PATHLEN
#endif /* WEBSERVER_CONF_CFS_CONNS */
@ -56,8 +57,8 @@ struct httpd_state {
struct timer timer;
struct psock sin, sout;
struct pt outputpt;
char inputbuf[HTTPD_PATHLEN + 30];
char outputbuf[UIP_TCP_MSS];
char inputbuf[HTTPD_PATHLEN + 24];
/*char outputbuf[UIP_TCP_MSS]; */
char filename[HTTPD_PATHLEN];
httpd_simple_script_t script;
char state;

View file

@ -0,0 +1,9 @@
all: broadcast-example unicast-sender unicast-receiver
APPS=servreg-hack
CONTIKI=../../..
WITH_UIP6=1
UIP_CONF_IPV6=1
CFLAGS+= -DUIP_CONF_IPV6_RPL
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "lib/random.h"
#include "sys/ctimer.h"
#include "sys/etimer.h"
#include "net/uip.h"
#include "net/uip-ds6.h"
#include "simple-udp.h"
#include <stdio.h>
#include <string.h>
#define UDP_PORT 1234
#define SEND_INTERVAL (20 * CLOCK_SECOND)
#define SEND_TIME (random_rand() % (SEND_INTERVAL))
static struct simple_udp_connection broadcast_connection;
/*---------------------------------------------------------------------------*/
PROCESS(broadcast_example_process, "UDP broadcast example process");
AUTOSTART_PROCESSES(&broadcast_example_process);
/*---------------------------------------------------------------------------*/
static void
receiver(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
printf("Data received on port %d from port %d with length %d\n",
receiver_port, sender_port, datalen);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(broadcast_example_process, ev, data)
{
static struct etimer periodic_timer;
static struct etimer send_timer;
uip_ipaddr_t addr;
PROCESS_BEGIN();
simple_udp_register(&broadcast_connection, UDP_PORT,
NULL, UDP_PORT,
receiver);
etimer_set(&periodic_timer, SEND_INTERVAL);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
etimer_reset(&periodic_timer);
etimer_set(&send_timer, SEND_TIME);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer));
printf("Sending broadcast\n");
uip_create_linklocal_allnodes_mcast(&addr);
simple_udp_sendto(&broadcast_connection, "Test", 4, &addr);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,248 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/avrora</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/native_gateway</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/serial_socket</project>
<project EXPORT="discard">/home/user/contikiprojects/sics.se/mobility</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/collect-view</project>
<project EXPORT="discard">/home/user/nes/papers/smartip-paper/code/cooja_qr</project>
<simulation>
<title>Simple UDP broadcast example</title>
<delaytime>0</delaytime>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.mspmote.SkyMoteType
<identifier>sky1</identifier>
<description>Broadcast example</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.c</source>
<commands EXPORT="discard">make broadcast-example.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.sky</firmware>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>64.1956818968534</x>
<y>28.591062627059372</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>51.81261061627534</x>
<y>24.647047255346667</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>9.068527629624546</x>
<y>46.26817786392282</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>3</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>87.5626508274206</x>
<y>4.896101751816129</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>4</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>55.15853460164762</x>
<y>3.4681662067903796</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>5</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>99.33682438963966</x>
<y>49.73072195748186</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>6</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>61.26294736288044</x>
<y>61.845254356789646</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>7</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>70.4693668755668</x>
<y>52.43101713632271</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>8</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>33.5789440978246</x>
<y>48.10557568631877</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>9</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>62.6079314243491</x>
<y>76.96581640898913</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>10</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>318</width>
<z>3</z>
<height>192</height>
<location_x>0</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<viewport>2.9205864417411154 0.0 0.0 2.9205864417411154 -13.303600659817928 3.5428004585568913</viewport>
</plugin_config>
<width>300</width>
<z>2</z>
<height>300</height>
<location_x>1122</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
</plugin_config>
<width>1422</width>
<z>0</z>
<height>236</height>
<location_x>-1</location_x>
<location_y>302</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.TimeLine
<plugin_config>
<mote>0</mote>
<mote>1</mote>
<mote>2</mote>
<mote>3</mote>
<mote>4</mote>
<mote>5</mote>
<mote>6</mote>
<mote>7</mote>
<mote>8</mote>
<mote>9</mote>
<showRadioRXTX />
<showRadioHW />
<split>125</split>
<zoomfactor>500.0</zoomfactor>
</plugin_config>
<width>1422</width>
<z>1</z>
<height>190</height>
<location_x>0</location_x>
<location_y>539</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/avrora</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/native_gateway</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/serial_socket</project>
<project EXPORT="discard">/home/user/contikiprojects/sics.se/mobility</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/collect-view</project>
<project EXPORT="discard">/home/user/nes/papers/smartip-paper/code/cooja_qr</project>
<simulation>
<title>Simple UDP unicast example</title>
<delaytime>0</delaytime>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.mspmote.SkyMoteType
<identifier>sky1</identifier>
<description>UDP receiver</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.c</source>
<commands EXPORT="discard">make unicast-receiver.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.sky</firmware>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<motetype>
se.sics.cooja.mspmote.SkyMoteType
<identifier>sky2</identifier>
<description>UDP sender</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.c</source>
<commands EXPORT="discard">make unicast-sender.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.sky</firmware>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>82.45117687053667</x>
<y>90.0660093026363</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>44.53120632368774</x>
<y>89.83566130147413</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>91.76407203945963</x>
<y>8.764533976596468</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>3</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>10.771554112657956</x>
<y>16.155558894723033</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>4</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>40.99108749529099</x>
<y>33.68910640819968</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>5</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>49.762281669516085</x>
<y>15.219756237459913</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>6</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>26.209078576184762</x>
<y>97.71885344901867</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>7</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>96.30596045236783</x>
<y>3.353548431613529</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>8</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>52.22023117695779</x>
<y>56.516553603970586</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>9</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>57.92282771739404</x>
<y>34.17317501704098</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>10</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>3.8628214275088335</x>
<y>52.90298303308778</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>11</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>318</width>
<z>3</z>
<height>192</height>
<location_x>0</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<viewport>2.3409990660057263 0.0 0.0 2.3409990660057263 27.752487588138713 2.6948007992423</viewport>
</plugin_config>
<width>300</width>
<z>2</z>
<height>300</height>
<location_x>1122</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
</plugin_config>
<width>1422</width>
<z>1</z>
<height>239</height>
<location_x>0</location_x>
<location_y>293</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.TimeLine
<plugin_config>
<mote>0</mote>
<mote>1</mote>
<mote>2</mote>
<mote>3</mote>
<mote>4</mote>
<mote>5</mote>
<mote>6</mote>
<mote>7</mote>
<mote>8</mote>
<mote>9</mote>
<mote>10</mote>
<showRadioRXTX />
<showRadioHW />
<split>125</split>
<zoomfactor>500.0</zoomfactor>
</plugin_config>
<width>1422</width>
<z>0</z>
<height>198</height>
<location_x>0</location_x>
<location_y>531</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "lib/random.h"
#include "sys/ctimer.h"
#include "sys/etimer.h"
#include "net/uip.h"
#include "net/uip-ds6.h"
#include "net/uip-debug.h"
#include "simple-udp.h"
#include "servreg-hack.h"
#include "net/rpl/rpl.h"
#include <stdio.h>
#include <string.h>
#define UDP_PORT 1234
#define SERVICE_ID 190
#define SEND_INTERVAL (10 * CLOCK_SECOND)
#define SEND_TIME (random_rand() % (SEND_INTERVAL))
static struct simple_udp_connection unicast_connection;
/*---------------------------------------------------------------------------*/
PROCESS(unicast_receiver_process, "Unicast receiver example process");
AUTOSTART_PROCESSES(&unicast_receiver_process);
/*---------------------------------------------------------------------------*/
static void
receiver(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
printf("Data received from ");
uip_debug_ipaddr_print(sender_addr);
printf(" on port %d from port %d with length %d: '%s'\n",
receiver_port, sender_port, datalen, data);
}
/*---------------------------------------------------------------------------*/
static uip_ipaddr_t *
set_global_address(void)
{
static uip_ipaddr_t ipaddr;
int i;
uint8_t state;
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
printf("IPv6 addresses: ");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
printf("\n");
}
}
return &ipaddr;
}
/*---------------------------------------------------------------------------*/
static void
create_rpl_dag(uip_ipaddr_t *ipaddr)
{
struct uip_ds6_addr *root_if;
root_if = uip_ds6_addr_lookup(ipaddr);
if(root_if != NULL) {
rpl_dag_t *dag;
uip_ipaddr_t prefix;
rpl_set_root(ipaddr);
dag = rpl_get_dag(RPL_ANY_INSTANCE);
uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
rpl_set_prefix(dag, &prefix, 64);
PRINTF("created a new RPL dag\n");
} else {
PRINTF("failed to create a new RPL DAG\n");
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(unicast_receiver_process, ev, data)
{
uip_ipaddr_t *ipaddr;
PROCESS_BEGIN();
servreg_hack_init();
ipaddr = set_global_address();
create_rpl_dag(ipaddr);
servreg_hack_register(SERVICE_ID, ipaddr);
simple_udp_register(&unicast_connection, UDP_PORT,
NULL, UDP_PORT, receiver);
while(1) {
PROCESS_WAIT_EVENT();
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,137 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki.h"
#include "lib/random.h"
#include "sys/ctimer.h"
#include "sys/etimer.h"
#include "net/uip.h"
#include "net/uip-ds6.h"
#include "net/uip-debug.h"
#include "node-id.h"
#include "simple-udp.h"
#include "servreg-hack.h"
#include <stdio.h>
#include <string.h>
#define UDP_PORT 1234
#define SERVICE_ID 190
#define SEND_INTERVAL (60 * CLOCK_SECOND)
#define SEND_TIME (random_rand() % (SEND_INTERVAL))
static struct simple_udp_connection unicast_connection;
/*---------------------------------------------------------------------------*/
PROCESS(unicast_sender_process, "Unicast sender example process");
AUTOSTART_PROCESSES(&unicast_sender_process);
/*---------------------------------------------------------------------------*/
static void
receiver(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
printf("Data received on port %d from port %d with length %d\n",
receiver_port, sender_port, datalen);
}
/*---------------------------------------------------------------------------*/
static void
set_global_address(void)
{
uip_ipaddr_t ipaddr;
int i;
uint8_t state;
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
printf("IPv6 addresses: ");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
printf("\n");
}
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(unicast_sender_process, ev, data)
{
static struct etimer periodic_timer;
static struct etimer send_timer;
uip_ipaddr_t *addr;
PROCESS_BEGIN();
servreg_hack_init();
set_global_address();
simple_udp_register(&unicast_connection, UDP_PORT,
NULL, UDP_PORT, receiver);
etimer_set(&periodic_timer, SEND_INTERVAL);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
etimer_reset(&periodic_timer);
etimer_set(&send_timer, SEND_TIME);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer));
addr = servreg_hack_lookup(SERVICE_ID);
if(addr != NULL) {
static unsigned int message_number;
char buf[20];
printf("Sending unicast to ");
uip_debug_ipaddr_print(addr);
printf("\n");
sprintf(buf, "Message %d", message_number);
message_number++;
simple_udp_sendto(&unicast_connection, buf, strlen(buf) + 1, addr);
} else {
printf("Service %d not found\n", SERVICE_ID);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -48,25 +48,17 @@
PROCESS(example_servreg_server_process, "Example servreg server");
AUTOSTART_PROCESSES(&example_servreg_server_process);
/*---------------------------------------------------------------------------*/
static void
set_global_address(void)
PROCESS_THREAD(example_servreg_server_process, ev, data)
{
uip_ipaddr_t ipaddr;
PROCESS_BEGIN();
/* Set a global address. */
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(example_servreg_server_process, ev, data)
{
PROCESS_BEGIN();
set_global_address();
servreg_hack_init();
servreg_hack_register(188);
servreg_hack_register(188, &ipaddr);
PROCESS_END();
}

View file

@ -27,3 +27,8 @@ clean:
# rm ../../platform/avr-raven/apps/raven-webserver/httpd-fsdata.c
rm symbols.c symbols.h webserver6.elf $(OUTFILE).elf $(OUTFILE).hex
rm -rf obj_avr-raven
connect:
#Connect to serial debug port for timestamp log (requires PERL).
#Change the baud rate and device to agree with your serial connection.
../../tools/serial-log.pl -b 57600 -t /dev/com1 -l

View file

@ -4,6 +4,8 @@ all: webserver6
APPS=raven-webserver raven-lcd-interface
TARGET=avr-raven
UIP_CONF_IPV6=1
#WITH_RPL=1 //RPL is not yet the default.
#RF230BB=1 //Use radio driver that communicates with the core MAC layer. Now the default.
#COFFEE_FILES=1 //Use coffee file system in EEPROM
#COFFEE_FILES=2 //Use coffee file system in program flash

View file

@ -40,3 +40,15 @@ $make WEBDIR=xxx always forces regeneration of web content into httpd-fsdata.c a
so requires PERL. A bare $make after that will not regenerate httpd-fsdata.c.
Use $make WEBDIR=default to switch back to the default /http-fs/ content.
See Makefile.webserver for optional switches for RPL or a coffee file system.
$make WITH_RPL=1 for a RPL node, or if rpl has become the contiki default,
$make WITH_RPL=0 to override
Much headbanging can result if you do not $make clean when changing make options,
as the normal build dependencies are bypassed and the needed object modules
may not be rebuilt.
$make connect will invoke the /tools/serial-log.pl perl script to connect to
your serial debug port. This will log to the console and optional log file,
adding useful time stamps. Edit the makefile for your serial port configuration.

View file

@ -25,8 +25,12 @@ endif
#copy output to e.g. webserver-nano.sky, raven-webserver.avr-raven
$(WITH_WEBSERVER) : $(CONTIKI_PROJECT)
cp $(CONTIKI_PROJECT).$(TARGET) $(WITH_WEBSERVER).$(TARGET)
@if (test -n "$(ELF_SIZE)");then $(ELF_SIZE) $(WITH_WEBSERVER).$(TARGET);fi
else
APPS=webserver
all : $(CONTIKI_PROJECT)
@if (test -n "$(ELF_SIZE)");then $(ELF_SIZE) $(CONTIKI_PROJECT).$(TARGET);fi
endif
UIP_CONF_IPV6=1

View file

@ -2,7 +2,7 @@ CONTIKI_TARGET_DIRS = . apps net loader
CONTIKI_CORE=contiki-main
CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o
CONTIKI_TARGET_SOURCEFILES += contiki-main.c
CONTIKI_TARGET_SOURCEFILES += contiki-main.c params.c
#Needed for slip
CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c

View file

@ -101,7 +101,11 @@ void rs232_send(uint8_t port, unsigned char c);
void
raven_ping6(void)
{
#define PING_GOOGLE 0
#if UIP_CONF_IPV6_RPL||1
/* No default router, so pick on someone else */
#define PING_GOOGLE 1
seqno++;
#endif
UIP_IP_BUF->vtc = 0x60;
UIP_IP_BUF->tcflow = 1;
@ -291,7 +295,9 @@ raven_gui_loop(process_event_t ev, process_data_t data)
case ICMP6_ECHO_REQUEST:
/* We have received a ping request over the air. Tell the 3290 */
// send_frame(REPORT_PING_BEEP, 0, 0);
#if RF230BB_CONF_LEDONPORTE1
PORTE|=(1<<PE1);ledtimer=1000; //turn on led, set counter for turnoff
#endif
break;
case ICMP6_ECHO_REPLY:
/* We have received a ping reply over the air. Send frame back to 3290 */

View file

@ -1,7 +1,10 @@
#include <avr/eeprom.h>
/* Link layer ipv6 address will become fe80::11:22ff:fe33:4455 */
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t server_name[16] EEMEM = "Contiki-Raven";
uint8_t domain_name[30] EEMEM = "localhost";
/* Link layer ipv6 address will become fe80::ff:fe:1 */
uint8_t default_mac_address[8] PROGMEM = {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01};
uint8_t default_server_name[16] PROGMEM = "ATMEGA128rfa1";
uint8_t default_domain_name[30] PROGMEM = "localhost";
uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01};
uint8_t eemem_server_name[16] EEMEM = "ATMEGA128rfa1";
uint8_t eemem_domain_name[30] EEMEM = "localhost";

View file

@ -2,10 +2,15 @@
#include <avr/eeprom.h>
/* Link layer ipv6 address will become fe80::2 */
uint8_t mac_address[8] EEMEM = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
uint8_t server_name[16] EEMEM = "huginn";
uint8_t domain_name[30] EEMEM = "localhost";
/* Link layer ipv6 address will become fe80::ff:fe:1 */
uint8_t default_mac_address[8] PROGMEM = {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01};
uint8_t default_server_name[16] PROGMEM = "ATMEGA128rfa1";
uint8_t default_domain_name[30] PROGMEM = "localhost";
uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01};
uint8_t eemem_server_name[16] EEMEM = "ATMEGA128rfa1";
uint8_t eemem_domain_name[30] EEMEM = "localhost";
const char data_404_html[140] PROGMEM = {
/* /404.html */

View file

@ -459,6 +459,10 @@ httpd_appcall(void *state)
if (1) {
#else
struct httpd_state *s = (struct httpd_state *)state;
#if RF230BB_CONF_LEDONPORTE1
extern uint16_t ledtimer;
PORTE|=(1<<PE1);ledtimer=1000; //turn on led, set counter for turnoff
#endif
if(uip_closed() || uip_aborted() || uip_timedout()) {
if(s != NULL) {
memb_free(&conns, s);

View file

@ -78,8 +78,16 @@ unsigned long clock_seconds(void);
/* This has not been tested yet */
#define AVR_CONF_USE32KCRYSTAL 0
/* COM port to be used for SLIP connection. Not tested on Raven */
/* Michael Hartman's protobyte board has LED on PORTE1, can be used for pings and radio on indication */
/* However it requires disabling UART0. */
#define RF230BB_CONF_LEDONPORTE1 1
/* COM port to be used for SLIP connection. This is usually UART0, but see above */
#if RF230BB_CONF_LEDONPORTE1
#define SLIP_PORT RS232_PORT_1
#else
#define SLIP_PORT RS232_PORT_0
#endif
/* Pre-allocated memory for loadable modules heap space (in bytes)*/
/* Default is 4096. Currently used only when elfloader is present. Not tested on Raven */
@ -94,8 +102,11 @@ unsigned long clock_seconds(void);
/* More extensive stats */
#define ENERGEST_CONF_ON 1
/* Possible watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */
//#define WATCHDOG_CONF_TIMEOUT -1
/* Debugflow macro, useful for tracing path through mac and radio interrupts */
#define DEBUGFLOWSIZE 128
//#define DEBUGFLOWSIZE 128
/* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */
#if RF230BB
@ -268,6 +279,8 @@ unsigned long clock_seconds(void);
#undef UIP_CONF_UDP_CONNS
#define UIP_CONF_UDP_CONNS 12
/* For slow slip connections, to prevent buffer overruns */
//#define UIP_CONF_RECEIVE_WINDOW 300
#undef UIP_CONF_FWCACHE_SIZE
#define UIP_CONF_FWCACHE_SIZE 30
#define UIP_CONF_BROADCAST 1

View file

@ -29,14 +29,23 @@
* This file is part of the Contiki operating system.
*
*/
#ifndef LED_ON_PORT1E
#define LED_ON_PORTE1 0 //for Michael Hartman's prototype board
#endif
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
#if ANNOUNCE_BOOT
#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTA(...)
#endif
#define DEBUG DEBUG_PRINT
#include "uip-debug.h" ////Does #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) for AVR
#define DEBUG 0
#if DEBUG
#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTD(...)
#endif
/* Track interrupt flow through mac, rdc and radio driver */
#if DEBUGFLOWSIZE
uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
@ -54,20 +63,12 @@ uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#include "loader/symbols-def.h"
#include "loader/symtab.h"
#if RF230BB //radio driver using contiki core mac
#include "params.h"
#include "radio/rf230bb/rf230bb.h"
#include "net/mac/frame802154.h"
#include "net/mac/framer-802154.h"
#include "net/sicslowpan.h"
#else //radio driver using Atmel/Cisco 802.15.4'ish MAC
#include <stdbool.h>
#include "mac.h"
#include "sicslowmac.h"
#include "sicslowpan.h"
#include "ieee-15-4-manager.h"
#endif /*RF230BB*/
#include "contiki.h"
#include "contiki-net.h"
#include "contiki-lib.h"
@ -76,7 +77,6 @@ uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#include "dev/serial-line.h"
#include "dev/slip.h"
/* No 3290p to talk to but the lcd process still needed for uip stack ping callbacks */
#ifdef RAVEN_LCD_INTERFACE
#include "raven-lcd.h"
#endif
@ -100,13 +100,14 @@ uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */
/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */
/* STAMPS will print ENERGEST outputs if that is enabled. */
#define PERIODICPRINTS 1
#if PERIODICPRINTS
//#define PINGS 64
#define ROUTES 128
#define STAMPS 30
#define ROUTES 600
#define STAMPS 60
#define STACKMONITOR 1024
uint16_t clocktime;
uint32_t clocktime;
#define TESTRTIMER 0
#if TESTRTIMER
uint8_t rtimerflag=1;
@ -115,109 +116,86 @@ void rtimercycle(void) {rtimerflag=1;}
#endif
#endif
uint16_t ledtimer;
/*-------------------------------------------------------------------------*/
/*----------------------Configuration of the .elf file---------------------*/
typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t;
#if 1
/* The proper way to set the signature is */
#include <avr/signature.h>
#else
/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */
typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t;
#define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
SIGNATURE = {
/* Older AVR-GCCs may not define the SIGNATURE_n bytes so use explicit ATmega128rfa1 values */
.B2 = SIGNATURE_2,//0x01,//SIGNATURE_2,
.B1 = SIGNATURE_1,//0xA7,//SIGNATURE_1,
.B0 = SIGNATURE_0,//0x1E,//SIGNATURE_0,
.B2 = 0x01,//SIGNATURE_2, //ATMEGA128rfa1
.B1 = 0xA7,//SIGNATURE_1, //128KB flash
.B0 = 0x1E,//SIGNATURE_0, //Atmel
};
//JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK + 65 ms, Brownout disabled
#endif
#if 1
/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */
FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
//JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts
//FUSES ={.low = 0xC2, .high = 0x99, .extended = 0xfe,};
/*----------------------Configuration of EEPROM---------------------------*/
/* Use existing EEPROM if it passes the integrity test, else reinitialize with build values */
/* Put default MAC address in EEPROM */
#if AVR_WEBSERVER
extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t server_name[16];
extern uint8_t domain_name[30];
#else
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
/* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */
FUSES ={.low = 0xC2, .high = 0x99, .extended = 0xfe,};
#endif
#ifdef CHANNEL_802_15_4
uint8_t rf_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
//uint8_t rf_channel[2] EEMEM = {11, ~11}; //econotag test
uint8_t
rng_get_uint8(void) {
#if 1
/* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */
uint8_t j;
j = (PHY_RSSI>>6) | (PHY_RSSI>>4) | (PHY_RSSI>>4) | PHY_RSSI;
#else
uint8_t rf_channel[2] EEMEM = {26, ~26};
#endif
static uint8_t get_channel_from_eeprom() {
uint8_t eeprom_channel;
uint8_t eeprom_check;
eeprom_channel = eeprom_read_byte(&rf_channel[0]);
eeprom_check = eeprom_read_byte(&rf_channel[1]);
if(eeprom_channel==~eeprom_check)
return eeprom_channel;
#ifdef CHANNEL_802_15_4
//return(11);
return(CHANNEL_802_15_4);
#else
return 26;
/* Get a pseudo random number using the ADC */
uint8_t i,j;
ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock
for (i=0;i<4;i++) {
ADMUX = 0; //toggle reference to increase noise
ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference.
ADCSRA|=1<<ADSC; //Start conversion
while (ADCSRA&(1<<ADSC)); //Wait till done
j = (j<<2) + ADC;
}
ADCSRA=0; //Disable ADC
#endif
PRINTD("rng issues %d\n",j);
return j;
}
static bool get_mac_from_eeprom(uint8_t* macptr) {
eeprom_read_block ((void *)macptr, &mac_address, 8);
return true;
}
static uint16_t get_panid_from_eeprom(void) {
// TODO: Writeme!
return IEEE802154_PANID;
//return 0xaaaa; //econotag ack test
}
static uint16_t get_panaddr_from_eeprom(void) {
// TODO: Writeme!
return 0;
// return 0x1111; //econotag ack test
}
void calibrate_rc_osc_32k();
extern uint8_t osccal_calibrated;
/*-------------------------Low level initialization------------------------*/
/*------Done in a subroutine to keep main routine stack usage small--------*/
void initialize(void)
{
#if !LED_ON_PORTE1 //Conflicts with USART0
#if RAVEN_LCD_INTERFACE
/* First rs232 port for Raven 3290 port */
rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
/* Set input handler for 3290 port */
rs232_set_input(0,raven_lcd_serial_input);
watchdog_init();
watchdog_start();
/* The Raven implements a serial command and data interface via uart0 to a 3290p,
* which could be duplicated using another host computer.
*/
#if !RF230BB_CONF_LEDONPORTE1 //Conflicts with USART0
#ifdef RAVEN_LCD_INTERFACE
rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
rs232_set_input(0,raven_lcd_serial_input);
#else
//Slip border router on uart0
/* Generic or slip connection on uart0 */
rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
#endif
#endif
/* Second rs232 port for debugging */
/* Second rs232 port for debugging or slip alternative */
rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
/* Redirect stdout to second port */
rs232_redirect_stdout(RS232_PORT_1);
clock_init();
#if 1
if(MCUSR & (1<<PORF )) PRINTA("Power-on reset.\n");
if(MCUSR & (1<<EXTRF)) PRINTA("External reset!\n");
if(MCUSR & (1<<BORF )) PRINTA("Brownout reset!\n");
if(MCUSR & (1<<WDRF )) PRINTA("Watchdog reset!\n");
if(MCUSR & (1<<JTRF )) PRINTA("JTAG reset!\n");
#endif
watchdog_init();
watchdog_start();
if(MCUSR & (1<<PORF )) PRINTD("Power-on reset.\n");
if(MCUSR & (1<<EXTRF)) PRINTD("External reset!\n");
if(MCUSR & (1<<BORF )) PRINTD("Brownout reset!\n");
if(MCUSR & (1<<WDRF )) PRINTD("Watchdog reset!\n");
if(MCUSR & (1<<JTRF )) PRINTD("JTAG reset!\n");
#if STACKMONITOR
/* Simple stack pointer highwater monitor. Checks for magic numbers in the main
@ -233,85 +211,78 @@ uint16_t p=(uint16_t)&__bss_end;
} while (p<SP-10); //don't overwrite our own stack
}
#endif
#if 0
/* Get a random (or probably different) seed for the 802.15.4 packet sequence number.
* Some layers will ignore duplicates found in a history (e.g. Contikimac)
* causing the initial packets to be ignored after a short-cycle restart.
*/
ADMUX =0x5E; //Select AVDD as reference, measure 1.1 volt bandgap reference.
//ADCSRB|=1<<MUX5;
// ADMUX =0x49; //Select AVDD as reference, measure ADC0 10x differential.
ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock
ADCSRA|=1<<ADSC; //Start conversion
while (ADCSRA&(1<<ADSC)); //Wait till done
PRINTF("ADC=%d\n",ADC);
random_init(ADC);
ADCSRA=0; //Disable ADC
#endif
#define CONF_CALIBRATE_OSCCAL 0
#if CONF_CALIBRATE_OSCCAL
void calibrate_rc_osc_32k();
{
extern uint8_t osccal_calibrated;
uint8_t i;
watchdog_stop();
PRINTA("\nBefore calibration OSCCAL=%x\n",OSCCAL);
PRINTD("\nBefore calibration OSCCAL=%x\n",OSCCAL);
for (i=0;i<10;i++) {
calibrate_rc_osc_32k();
PRINTA("Calibrated=%x\n",osccal_calibrated);
PRINTD("Calibrated=%x\n",osccal_calibrated);
//#include <util/delay_basic.h>
//#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) )
// delay_us(50000);
}
clock_init();
watchdog_start();
}
#endif
#if ANNOUNCE_BOOT
PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
#endif
/* rtimers needed for radio cycling */
rtimer_init();
/* Initialize process subsystem */
process_init();
/* etimers must be started before ctimer_init */
/* etimers must be started before ctimer_init */
process_start(&etimer_process, NULL);
#if RF230BB
ctimer_init();
/* Start radio and radio receive process */
NETSTACK_RADIO.init();
#if 1
{uint8_t somebits;
/* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */
somebits= (PHY_RSSI>>6) | (PHY_RSSI>>4) | (PHY_RSSI>>4) | PHY_RSSI;
PRINTF("rnd=%d\n", somebits);
random_init(somebits);
}
#endif
/* Get a random seed for the 802.15.4 packet sequence number.
* Some layers will ignore duplicates found in a history (e.g. Contikimac)
* causing the initial packets to be ignored after a short-cycle restart.
*/
random_init(rng_get_uint8());
/* Set addresses BEFORE starting tcpip process */
rimeaddr_t addr;
memset(&addr, 0, sizeof(rimeaddr_t));
get_mac_from_eeprom(addr.u8);
if (params_get_eui64(addr.u8)) {
PRINTA("Random EUI64 address generated\n");
}
#if UIP_CONF_IPV6
memcpy(&uip_lladdr.addr, &addr.u8, 8);
memcpy(&uip_lladdr.addr, &addr.u8, sizeof(rimeaddr_t));
#elif WITH_NODE_ID
node_id=get_panaddr_from_eeprom();
addr.u8[1]=node_id&0xff;
addr.u8[0]=(node_id&0xff00)>>8;
PRINTA("Node ID from eeprom: %X\n",node_id);
#endif
rf230_set_pan_addr(
get_panid_from_eeprom(),
get_panaddr_from_eeprom(),
(uint8_t *)&addr.u8
);
rf230_set_channel(get_channel_from_eeprom());
rimeaddr_set_node_addr(&addr);
PRINTF("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]);
rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8);
rf230_set_channel(params_get_channel());
rf230_set_txpower(params_get_txpower());
#if UIP_CONF_IPV6
PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]);
#else
PRINTA("MAC address ");
uint8_t i;
for (i=sizeof(rimeaddr_t); i>0; i--){
PRINTA("%x:",addr.u8[i-1]);
}
PRINTA("\n");
#endif
/* Initialize stack protocols */
queuebuf_init();
@ -320,7 +291,7 @@ uint8_t i;
NETSTACK_NETWORK.init();
#if ANNOUNCE_BOOT
PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
PRINTA("%s %s, channel %u power %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel(),rf230_get_txpower());
if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac
unsigned short tmp;
tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
@ -328,24 +299,18 @@ uint8_t i;
if (tmp<65535) PRINTA(", check rate %u Hz",tmp);
}
PRINTA("\n");
#endif
#if UIP_CONF_IPV6_RPL
PRINTA("RPL Enabled\n");
#endif
#if UIP_CONF_ROUTER
#if ANNOUNCE_BOOT
PRINTA("Routing Enabled\n");
#endif
// rime_init(rime_udp_init(NULL));
// uip_router_register(&rimeroute);
#endif
#endif /* ANNOUNCE_BOOT */
process_start(&tcpip_process, NULL);
#else
/* mac process must be started before tcpip process! */
process_start(&mac_process, NULL);
process_start(&tcpip_process, NULL);
#endif /*RF230BB*/
#ifdef RAVEN_LCD_INTERFACE
process_start(&raven_lcd_process, NULL);
#endif
@ -353,20 +318,17 @@ uint8_t i;
/* Autostart other processes */
autostart_start(autostart_processes);
//Give ourselves a prefix
// init_net();
/*---If using coffee file system create initial web content if necessary---*/
#if COFFEE_FILES
int fa = cfs_open( "/index.html", CFS_READ);
if (fa<0) { //Make some default web content
PRINTF("No index.html file found, creating upload.html!\n");
PRINTA("No index.html file found, creating upload.html!\n");
PRINTA("Formatting FLASH file system for coffee...");
cfs_coffee_format();
PRINTA("Done!\n");
fa = cfs_open( "/index.html", CFS_WRITE);
int r = cfs_write(fa, &"It works!", 9);
if (r<0) PRINTF("Can''t create /index.html!\n");
if (r<0) PRINTA("Can''t create /index.html!\n");
cfs_close(fa);
// fa = cfs_open("upload.html"), CFW_WRITE);
// <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html>
@ -385,9 +347,8 @@ uint8_t i;
/*--------------------------Announce the configuration---------------------*/
#if ANNOUNCE_BOOT
#if AVR_WEBSERVER
uint8_t i;
{ uint8_t i;
char buf[80];
unsigned int size;
@ -397,11 +358,15 @@ uint8_t i;
PRINTA("IPv6 Address: %s\n",buf);
}
}
eeprom_read_block (buf,server_name, sizeof(server_name));
buf[sizeof(server_name)]=0;
cli();
eeprom_read_block (buf,eemem_server_name, sizeof(eemem_server_name));
sei();
buf[sizeof(eemem_server_name)]=0;
PRINTA("%s",buf);
eeprom_read_block (buf,domain_name, sizeof(domain_name));
buf[sizeof(domain_name)]=0;
cli();
eeprom_read_block (buf,eemem_domain_name, sizeof(eemem_domain_name));
sei();
buf[sizeof(eemem_domain_name)]=0;
size=httpd_fs_get_size();
#ifndef COFFEE_FILES
PRINTA(".%s online with fixed %u byte web content\n",buf,size);
@ -414,25 +379,40 @@ uint8_t i;
#elif COFFEE_FILES==4
PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
#endif /* COFFEE_FILES */
}
#else
PRINTA("Online\n");
#endif /* AVR_WEBSERVER */
#endif /* ANNOUNCE_BOOT */
}
/*---------------------------------------------------------------------------*/
void log_message(char *m1, char *m2)
{
PRINTA("%s%s\n", m1, m2);
}
#if RF230BB
extern char rf230_interrupt_flag, rf230processflag;
#endif
#endif /* ANNOUNCE_BOOT */
uint16_t ledtimer;
#if RF230BB_CONF_LEDONPORTE1
/* NB: PORTE1 conflicts with UART0 */
DDRE|=(1<<DDE1); //set led pin to output (Micheal Hatrtman board)
PORTE&=~(1<<PE1); //and low to turn led off
#endif
}
#if ROUTES && UIP_CONF_IPV6
static void
ipaddr_add(const uip_ipaddr_t *addr)
{
uint16_t a;
int8_t i, f;
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) PRINTF("::");
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTF(":");
}
PRINTF("%x",a);
}
}
}
#endif
/*-------------------------------------------------------------------------*/
/*------------------------- Main Scheduler loop----------------------------*/
@ -440,37 +420,25 @@ uint16_t ledtimer;
int
main(void)
{
initialize();
#if LED_ON_PORTE1
/* NB: PORTE1 conflicts with UART0 */
DDRE|=(1<<DDE1); //set led pin to output (Micheal Hatrtman board)
PORTE&=~(1<<PE1); //and low to turn led off
#endif
while(1) {
process_run();
process_run();
watchdog_periodic();
#if DEBUGFLOWSIZE
if (debugflowsize) {
debugflow[debugflowsize]=0;
PRINTA("%s",debugflow);
debugflowsize=0;
}
#endif
#if LED_ON_PORTE1
/* Turn off LED after a while */
if (ledtimer) {
if (--ledtimer==0) {
#if RF230BB_CONF_LEDONPORTE1
PORTE&=~(1<<PE1);
/* Currently LED was turned on by received ping; ping the other way for testing */
extern void raven_ping6(void);
// raven_ping6(); //ping back
#endif
#if defined(RAVEN_LCD_INTERFACE)&&0
/* ledtimer can be set by received ping; ping the other way for testing */
extern void raven_ping6(void);
raven_ping6();
#endif
}
}
#endif
#if 0
/* Various entry points for debugging in the AVR Studio simulator.
@ -484,18 +452,26 @@ main(void)
NETSTACK_RDC.input();
#endif
watchdog_periodic();
#if 0
/* Clock.c can trigger a periodic PLL calibration in the RF230BB driver.
* This can show when that happens.
*/
extern uint8_t rf230_calibrated;
if (rf230_calibrated) {
PRINTA("\nRF230 calibrated!\n");
PRINTD("\nRF230 calibrated!\n");
rf230_calibrated=0;
}
#endif
/* Set DEBUGFLOWSIZE in contiki-conf.h to track path through MAC, RDC, and RADIO */
#if DEBUGFLOWSIZE
if (debugflowsize) {
debugflow[debugflowsize]=0;
PRINTF("%s",debugflow);
debugflowsize=0;
}
#endif
#if PERIODICPRINTS
#if TESTRTIMER
/* Timeout can be increased up to 8 seconds maximum.
@ -517,9 +493,9 @@ if ((clocktime%STAMPS)==0) {
print_stats();
#elif RADIOSTATS
extern volatile unsigned long radioontime;
PRINTA("%u(%u)s",clocktime,radioontime);
PRINTF("%u(%u)s\n",clocktime,radioontime);
#else
PRINTA("%us ",clocktime);
PRINTF("%us\n",clocktime);
#endif
}
@ -531,7 +507,7 @@ extern volatile unsigned long radioontime;
#if PINGS && UIP_CONF_IPV6
extern void raven_ping6(void);
if ((clocktime%PINGS)==1) {
PRINTA("**Ping\n");
PRINTF("**Ping\n");
raven_ping6();
}
#endif
@ -544,38 +520,38 @@ extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j;
PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
PRINTA("\n");
ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n");
}
}
PRINTA("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
PRINTF("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
PRINTA("\n");
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
PRINTF("\n");
j=0;
}
}
if (j) PRINTA(" <none>");
PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
if (j) PRINTF(" <none>");
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
PRINTA("/%u (via ", uip_ds6_routing_table[i].length);
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
PRINTF("/%u (via ", uip_ds6_routing_table[i].length);
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
// } else {
// PRINTA(")\n");
// PRINTF(")\n");
// }
j=0;
}
}
if (j) PRINTA(" <none>");
PRINTA("\n---------\n");
if (j) PRINTF(" <none>");
PRINTF("\n---------\n");
}
#endif
@ -585,7 +561,7 @@ if ((clocktime%STACKMONITOR)==3) {
uint16_t p=(uint16_t)&__bss_end;
do {
if (*(uint16_t *)p != 0x4242) {
PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
break;
}
p+=10;
@ -597,20 +573,29 @@ if ((clocktime%STACKMONITOR)==3) {
#endif /* PERIODICPRINTS */
#if RF230BB&&0
extern uint8_t rf230processflag;
if (rf230processflag) {
PRINTA("rf230p%d",rf230processflag);
PRINTF("rf230p%d",rf230processflag);
rf230processflag=0;
}
#endif
#if RF230BB&&0
extern uint8_t rf230_interrupt_flag;
if (rf230_interrupt_flag) {
// if (rf230_interrupt_flag!=11) {
PRINTA("**RI%u",rf230_interrupt_flag);
PRINTF("**RI%u",rf230_interrupt_flag);
// }
rf230_interrupt_flag=0;
}
#endif
}
return 0;
}
}
/*---------------------------------------------------------------------------*/
void log_message(char *m1, char *m2)
{
PRINTF("%s%s\n", m1, m2);
}

View file

@ -0,0 +1,264 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#define DEBUG 1
#if DEBUG
#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTD(...)
#endif
#include "contiki.h"
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdio.h>
#include <string.h>
#if AVR_WEBSERVER
//#include "httpd-fs.h"
//#include "httpd-cgi.h"
#endif
#include "contiki-net.h"
#include "params.h"
#if WITH_NODE_ID
uint16_t node_id;
#endif
#if CONTIKI_CONF_RANDOM_MAC
extern uint8_t rng_get_uint8(void);
static void
generate_new_eui64(uint8_t eui64[8]) {
eui64[0] = 0x02;
eui64[1] = rng_get_uint8();
eui64[2] = rng_get_uint8();
eui64[3] = 0xFF;
eui64[4] = 0xFE;
eui64[5] = rng_get_uint8();
eui64[6] = rng_get_uint8();
eui64[7] = rng_get_uint8();
}
#endif
#if AVR_WEBSERVER
/* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */
extern uint8_t default_mac_address[8];
extern uint8_t default_server_name[16];
extern uint8_t default_domain_name[30];
#else
uint8_t default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR;
uint8_t default_server_name[] PROGMEM = PARAMS_SERVERNAME;
uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME;
#endif
#if PARAMETER_STORAGE==0
/* 0 Hard coded, minmal program and eeprom usage. */
uint8_t
params_get_eui64(uint8_t *eui64) {
#if CONTIKI_CONF_RANDOM_MAC
PRINTD("Generating random EUI64 MAC\n");
generate_new_eui64(eui64);
return 1;
#else
uint8_t i;
for (i=0;i<sizeof(default_mac_address);i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);
return 0;
#endif
}
#elif PARAMETER_STORAGE==1
/* 1 Stored in fixed eeprom locations, rewritten from flash if corrupt.
* They can be manually changed and kept over program reflash.
* The channel and bit complement are used to check EEMEM integrity,
* If corrupt all values will be rewritten with the default flash values.
* To make this work, get the channel before anything else.
*/
#if !AVR_WEBSERVER
uint8_t eemem_mac_address[] EEMEM = PARAMS_EUI64ADDR;
uint8_t eemem_server_name[] EEMEM = PARAMS_SERVERNAME;
uint8_t eemem_domain_name[] EEMEM = PARAMS_DOMAINNAME;
#endif /*AVR_WEBSERVER */
uint16_t eemem_nodeid EEMEM = PARAMS_NODEID;
uint8_t eemem_channel[2] EEMEM = {PARAMS_CHANNEL, ~PARAMS_CHANNEL};
uint16_t eemem_panid EEMEM = PARAMS_PANID;
uint16_t eemem_panaddr EEMEM = PARAMS_PANADDR;
uint8_t eemem_txpower EEMEM = PARAMS_TXPOWER;
#if CONTIKI_CONF_RANDOM_MAC
static uint8_t randomeui64;
#endif
uint8_t
params_get_channel(void) {
uint8_t x[2];
*(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
/* Don't return an invalid channel number */
if( (x[0]<11) || (x[0] > 26)) x[1]=x[0];
/* Do exclusive or test on the two values read */
if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit
/* Verification fails, rewrite everything */
uint8_t i,buffer[32];
PRINTD("EEPROM is corrupt, rewriting with defaults.\n");
#if CONTIKI_CONF_RANDOM_MAC
PRINTD("Generating random EUI64 MAC\n");
generate_new_eui64(&buffer);
randomeui64=1;
#else
for (i=0;i<sizeof(default_mac_address);i++) buffer[i] = pgm_read_byte_near(default_mac_address+i);
#endif
/* eeprom_write_block should not be interrupted */
cli();
eeprom_write_block(&buffer, &eemem_mac_address, sizeof(eemem_mac_address));
for (i=0;i<sizeof(default_server_name);i++) buffer[i] = pgm_read_byte_near(default_server_name+i);
eeprom_write_block(&buffer, &eemem_server_name, sizeof(eemem_server_name));
for (i=0;i<sizeof(default_domain_name);i++) buffer[i] = pgm_read_byte_near(default_domain_name+i);
eeprom_write_block(&buffer, &eemem_domain_name, sizeof(eemem_domain_name));
eeprom_write_word(&eemem_panid , PARAMS_PANID);
eeprom_write_word(&eemem_panaddr, PARAMS_PANADDR);
eeprom_write_byte(&eemem_txpower, PARAMS_TXPOWER);
eeprom_write_word(&eemem_nodeid, PARAMS_NODEID);
x[0] = PARAMS_CHANNEL;
x[1]= ~x[0];
eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
sei();
}
/* Always returns a valid channel */
return x[0];
}
uint8_t
params_get_eui64(uint8_t *eui64) {
cli();
eeprom_read_block ((void *)eui64, &eemem_mac_address, sizeof(rimeaddr_t));
sei();
#if CONTIKI_CONF_RANDOM_MAC
return randomeui64;
#else
return 0;
#endif
}
uint16_t
params_get_panid(void) {
return eeprom_read_word(&eemem_panid);
}
uint16_t
params_get_panaddr(void) {
return eeprom_read_word (&eemem_panaddr);
}
uint8_t
params_get_txpower(void)
{
return eeprom_read_byte(&eemem_txpower);
}
#else /* CONTIKI_CONF_SETTINGS_MANAGER */
uint8_t
params_get_channel() {
uint8_t x;
size_t size = 1;
if (settings_get(SETTINGS_KEY_CHANNEL, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get RF channel %u\n",x);
} else {
x = PARAMS_CHANNEL;
if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM RF channel to %d\n",x);
}
}
return x;
}
uint8_t
params_get_eui64(uint8_t *eui64) {
size_t size = sizeof(rimeaddr_t);
if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)eui64, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get EUI64 MAC\n");
return 0;
}
#if CONTIKI_CONF_RANDOM_MAC
PRINTD("Generating random EUI64 MAC\n");
generate_new_eui64(eui64);
#else
{uint8_t i;for (i=0;i<8;i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);} //test this
#endif
if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)eui64,8) == SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM MAC address\n");
}
#if CONTIKI_CONF_RANDOM_MAC
return 1;
#else
return 0;
#endif
}
uint16_t
params_get_panid(void) {
uint16_t x;
size_t size = 2;
if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get PAN ID of %04x\n",x);
} else {
x=PARAMS_PANID;
if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM PAN ID to %04x\n",x);
}
}
return x;
}
uint16_t
params_get_panaddr(void) {
uint16_t x;
size_t size = 2;
if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get PAN address of %04x\n",x);
} else {
x=PARAMS_PANADDR;
if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM PAN address to %04x\n",x);
}
}
return x;
}
uint8_t
params_get_txpower(void) {
uint8_t x;
size_t size = 1;
if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get tx power of %d (0=max)\n",x);
} else {
x=PARAMS_TXPOWER;
if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM tx power of %d (0=max)\n",x);
}
}
return x;
}
#endif /* CONTIKI_CONF_SETTINGS_MANAGER */

View file

@ -0,0 +1,108 @@
#ifndef __PARAMS_H__
#define __PARAMS_H__
/* PARAMETER_STORAGE =
* 0 Hard coded, minmal program and eeprom usage.
* 1 Stored in fixed eeprom locations, rewritten from flash if corrupt.
* This allows parameter changes using a hardware programmer or custom application code.
* Corruption test is based on channel verify so get the channel before anything else!
* 2 Obtained from eeprom using the general settings manager and read from program flash if not present.
* Useful for for testing builds without wearing out flash memory.
* 3 Obtained from eeprom using the settings manager and rewritten from flash if not present.
* This ensures all parameters are present in upper eeprom flash.
*
* Note the parameters in this file can be changed without forcing a complete rebuild.
*/
#define CONTIKI_CONF_RANDOM_MAC 0 //adds 78 bytes
#define CONTIKI_CONF_SETTINGS_MANAGER 0 //adds 1696 bytes
#if CONTIKI_CONF_SETTINGS_MANAGER
//#define PARAMETER_STORAGE 2
#define PARAMETER_STORAGE 2
#else
#define PARAMETER_STORAGE 1
#endif
/* Include settings.h, then dummy out the write routines */
#include "settings.h"
#if PARAMETER_STORAGE==2
#define settings_add(...) 0
#define settings_add_uint8(...) 0
#define settings_add_uint16(...) 0
#endif
#if AVR_WEBSERVER
/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */
extern uint8_t eemem_mac_address[8];
extern uint8_t eemem_server_name[16];
extern uint8_t eemem_domain_name[30];
#endif
#ifdef SERVER_NAME
#define PARAMS_SERVERNAME SERVER_NAME
#else
#define PARAMS_SERVERNAME "ATMEGA128rfa1"
#endif
#ifdef DOMAIN_NAME
#define PARAMS_DOMAINNAME DOMAIN_NAME
#else
#define PARAMS_DOMAINNAME "localhost"
#endif
#ifdef NODE_ID
#define PARAMS_NODEID NODE_ID
#else
#define PARAMS_NODEID 0
#endif
#ifdef CHANNEL_802_15_4
#define PARAMS_CHANNEL CHANNEL_802_15_4
#else
#define PARAMS_CHANNEL 26
#endif
#ifdef IEEE802154_PANID
#define PARAMS_PANID IEEE802154_PANID
#else
#define PARAMS_PANID 0xABCD
#endif
#ifdef IEEE802154_PANADDR
#define PARAMS_PANADDR IEEE802154_PANADDR
#else
#define PARAMS_PANADDR 0
#endif
#ifdef RF230_MAX_TX_POWER
#define PARAMS_TXPOWER RF230_MAX_TX_POWER
#else
#define PARAMS_TXPOWER 0
#endif
#ifdef EUI64_ADDRESS
#define PARAMS_EUI64ADDR EUI64_ADDRESS
#else
/* This form of of EUI64 mac allows full 6LoWPAN header compression from mac address */
#if UIP_CONF_LL_802154
//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN}
#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01}
#else
//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xff, 0xfe, 0xNN, 0xNN, 0xNN}
#define PARAMS_EUI64ADDR {0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01}
#endif
/* This form of of EUI64 mac allows 16 bit 6LoWPAN header compression on multihops */
//#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xNN, 0xNN}
#endif
uint8_t params_get_eui64(uint8_t *eui64);
#if PARAMETER_STORAGE==0
/* Hard coded program flash parameters */
#define params_get_servername(...)
#define params_get_nodeid(...) PARAMS_NODEID
#define params_get_channel(...) PARAMS_CHANNEL
#define params_get_panid(...) PARAMS_PANID
#define params_get_panaddr(...) PARAMS_PANADDR
#define params_get_txpower(...) PARAMS_TXPOWER
#else
/* Parameters stored in eeprom */
uint16_t params_get_nodeid(void);
uint8_t params_get_channel(void);
uint16_t params_get_panid(void);
uint16_t params_get_panaddr(void);
uint8_t params_get_txpower(void);
#endif
#endif /* __PARAMS_H__ */

View file

@ -76,7 +76,7 @@ static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL,
void
slip_arch_init(unsigned long ubr)
{
rs232_set_input(RS232_PORT_0, slip_input_byte);
rs232_set_input(SLIP_PORT, slip_input_byte);
stdout = &slip_stdout;
}
/*---------------------------------------------------------------------------*/

View file

@ -452,12 +452,12 @@ raven_lcd_show_text(char *text) {
static void
lcd_show_servername(void) {
//extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t server_name[16];
//extern uint8_t domain_name[30];
char buf[sizeof(server_name)+1];
eeprom_read_block (buf,server_name, sizeof(server_name));
buf[sizeof(server_name)]=0;
//extern uint8_t eemem_mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t eemem_server_name[16];
//extern uint8_t eemem_domain_name[30];
char buf[sizeof(eemem_server_name)+1];
eeprom_read_block (buf,eemem_server_name, sizeof(eemem_server_name));
buf[sizeof(eemem_server_name)]=0;
raven_lcd_show_text(buf); //must fit in all the buffers or it will be truncated!
}
#endif

View file

@ -1,7 +1,10 @@
#include <avr/eeprom.h>
/* Link layer ipv6 address will become fe80::11:22ff:fe33:4455 */
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t server_name[16] EEMEM = "Contiki-Raven";
uint8_t domain_name[30] EEMEM = "localhost";
uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t default_server_name[16] PROGMEM = "Contiki-Raven";
uint8_t default_domain_name[30] PROGMEM = "localhost";
uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
uint8_t eemem_server_name[16] EEMEM = "Contiki-Raven";
uint8_t eemem_domain_name[30] EEMEM = "localhost";

View file

@ -99,11 +99,22 @@ unsigned long clock_seconds(void);
//#define RADIO_CONF_CALIBRATE_INTERVAL 256
/* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */
#define RADIOSTATS 1
#define RADIOSTATS 1
/* More extensive stats */
#define ENERGEST_CONF_ON 0
/* Use settings manager to save configuration in EEPROM */
/* Adds ~1700 bytes to progmem */
#define CONTIKI_CONF_SETTINGS_MANAGER 1
/* Possible watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */
/* AVR Studio simulator tends to reboot due to clocking the WD 8 times too fast */
//#define WATCHDOG_CONF_TIMEOUT -1
/* Debugflow macro, useful for tracing path through mac and radio interrupts */
//#define DEBUGFLOWSIZE 128
/* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */
#if RF230BB
#undef PACKETBUF_CONF_HDR_SIZE //Use the packetbuf default for header size

View file

@ -30,14 +30,28 @@
*
* @(#)$$
*/
#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size
#if ANNOUNCE_BOOT
#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTA(...)
#endif
#define DEBUG 0
#if DEBUG
#define PRINTFD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTFD(...)
#define PRINTD(...)
#endif
/* Track interrupt flow through mac, rdc and radio driver */
#if DEBUGFLOWSIZE
uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
#else
#define DEBUGFLOW(c)
#endif
#include <avr/pgmspace.h>
@ -93,85 +107,334 @@
#include "net/rime.h"
/* Test rtimers, also for pings, stack monitor, neighbor/route printout and time stamps */
#define TESTRTIMER 0
#if TESTRTIMER
/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */
/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */
/* STAMPS will print ENERGEST outputs if that is enabled. */
#define PERIODICPRINTS 1
#if PERIODICPRINTS
//#define PINGS 64
#define ROUTES 300
#define ROUTES 600
#define STAMPS 60
#define STACKMONITOR 600
uint32_t clocktime;
#define TESTRTIMER 0
#if TESTRTIMER
uint8_t rtimerflag=1;
uint16_t rtime;
struct rtimer rt;
void rtimercycle(void) {rtimerflag=1;}
static void ipaddr_add(const uip_ipaddr_t *addr);
#endif
#endif
#endif /* TESTRTIMER */
#if WITH_NODE_ID
uint16_t node_id;
#endif
/*-------------------------------------------------------------------------*/
/*----------------------Configuration of the .elf file---------------------*/
typedef struct {unsigned char B2;unsigned char B1;unsigned char B0;} __signature_t;
#if 1
/* The proper way to set the signature is */
#include <avr/signature.h>
#else
/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */
typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t;
#define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
SIGNATURE = {
/* Older AVR-GCCs may not define the SIGNATURE_n bytes so use explicit 1284p values */
.B2 = 0x05,//SIGNATURE_2,
.B1 = 0x97,//SIGNATURE_1,
.B0 = 0x1E,//SIGNATURE_0,
.B2 = 0x05,//SIGNATURE_2, //ATMEGA1284p
.B1 = 0x97,//SIGNATURE_1, //128KB flash
.B0 = 0x1E,//SIGNATURE_0, //Atmel
};
#endif
/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */
FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
/*----------------------Configuration of EEPROM---------------------------*/
/* Use existing EEPROM if it passes the integrity test, else reinitialize with build values */
/* Put default MAC address in EEPROM */
/* Put the default settings into program flash memory */
/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */
#if AVR_WEBSERVER
extern uint8_t mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t server_name[16];
extern uint8_t domain_name[30];
extern uint8_t default_mac_address[8];
extern uint8_t default_server_name[16];
extern uint8_t default_domain_name[30];
#else
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
#ifdef MAC_ADDRESS
uint8_t default_mac_address[8] PROGMEM = MAC_ADDRESS;
#else
uint8_t default_mac_address[8] PROGMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
#endif
#ifdef SERVER_NAME
uint8_t default_server_name[16] PROGMEM = SERVER_NAME;
#else
uint8_t default_server_name[16] PROGMEM = "Raven_webserver";
#endif
#ifdef DOMAIN_NAME
uint8_t default_domain_name[30] PROGMEM = DOMAIN_NAME
#else
uint8_t default_domain_name[30] PROGMEM = "localhost";
#endif
#endif /* AVR_WEBSERVER */
#ifdef NODE_ID
uint16_t default_nodeid PROGMEM = NODEID;
#else
uint16_t default_nodeid PROGMEM = 0;
#endif
#ifdef CHANNEL_802_15_4
uint8_t rf_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
#else
uint8_t rf_channel[2] EEMEM = {22, ~22};
uint8_t default_channel PROGMEM = 26;
#endif
#ifdef IEEE802154_PANID
uint16_t default_panid PROGMEM = IEEE802154_PANID;
#else
uint16_t default_panid PROGMEM = 0xABCD;
#endif
#ifdef IEEE802154_PANADDR
uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
#else
uint16_t default_panaddr PROGMEM = 0;
#endif
#ifdef RF230_MAX_TX_POWER
uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
#else
uint8_t default_txpower PROGMEM = 0;
#endif
volatile uint8_t eeprom_channel;
static uint8_t get_channel_from_eeprom() {
// volatile uint8_t eeprom_channel;
uint8_t eeprom_check;
eeprom_channel = eeprom_read_byte(&rf_channel[0]);
eeprom_check = eeprom_read_byte(&rf_channel[1]);
if(eeprom_channel==~eeprom_check)
return eeprom_channel;
/* Get a pseudo random number using the ADC */
static uint8_t
rng_get_uint8(void) {
uint8_t i,j;
ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock
for (i=0;i<4;i++) {
ADMUX = 0; //toggle reference to increase noise
ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference.
ADCSRA|=1<<ADSC; //Start conversion
while (ADCSRA&(1<<ADSC)); //Wait till done
j = (j<<2) + ADC;
}
ADCSRA=0; //Disable ADC
PRINTD("rng issues %d\n",j);
return j;
}
#if CONTIKI_CONF_RANDOM_MAC
static void
generate_new_eui64(uint8_t eui64[8]) {
eui64[0] = 0x02;
eui64[1] = rng_get_uint8();
eui64[2] = rng_get_uint8();
eui64[3] = 0xFF;
eui64[4] = 0xFE;
eui64[5] = rng_get_uint8();
eui64[6] = rng_get_uint8();
eui64[7] = rng_get_uint8();
}
#endif
#if !CONTIKI_CONF_SETTINGS_MANAGER
/****************************No settings manager*****************************/
/* If not using the settings manager, put the default values into EEMEM
* These can be manually changed and kept over program reflash.
* The channel and bit complement are used to check EEMEM integrity,
* If corrupt all values will be rewritten with the default flash values.
* To make this work, get the channel before anything else.
*/
#if AVR_WEBSERVER
extern uint8_t eemem_mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t eemem_server_name[16];
extern uint8_t eemem_domain_name[30];
#else
#ifdef MAC_ADDRESS
uint8_t eemem_mac_address[8] EEMEM = MAC_ADDRESS;
#else
uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
#endif
#ifdef SERVER_NAME
uint8_t eemem_server_name[16] EEMEM = SERVER_NAME;
#else
uint8_t eemem_server_name[16] EEMEM = "Raven_webserver";
#endif
#ifdef DOMAIN_NAME
uint8_t eemem_domain_name[30] EEMEM = DOMAIN_NAME
#else
uint8_t eemem_domain_name[30] EEMEM = "localhost";
#endif
#endif /*AVR_WEBSERVER */
#ifdef NODE_ID
uint16_t eemem_nodeid EEMEM = NODEID;
#else
uint16_t eemem_nodeid EEMEM = 0;
#endif
#ifdef CHANNEL_802_15_4
return(CHANNEL_802_15_4);
uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
#else
return 26;
uint8_t eemem_channel[2] EMEM = {26, ~26};
#endif
#ifdef IEEE802154_PANID
uint16_t eemem_panid EEMEM = IEEE802154_PANID;
#else
uint16_t eemem_panid EEMEM = 0xABCD;
#endif
#ifdef IEEE802154_PANADDR
uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
#else
uint16_t eemem_panaddr EEMEM = 0;
#endif
#ifdef RF230_MAX_TX_POWER
uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
#else
uint8_t eemem_txpower EEMEM = 0;
#endif
static uint8_t
get_channel_from_eeprom() {
uint8_t x[2];
*(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
/* Don't return an invalid channel number */
if( (x[0]<11) || (x[0] > 26)) x[1]=x[0];
/* Do exclusive or test on the two values read */
if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit
/* Verification fails, rewrite everything */
uint8_t i,buffer[32];
PRINTD("EEPROM is corrupt, rewriting with defaults.\n");
#if CONTIKI_CONF_RANDOM_MAC
PRINTA("Generating random MAC address.\n");
generate_new_eui64(&buffer);
#else
for (i=0;i<sizeof(default_mac_address);i++) buffer[i] = pgm_read_byte_near(default_mac_address+i);
#endif
cli();
eeprom_write_block(&buffer, &eemem_mac_address, sizeof(eemem_mac_address));
for (i=0;i<sizeof(default_server_name);i++) buffer[i] = pgm_read_byte_near(default_server_name+i);
eeprom_write_block(&buffer, &eemem_server_name, sizeof(eemem_server_name));
for (i=0;i<sizeof(default_domain_name);i++) buffer[i] = pgm_read_byte_near(default_domain_name+i);
eeprom_write_block(&buffer, &eemem_domain_name, sizeof(eemem_domain_name));
eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
eeprom_write_word(&eemem_nodeid, pgm_read_word_near(&default_nodeid));
x[0] = pgm_read_byte_near(&default_channel);
x[1]= ~x[0];
eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
sei();
}
/* Always returns a valid channel */
return x[0];
}
static bool
get_eui64_from_eeprom(uint8_t macptr[sizeof(rimeaddr_t)]) {
cli();
eeprom_read_block ((void *)macptr, &eemem_mac_address, sizeof(rimeaddr_t));
sei();
return macptr[0]!=0xFF;
}
static uint16_t
get_panid_from_eeprom(void) {
return eeprom_read_word(&eemem_panid);
}
static uint16_t
get_panaddr_from_eeprom(void) {
return eeprom_read_word (&eemem_panaddr);
}
static uint8_t
get_txpower_from_eeprom(void)
{
return eeprom_read_byte(&eemem_txpower);
}
static bool get_mac_from_eeprom(uint8_t* macptr) {
eeprom_read_block ((void *)macptr, &mac_address, 8);
return true;
}
#else /* !CONTIKI_CONF_SETTINGS_MANAGER */
/******************************Settings manager******************************/
#include "settings.h"
/* Disable the settings add routines to reduce eeprom wear during testing */
#if 0
#define settings_add(...) 0
#define settings_add_uint8(...) 0
#define settings_add_uint16(...) 0
#endif
static uint16_t get_panid_from_eeprom(void) {
// TODO: Writeme!
return IEEE802154_PANID;
}
#if AVR_WEBSERVER
extern uint8_t eemem_mac_address[8]; //These are defined in httpd-fsdata.c via makefsdata.h
extern uint8_t eemem_server_name[16];
extern uint8_t eemem_domain_name[30];
#endif
static uint16_t get_panaddr_from_eeprom(void) {
// TODO: Writeme!
return 0;
static uint8_t
get_channel_from_eeprom() {
uint8_t x;
size_t size = 1;
if (settings_get(SETTINGS_KEY_CHANNEL, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
if ((x<11) || (x>26)) {
PRINTF("Unusual RF channel %u in EEPROM\n",x);
}
PRINTD("<=Get RF channel %u.\n",x);
} else {
x = pgm_read_byte_near(&default_channel);
if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM RF channel to %d.\n",x);
}
}
return x;
}
void calibrate_rc_osc_32k();
static bool
get_eui64_from_eeprom(uint8_t macptr[8]) {
size_t size = sizeof(rimeaddr_t);
if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)macptr, &size) == SETTINGS_STATUS_OK) {
PRINTD("<=Get MAC address.\n");
return true;
}
#if CONTIKI_CONF_RANDOM_MAC
PRINTD("--Generating random MAC address.\n");
generate_new_eui64(macptr);
#else
{uint8_t i;for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
#endif
if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)macptr,8)) {
PRINTD("->Set EEPROM MAC address.\n");
}
return true;
}
static uint16_t
get_panid_from_eeprom(void) {
uint16_t x;
size_t size = 2;
if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get PAN ID of %04x.\n",x);
} else {
x=pgm_read_word_near(&default_panid);
if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM PAN ID to %04x.\n",x);
}
}
return x;
}
static uint16_t
get_panaddr_from_eeprom(void) {
uint16_t x;
size_t size = 2;
if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get PAN address of %04x.\n",x);
} else {
x=pgm_read_word_near(&default_panaddr);
if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM PAN address to %04x.\n",x);
}
}
return x;
}
static uint8_t
get_txpower_from_eeprom(void) {
uint8_t x;
size_t size = 1;
if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
PRINTD("<-Get tx power of %d. (0=max)\n",x);
} else {
x=pgm_read_byte_near(&default_txpower);
if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
PRINTD("->Set EEPROM tx power of %d. (0=max)\n",x);
}
}
return x;
}
#endif /* CONTIKI_CONF_SETTINGS_MANAGER */
/*-------------------------Low level initialization------------------------*/
/*------Done in a subroutine to keep main routine stack usage small--------*/
@ -195,7 +458,7 @@ void initialize(void)
#if STACKMONITOR
/* Simple stack pointer highwater monitor. Checks for magic numbers in the main
* loop. In conjuction with TESTRTIMER, never-used stack will be printed
* loop. In conjuction with PERIODICPRINTS, never-used stack will be printed
* every STACKMONITOR seconds.
*/
{
@ -212,23 +475,18 @@ uint16_t p=(uint16_t)&__bss_end;
* Some layers will ignore duplicates found in a history (e.g. Contikimac)
* causing the initial packets to be ignored after a short-cycle restart.
*/
ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference.
ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock
ADCSRA|=1<<ADSC; //Start conversion
while (ADCSRA&(1<<ADSC)); //Wait till done
PRINTFD("ADC=%d\n",ADC);
random_init(ADC);
ADCSRA=0; //Disable ADC
random_init(rng_get_uint8());
#define CONF_CALIBRATE_OSCCAL 0
#if CONF_CALIBRATE_OSCCAL
void calibrate_rc_osc_32k();
{
extern uint8_t osccal_calibrated;
uint8_t i;
PRINTF("\nBefore calibration OSCCAL=%x\n",OSCCAL);
PRINTD("\nBefore calibration OSCCAL=%x\n",OSCCAL);
for (i=0;i<10;i++) {
calibrate_rc_osc_32k();
PRINTF("Calibrated=%x\n",osccal_calibrated);
PRINTD("Calibrated=%x\n",osccal_calibrated);
//#include <util/delay_basic.h>
//#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) )
// delay_us(50000);
@ -237,16 +495,15 @@ uint8_t i;
}
#endif
#if ANNOUNCE_BOOT
PRINTF("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
#endif
PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
/* rtimers needed for radio cycling */
rtimer_init();
/* Initialize process subsystem */
process_init();
/* etimers must be started before ctimer_init */
/* etimers must be started before ctimer_init */
process_start(&etimer_process, NULL);
#if RF230BB
@ -258,22 +515,37 @@ uint8_t i;
/* Set addresses BEFORE starting tcpip process */
rimeaddr_t addr;
memset(&addr, 0, sizeof(rimeaddr_t));
get_mac_from_eeprom(addr.u8);
// memset(&addr, 0, sizeof(rimeaddr_t));
get_eui64_from_eeprom(addr.u8);
#if UIP_CONF_IPV6
memcpy(&uip_lladdr.addr, &addr.u8, 8);
memcpy(&uip_lladdr.addr, &addr.u8, sizeof(rimeaddr_t));
#elif WITH_NODE_ID
node_id=get_panaddr_from_eeprom();
addr.u8[1]=node_id&0xff;
addr.u8[0]=(node_id&0xff00)>>8;
PRINTA("Node ID from eeprom: %X\n",node_id);
#endif
rimeaddr_set_node_addr(&addr);
rf230_set_pan_addr(
get_panid_from_eeprom(),
get_panaddr_from_eeprom(),
(uint8_t *)&addr.u8
);
rf230_set_channel(get_channel_from_eeprom());
rf230_set_txpower(get_txpower_from_eeprom());
rimeaddr_set_node_addr(&addr);
PRINTFD("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]);
#if UIP_CONF_IPV6
PRINTA("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]);
#else
PRINTA("MAC address ");
uint8_t i;
for (i=sizeof(rimeaddr_t); i>0; i--){
PRINTA("%x:",addr.u8[i-1]);
}
PRINTA("\n");
#endif
/* Initialize stack protocols */
queuebuf_init();
@ -282,20 +554,20 @@ uint8_t i;
NETSTACK_NETWORK.init();
#if ANNOUNCE_BOOT
PRINTF("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
PRINTA("%s %s, channel %u power %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()),rf230_get_txpower();
if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac
unsigned short tmp;
tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
NETSTACK_RDC.channel_check_interval());
if (tmp<65535) printf_P(PSTR(", check rate %u Hz"),tmp);
if (tmp<65535) PRINTA(", check rate %u Hz",tmp);
}
PRINTF("\n");
PRINTA("\n");
#if UIP_CONF_IPV6_RPL
PRINTF("RPL Enabled\n");
PRINTA("RPL Enabled\n");
#endif
#if UIP_CONF_ROUTER
PRINTF("Routing Enabled\n");
PRINTA("Routing Enabled\n");
#endif
#endif /* ANNOUNCE_BOOT */
@ -305,12 +577,12 @@ uint8_t i;
process_start(&tcpip_process, NULL);
#else
#else /* !RF230BB */
/* Original RF230 combined mac/radio driver */
/* mac process must be started before tcpip process! */
process_start(&mac_process, NULL);
process_start(&tcpip_process, NULL);
#endif /*RF230BB*/
#endif /* RF230BB */
#ifdef RAVEN_LCD_INTERFACE
process_start(&raven_lcd_process, NULL);
@ -326,13 +598,13 @@ uint8_t i;
#if COFFEE_FILES
int fa = cfs_open( "/index.html", CFS_READ);
if (fa<0) { //Make some default web content
PRINTF("No index.html file found, creating upload.html!\n");
PRINTF("Formatting FLASH file system for coffee...");
PRINTA("No index.html file found, creating upload.html!\n");
PRINTA("Formatting FLASH file system for coffee...");
cfs_coffee_format();
PRINTF("Done!\n");
PRINTA("Done!\n");
fa = cfs_open( "/index.html", CFS_WRITE);
int r = cfs_write(fa, &"It works!", 9);
if (r<0) PRINTF("Can''t create /index.html!\n");
if (r<0) PRINTA("Can''t create /index.html!\n");
cfs_close(fa);
// fa = cfs_open("upload.html"), CFW_WRITE);
// <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html>
@ -351,7 +623,7 @@ uint8_t i;
/*--------------------------Announce the configuration---------------------*/
#if ANNOUNCE_BOOT
{
#if AVR_WEBSERVER
uint8_t i;
char buf[80];
@ -360,36 +632,59 @@ uint8_t i;
for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) {
httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf);
PRINTF("IPv6 Address: %s\n",buf);
PRINTA("IPv6 Address: %s\n",buf);
}
}
eeprom_read_block (buf,server_name, sizeof(server_name));
buf[sizeof(server_name)]=0;
PRINTF("%s",buf);
eeprom_read_block (buf,domain_name, sizeof(domain_name));
buf[sizeof(domain_name)]=0;
cli();
eeprom_read_block (buf,eemem_server_name, sizeof(eemem_server_name));
sei();
buf[sizeof(eemem_server_name)]=0;
PRINTA("%s",buf);
cli();
eeprom_read_block (buf,eemem_domain_name, sizeof(eemem_domain_name));
sei();
buf[sizeof(eemem_domain_name)]=0;
size=httpd_fs_get_size();
#ifndef COFFEE_FILES
PRINTF(".%s online with fixed %u byte web content\n",buf,size);
PRINTA(".%s online with fixed %u byte web content\n",buf,size);
#elif COFFEE_FILES==1
PRINTF(".%s online with static %u byte EEPROM file system\n",buf,size);
PRINTA(".%s online with static %u byte EEPROM file system\n",buf,size);
#elif COFFEE_FILES==2
PRINTF(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
PRINTA(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10);
#elif COFFEE_FILES==3
PRINTF(".%s online with static %u byte program memory file system\n",buf,size);
PRINTA(".%s online with static %u byte program memory file system\n",buf,size);
#elif COFFEE_FILES==4
PRINTF(".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10);
#endif /* COFFEE_FILES */
#else
PRINTF("Online\n");
PRINTA("Online\n");
#endif /* AVR_WEBSERVER */
#endif /* ANNOUNCE_BOOT */
}
}
#if RF230BB
extern char rf230_interrupt_flag, rf230processflag;
#if ROUTES && UIP_CONF_IPV6
static void
ipaddr_add(const uip_ipaddr_t *addr)
{
uint16_t a;
int8_t i, f;
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) PRINTF("::");
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTF(":");
}
PRINTF("%x",a);
}
}
}
#endif
/*-------------------------------------------------------------------------*/
@ -422,39 +717,64 @@ main(void)
*/
extern uint8_t rf230_calibrated;
if (rf230_calibrated) {
PRINTF("\nRF230 calibrated!\n");
PRINTD("\nRF230 calibrated!\n");
rf230_calibrated=0;
}
#endif
#if DEBUGFLOWSIZE
if (debugflowsize) {
debugflow[debugflowsize]=0;
PRINTF("%s",debugflow);
debugflowsize=0;
}
#endif
watchdog_periodic();
#if PERIODICPRINTS
#if TESTRTIMER
/* Timeout can be increased up to 8 seconds maximum (at 8MHz with 1024 prescaler)
/* Timeout can be increased up to 8 seconds maximum.
* A one second cycle is convenient for triggering the various debug printouts.
* The triggers are staggered to avoid printing everything at once.
*/
if (rtimerflag) {
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
rtimerflag=0;
#else
if (clocktime!=clock_seconds()) {
clocktime=clock_seconds();
#endif
#if STAMPS
if ((rtime%STAMPS)==0) {
PRINTF("%us ",rtime);
if ((clocktime%STAMPS)==0) {
#if ENERGEST_CONF_ON
#include "lib/print-stats.h"
print_stats();
#elif RADIOSTATS
extern volatile unsigned long radioontime;
PRINTF("%u(%u)s\n",clocktime,radioontime);
#else
PRINTF("%us\n",clocktime);
#endif
}
#endif
rtime+=1;
#if TESTRTIMER
clocktime+=1;
#endif
#if PINGS
if ((rtime%PINGS)==1) {
#if PINGS && UIP_CONF_IPV6
extern void raven_ping6(void);
if ((clocktime%PINGS)==1) {
PRINTF("**Ping\n");
raven_ping6();
}
#endif
#if ROUTES
if ((rtime%ROUTES)==2) {
#if ROUTES && UIP_CONF_IPV6
if ((clocktime%ROUTES)==2) {
//#if UIP_CONF_IPV6_RPL
//#include "rpl.h"
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if;
@ -462,7 +782,7 @@ extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j;
PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) {
if (uip_ds6_if.addr_list[i].isused) {
ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n");
}
@ -496,7 +816,7 @@ extern uip_ds6_netif_t uip_ds6_if;
#endif
#if STACKMONITOR
if ((rtime%STACKMONITOR)==3) {
if ((clocktime%STACKMONITOR)==3) {
extern uint16_t __bss_end;
uint16_t p=(uint16_t)&__bss_end;
do {
@ -510,19 +830,10 @@ if ((rtime%STACKMONITOR)==3) {
#endif
}
#endif /* TESTRTIMER */
//Use with RF230BB DEBUGFLOW to show path through driver
#if RF230BB&&0
extern uint8_t debugflowsize,debugflow[];
if (debugflowsize) {
debugflow[debugflowsize]=0;
PRINTF("%s",debugflow);
debugflowsize=0;
}
#endif
#endif /* PERIODICPRINTS */
#if RF230BB&&0
extern uint8_t rf230processflag;
if (rf230processflag) {
PRINTF("rf230p%d",rf230processflag);
rf230processflag=0;
@ -530,6 +841,7 @@ extern uint8_t debugflowsize,debugflow[];
#endif
#if RF230BB&&0
extern uint8_t rf230_interrupt_flag;
if (rf230_interrupt_flag) {
// if (rf230_interrupt_flag!=11) {
PRINTF("**RI%u",rf230_interrupt_flag);
@ -547,25 +859,3 @@ void log_message(char *m1, char *m2)
{
PRINTF("%s%s\n", m1, m2);
}
#if ROUTES
static void
ipaddr_add(const uip_ipaddr_t *addr)
{
uint16_t a;
int8_t i, f;
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) PRINTF("::");
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTF(":");
}
PRINTF("%x",a);
}
}
}
#endif

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef NODE_ID_H
#define NODE_ID_H
#include "contiki-conf.h"
void node_id_restore(void);
void node_id_burn(uint16_t node_id);
extern uint16_t node_id;
#endif /* !NODE_ID_H */

View file

@ -393,7 +393,7 @@ extern void mac_log_802_15_4_rx(const uint8_t* buffer, size_t total_len);
*/
#define UIP_CONF_ROUTER 1
#define UIP_CONF_ND6_SEND_RA........0
#define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000
#define UIP_CONF_ND6_RETRANS_TIMER 10000

View file

@ -280,7 +280,7 @@ uint16_t eemem_panid EEMEM = IEEE802154_PANID;
uint16_t eemem_panid EEMEM = 0xABCD;
#endif
#ifdef IEEE802154_PANADDR
uint16_t eemem_panaddr EEMEM = IEEE802154_PANID;
uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
#else
uint16_t eemem_panaddr EEMEM = 0;
#endif

View file

@ -39,6 +39,7 @@
*/
#include "sys/clock.h"
#include <stdlib.h>
#include <sys/time.h>
static long startsecs=0,startmsecs=0;

View file

@ -89,6 +89,11 @@
/* end of mc1322x specific config. */
/* start of conitki config. */
/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_LT is defined */
typedef unsigned long rtimer_clock_t;
#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0)
#define RIMEADDR_CONF_SIZE 8
/* EUI64 generation */

View file

@ -100,6 +100,10 @@
#define PLATFORM_HAS_LEDS 1
#define PLATFORM_HAS_BUTTON 1
/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_LT is defined */
typedef unsigned long rtimer_clock_t;
#define RTIMER_CLOCK_LT(a,b) ((signed long)((a)-(b)) < 0)
#define RIMEADDR_CONF_SIZE 8
/* EUI64 generation */

View file

@ -67,6 +67,24 @@
#include "contiki-maca.h"
#include "contiki-uart.h"
/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */
/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */
#define PERIODICPRINTS 0
#if PERIODICPRINTS
//#define PINGS 64
#define ROUTES 300
#define STAMPS 60
#define STACKMONITOR 600
//#define HEAPMONITOR 60
uint16_t clocktime;
#define TESTRTIMER 0
#if TESTRTIMER
uint8_t rtimerflag=1;
struct rtimer rt;
void rtimercycle(void) {rtimerflag=1;}
#endif
#endif
#define DEBUG 0
#if DEBUG
#include <stdio.h>
@ -327,6 +345,36 @@ main(void)
/* go into user mode */
init_lowlevel();
#if STACKMONITOR
/* Simple stack pointer highwater monitor. Checks for magic numbers in the main
* loop. In conjuction with PERIODICPRINTS, never-used stack will be printed
* every STACKMONITOR seconds.
*/
{
extern uint32_t __und_stack_top__, __sys_stack_top__;
uint32_t p=(uint32_t)&__und_stack_top__;
do {
*(uint32_t *)p = 0x42424242;
p+=16;
} while (p<(uint32_t)&__sys_stack_top__-100); //don't overwrite our own stack
}
#endif
#if HEAPMONITOR
/* Simple heap pointer highwater monitor. Checks for magic numbers in the main
* loop. In conjuction with PERIODICPRINTS, never-used heap will be printed
* every HEAPMONITOR seconds.
* This routine assumes a linear FIFO heap as used by the printf _sbrk call.
*/
{
extern uint32_t __heap_start__, __heap_end__;
uint32_t p=(uint32_t)&__heap_end__-4;
do {
*(uint32_t *)p = 0x42424242;
p-=4;
} while (p>=(uint32_t)&__heap_start__);
}
#endif
/* Clock */
clock_init();
@ -498,6 +546,124 @@ main(void)
}
process_run();
#if PERIODICPRINTS
#if TESTRTIMER
/* Timeout can be increased up to 8 seconds maximum.
* A one second cycle is convenient for triggering the various debug printouts.
* The triggers are staggered to avoid printing everything at once.
*/
if (rtimerflag) {
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
rtimerflag=0;
#else
if (clocktime!=clock_seconds()) {
clocktime=clock_seconds();
#endif
#if STAMPS
if ((clocktime%STAMPS)==0) {
#if ENERGEST_CONF_ON
#include "lib/print-stats.h"
print_stats();
#elif RADIOSTATS
extern volatile unsigned long radioontime;
printf("\r%u(%u)s ",clocktime,radioontime);
#else
printf("%us\n",clocktime);
#endif
}
#endif
#if TESTRTIMER
clocktime+=1;
#endif
#if PINGS && UIP_CONF_IPV6
extern void raven_ping6(void);
if ((clocktime%PINGS)==1) {
printf("**Ping\n");
raven_ping6();
}
#endif
#if ROUTES && UIP_CONF_IPV6
if ((clocktime%ROUTES)==2) {
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j;
printf("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
printf("\n");
}
}
printf("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
printf("\n");
j=0;
}
}
if (j) printf(" <none>");
printf("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
printf("/%u (via ", uip_ds6_routing_table[i].length);
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
printf(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
// } else {
// printf(")\n");
// }
j=0;
}
}
if (j) printf(" <none>");
printf("\n---------\n");
}
#endif
#if STACKMONITOR
if ((clocktime%STACKMONITOR)==3) {
extern uint32_t __und_stack_top__, __sys_stack_top__;
uint32_t p=(uint32_t)&__und_stack_top__;
do {
if (*(uint32_t *)p != 0x42424242) {
printf("Never-Used stack > %d bytes\n",p-(uint32_t)&__und_stack_top__);
break;
}
p+=16;
} while (p<(uint32_t)&__sys_stack_top__-100);
}
#endif
#if HEAPMONITOR
if ((clocktime%HEAPMONITOR)==4) {
extern uint32_t __heap_start__, __heap_end__;
uint32_t p=(uint32_t)&__heap_end__-4;
do {
if (*(uint32_t *)p != 0x42424242) {
break;
}
p-=4;
} while (p>=(uint32_t)&__heap_start__);
printf("Never-used heap >= %d bytes\n",(uint32_t)&__heap_end__-p-4);
#if 0
#include <stdlib.h>
char *ptr=malloc(1); //allocates 16 bytes from the heap
printf("********Got pointer %x\n",ptr);
#endif
}
#endif
}
#endif /* PERIODICPRINTS */
}
return 0;

View file

@ -4,7 +4,6 @@
#ifndef CONTIKI_CONF_H
#define CONTIKI_CONF_H
#ifdef PROJECT_CONF_H
#include "project-conf.h"
#endif /* PROJECT_CONF_H */
@ -43,6 +42,14 @@
#if WITH_UIP6
/* Network setup for IPv6 */
#define NETSTACK_CONF_NETWORK sicslowpan_driver
/* Specify a minimum packet size for 6lowpan compression to be
enabled. This is needed for ContikiMAC, which needs packets to be
larger than a specified size, if no ContikiMAC header should be
used. */
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 60
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define CXMAC_CONF_ANNOUNCEMENTS 0
#define XMAC_CONF_ANNOUNCEMENTS 0

View file

@ -41,13 +41,18 @@
/* Network setup for IPv6 */
#define NETSTACK_CONF_NETWORK sicslowpan_driver
/* #define NETSTACK_CONF_MAC nullmac_driver */
/* #define NETSTACK_CONF_RDC sicslowmac_driver */
#define NETSTACK_CONF_MAC csma_driver
#define NETSTACK_CONF_RDC contikimac_driver
#define NETSTACK_CONF_RADIO cc2420_driver
#define NETSTACK_CONF_FRAMER framer_802154
/* Specify a minimum packet size for 6lowpan compression to be
enabled. This is needed for ContikiMAC, which needs packets to be
larger than a specified size, if no ContikiMAC header should be
used. */
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 60
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define CC2420_CONF_AUTOACK 1
#define NETSTACK_RDC_CHANNEL_CHECK_RATE 8
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0

View file

@ -88,6 +88,7 @@ import se.sics.cooja.interfaces.Radio;
import se.sics.cooja.plugins.analyzers.ICMPv6Analyzer;
import se.sics.cooja.plugins.analyzers.IEEE802154Analyzer;
import se.sics.cooja.plugins.analyzers.IPHCPacketAnalyzer;
import se.sics.cooja.plugins.analyzers.IPv6PacketAnalyzer;
import se.sics.cooja.plugins.analyzers.PacketAnalyzer;
import se.sics.cooja.plugins.analyzers.RadioLoggerAnalyzerSuite;
import se.sics.cooja.util.StringUtils;
@ -142,11 +143,13 @@ public class RadioLogger extends VisPlugin {
ArrayList<PacketAnalyzer> lowpanAnalyzers = new ArrayList<PacketAnalyzer>();
lowpanAnalyzers.add(new IEEE802154Analyzer(false));
lowpanAnalyzers.add(new IPHCPacketAnalyzer());
lowpanAnalyzers.add(new IPv6PacketAnalyzer());
lowpanAnalyzers.add(new ICMPv6Analyzer());
ArrayList<PacketAnalyzer> lowpanAnalyzersPcap = new ArrayList<PacketAnalyzer>();
lowpanAnalyzersPcap.add(new IEEE802154Analyzer(true));
lowpanAnalyzersPcap.add(new IPHCPacketAnalyzer());
lowpanAnalyzersPcap.add(new IPv6PacketAnalyzer());
lowpanAnalyzersPcap.add(new ICMPv6Analyzer());
model = new AbstractTableModel() {

View file

@ -0,0 +1,81 @@
package se.sics.cooja.plugins.analyzers;
import se.sics.cooja.util.StringUtils;
public class IPv6PacketAnalyzer extends PacketAnalyzer {
public final static int PROTO_UDP = 17;
public final static int PROTO_TCP = 6;
public final static int PROTO_ICMP = 58;
public final static byte[] UNSPECIFIED_ADDRESS =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
private static final int IPV6_DISPATCH = 0x41;
public boolean matchPacket(Packet packet) {
return packet.get(0) == IPV6_DISPATCH;
}
public int analyzePacket(Packet packet, StringBuffer brief,
StringBuffer verbose) {
/* if packet has less than 40 bytes it is not interesting ... */
if (packet.size() < 40) return ANALYSIS_FAILED;
brief.append("IPv6");
/* need to decompress while analyzing - add that later... */
verbose.append("<b>IPv6</b><br>");
int pos = 1;
int version = 6;
int trafficClass = 0;
int flowLabel = 0;
int len = packet.getInt(pos + 4, 2);
int proto = packet.getInt(pos + 6, 1);
int ttl = packet.getInt(pos + 7, 1);
byte[] srcAddress = new byte[16];
byte[] destAddress = new byte[16];
packet.copy(pos + 8, srcAddress, 0, 16);
packet.copy(pos + 24, destAddress, 0, 16);
String protoStr = "" + proto;
if (proto == PROTO_ICMP) {
protoStr = "ICMPv6";
} else if (proto == PROTO_UDP) protoStr = "UDP";
else if (proto == PROTO_TCP) protoStr = "TCP";
/* consume dispatch + IP header */
packet.pos += 41;
verbose.append("<br><b>IPv6 ").append(protoStr).append("</b> TC = " + trafficClass +
" FL: " + flowLabel + "<br>");
verbose.append("From ");
printAddress(verbose, srcAddress);
verbose.append(" to ");
printAddress(verbose, destAddress);
packet.lastDispatch = (byte) (proto & 0xff);
packet.level = NETWORK_LEVEL;
return ANALYSIS_OK_CONTINUE;
}
public static void printAddress(StringBuffer out, byte[] address) {
for (int i = 0; i < 16; i+=2) {
out.append(StringUtils.toHex((byte) (address[i] & 0xff)) +
StringUtils.toHex((byte) (address[i + 1] & 0xff)));
if (i < 14) {
out.append(":");
}
}
}
}

View file

@ -1,6 +1,6 @@
ifndef TAG
ifndef RELEASE
${error You must specify the RELEASE variable (e.g. make RELEASE=2.2)}
${error You must specify the RELEASE variable (e.g. make RELEASE=2.5)}
endif
RELEASETAG=$(subst .,-,$(RELEASE))
TAG=contiki-$(RELEASETAG)
@ -8,33 +8,29 @@ else
RELEASE=$(TAG)
endif
ifndef CVSUSER
CVSUSER=:pserver:anonymous
endif
CVSROOT=$(CVSUSER)@contiki.cvs.sourceforge.net:/cvsroot/contiki
GITROOT=git://contiki.git.sourceforge.net/gitroot/contiki/contiki
package: all
test: export-package compile almost-clean
export-package: clean export copy tgz zip
export-package: clean checkout copy tgz zip
almost-clean:
rm -rf contiki-2.x contiki-$(RELEASE) contiki-collect-$(RELEASE)
rm -rf contiki contiki-$(RELEASE) contiki-collect-$(RELEASE)
clean:
rm -rf contiki-2.x contiki-$(RELEASE) contiki-collect-$(RELEASE) *.zip *.tar.gz
rm -rf contiki contiki-$(RELEASE) contiki-collect-$(RELEASE) *.zip *.tar.gz
copy:
cp -r contiki-2.x contiki-$(RELEASE)
cp -r contiki contiki-$(RELEASE)
doc:
(cd contiki-2.x/doc; make dox pdf)
(cd contiki/doc; make dox pdf)
copydoc:
cp contiki-2.x/doc/latex/refman.pdf contiki-$(RELEASE)/doc/
cp -r contiki-2.x/doc/html contiki-$(RELEASE)/doc/
cp contiki/doc/latex/refman.pdf contiki-$(RELEASE)/doc/
cp -r contiki/doc/html contiki-$(RELEASE)/doc/
tgz:
tar czf contiki-$(RELEASE).tar.gz contiki-$(RELEASE)
@ -45,13 +41,12 @@ zip:
chmod 644 contiki-$(RELEASE).zip
compile:
(cd contiki-2.x/examples/compile-platforms; make)
(cd contiki/examples/compile-platforms; make)
checkout:
cvs -d $(CVSROOT) co -r $(TAG) contiki-2.x
export:
cvs -d $(CVSROOT) export -r $(TAG) contiki-2.x
git clone $(GITROOT)
git checkout $(TAG)
rm -rf contiki/.git
-include Makefile.sky
-include Makefile.raven

View file

@ -12,14 +12,17 @@ tools:
@(cd ../../../tools ; $(MAKE))
@(cd ../../../tools/sky/uip6-bridge ; $(MAKE))
shell: example-example-shell.native example-example-shell.netsim
shell: example-example-shell.native
hello-world: example-hello-world.sky example-hello-world.native \
example-hello-world.netsim example-hello-world.minimal-net example-hello-world.msb430
rime-examples: example-rime.sky example-rime.netsim example-rime.esb
example-hello-world.minimal-net example-hello-world.msb430 \
example-hello-world.micaz example-hello-world.raven \
example-hello-world.redbee-econotag example-hello-world.z1
rime-examples: example-rime.sky example-rime.z1 example-rime.esb example-rime.redbee-econotag
ipso-ipv6-raven: example-ipso-ipv6-raven.raven
jcreate: example-jcreate.jcreate
multi-threading: example-multi-threading.sky \
example-multi-threading.native example-multi-threading.msb430
example-multi-threading.native example-multi-threading.msb430 \
example-multi-threading.z1
sky: example-sky.sky
sky-ip: example-sky-ip.sky
sky-shell: example-sky-shell.sky

View file

@ -4,12 +4,13 @@ all:
@uname -a
@$(MAKE) -s -k compile || cat *.output
compile: 6502 msp430 native avr
compile: 6502 msp430 native avr arm
6502: c64.platform c128.platform apple2enh.platform atari.platform
msp430: sky.platform esb.platform # msb430.platform
native: native.platform netsim.platform minimal-net.platform
msp430: sky.platform esb.platform z1.platform
native: native.platform minimal-net.platform
avr: avr-raven.platform
arm: redbee-econotag.platform redbee-dev.platform
clean:
@rm -rf [a-z]*

124
tools/serial-log.pl Normal file
View file

@ -0,0 +1,124 @@
#!/usr/bin/perl -w
#Log serial port to terminal and file with timestamps
#D.Kopf 8/28/2001
#
use Device::SerialPort;
use Term::ReadKey;
use Getopt::Long;
use Time::HiRes qw(usleep);
use strict;
my $term = '/dev/com1';
my $baud = '57600';
my $rts = 'none';
my $logfile = 'none';
my $ssss = '';
GetOptions ('terminal=s' => \$term,
'baud=s' => \$baud,
'rts=s' => \$rts,
'seconds!' => \$ssss,
'logfile:s' =>\$logfile
) or goto printhelp;
goto bypass;
printhelp:
print "Example serial-log.pl -t /dev/ttyS0 -b 57600 -r none -l logfile\n";
print " -t, --terminal\n";
print " -b, --baud\n";
print " -r,--rts [none|rts] flow control\n";
print " -s,--seconds Display ssss instead of hh:mm:ss\n";
print " -l,--logfile outputfile (.log will be added, -l defaults to serial.log)\n";
print "\n";
print "The default is equivalent to serial-log.pl -t /dev/com1 -b 57600 -r none\n";
exit;
bypass:
my $ob = Device::SerialPort->new ($term) or die "Can't start $term\n";
# next test will die at runtime unless $ob
$ob->baudrate($baud);
$ob->parity('none');
$ob->databits(8);
$ob->stopbits(1);
if($rts eq 'rts') {
$ob->handshake('rts');
} else {
$ob->handshake('none');
}
$ob->read_const_time(1000); # 1 second per unfulfilled "read" call
$ob->rts_active(1);
my $c; my $count;
my ($hh,$mm,$ss,$mday,$mon,$year,$wday,$yday,$isdst,$theTime,$seconds,$startseconds);
#use POSIX qw(strftime);
($ss,$mm,$hh,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
$theTime = sprintf "on %02d/%02d/%04d at %02d:%02d:%02d\n", $mon+1, $mday, $year+1900, $hh, $mm, $ss;
if($logfile ne 'none') {
if($logfile eq '') {$logfile = 'serial';}
$logfile ="${logfile}.log";
$c=1;
open LOGFILE, "$logfile" or do {$c=0;};
if ($c) {
print "File $logfile exists. Restart, append, or quit (r,a,q) (q) ? ";
#$| = 1; # force a flush after print
$_ = <STDIN>;chomp;
if ($_ eq 'r') {
open LOGFILE, ">$logfile" or die $!;
print "Restarting $logfile $theTime\n";
print LOGFILE "serial-log.pl logging to $logfile started $theTime\n";
} else {
if ($_ eq 'a') {
open LOGFILE, ">>$logfile" or die $!;
print "Appending to $logfile $theTime\n";
print LOGFILE "serial-log.pl appending to $logfile $theTime\n";
} else {
print "Quitting, file unchanged.\n";
exit;
}
}
} else {
open LOGFILE, ">$logfile" or die $!;
print LOGFILE "serial-log.pl logging to $logfile started $theTime\n";
print "Starting $logfile $theTime\n";
}
LOGFILE->autoflush(1);
} else {
$logfile='';
print "Serial logging of $term started $theTime\n";
}
if($ssss ne '') {
$startseconds=$hh*3600+$mm*60+$ss;
}
$theTime='';
while(1) {
($count, $c) = $ob->read(1);
if (defined($count) && ($count != 0)) {
if ($theTime eq '') {
($ss,$mm,$hh) = localtime(time);
if ($ssss ne '') {
$seconds = $hh*3600+$mm*60+$ss-$startseconds;
if ($seconds < 0) {$seconds+=24*60*60;}
$theTime = sprintf("%04d ",$seconds);
} else {
$theTime = sprintf("%02d:%02s:%02d ", $hh,$mm,$ss);
#$theTime = strftime "%H:%M:%S ", localtime;
}
print $theTime ;
if ($logfile) {LOGFILE->autoflush(1);print LOGFILE $theTime;}
}
print $c ;
if ($logfile) { print LOGFILE $c;}
if ($c eq "\n") {$theTime=''};
}
}
if ($logfile) {close LOGFILE or die $!}
$ob -> close or die "Serial port close failed: $!\n";
ReadMode 0;
undef $ob; # closes port AND frees memory in perl
exit;

View file

@ -86,7 +86,7 @@ int ssystem(const char *fmt, ...)
__attribute__((__format__ (__printf__, 1, 2)));
void write_to_serial(void *inbuf, int len);
#define PRINTF(...) if(verbose)printf(__VA_ARGS__)
#define PRINTF(...) if(verbose)fprintf(stderr,__VA_ARGS__)
//#define PROGRESS(s) fprintf(stderr, s)
#define PROGRESS(s) do { } while (0)
@ -113,6 +113,7 @@ static bool clean_route = false;
static bool clean_neighb = false;
static struct uip_eth_addr adapter_eth_addr;
static char * if_name;
static int timestamp = 1;
OSVERSIONINFO osVersionInfo;
@ -150,6 +151,7 @@ void print_help()
fprintf(stderr, "Options:\r\n");
fprintf(stderr, "-s siodev\tDevice that identifies the bridge or the boder router.\r\n");
fprintf(stderr, "-B baudrate\tBaudrate of the serial port (default:115200).\r\n");
fprintf(stderr, "-L Log time\t-L1 HH:MM:SS -L2 HH:MM:SS.xxx -L3 SSSS -L4 SSSS.xxxx\r\n");
fprintf(stderr, " One between:\n");
fprintf(stderr, " -a ipaddress/[prefixlen] The address to be assigned to the local interface.\r\n");
fprintf(stderr, "\t\tadapter.\r\n");
@ -236,7 +238,52 @@ execProcess(LPDWORD exitCode,const char *fmt, ...)
}
void
stamptime(void)
{
static long startsecs=0,startmsecs=0;
long secs,msecs;
struct timeval tv;
time_t t;
struct tm *tmp;
char timec[20];
gettimeofday(&tv, NULL) ;
msecs=tv.tv_usec/1000;
secs=tv.tv_sec;
if (startsecs) {
if (timestamp<3) {
t=time(NULL);
tmp=localtime(&t);
strftime(timec,sizeof(timec),"%T",tmp);
if (timestamp==2) {
fprintf(stderr,"%s.%03lu ",timec,msecs);
} else {
fprintf(stderr,"%s ",timec);
}
} else {
secs -=startsecs;
msecs-=startmsecs;
if (msecs<0) {secs--;msecs+=1000;}
if (timestamp==3) {
fprintf(stderr,"%04lu ", secs);
} else {
fprintf(stderr,"%04lu.%03lu ", secs, msecs);
}
}
} else {
startsecs=secs;
startmsecs=msecs;
t=time(NULL);
tmp=localtime(&t);
strftime(timec,sizeof(timec),"%T",tmp);
if ((timestamp==2) || (timestamp>3)) {
fprintf(stderr,"\n%s.%03lu ",timec,msecs);
} else {
fprintf(stderr,"\n%s ",timec);
}
}
}
#define SLIP_END 0300
@ -257,7 +304,7 @@ print_packet(u_int8_t *p, int len) {
}
printf("\n");
}*/
#if 0
int
is_sensible_string(const unsigned char *s, int len)
{
@ -266,12 +313,13 @@ is_sensible_string(const unsigned char *s, int len)
if(s[i] == 0 || s[i] == '\r' || s[i] == '\n' || s[i] == '\t') {
continue;
} else if(s[i] < ' ' || '~' < s[i]) {
printf("\nbad character at %d:%x\n",i,s[i]);
return 0;
}
}
return 1;
}
#endif
/*
* Read from serial, when we have a packet write it to tun. No output
@ -286,7 +334,7 @@ serial_to_wpcap(FILE *inslip)
u16_t buf_aligned[BUF_SIZE/2 + 42]; //extra for possible eth_hdr and ip_process expansion
u8_t *buf = (u8_t *)buf_aligned;
static int inbufptr = 0;
static int inbufptr = 0, issensiblestring=1;
int ret;
unsigned char c;
@ -313,6 +361,7 @@ read_more:
if(ret == 0) {
clearerr(inslip);
return;
if (timestamp) stamptime();
fprintf(stderr, "serial_to_tun: EOF\n");
exit(1);
}
@ -333,7 +382,8 @@ read_more:
}
}
macs64[pos] = '\0';
printf("*** Gateway's MAC address: %s\n", macs64);
if (timestamp) stamptime();
fprintf(stderr, "*** Gateway's MAC address: %s\n", macs64);
mac_received = true;
sscanf(macs64, "%2X-%2X-%2X-%2X-%2X-%2X-%2X-%2X",
@ -361,13 +411,13 @@ read_more:
dev_eth_addr.addr[3],
dev_eth_addr.addr[4],
dev_eth_addr.addr[5]);
printf("Fictitious MAC-48: %s\n", macs48);
if (timestamp) stamptime();
fprintf(stderr,"Fictitious MAC-48: %s\n", macs48);
if(autoconf){
if(IPAddrFromPrefix(autoconf_addr, ipprefix, macs64)!=0){
if (timestamp) stamptime();
fprintf(stderr, "Invalid IPv6 address.\n");
exit(1);
}
@ -379,6 +429,7 @@ read_more:
/* RPL Border Router mode. Add route towards LoWPAN. */
if(IPAddrFromPrefix(rem_ipaddr, br_prefix, macs64)!=0){
if (timestamp) stamptime();
fprintf(stderr, "Invalid IPv6 address.\n");
exit(1);
}
@ -404,11 +455,31 @@ read_more:
}
}
else if(inpktbuf[0] == DEBUG_LINE_MARKER) {
/* Dont insert timestamp on wireshark packet dumps starting with 0000 */
if (timestamp) {
if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
}
fwrite(inpktbuf + 1, inbufptr - 1, 1, stderr);
issensiblestring=1;
}
#if 0
else if(is_sensible_string(inpktbuf, inbufptr)) {
/* Dont insert timestamp on wireshark packet dumps starting with 0000 */
if (timestamp) {
if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
}
fwrite(inpktbuf, inbufptr, 1, stderr);
}
#else
else if(issensiblestring) {
/* Dont insert timestamp on wireshark packet dumps starting with 0000 */
if (timestamp) {
if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
}
fwrite(inpktbuf, inbufptr, 1, stderr);
}
#endif
else {
PRINTF("Sending to wpcap\n");
@ -436,6 +507,7 @@ read_more:
/* printf("After sending to wpcap\n");*/
}
inbufptr = 0;
issensiblestring=1;
}
break;
@ -458,6 +530,26 @@ read_more:
/* FALLTHROUGH */
default:
inpktbuf[inbufptr++] = c;
if (issensiblestring) {
if(c == '\n') {
/* Dont insert timestamp on wireshark packet dumps starting with 0000 */
if (timestamp) {
if (inpktbuf[0]!='0' || inpktbuf[1]!=0 || inpktbuf[2]!=0 || inpktbuf[3]!=0) stamptime();
}
/* This could be a proper debug string starting with CR just a print to stdout */
/* Trap the CR which would cause overwriting of the timestamp */
//{int i;for (i=0;i<inbufptr;i++) fprintf(stderr,"%2x ",inpktbuf[i]);}
if(inpktbuf[0] == DEBUG_LINE_MARKER) {
fwrite(inpktbuf + 1, inbufptr - 1, 1, stderr);
} else {
fwrite(inpktbuf, inbufptr, 1, stderr);
}
inbufptr=0;
} else if (c == 0 || c == '\t' || c == '\r') {
} else if(c < ' ' || '~' < c) {
issensiblestring=0;
}
}
break;
}
@ -673,6 +765,7 @@ cleanup(void)
void
sigcleanup(int signo)
{
if (timestamp) stamptime();
fprintf(stderr, "signal %d\n", signo);
exit(0); /* exit(0) will call cleanup() */
}
@ -681,6 +774,7 @@ void
sigalarm(int signo)
{
if(!mac_received){
if (timestamp) stamptime();
fprintf(stderr, "Bridge/Router not found!\n");
exit(2);
}
@ -763,7 +857,7 @@ void send_commands(void)
int i;
inet_pton(AF_INET6, br_prefix, &addr);
if (timestamp) stamptime();
fprintf(stderr,"*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
br_prefix,
addr.s6_addr[0], addr.s6_addr[1],
@ -794,25 +888,30 @@ void addAddress(const char * ifname, const char * ipaddr)
strncpy(tmpaddr,ipaddr,sizeof(tmpaddr));
strtok(tmpaddr,"/"); // Remove possible prefix length.
if (timestamp) stamptime();
execProcess(&exitCode,"netsh interface ipv6 add address \"%s\" %s",if_name,tmpaddr);
substr = strtok(NULL,"/");
if(substr == NULL){ // A prefix length is not specified.
// Use a 64 bit prefix
strcat(tmpaddr,"/64");
if (timestamp) stamptime();
execProcess(NULL,"netsh interface ipv6 add route %s \"%s\"",tmpaddr,if_name);
}
else {
if (timestamp) stamptime();
execProcess(NULL,"netsh interface ipv6 add route %s \"%s\"",ipaddr,if_name);
}
}
else{
if (timestamp) stamptime();
execProcess(&exitCode,"netsh interface ipv6 add address \"%s\" %s",if_name,ipaddr);
}
if(exitCode==0){
clean_addr = true;
}
else {
if (timestamp) stamptime();
fprintf(stderr, "WARNING: subprocess exited with code %ld\n", exitCode);
}
}
@ -823,15 +922,17 @@ void delAddress(const char * ifname, const char * ipaddr)
strncpy(tmpaddr,ipaddr,sizeof(tmpaddr));
strtok(tmpaddr,"/"); // Remove possible prefix length.
if (timestamp) stamptime();
if(osVersionInfo.dwMajorVersion < 6){ // < Windows Vista (i.e., Windows XP; check if this command is ok for Windows Server 2003 too).
char * substr;
execProcess(NULL,"netsh interface ipv6 delete address \"%s\" %s",if_name,tmpaddr);
if (timestamp) stamptime();
substr = strtok(NULL,"/");
if(substr == NULL){ // A prefix length is not specified.
// Use a 64 bit prefix
strcat(tmpaddr,"/64");
strcat(tmpaddr,"/64");
execProcess(NULL,"netsh interface ipv6 delete route %s \"%s\"",tmpaddr,if_name);
}
else {
@ -849,18 +950,20 @@ void delAddress(const char * ifname, const char * ipaddr)
void addLoWPANRoute(const char * ifname, const char * net, const char * gw)
{
DWORD exitCode = -1;
if (timestamp) stamptime();
execProcess(&exitCode,"netsh interface ipv6 add route %s/64 \"%s\" %s", net, if_name, gw);
if(exitCode==0){
clean_route = true;
}
else {
if (timestamp) stamptime();
fprintf(stderr, "WARNING: subprocess exited with code %ld\n", exitCode);
}
}
void delLoWPANRoute(const char * ifname, const char * net)
{
if (timestamp) stamptime();
execProcess(NULL,"netsh interface ipv6 delete route %s/64 \"%s\"", net, if_name);
}
@ -869,11 +972,13 @@ void addNeighbor(const char * ifname, const char * neighb, const char * neighb_m
DWORD exitCode = -1;
if(osVersionInfo.dwMajorVersion >= 6){
if (timestamp) stamptime();
execProcess(&exitCode,"netsh interface ipv6 add neighbor \"%s\" %s \"%s\"", if_name, neighb, neighb_mac);
if(exitCode==0){
clean_neighb = true;
}
else {
if (timestamp) stamptime();
fprintf(stderr, "WARNING: subprocess exited with code %ld\n", exitCode);
}
}
@ -881,6 +986,7 @@ void addNeighbor(const char * ifname, const char * neighb, const char * neighb_m
void delNeighbor(const char * ifname, const char * neighb)
{
if (timestamp) stamptime();
execProcess(NULL,"netsh interface ipv6 delete neighbor \"%s\" %s", if_name, neighb);
}
@ -995,12 +1101,21 @@ main(int argc, char **argv)
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osVersionInfo);
while((c = getopt(argc, argv, "B:D:hs:c:ra:p:vtb:")) != -1) {
while((c = getopt(argc, argv, "B:D:L:hs:c:ra:p:vtb:")) != -1) {
switch (c) {
case 'B':
baudrate = atoi(optarg);
break;
case 'L':
if(strncmp("0", optarg, 1) == 0) {
timestamp = 0;
} else {
timestamp = atoi(optarg);
if (timestamp==0) timestamp=1;
}
break;
case 's':
if(strncmp("/dev/", optarg, 5) == 0) {
strncpy(siodev,optarg + 5,sizeof(siodev)-1);
@ -1035,6 +1150,7 @@ main(int argc, char **argv)
}
local_ipaddr = optarg;
if (!validIPAddr(local_ipaddr, 0)){
if (timestamp) stamptime();
fprintf(stderr, "Invalid IPv6 address: %s", local_ipaddr);
exit(1);
}
@ -1047,6 +1163,7 @@ main(int argc, char **argv)
autoconf = true;
ipprefix = optarg;
if (!validIPAddr(ipprefix, 0)){
if (timestamp) stamptime();
fprintf(stderr, "Invalid IPv6 prefix: %s", ipprefix);
exit(1);
}
@ -1067,6 +1184,7 @@ main(int argc, char **argv)
tun = true;
if (!validIPAddr(br_prefix, 64)){
if (timestamp) stamptime();
fprintf(stderr, "Invalid IPv6 64-bit prefix: %s", br_prefix);
exit(1);
}
@ -1088,6 +1206,7 @@ main(int argc, char **argv)
}
if(autoconf == true && br_prefix != NULL){
if (timestamp) stamptime();
fprintf(stderr, "-p and -b options cannot be used together.\r\n");
print_help();
}
@ -1135,13 +1254,12 @@ main(int argc, char **argv)
}
slipfd = devopen(siodev, O_RDWR | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC );
if(slipfd == -1) {
err(1, "can't open siodev ``/dev/%s''", siodev);
}
fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
if (timestamp) stamptime();
fprintf(stderr, "wpcapslip6 started on ``/dev/%s''\n", siodev);
stty_telos(slipfd);
slip_send(SLIP_END);
inslip = fdopen(slipfd, "r");