diff --git a/core/net/psock.c b/core/net/psock.c index be4973b8a..458e29b6b 100644 --- a/core/net/psock.c +++ b/core/net/psock.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: psock.c,v 1.9 2009/07/23 16:13:48 dak664 Exp $ + * $Id: psock.c,v 1.10 2010/03/24 21:03:32 adamdunkels Exp $ */ #include @@ -296,16 +296,15 @@ PT_THREAD(psock_readbuf(CC_REGISTER_ARG struct psock *psock)) /* XXX: Should add buf_checkmarker() before do{} loop, if incoming data has been handled while waiting for a write. */ - do { - if(psock->readlen == 0) { - PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); - psock->state = STATE_READ; - psock->readptr = (u8_t *)uip_appdata; - psock->readlen = uip_datalen(); - } - } while(buf_bufdata(&psock->buf, psock->bufsize, - &psock->readptr, - &psock->readlen) != BUF_FULL); + if(psock->readlen == 0) { + PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); + psock->state = STATE_READ; + psock->readptr = (u8_t *)uip_appdata; + psock->readlen = uip_datalen(); + } + buf_bufdata(&psock->buf, psock->bufsize, + &psock->readptr, + &psock->readlen); if(psock_datalen(psock) == 0) { psock->state = STATE_NONE; @@ -327,3 +326,54 @@ psock_init(CC_REGISTER_ARG struct psock *psock, PT_INIT(&psock->psockpt); } /*---------------------------------------------------------------------------*/ +static char +copy_to_buf(char **buffer, uint16_t *bufsize, const char **str) +{ + uint16_t len = strlen(*str); + uint16_t copysize = len; + + if(len > *bufsize) { + copysize = *bufsize; + } + + memcpy(*buffer, *str, copysize); + *bufsize -= copysize; + *buffer += copysize; + *str += copysize; + + return (*bufsize != 0); +} +/*---------------------------------------------------------------------------*/ +void +psock_buffered_string_send_begin(CC_REGISTER_ARG struct psock *s) +{ + s->state = STATE_NONE; + s->sendlen = uip_mss(); /* used as buf size */ + s->sendptr = uip_appdata; +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_buffered_string_send(CC_REGISTER_ARG struct psock *s, + const char **string, char push)) +{ + PT_BEGIN(&s->psockpt); + + do { + static char bufnotfull; + + s->state = STATE_NONE; + bufnotfull = copy_to_buf(&(s->sendptr), &(s->sendlen), string); + + if(!bufnotfull || push) { + + s->sendptr = uip_appdata; + s->sendlen = uip_mss() - (s->sendlen); + + PT_WAIT_UNTIL(&s->psockpt, data_is_sent_and_acked(s)); + + psock_buffered_string_send_begin(s); + } + } while(**string); + + PT_END(&s->psockpt); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/psock.h b/core/net/psock.h index 94dfb89f9..7d22de1df 100644 --- a/core/net/psock.h +++ b/core/net/psock.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: psock.h,v 1.6 2009/05/06 15:07:09 adamdunkels Exp $ + * $Id: psock.h,v 1.7 2010/03/24 21:03:32 adamdunkels Exp $ */ /** @@ -382,6 +382,13 @@ char psock_newdata(struct psock *s); #define PSOCK_WAIT_THREAD(psock, condition) \ PT_WAIT_THREAD(&((psock)->pt), (condition)) +void psock_buffered_string_send_begin(struct psock *s); +PT_THREAD(psock_buffered_string_send(struct psock *s, const char **string, char push)); + +#define PSOCK_BUFFERED_STRING_SEND(psock, str, push) \ + PT_WAIT_THREAD(&((psock)->pt), \ + psock_buffered_string_send(psock, str, push)) + #endif /* __PSOCK_H__ */ /** @} */