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