I found a problem on retransmission when using the macro PSOCK_GENERATOR_SEND. Basically the problem happens because the generator function is just called once and uip_appdata buffer may be overwritten by another connection or even ping requests (that was how I found it).
On function psock_generator_send the "ping-pong" PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); does not leave until all data is transmitted but does not regenerate data on successive send_data(s) calls. My solution was changing the do loop from:
do {
/* Call the generator function again if we are called to perform a
retransmission. */
if(uip_rexmit()) {
generate(arg);
}
/* Wait until all data is sent and acknowledged. */
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
} while(s->sendlen > 0);
to:
do {
/* Wait until all data is sent and acknowledged. */
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data_gen(s, generate, arg));
} while(s->sendlen > 0);
where send_data_gen is:
static char
send_data_gen(register struct psock *s, unsigned short (*generate)(void *), void *arg)
{
if(s->state != STATE_DATA_SENT || uip_rexmit()) {
if ((s->state != STATE_NONE) && (s->sendlen > 0))
{
/* new data needs to be generated because uip_appdata may have changed
since last PTTHREAD block operation */
generate(arg);
}
if(s->sendlen > uip_mss()) {
uip_send(s->sendptr, uip_mss());
} else {
uip_send(s->sendptr, s->sendlen);
}
s->state = STATE_DATA_SENT;
return 1;
}
return 0;
}