diff --git a/Makefile.include b/Makefile.include index 8ed358203..92e49e5f2 100644 --- a/Makefile.include +++ b/Makefile.include @@ -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 diff --git a/apps/servreg-hack/servreg-hack.c b/apps/servreg-hack/servreg-hack.c index 25cfc8695..8a0165f2c 100644 --- a/apps/servreg-hack/servreg-hack.c +++ b/apps/servreg-hack/servreg-hack.c @@ -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(®istrations); + if(started == 0) { + list_init(others_services); + list_init(own_services); + memb_init(®istrations); - 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) { diff --git a/apps/servreg-hack/servreg-hack.h b/apps/servreg-hack/servreg-hack.h index e2ab306ad..57657d381 100644 --- a/apps/servreg-hack/servreg-hack.h +++ b/apps/servreg-hack/servreg-hack.h @@ -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); /** diff --git a/apps/shell/shell-ps.c b/apps/shell/shell-ps.c index c1d6643db..673369515 100644 --- a/apps/shell/shell-ps.c +++ b/apps/shell/shell-ps.c @@ -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(); diff --git a/apps/webserver-nano/Makefile.webserver-nano b/apps/webserver-nano/Makefile.webserver-nano index 1929865ec..2803c3c0c 100644 --- a/apps/webserver-nano/Makefile.webserver-nano +++ b/apps/webserver-nano/Makefile.webserver-nano @@ -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 diff --git a/apps/webserver-nano/httpd-cgi.c b/apps/webserver-nano/httpd-cgi.c index dec9c5d02..7608a9da2 100644 --- a/apps/webserver-nano/httpd-cgi.c +++ b/apps/webserver-nano/httpd-cgi.c @@ -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 = ""; 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 = "Contiki-nano"; #else +#define _MSS2 52 static const char httpd_cgi_header1[] HTTPD_STRING_ATTR = "Contiki-nano"; #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 = "
Front page";
   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 = "|Status";
   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 = "|Network connections";
   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 = "|System processes";
   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 = "|File statistics";
   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 = "|TicTacToe";
   numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm6);
 #endif
   static const char httpd_cgi_headerme[] HTTPD_STRING_ATTR = "
"; 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; diff --git a/apps/webserver-nano/httpd.h b/apps/webserver-nano/httpd.h index 671510218..9f093e305 100644 --- a/apps/webserver-nano/httpd.h +++ b/apps/webserver-nano/httpd.h @@ -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 diff --git a/apps/webserver-nano/webserver-nogui.c b/apps/webserver-nano/webserver-nogui.c index a5ce9c664..fd1cf029a 100644 --- a/apps/webserver-nano/webserver-nogui.c +++ b/apps/webserver-nano/webserver-nogui.c @@ -35,9 +35,7 @@ #include #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 */ diff --git a/core/contiki-net.h b/core/contiki-net.h index 3bed481a6..9f443bd5c 100644 --- a/core/contiki-net.h +++ b/core/contiki-net.h @@ -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" diff --git a/core/net/mac/contikimac.c b/core/net/mac/contikimac.c index 7e4c3deb5..e81f6c953 100644 --- a/core/net/mac/contikimac.c +++ b/core/net/mac/contikimac.c @@ -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 * Niclas Finne * Joakim Eriksson */ -#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 @@ -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 @@ -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 diff --git a/core/net/mac/contikimac.h b/core/net/mac/contikimac.h index 96f7ff86c..e32921624 100644 --- a/core/net/mac/contikimac.h +++ b/core/net/mac/contikimac.h @@ -33,13 +33,13 @@ /** * \file - * The Contiki power-saving MAC protocol (ContikiMAC) + * Header file for the ContikiMAC radio duty cycling protocol * \author * Adam Dunkels */ -#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 */ diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index 9bf349a4c..f5aac383a 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -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 */ diff --git a/core/net/simple-udp.c b/core/net/simple-udp.c new file mode 100644 index 000000000..97a39c89b --- /dev/null +++ b/core/net/simple-udp.c @@ -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 + * + */ + +#include "contiki-net.h" +#include "net/simple-udp.h" + +#include + + +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(); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/net/simple-udp.h b/core/net/simple-udp.h new file mode 100644 index 000000000..8579dc497 --- /dev/null +++ b/core/net/simple-udp.h @@ -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 + * + */ + +#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 */ + +/** @} */ +/** @} */ diff --git a/core/net/uip-udp-packet.c b/core/net/uip-udp-packet.c index 0731dbf1e..3ef0fb30e 100644 --- a/core/net/uip-udp-packet.c +++ b/core/net/uip-udp-packet.c @@ -46,23 +46,25 @@ extern u16_t uip_slen; #include - /*---------------------------------------------------------------------------*/ 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; + } } /*---------------------------------------------------------------------------*/ diff --git a/core/net/uip6.c b/core/net/uip6.c index 5e7cdc6d9..7a054dcc4 100644 --- a/core/net/uip6.c +++ b/core/net/uip6.c @@ -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, diff --git a/cpu/avr/Makefile.avr b/cpu/avr/Makefile.avr index 623879372..8a94b9eb0 100644 --- a/cpu/avr/Makefile.avr +++ b/cpu/avr/Makefile.avr @@ -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 \ diff --git a/cpu/avr/dev/clock.c b/cpu/avr/dev/clock.c index e433eefcf..b71c8660e 100644 --- a/cpu/avr/dev/clock.c +++ b/cpu/avr/dev/clock.c @@ -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 \ No newline at end of file +#endif diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index 3164b1099..0ac1f91d8 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -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<t) { *CRM_RTC_TIMEOUT = 1; } else { *CRM_RTC_TIMEOUT = t - now; } +#endif clear_rtc_wu_evt(); enable_rtc_wu(); diff --git a/cpu/mc1322x/rtimer-arch.h b/cpu/mc1322x/rtimer-arch.h index 80065e953..3b4e932de 100644 --- a/cpu/mc1322x/rtimer-arch.h +++ b/cpu/mc1322x/rtimer-arch.h @@ -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) diff --git a/examples/ipv6/rpl-border-router/Makefile b/examples/ipv6/rpl-border-router/Makefile index 480e70b97..dbc8abbb1 100644 --- a/examples/ipv6/rpl-border-router/Makefile +++ b/examples/ipv6/rpl-border-router/Makefile @@ -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 diff --git a/examples/ipv6/rpl-border-router/httpd-simple.h b/examples/ipv6/rpl-border-router/httpd-simple.h index 5fda299e8..4a2efa30f 100644 --- a/examples/ipv6/rpl-border-router/httpd-simple.h +++ b/examples/ipv6/rpl-border-router/httpd-simple.h @@ -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; diff --git a/examples/ipv6/simple-udp-rpl/Makefile b/examples/ipv6/simple-udp-rpl/Makefile new file mode 100644 index 000000000..5721b46aa --- /dev/null +++ b/examples/ipv6/simple-udp-rpl/Makefile @@ -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 diff --git a/examples/ipv6/simple-udp-rpl/broadcast-example.c b/examples/ipv6/simple-udp-rpl/broadcast-example.c new file mode 100644 index 000000000..b394a8e3d --- /dev/null +++ b/examples/ipv6/simple-udp-rpl/broadcast-example.c @@ -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 +#include + +#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(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/simple-udp-rpl/broadcast-example.csc b/examples/ipv6/simple-udp-rpl/broadcast-example.csc new file mode 100644 index 000000000..9332ae032 --- /dev/null +++ b/examples/ipv6/simple-udp-rpl/broadcast-example.csc @@ -0,0 +1,248 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/nes/papers/smartip-paper/code/cooja_qr + + Simple UDP broadcast example + 0 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + sky1 + Broadcast example + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.c + make broadcast-example.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/broadcast-example.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 64.1956818968534 + 28.591062627059372 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 51.81261061627534 + 24.647047255346667 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 9.068527629624546 + 46.26817786392282 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 87.5626508274206 + 4.896101751816129 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 55.15853460164762 + 3.4681662067903796 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 99.33682438963966 + 49.73072195748186 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 61.26294736288044 + 61.845254356789646 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 70.4693668755668 + 52.43101713632271 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 33.5789440978246 + 48.10557568631877 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 62.6079314243491 + 76.96581640898913 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + se.sics.cooja.plugins.SimControl + 318 + 3 + 192 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.GridVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + 2.9205864417411154 0.0 0.0 2.9205864417411154 -13.303600659817928 3.5428004585568913 + + 300 + 2 + 300 + 1122 + 0 + + + se.sics.cooja.plugins.LogListener + + + + 1422 + 0 + 236 + -1 + 302 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + + 125 + 500.0 + + 1422 + 1 + 190 + 0 + 539 + + + diff --git a/examples/ipv6/simple-udp-rpl/unicast-example.csc b/examples/ipv6/simple-udp-rpl/unicast-example.csc new file mode 100644 index 000000000..b48690e71 --- /dev/null +++ b/examples/ipv6/simple-udp-rpl/unicast-example.csc @@ -0,0 +1,287 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/native_gateway + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + /home/user/contikiprojects/sics.se/mobility + [CONTIKI_DIR]/tools/cooja/apps/collect-view + /home/user/nes/papers/smartip-paper/code/cooja_qr + + Simple UDP unicast example + 0 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + sky1 + UDP receiver + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.c + make unicast-receiver.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-receiver.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + sky2 + UDP sender + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.c + make unicast-sender.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/simple-udp-rpl/unicast-sender.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 82.45117687053667 + 90.0660093026363 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 44.53120632368774 + 89.83566130147413 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 91.76407203945963 + 8.764533976596468 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 10.771554112657956 + 16.155558894723033 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 4 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 40.99108749529099 + 33.68910640819968 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 5 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 49.762281669516085 + 15.219756237459913 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 6 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 26.209078576184762 + 97.71885344901867 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 7 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 96.30596045236783 + 3.353548431613529 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 8 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 52.22023117695779 + 56.516553603970586 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 9 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 57.92282771739404 + 34.17317501704098 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 10 + + sky2 + + + + + se.sics.cooja.interfaces.Position + 3.8628214275088335 + 52.90298303308778 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 11 + + sky2 + + + + se.sics.cooja.plugins.SimControl + 318 + 3 + 192 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.GridVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + 2.3409990660057263 0.0 0.0 2.3409990660057263 27.752487588138713 2.6948007992423 + + 300 + 2 + 300 + 1122 + 0 + + + se.sics.cooja.plugins.LogListener + + + + 1422 + 1 + 239 + 0 + 293 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + 125 + 500.0 + + 1422 + 0 + 198 + 0 + 531 + + + diff --git a/examples/ipv6/simple-udp-rpl/unicast-receiver.c b/examples/ipv6/simple-udp-rpl/unicast-receiver.c new file mode 100644 index 000000000..69ba6f943 --- /dev/null +++ b/examples/ipv6/simple-udp-rpl/unicast-receiver.c @@ -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 +#include + +#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(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/simple-udp-rpl/unicast-sender.c b/examples/ipv6/simple-udp-rpl/unicast-sender.c new file mode 100644 index 000000000..c984b12d5 --- /dev/null +++ b/examples/ipv6/simple-udp-rpl/unicast-sender.c @@ -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 +#include + +#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(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/servreg-hack/example-servreg-server.c b/examples/servreg-hack/example-servreg-server.c index 293263270..5a6f7686d 100644 --- a/examples/servreg-hack/example-servreg-server.c +++ b/examples/servreg-hack/example-servreg-server.c @@ -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(); } diff --git a/examples/webserver-ipv6-raven/Makefile b/examples/webserver-ipv6-raven/Makefile index a9b6f3e6b..a61e71506 100644 --- a/examples/webserver-ipv6-raven/Makefile +++ b/examples/webserver-ipv6-raven/Makefile @@ -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 \ No newline at end of file diff --git a/examples/webserver-ipv6-raven/Makefile.webserver b/examples/webserver-ipv6-raven/Makefile.webserver index 3faa39b7a..fb7f12964 100644 --- a/examples/webserver-ipv6-raven/Makefile.webserver +++ b/examples/webserver-ipv6-raven/Makefile.webserver @@ -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 diff --git a/examples/webserver-ipv6-raven/README b/examples/webserver-ipv6-raven/README index ad7d725fd..50d5887d6 100644 --- a/examples/webserver-ipv6-raven/README +++ b/examples/webserver-ipv6-raven/README @@ -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. + diff --git a/examples/webserver-ipv6/Makefile b/examples/webserver-ipv6/Makefile index 549656638..c87a5e85b 100644 --- a/examples/webserver-ipv6/Makefile +++ b/examples/webserver-ipv6/Makefile @@ -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 diff --git a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 index d845dd61f..46b03bf28 100644 --- a/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 +++ b/platform/avr-atmega128rfa1/Makefile.avr-atmega128rfa1 @@ -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 diff --git a/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c b/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c index 5f85f0ca8..0ce1e9c6a 100644 --- a/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c +++ b/platform/avr-atmega128rfa1/apps/raven-lcd-interface/raven-lcd.c @@ -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< -/* 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"; diff --git a/platform/avr-atmega128rfa1/apps/raven-webserver/httpd-fsdata.c b/platform/avr-atmega128rfa1/apps/raven-webserver/httpd-fsdata.c index 47b714f6b..4480bb838 100644 --- a/platform/avr-atmega128rfa1/apps/raven-webserver/httpd-fsdata.c +++ b/platform/avr-atmega128rfa1/apps/raven-webserver/httpd-fsdata.c @@ -2,10 +2,15 @@ #include -/* 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 */ diff --git a/platform/avr-atmega128rfa1/apps/raven-webserver/httpd.c b/platform/avr-atmega128rfa1/apps/raven-webserver/httpd.c index 17a1032ff..af2f1cd35 100644 --- a/platform/avr-atmega128rfa1/apps/raven-webserver/httpd.c +++ b/platform/avr-atmega128rfa1/apps/raven-webserver/httpd.c @@ -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< -#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 +#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< //#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); //
@@ -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<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<"); - PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + if (j) PRINTF(" "); + 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(" "); - PRINTA("\n---------\n"); + if (j) PRINTF(" "); + 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; -} \ No newline at end of file +} + +/*---------------------------------------------------------------------------*/ + +void log_message(char *m1, char *m2) +{ + PRINTF("%s%s\n", m1, m2); +} diff --git a/platform/avr-atmega128rfa1/params.c b/platform/avr-atmega128rfa1/params.c new file mode 100644 index 000000000..480ee3ee5 --- /dev/null +++ b/platform/avr-atmega128rfa1/params.c @@ -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 +#include +#include +#include + +#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 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;iSet 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 */ diff --git a/platform/avr-atmega128rfa1/params.h b/platform/avr-atmega128rfa1/params.h new file mode 100644 index 000000000..7a5e8aaae --- /dev/null +++ b/platform/avr-atmega128rfa1/params.h @@ -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__ */ diff --git a/platform/avr-atmega128rfa1/slip_uart0.c b/platform/avr-atmega128rfa1/slip_uart0.c index bf36616ad..edff55385 100644 --- a/platform/avr-atmega128rfa1/slip_uart0.c +++ b/platform/avr-atmega128rfa1/slip_uart0.c @@ -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; } /*---------------------------------------------------------------------------*/ diff --git a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c index dafc52a9b..635ed9a73 100644 --- a/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c +++ b/platform/avr-raven/apps/raven-lcd-interface/raven-lcd.c @@ -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 diff --git a/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h b/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h index 612ebf949..b146f8dc6 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h +++ b/platform/avr-raven/apps/raven-webserver/httpd-fs/makefsdata.h @@ -1,7 +1,10 @@ #include /* 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"; diff --git a/platform/avr-raven/contiki-conf.h b/platform/avr-raven/contiki-conf.h index b9e72fedb..9213758a9 100644 --- a/platform/avr-raven/contiki-conf.h +++ b/platform/avr-raven/contiki-conf.h @@ -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 diff --git a/platform/avr-raven/contiki-raven-main.c b/platform/avr-raven/contiki-raven-main.c index ff0865934..3a362be4e 100644 --- a/platform/avr-raven/contiki-raven-main.c +++ b/platform/avr-raven/contiki-raven-main.c @@ -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 @@ -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 +#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< 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;i26)) { + 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< //#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); //
@@ -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>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;iu8[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 diff --git a/platform/avr-raven/node-id.h b/platform/avr-raven/node-id.h new file mode 100644 index 000000000..6c3a2d9c7 --- /dev/null +++ b/platform/avr-raven/node-id.h @@ -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 + * + */ + +#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 */ diff --git a/platform/avr-ravenusb/contiki-conf.h b/platform/avr-ravenusb/contiki-conf.h index 9986e2adc..0e7911a24 100644 --- a/platform/avr-ravenusb/contiki-conf.h +++ b/platform/avr-ravenusb/contiki-conf.h @@ -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 diff --git a/platform/avr-ravenusb/contiki-raven-main.c b/platform/avr-ravenusb/contiki-raven-main.c index edd3b7b71..59595170e 100644 --- a/platform/avr-ravenusb/contiki-raven-main.c +++ b/platform/avr-ravenusb/contiki-raven-main.c @@ -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 diff --git a/platform/minimal-net/clock.c b/platform/minimal-net/clock.c index ce2be44c8..88188d76b 100644 --- a/platform/minimal-net/clock.c +++ b/platform/minimal-net/clock.c @@ -39,6 +39,7 @@ */ #include "sys/clock.h" +#include #include static long startsecs=0,startmsecs=0; diff --git a/platform/redbee-dev/contiki-conf.h b/platform/redbee-dev/contiki-conf.h index cce8dae22..ab1271823 100644 --- a/platform/redbee-dev/contiki-conf.h +++ b/platform/redbee-dev/contiki-conf.h @@ -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 */ diff --git a/platform/redbee-econotag/contiki-conf.h b/platform/redbee-econotag/contiki-conf.h index 44b321ed9..0f7f91a48 100644 --- a/platform/redbee-econotag/contiki-conf.h +++ b/platform/redbee-econotag/contiki-conf.h @@ -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 */ diff --git a/platform/redbee-econotag/contiki-mc1322x-main.c b/platform/redbee-econotag/contiki-mc1322x-main.c index 313ff70e2..33deca6c6 100644 --- a/platform/redbee-econotag/contiki-mc1322x-main.c +++ b/platform/redbee-econotag/contiki-mc1322x-main.c @@ -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 @@ -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"); + 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(" "); + 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 +char *ptr=malloc(1); //allocates 16 bytes from the heap +printf("********Got pointer %x\n",ptr); +#endif +} +#endif + + } +#endif /* PERIODICPRINTS */ } return 0; diff --git a/platform/sky/contiki-conf.h b/platform/sky/contiki-conf.h index f87d10ae6..7a4ecbc8c 100644 --- a/platform/sky/contiki-conf.h +++ b/platform/sky/contiki-conf.h @@ -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 diff --git a/platform/z1/contiki-conf.h b/platform/z1/contiki-conf.h index 9753b54c0..f3c6240b3 100644 --- a/platform/z1/contiki-conf.h +++ b/platform/z1/contiki-conf.h @@ -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 diff --git a/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java b/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java index d34655c9f..8b26ee4fc 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java +++ b/tools/cooja/java/se/sics/cooja/plugins/RadioLogger.java @@ -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 lowpanAnalyzers = new ArrayList(); lowpanAnalyzers.add(new IEEE802154Analyzer(false)); lowpanAnalyzers.add(new IPHCPacketAnalyzer()); + lowpanAnalyzers.add(new IPv6PacketAnalyzer()); lowpanAnalyzers.add(new ICMPv6Analyzer()); ArrayList lowpanAnalyzersPcap = new ArrayList(); lowpanAnalyzersPcap.add(new IEEE802154Analyzer(true)); lowpanAnalyzersPcap.add(new IPHCPacketAnalyzer()); + lowpanAnalyzersPcap.add(new IPv6PacketAnalyzer()); lowpanAnalyzersPcap.add(new ICMPv6Analyzer()); model = new AbstractTableModel() { diff --git a/tools/cooja/java/se/sics/cooja/plugins/analyzers/IPv6PacketAnalyzer.java b/tools/cooja/java/se/sics/cooja/plugins/analyzers/IPv6PacketAnalyzer.java new file mode 100644 index 000000000..3fee2ae94 --- /dev/null +++ b/tools/cooja/java/se/sics/cooja/plugins/analyzers/IPv6PacketAnalyzer.java @@ -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("IPv6
"); + + 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("
IPv6 ").append(protoStr).append(" TC = " + trafficClass + + " FL: " + flowLabel + "
"); + 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(":"); + } + } + } + + +} diff --git a/tools/release-tools/Makefile b/tools/release-tools/Makefile index 35c369a87..f89f5e175 100644 --- a/tools/release-tools/Makefile +++ b/tools/release-tools/Makefile @@ -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 diff --git a/tools/release-tools/compile-examples/Makefile b/tools/release-tools/compile-examples/Makefile index 6180aeb31..b19807e1a 100644 --- a/tools/release-tools/compile-examples/Makefile +++ b/tools/release-tools/compile-examples/Makefile @@ -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 diff --git a/tools/release-tools/compile-platforms/Makefile b/tools/release-tools/compile-platforms/Makefile index 459489a32..cd522110f 100644 --- a/tools/release-tools/compile-platforms/Makefile +++ b/tools/release-tools/compile-platforms/Makefile @@ -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]* diff --git a/tools/serial-log.pl b/tools/serial-log.pl new file mode 100644 index 000000000..81b49a515 --- /dev/null +++ b/tools/serial-log.pl @@ -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 + $_ = ;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; diff --git a/tools/stm32w/wpcapslip6/wpcapslip6.c b/tools/stm32w/wpcapslip6/wpcapslip6.c index 386bee483..5d4f5d3cf 100755 --- a/tools/stm32w/wpcapslip6/wpcapslip6.c +++ b/tools/stm32w/wpcapslip6/wpcapslip6.c @@ -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 %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");