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