Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <stdio.h>
00037 #include <string.h>
00038
00039 #include "../proj/cli/debug.h"
00040
00041 #include "uipopt.h"
00042 #include "psock.h"
00043 #include "uip.h"
00044
00045 #define STATE_NONE 0
00046 #define STATE_ACKED 1
00047 #define STATE_READ 2
00048 #define STATE_BLOCKED_NEWDATA 3
00049 #define STATE_BLOCKED_CLOSE 4
00050 #define STATE_BLOCKED_SEND 5
00051 #define STATE_DATA_SENT 6
00052
00053
00054
00055
00056
00057
00058 #define BUF_NOT_FULL 0
00059 #define BUF_NOT_FOUND 0
00060
00061
00062
00063
00064
00065
00066 #define BUF_FULL 1
00067
00068
00069
00070
00071
00072
00073 #define BUF_FOUND 2
00074
00075
00076 static void
00077 buf_setup(struct psock_buf *buf,
00078 u8_t *bufptr, u16_t bufsize)
00079 {
00080 buf->ptr = bufptr;
00081 buf->left = bufsize;
00082 }
00083
00084 static u8_t
00085 buf_bufdata(struct psock_buf *buf, u16_t len,
00086 u8_t **dataptr, u16_t *datalen)
00087 {
00088 ( void ) len;
00089 if(*datalen < buf->left) {
00090 memcpy(buf->ptr, *dataptr, *datalen);
00091 buf->ptr += *datalen;
00092 buf->left -= *datalen;
00093 *dataptr += *datalen;
00094 *datalen = 0;
00095 return BUF_NOT_FULL;
00096 } else if(*datalen == buf->left) {
00097 memcpy(buf->ptr, *dataptr, *datalen);
00098 buf->ptr += *datalen;
00099 buf->left = 0;
00100 *dataptr += *datalen;
00101 *datalen = 0;
00102 return BUF_FULL;
00103 } else {
00104 memcpy(buf->ptr, *dataptr, buf->left);
00105 buf->ptr += buf->left;
00106 *datalen -= buf->left;
00107 *dataptr += buf->left;
00108 buf->left = 0;
00109 return BUF_FULL;
00110 }
00111 }
00112
00113 static u8_t
00114 buf_bufto(register struct psock_buf *buf, u8_t endmarker,
00115 register u8_t **dataptr, register u16_t *datalen)
00116 {
00117 u8_t c;
00118 while(buf->left > 0 && *datalen > 0) {
00119 c = *buf->ptr = **dataptr;
00120 ++*dataptr;
00121 ++buf->ptr;
00122 --*datalen;
00123 --buf->left;
00124
00125 if(c == endmarker) {
00126 return BUF_FOUND;
00127 }
00128 }
00129
00130 if(*datalen == 0) {
00131 return BUF_NOT_FOUND;
00132 }
00133
00134 while(*datalen > 0) {
00135 c = **dataptr;
00136 --*datalen;
00137 ++*dataptr;
00138
00139 if(c == endmarker) {
00140 return BUF_FOUND | BUF_FULL;
00141 }
00142 }
00143
00144 return BUF_FULL;
00145 }
00146
00147 static char
00148 send_data(register struct psock *s)
00149 {
00150 if(s->state != STATE_DATA_SENT || uip_rexmit()) {
00151 if(s->sendlen > uip_mss()) {
00152 uip_send(s->sendptr, uip_mss());
00153 } else {
00154 uip_send(s->sendptr, s->sendlen);
00155 }
00156 s->state = STATE_DATA_SENT;
00157 return 1;
00158 }
00159 return 0;
00160 }
00161
00162 static char
00163 data_acked(register struct psock *s)
00164 {
00165 if(s->state == STATE_DATA_SENT && uip_acked()) {
00166 if(s->sendlen > uip_mss()) {
00167 s->sendlen -= uip_mss();
00168 s->sendptr += uip_mss();
00169 } else {
00170 s->sendptr += s->sendlen;
00171 s->sendlen = 0;
00172 }
00173 s->state = STATE_ACKED;
00174 return 1;
00175 }
00176 return 0;
00177 }
00178
00179 PT_THREAD(psock_send(register struct psock *s, const char *buf,
00180 unsigned int len))
00181 {
00182
00183 PT_BEGIN(&s->psockpt);
00184
00185
00186 if(len == 0) {
00187 PT_EXIT(&s->psockpt);
00188 }
00189
00190
00191
00192 s->sendptr = (unsigned char*)buf;
00193 s->sendlen = len;
00194
00195 s->state = STATE_NONE;
00196
00197
00198
00199
00200 while(s->sendlen > 0) {
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
00213 }
00214
00215 s->state = STATE_NONE;
00216
00217 PT_END(&s->psockpt);
00218
00219
00220 }
00221
00222 PT_THREAD(psock_generator_send(register struct psock *s,
00223 unsigned short (*generate)(void *), void *arg))
00224 {
00225 PT_BEGIN(&s->psockpt);
00226
00227
00228 if(generate == NULL) {
00229 PT_EXIT(&s->psockpt);
00230 }
00231
00232
00233
00234 s->sendlen = generate(arg);
00235 s->sendptr = uip_appdata;
00236
00237 s->state = STATE_NONE;
00238 do {
00239
00240
00241 if(uip_rexmit()) {
00242 generate(arg);
00243 }
00244
00245 PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
00246 } while(s->sendlen > 0);
00247
00248 s->state = STATE_NONE;
00249
00250 PT_END(&s->psockpt);
00251 }
00252
00253 u16_t
00254 psock_datalen(struct psock *psock)
00255 {
00256 return psock->bufsize - psock->buf.left;
00257 }
00258
00259 char
00260 psock_newdata(struct psock *s)
00261 {
00262 if(s->readlen > 0) {
00263
00264
00265 return 1;
00266 } else if(s->state == STATE_READ) {
00267
00268 s->state = STATE_BLOCKED_NEWDATA;
00269 return 0;
00270 } else if(uip_newdata()) {
00271
00272 return 1;
00273 } else {
00274
00275 return 0;
00276 }
00277 }
00278
00279 PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
00280 {
00281 PT_BEGIN(&psock->psockpt);
00282
00283 buf_setup(&psock->buf, (unsigned char*)psock->bufptr, psock->bufsize);
00284
00285
00286
00287
00288 do {
00289 if(psock->readlen == 0) {
00290 PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
00291 psock->state = STATE_READ;
00292 psock->readptr = (u8_t *)uip_appdata;
00293 psock->readlen = uip_datalen();
00294 }
00295 } while((buf_bufto(&psock->buf, c,
00296 &psock->readptr,
00297 &psock->readlen) & BUF_FOUND) == 0);
00298
00299 if(psock_datalen(psock) == 0) {
00300 psock->state = STATE_NONE;
00301 PT_RESTART(&psock->psockpt);
00302 }
00303 PT_END(&psock->psockpt);
00304 }
00305
00306 PT_THREAD(psock_readbuf(register struct psock *psock))
00307 {
00308 PT_BEGIN(&psock->psockpt);
00309
00310 buf_setup(&psock->buf, (unsigned char * ) psock->bufptr, psock->bufsize);
00311
00312
00313
00314
00315 do {
00316 if(psock->readlen == 0) {
00317 PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
00318 printf("Waited for newdata\n");
00319 psock->state = STATE_READ;
00320 psock->readptr = (u8_t *)uip_appdata;
00321 psock->readlen = uip_datalen();
00322 }
00323 } while(buf_bufdata(&psock->buf, psock->bufsize,
00324 &psock->readptr,
00325 &psock->readlen) != BUF_FULL);
00326
00327 if(psock_datalen(psock) == 0) {
00328 psock->state = STATE_NONE;
00329 PT_RESTART(&psock->psockpt);
00330 }
00331 PT_END(&psock->psockpt);
00332 }
00333
00334 void
00335 psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
00336 {
00337 psock->state = STATE_NONE;
00338 psock->readlen = 0;
00339 psock->bufptr = buffer;
00340 psock->bufsize = buffersize;
00341 buf_setup(&psock->buf, (unsigned char*) buffer, buffersize);
00342 PT_INIT(&psock->pt);
00343 PT_INIT(&psock->psockpt);
00344 }
00345