73 #include "contiki-net.h"
75 #include "codeprop-otf.h"
79 static const char *err_msgs[] =
80 {
"OK\r\n",
"Bad ELF header\r\n",
"No symtab\r\n",
"No strtab\r\n",
81 "No text\r\n",
"Symbol not found\r\n",
"Segment not found\r\n",
82 "No startpoint\r\n",
"Unhandled relocation\r\n",
83 "Relocation out of range\r\n",
"Relocations not sorted\r\n",
84 "Input error\r\n" ,
"Ouput error\r\n" };
86 #define CODEPROP_DATA_PORT 6510
91 #define PRINTF(x) printf x
96 #define START_TIMEOUT 12 * CLOCK_SECOND
97 #define MISS_NACK_TIMEOUT (CLOCK_SECOND / 8) * (random_rand() % 8)
98 #define HIT_NACK_TIMEOUT (CLOCK_SECOND / 8) * (8 + random_rand() % 16)
99 #define NACK_REXMIT_TIMEOUT CLOCK_SECOND * (4 + random_rand() % 4)
101 #define WAITING_TIME CLOCK_SECOND * 10
103 #define NUM_SEND_DUPLICATES 2
105 #define UDPHEADERSIZE 8
106 #define UDPDATASIZE 32
108 struct codeprop_udphdr {
111 #define TYPE_DATA 0x0001
112 #define TYPE_NACK 0x0002
115 u8_t data[UDPDATASIZE];
118 struct codeprop_tcphdr {
123 static void uipcall(
void *state);
125 PROCESS(codeprop_process,
"Code propagator");
127 struct codeprop_state {
130 #define STATE_RECEIVING_TCPDATA 1
131 #define STATE_RECEIVING_UDPDATA 2
132 #define STATE_SENDING_UDPDATA 3
141 struct pt tcpthread_pt;
142 struct pt udpthread_pt;
143 struct pt recv_udpthread_pt;
150 static struct codeprop_state s;
152 void system_log(
char *msg);
154 static clock_time_t send_time;
156 #define CONNECTION_TIMEOUT (30 * CLOCK_SECOND)
160 codeprop_set_rate(clock_time_t time)
182 s.state = STATE_NONE;
195 }
else if(ev == PROCESS_EVENT_TIMER) {
204 send_udpdata(
struct codeprop_udphdr *uh)
212 if(s.len - s.addr > UDPDATASIZE) {
215 len = s.len - s.addr;
219 cfs_read(fd, (
char*)&uh->data[0], len);
225 PRINTF((
"codeprop: sending packet from address 0x%04x\n", s.addr));
235 struct codeprop_udphdr *uh = (
struct codeprop_udphdr *)
uip_appdata;
243 for(s.addr = 0; s.addr < s.len; ) {
244 len = send_udpdata(uh);
253 PRINTF((
"send_udpthread: got NACK for address 0x%x (now 0x%x)\n",
266 s.state = STATE_NONE;
274 send_nack(
struct codeprop_udphdr *uh,
unsigned short addr)
285 struct codeprop_udphdr *uh = (
struct codeprop_udphdr *)
uip_appdata;
317 while(s.addr < s.len) {
326 cfs_write(fd, (
char*)&uh->data[0], len);
329 PRINTF((
"Saved %d bytes at address %d, %d bytes left\n",
336 }
else if(
uip_htons(uh->addr) > s.addr) {
337 PRINTF((
"sending nack since 0x%x != 0x%x\n",
uip_htons(uh->addr), s.addr));
338 send_nack(uh, s.addr);
346 timer_set(&s.nacktimer, HIT_NACK_TIMEOUT);
352 send_nack(uh, s.addr);
362 codeprop_start_program();
370 #define CODEPROP_TCPHDR_SIZE sizeof(struct codeprop_tcphdr)
375 struct codeprop_tcphdr *th;
383 codeprop_exit_program();
385 s.state = STATE_RECEIVING_TCPDATA;
394 PRINTF((
"codeprop: header not found in first tcp segment\n"));
401 datalen -= CODEPROP_TCPHDR_SIZE;
409 PRINTF((
"codeprop: seek in buffer file failed\n"));
413 if (cfs_write(fd,
uip_appdata, datalen) != datalen) {
414 PRINTF((
"codeprop: write to buffer file failed\n"));
422 }
while(s.addr < s.len);
428 err = codeprop_start_program();
432 if (err >= 0 && err <
sizeof(err_msgs)/
sizeof(
char*)) {
433 uip_send(err_msgs[err], strlen(err_msgs[err]));
445 s.state = STATE_SENDING_UDPDATA;
456 codeprop_start_broadcast(
unsigned int len)
461 s.state = STATE_SENDING_UDPDATA;
466 codeprop_exit_program(
void)
474 codeprop_start_program(
void)
478 codeprop_exit_program();
482 PRINTF((
"codeprop: starting %s\n",
493 recv_udpthread(&s.recv_udpthread_pt);
494 send_udpthread(&s.udpthread_pt);
508 PRINTF((
"codeprop: uip_connected() and state != NULL\n"));
512 recv_tcpthread(&s.tcpthread_pt);
516 PRINTF((
"codeprop: connection down\n"));