ban4jp -
/
uIP-1-0_webserver
uIP 1.0 based webserver for LPC1114 + ENC28J60
Embed:
(wiki syntax)
Show/hide line numbers
psock.c
00001 /* 00002 * Copyright (c) 2004, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the uIP TCP/IP stack 00030 * 00031 * Author: Adam Dunkels <adam@sics.se> 00032 * 00033 * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $ 00034 */ 00035 00036 #include <string.h> 00037 00038 #include "uipopt.h" 00039 #include "psock.h" 00040 #include "uip.h" 00041 00042 #define STATE_NONE 0 00043 #define STATE_ACKED 1 00044 #define STATE_READ 2 00045 #define STATE_BLOCKED_NEWDATA 3 00046 #define STATE_BLOCKED_CLOSE 4 00047 #define STATE_BLOCKED_SEND 5 00048 #define STATE_DATA_SENT 6 00049 00050 /* 00051 * Return value of the buffering functions that indicates that a 00052 * buffer was not filled by incoming data. 00053 * 00054 */ 00055 #define BUF_NOT_FULL 0 00056 #define BUF_NOT_FOUND 0 00057 00058 /* 00059 * Return value of the buffering functions that indicates that a 00060 * buffer was completely filled by incoming data. 00061 * 00062 */ 00063 #define BUF_FULL 1 00064 00065 /* 00066 * Return value of the buffering functions that indicates that an 00067 * end-marker byte was found. 00068 * 00069 */ 00070 #define BUF_FOUND 2 00071 00072 /*---------------------------------------------------------------------------*/ 00073 static void 00074 buf_setup(struct psock_buf *buf, 00075 u8_t *bufptr, u16_t bufsize) 00076 { 00077 buf->ptr = bufptr; 00078 buf->left = bufsize; 00079 } 00080 /*---------------------------------------------------------------------------*/ 00081 static u8_t 00082 buf_bufdata(struct psock_buf *buf, u16_t len, 00083 u8_t **dataptr, u16_t *datalen) 00084 { 00085 if(*datalen < buf->left) { 00086 memcpy(buf->ptr, *dataptr, *datalen); 00087 buf->ptr += *datalen; 00088 buf->left -= *datalen; 00089 *dataptr += *datalen; 00090 *datalen = 0; 00091 return BUF_NOT_FULL; 00092 } else if(*datalen == buf->left) { 00093 memcpy(buf->ptr, *dataptr, *datalen); 00094 buf->ptr += *datalen; 00095 buf->left = 0; 00096 *dataptr += *datalen; 00097 *datalen = 0; 00098 return BUF_FULL; 00099 } else { 00100 memcpy(buf->ptr, *dataptr, buf->left); 00101 buf->ptr += buf->left; 00102 *datalen -= buf->left; 00103 *dataptr += buf->left; 00104 buf->left = 0; 00105 return BUF_FULL; 00106 } 00107 } 00108 /*---------------------------------------------------------------------------*/ 00109 static u8_t 00110 buf_bufto(register struct psock_buf *buf, u8_t endmarker, 00111 register u8_t **dataptr, register u16_t *datalen) 00112 { 00113 u8_t c; 00114 while(buf->left > 0 && *datalen > 0) { 00115 c = *buf->ptr = **dataptr; 00116 ++*dataptr; 00117 ++buf->ptr; 00118 --*datalen; 00119 --buf->left; 00120 00121 if(c == endmarker) { 00122 return BUF_FOUND; 00123 } 00124 } 00125 00126 if(*datalen == 0) { 00127 return BUF_NOT_FOUND; 00128 } 00129 00130 return BUF_FULL; 00131 } 00132 /*---------------------------------------------------------------------------*/ 00133 static char 00134 data_is_sent_and_acked(register struct psock *s) 00135 { 00136 /* If data has previously been sent, and the data has been acked, we 00137 increase the send pointer and call send_data() to send more 00138 data. */ 00139 if(s->state != STATE_DATA_SENT || uip_rexmit()) { 00140 if(s->sendlen > uip_mss()) { 00141 uip_send(s->sendptr, uip_mss()); 00142 } else { 00143 uip_send(s->sendptr, s->sendlen); 00144 } 00145 s->state = STATE_DATA_SENT; 00146 return 0; 00147 } else if(s->state == STATE_DATA_SENT && uip_acked()) { 00148 if(s->sendlen > uip_mss()) { 00149 s->sendlen -= uip_mss(); 00150 s->sendptr += uip_mss(); 00151 } else { 00152 s->sendptr += s->sendlen; 00153 s->sendlen = 0; 00154 } 00155 s->state = STATE_ACKED; 00156 return 1; 00157 } 00158 return 0; 00159 } 00160 /*---------------------------------------------------------------------------*/ 00161 PT_THREAD(psock_send(register struct psock *s, const char *buf, 00162 unsigned int len)) 00163 { 00164 PT_BEGIN(&s->psockpt); 00165 00166 /* If there is no data to send, we exit immediately. */ 00167 if(len == 0) { 00168 PT_EXIT(&s->psockpt); 00169 } 00170 00171 /* Save the length of and a pointer to the data that is to be 00172 sent. */ 00173 s->sendptr = buf; 00174 s->sendlen = len; 00175 00176 s->state = STATE_NONE; 00177 00178 /* We loop here until all data is sent. The s->sendlen variable is 00179 updated by the data_sent() function. */ 00180 while(s->sendlen > 0) { 00181 00182 /* 00183 * The protothread will wait here until all data has been 00184 * acknowledged and sent (data_is_acked_and_send() returns 1). 00185 */ 00186 PT_WAIT_UNTIL(&s->psockpt, data_is_sent_and_acked(s)); 00187 } 00188 00189 s->state = STATE_NONE; 00190 00191 PT_END(&s->psockpt); 00192 } 00193 /*---------------------------------------------------------------------------*/ 00194 PT_THREAD(psock_generator_send(register struct psock *s, 00195 unsigned short (*generate)(void *), void *arg)) 00196 { 00197 PT_BEGIN(&s->psockpt); 00198 00199 /* Ensure that there is a generator function to call. */ 00200 if(generate == NULL) { 00201 PT_EXIT(&s->psockpt); 00202 } 00203 00204 s->state = STATE_NONE; 00205 do { 00206 /* Call the generator function to generate the data in the 00207 uip_appdata buffer. */ 00208 s->sendlen = generate(arg); 00209 s->sendptr = uip_appdata; 00210 00211 if(s->sendlen > uip_mss()) { 00212 uip_send(s->sendptr, uip_mss()); 00213 } else { 00214 uip_send(s->sendptr, s->sendlen); 00215 } 00216 s->state = STATE_DATA_SENT; 00217 00218 /* Wait until all data is sent and acknowledged. */ 00219 // if (!s->sendlen) break; //useful debugging aid 00220 PT_YIELD_UNTIL(&s->psockpt, uip_acked() || uip_rexmit()); 00221 } while(!uip_acked()); 00222 00223 s->state = STATE_NONE; 00224 00225 PT_END(&s->psockpt); 00226 } 00227 /*---------------------------------------------------------------------------*/ 00228 u16_t 00229 psock_datalen(struct psock *psock) 00230 { 00231 return psock->bufsize - psock->buf.left; 00232 } 00233 /*---------------------------------------------------------------------------*/ 00234 char 00235 psock_newdata(struct psock *s) 00236 { 00237 if(s->readlen > 0) { 00238 /* There is data in the uip_appdata buffer that has not yet been 00239 read with the PSOCK_READ functions. */ 00240 return 1; 00241 } else if(s->state == STATE_READ) { 00242 /* All data in uip_appdata buffer already consumed. */ 00243 s->state = STATE_BLOCKED_NEWDATA; 00244 return 0; 00245 } else if(uip_newdata()) { 00246 /* There is new data that has not been consumed. */ 00247 return 1; 00248 } else { 00249 /* There is no new data. */ 00250 return 0; 00251 } 00252 } 00253 /*---------------------------------------------------------------------------*/ 00254 PT_THREAD(psock_readto(register struct psock *psock, unsigned char c)) 00255 { 00256 PT_BEGIN(&psock->psockpt); 00257 00258 buf_setup(&psock->buf, psock->bufptr, psock->bufsize); 00259 00260 /* XXX: Should add buf_checkmarker() before do{} loop, if 00261 incoming data has been handled while waiting for a write. */ 00262 00263 do { 00264 if(psock->readlen == 0) { 00265 PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); 00266 psock->state = STATE_READ; 00267 psock->readptr = (u8_t *)uip_appdata; 00268 psock->readlen = uip_datalen(); 00269 } 00270 } while(buf_bufto(&psock->buf, c, 00271 &psock->readptr, 00272 &psock->readlen) == BUF_NOT_FOUND); 00273 00274 if(psock_datalen(psock) == 0) { 00275 psock->state = STATE_NONE; 00276 PT_RESTART(&psock->psockpt); 00277 } 00278 PT_END(&psock->psockpt); 00279 } 00280 /*---------------------------------------------------------------------------*/ 00281 PT_THREAD(psock_readbuf_len(register struct psock *psock, uint16_t len)) 00282 { 00283 PT_BEGIN(&psock->psockpt); 00284 00285 buf_setup(&psock->buf, psock->bufptr, psock->bufsize); 00286 00287 /* XXX: Should add buf_checkmarker() before do{} loop, if 00288 incoming data has been handled while waiting for a write. */ 00289 00290 do { 00291 if(psock->readlen == 0) { 00292 PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); 00293 psock->state = STATE_READ; 00294 psock->readptr = (u8_t *)uip_appdata; 00295 psock->readlen = uip_datalen(); 00296 } 00297 } while(buf_bufdata(&psock->buf, psock->bufsize, 00298 &psock->readptr, &psock->readlen) == BUF_NOT_FULL && 00299 psock_datalen(psock) < len); 00300 00301 if(psock_datalen(psock) == 0) { 00302 psock->state = STATE_NONE; 00303 PT_RESTART(&psock->psockpt); 00304 } 00305 PT_END(&psock->psockpt); 00306 } 00307 /*---------------------------------------------------------------------------*/ 00308 void 00309 psock_init(register struct psock *psock, char *buffer, unsigned int buffersize) 00310 { 00311 psock->state = STATE_NONE; 00312 psock->readlen = 0; 00313 psock->bufptr = buffer; 00314 psock->bufsize = buffersize; 00315 buf_setup(&psock->buf, buffer, buffersize); 00316 PT_INIT(&psock->pt); 00317 PT_INIT(&psock->psockpt); 00318 } 00319 /*---------------------------------------------------------------------------*/
Generated on Tue Jul 12 2022 12:52:12 by 1.7.2