72 #include "contiki-net.h"
74 #include "codeprop-otf.h"
78 static const char *err_msgs[] =
79 {
"OK\r\n",
"Bad ELF header\r\n",
"No symtab\r\n",
"No strtab\r\n",
80 "No text\r\n",
"Symbol not found\r\n",
"Segment not found\r\n",
81 "No startpoint\r\n",
"Unhandled relocation\r\n",
82 "Relocation out of range\r\n",
"Relocations not sorted\r\n",
83 "Input error\r\n" ,
"Ouput error\r\n" };
85 #define CODEPROP_DATA_PORT 6510
90 #define PRINTF(x) printf x
95 #define START_TIMEOUT 12 * CLOCK_SECOND
96 #define MISS_NACK_TIMEOUT (CLOCK_SECOND / 8) * (random_rand() % 8)
97 #define HIT_NACK_TIMEOUT (CLOCK_SECOND / 8) * (8 + random_rand() % 16)
98 #define NACK_REXMIT_TIMEOUT CLOCK_SECOND * (4 + random_rand() % 4)
100 #define WAITING_TIME CLOCK_SECOND * 10
102 #define NUM_SEND_DUPLICATES 2
104 #define UDPHEADERSIZE 8
105 #define UDPDATASIZE 32
107 struct codeprop_udphdr {
110 #define TYPE_DATA 0x0001
111 #define TYPE_NACK 0x0002
114 uint8_t data[UDPDATASIZE];
117 struct codeprop_tcphdr {
122 static void uipcall(
void *state);
124 PROCESS(codeprop_process,
"Code propagator");
126 struct codeprop_state {
129 #define STATE_RECEIVING_TCPDATA 1
130 #define STATE_RECEIVING_UDPDATA 2
131 #define STATE_SENDING_UDPDATA 3
139 uint8_t send_counter;
140 struct pt tcpthread_pt;
141 struct pt udpthread_pt;
142 struct pt recv_udpthread_pt;
149 static struct codeprop_state s;
151 void system_log(
char *msg);
153 static clock_time_t send_time;
155 #define CONNECTION_TIMEOUT (30 * CLOCK_SECOND)
159 codeprop_set_rate(clock_time_t time)
181 s.state = STATE_NONE;
194 }
else if(ev == PROCESS_EVENT_TIMER) {
203 send_udpdata(
struct codeprop_udphdr *uh)
211 if(s.len - s.addr > UDPDATASIZE) {
214 len = s.len - s.addr;
218 cfs_read(fd, (
char*)&uh->data[0], len);
224 PRINTF((
"codeprop: sending packet from address 0x%04x\n", s.addr));
234 struct codeprop_udphdr *uh = (
struct codeprop_udphdr *)
uip_appdata;
242 for(s.addr = 0; s.addr < s.len; ) {
243 len = send_udpdata(uh);
252 PRINTF((
"send_udpthread: got NACK for address 0x%x (now 0x%x)\n",
265 s.state = STATE_NONE;
273 send_nack(
struct codeprop_udphdr *uh,
unsigned short addr)
284 struct codeprop_udphdr *uh = (
struct codeprop_udphdr *)
uip_appdata;
316 while(s.addr < s.len) {
325 cfs_write(fd, (
char*)&uh->data[0], len);
328 PRINTF((
"Saved %d bytes at address %d, %d bytes left\n",
335 }
else if(
uip_htons(uh->addr) > s.addr) {
336 PRINTF((
"sending nack since 0x%x != 0x%x\n",
uip_htons(uh->addr), s.addr));
337 send_nack(uh, s.addr);
345 timer_set(&s.nacktimer, HIT_NACK_TIMEOUT);
351 send_nack(uh, s.addr);
361 codeprop_start_program();
369 #define CODEPROP_TCPHDR_SIZE sizeof(struct codeprop_tcphdr)
374 struct codeprop_tcphdr *th;
382 codeprop_exit_program();
384 s.state = STATE_RECEIVING_TCPDATA;
393 PRINTF((
"codeprop: header not found in first tcp segment\n"));
400 datalen -= CODEPROP_TCPHDR_SIZE;
408 PRINTF((
"codeprop: seek in buffer file failed\n"));
412 if (cfs_write(fd,
uip_appdata, datalen) != datalen) {
413 PRINTF((
"codeprop: write to buffer file failed\n"));
421 }
while(s.addr < s.len);
427 err = codeprop_start_program();
431 if (err >= 0 && err <
sizeof(err_msgs)/
sizeof(
char*)) {
432 uip_send(err_msgs[err], strlen(err_msgs[err]));
444 s.state = STATE_SENDING_UDPDATA;
455 codeprop_start_broadcast(
unsigned int len)
460 s.state = STATE_SENDING_UDPDATA;
465 codeprop_exit_program(
void)
473 codeprop_start_program(
void)
477 codeprop_exit_program();
481 PRINTF((
"codeprop: starting %s\n",
492 recv_udpthread(&s.recv_udpthread_pt);
493 send_udpthread(&s.udpthread_pt);
507 PRINTF((
"codeprop: uip_connected() and state != NULL\n"));
511 recv_tcpthread(&s.tcpthread_pt);
515 PRINTF((
"codeprop: connection down\n"));