Added configurable delay between slip packets to avoid losing data

This commit is contained in:
Niclas Finne 2012-04-20 13:23:07 +02:00
parent 28c62208cb
commit 16bb9295f3
2 changed files with 62 additions and 28 deletions

View file

@ -42,6 +42,8 @@
#undef UIP_CONF_RECEIVE_WINDOW #undef UIP_CONF_RECEIVE_WINDOW
#define UIP_CONF_RECEIVE_WINDOW 60 #define UIP_CONF_RECEIVE_WINDOW 60
#define SLIP_DEV_CONF_SEND_DELAY (CLOCK_SECOND / 32)
#undef WEBSERVER_CONF_CFS_CONNS #undef WEBSERVER_CONF_CFS_CONNS
#define WEBSERVER_CONF_CFS_CONNS 2 #define WEBSERVER_CONF_CFS_CONNS 2

View file

@ -32,7 +32,6 @@
/* Below define allows importing saved output into Wireshark as "Raw IP" packet type */ /* Below define allows importing saved output into Wireshark as "Raw IP" packet type */
#define WIRESHARK_IMPORT_FORMAT 1 #define WIRESHARK_IMPORT_FORMAT 1
#include "contiki.h" #include "contiki.h"
#include "net/uip.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -65,6 +64,11 @@ extern const char *slip_config_port;
extern uint16_t slip_config_basedelay; extern uint16_t slip_config_basedelay;
extern speed_t slip_config_b_rate; extern speed_t slip_config_b_rate;
#ifdef SLIP_DEV_CONF_SEND_DELAY
#define SEND_DELAY SLIP_DEV_CONF_SEND_DELAY
#else
#define SEND_DELAY 0
#endif
int devopen(const char *dev, int flags); int devopen(const char *dev, int flags);
@ -76,7 +80,6 @@ long slip_received = 0;
int slipfd = 0; int slipfd = 0;
void slip_send(int fd, unsigned char c);
//#define PROGRESS(s) fprintf(stderr, s) //#define PROGRESS(s) fprintf(stderr, s)
#define PROGRESS(s) do { } while(0) #define PROGRESS(s) do { } while(0)
@ -173,9 +176,7 @@ slip_packet_input(unsigned char *data, int len)
void void
serial_input(FILE *inslip) serial_input(FILE *inslip)
{ {
static union { unsigned char inbuf[2048];
unsigned char inbuf[2000];
} uip;
static int inbufptr = 0; static int inbufptr = 0;
int ret,i; int ret,i;
unsigned char c; unsigned char c;
@ -187,7 +188,7 @@ serial_input(FILE *inslip)
#endif #endif
read_more: read_more:
if(inbufptr >= sizeof(uip.inbuf)) { if(inbufptr >= sizeof(inbuf)) {
fprintf(stderr, "*** dropping large %d byte packet\n", inbufptr); fprintf(stderr, "*** dropping large %d byte packet\n", inbufptr);
inbufptr = 0; inbufptr = 0;
} }
@ -206,16 +207,16 @@ serial_input(FILE *inslip)
switch(c) { switch(c) {
case SLIP_END: case SLIP_END:
if(inbufptr > 0) { if(inbufptr > 0) {
if(uip.inbuf[0] == '!') { if(inbuf[0] == '!') {
command_context = CMD_CONTEXT_RADIO; command_context = CMD_CONTEXT_RADIO;
cmd_input(uip.inbuf, inbufptr); cmd_input(inbuf, inbufptr);
} else if(uip.inbuf[0] == '?') { } else if(inbuf[0] == '?') {
#define DEBUG_LINE_MARKER '\r' #define DEBUG_LINE_MARKER '\r'
} else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { } else if(inbuf[0] == DEBUG_LINE_MARKER) {
fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout); fwrite(inbuf + 1, inbufptr - 1, 1, stdout);
} else if(is_sensible_string(uip.inbuf, inbufptr)) { } else if(is_sensible_string(inbuf, inbufptr)) {
if(slip_config_verbose == 1) { /* strings already echoed below for verbose>1 */ if(slip_config_verbose == 1) { /* strings already echoed below for verbose>1 */
fwrite(uip.inbuf, inbufptr, 1, stdout); fwrite(inbuf, inbufptr, 1, stdout);
} }
} else { } else {
if(slip_config_verbose > 2) { if(slip_config_verbose > 2) {
@ -223,11 +224,11 @@ serial_input(FILE *inslip)
if(slip_config_verbose > 4) { if(slip_config_verbose > 4) {
#if WIRESHARK_IMPORT_FORMAT #if WIRESHARK_IMPORT_FORMAT
printf("0000"); printf("0000");
for(i = 0; i < inbufptr; i++) printf(" %02x", uip.inbuf[i]); for(i = 0; i < inbufptr; i++) printf(" %02x", inbuf[i]);
#else #else
printf(" "); printf(" ");
for(i = 0; i < inbufptr; i++) { for(i = 0; i < inbufptr; i++) {
printf("%02x", uip.inbuf[i]); printf("%02x", inbuf[i]);
if((i & 3) == 3) printf(" "); if((i & 3) == 3) printf(" ");
if((i & 15) == 15) printf("\n "); if((i & 15) == 15) printf("\n ");
} }
@ -235,7 +236,7 @@ serial_input(FILE *inslip)
printf("\n"); printf("\n");
} }
} }
slip_packet_input(uip.inbuf, inbufptr); slip_packet_input(inbuf, inbufptr);
} }
inbufptr = 0; inbufptr = 0;
} }
@ -259,7 +260,7 @@ serial_input(FILE *inslip)
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
uip.inbuf[inbufptr++] = c; inbuf[inbufptr++] = c;
/* Echo lines as they are received for verbose=2,3,5+ */ /* Echo lines as they are received for verbose=2,3,5+ */
/* Echo all printable characters for verbose==4 */ /* Echo all printable characters for verbose==4 */
@ -268,8 +269,8 @@ serial_input(FILE *inslip)
fwrite(&c, 1, 1, stdout); fwrite(&c, 1, 1, stdout);
} }
} else if(slip_config_verbose >= 2) { } else if(slip_config_verbose >= 2) {
if(c == '\n' && is_sensible_string(uip.inbuf, inbufptr)) { if(c == '\n' && is_sensible_string(inbuf, inbufptr)) {
fwrite(uip.inbuf, inbufptr, 1, stdout); fwrite(inbuf, inbufptr, 1, stdout);
inbufptr = 0; inbufptr = 0;
} }
} }
@ -279,10 +280,13 @@ serial_input(FILE *inslip)
goto read_more; goto read_more;
} }
unsigned char slip_buf[2000]; unsigned char slip_buf[2048];
int slip_end, slip_begin; int slip_end, slip_begin, slip_packet_end, slip_packet_count;
static struct timer send_delay_timer;
/* delay between slip packets */
static clock_time_t send_delay = SEND_DELAY;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void static void
slip_send(int fd, unsigned char c) slip_send(int fd, unsigned char c)
{ {
if(slip_end >= sizeof(slip_buf)) { if(slip_end >= sizeof(slip_buf)) {
@ -291,12 +295,19 @@ slip_send(int fd, unsigned char c)
slip_buf[slip_end] = c; slip_buf[slip_end] = c;
slip_end++; slip_end++;
slip_sent++; slip_sent++;
if(c == SLIP_END) {
/* Full packet received. */
slip_packet_count++;
if(slip_packet_end == 0) {
slip_packet_end = slip_end;
}
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
slip_empty() slip_empty()
{ {
return slip_end == 0; return slip_packet_end == 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
@ -308,16 +319,35 @@ slip_flushbuf(int fd)
return; return;
} }
n = write(fd, slip_buf + slip_begin, slip_end - slip_begin); n = write(fd, slip_buf + slip_begin, slip_packet_end - slip_begin);
if(n == -1 && errno != EAGAIN) { if(n == -1 && errno != EAGAIN) {
err(1, "slip_flushbuf write failed"); err(1, "slip_flushbuf write failed");
} else if(n == -1) { } else if(n == -1) {
PROGRESS("Q"); /* Outqueueis full! */ PROGRESS("Q"); /* Outqueue is full! */
} else { } else {
slip_begin += n; slip_begin += n;
if(slip_begin == slip_end) { if(slip_begin == slip_packet_end) {
slip_begin = slip_end = 0; slip_packet_count--;
if(slip_end > slip_packet_end) {
memcpy(slip_buf, slip_buf + slip_packet_end,
slip_end - slip_packet_end);
}
slip_end -= slip_packet_end;
slip_begin = slip_packet_end = 0;
if(slip_end > 0) {
/* Find end of next slip packet */
for(n = 1; n < slip_end; n++) {
if(slip_buf[n] == SLIP_END) {
slip_packet_end = n + 1;
break;
}
}
/* a delay between slip packets to avoid losing data */
if(send_delay > 0) {
timer_set(&send_delay_timer, send_delay);
}
}
} }
} }
} }
@ -432,7 +462,8 @@ stty_telos(int fd)
static int static int
set_fd(fd_set *rset, fd_set *wset) set_fd(fd_set *rset, fd_set *wset)
{ {
if(!slip_empty()) { /* Anything to flush? */ /* Anything to flush? */
if(!slip_empty() && (send_delay == 0 || timer_expired(&send_delay_timer))) {
FD_SET(slipfd, wset); FD_SET(slipfd, wset);
} }
@ -505,6 +536,7 @@ slip_init(void)
stty_telos(slipfd); stty_telos(slipfd);
} }
timer_set(&send_delay_timer, 0);
slip_send(slipfd, SLIP_END); slip_send(slipfd, SLIP_END);
inslip = fdopen(slipfd, "r"); inslip = fdopen(slipfd, "r");
if(inslip == NULL) { if(inslip == NULL) {