uIP 1.0
|
00001 /* 00002 * Copyright (c) 2004, Swedish Institute of Computer Science. 00003 * Все права зарезервированы. * 00004 * Повторное распространение, использование в исходном и двоичном виде, 00005 * с модификацией или без - разрешается, если выполняются следующие 00006 * условия: 00007 * 1. Распространение исходного кода должно сохранить вышеуказанную пометку 00008 * копирайта, этот список условий и следующую правовую оговорку. 00009 * 2. Распространение исходного кода должно сохранить вышеуказанную пометку 00010 * копирайта, этот список условий и следующую правовую оговорку в 00011 * документации и/или других материалах, которые будут предоставлены 00012 * вместе с распространяемыми материалами. 00013 * 3. Имя автора не может использоваться, чтобы подтвердить или продвинуть 00014 * продукты, написанные с использованием этого программного обеспечения 00015 * без специального на то разрешения. 00016 * 00017 * ЭТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ АВТОРОМ ``КАК ЕСТЬ'', БЕЗ 00018 * КАКОЙ-ЛИБО ЛЮБОЙ РАСШИРЕННОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ГАРАНТИИ, ВКЛЮЧАЯ, 00019 * НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ГАРАНТИИ ВЫСОКОГО СПРОСА И ПРИГОДНОСТИ 00020 * ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. АВТОР НИ ПРИ КАКИХ УСЛОВИЯХ НЕ ОТВЕТСТВЕНЕН 00021 * ЗА ЛЮБЫЕ УБЫТКИ - ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ОБРАЗЦОВЫЕ 00022 * ИЛИ ПОСЛЕДОВАТЕЛЬНЫЕ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ТРЕБОВАНИЯ 00023 * ЗАМЕНЫ ТОВАРА ИЛИ СЕРВИСА; ПОТЕРИ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ВЫГОДЫ; 00024 * ИЛИ ПРЕКРАЩЕНИЕ БИЗНЕСА), ОДНАКО ВЫЗВАННЫЕ ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ, 00025 * ЛИБО В КОНТРАКТЕ, ПРЯМОЙ ОТВЕТСТВЕННОСТИ, ЛИБО В НАРУШЕНИИ ЗАКОННЫХ ПРАВ 00026 * (ВКЛЮЧАЯ ТАК ИЛИ ИНАЧЕ НЕБРЕЖНОСТЬ), ВОЗНИКАЮЩИЕ ВСЕГДА ИЗ ИСПОЛЬЗОВАНИЯ 00027 * ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ БЫЛО ПРЕДУПРЕЖДЕНИЕ О ВОЗМОЖНОСТИ 00028 * ТАКОГО ПОВРЕЖДЕНИЯ. 00029 * 00030 * Этот файл является частью стека uIP TCP/IP. 00031 * 00032 * Author: Adam Dunkels <adam@sics.se> 00033 * 00034 * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $ 00035 */ 00036 00037 #include <stdio.h> 00038 #include <string.h> 00039 00040 #include "uipopt.h" 00041 #include "psock.h" 00042 #include "uip.h" 00043 00044 #define STATE_NONE 0 00045 #define STATE_ACKED 1 00046 #define STATE_READ 2 00047 #define STATE_BLOCKED_NEWDATA 3 00048 #define STATE_BLOCKED_CLOSE 4 00049 #define STATE_BLOCKED_SEND 5 00050 #define STATE_DATA_SENT 6 00051 00052 /* 00053 * Возвращаемое значение буферизирующих фунций, которое показывает, что 00054 * буфер не был заполнен приходящими данными. 00055 * 00056 */ 00057 #define BUF_NOT_FULL 0 00058 #define BUF_NOT_FOUND 0 00059 00060 /* 00061 * Возвращаемое значение буферизирующих фунций, которое показывает, что 00062 * буфер полностью заполнен приходящими данными. 00063 * 00064 */ 00065 #define BUF_FULL 1 00066 00067 /* 00068 * Возвращаемое значение буферизирующих фунций, которое показывает, что 00069 * найден байт - маркер конца (end-marker byte). 00070 * 00071 */ 00072 #define BUF_FOUND 2 00073 00074 /*---------------------------------------------------------------------------*/ 00075 static void 00076 buf_setup(struct psock_buf *buf, 00077 u8_t *bufptr, u16_t bufsize) 00078 { 00079 buf->ptr = bufptr; 00080 buf->left = bufsize; 00081 } 00082 /*---------------------------------------------------------------------------*/ 00083 static u8_t 00084 buf_bufdata(struct psock_buf *buf, u16_t len, 00085 u8_t **dataptr, u16_t *datalen) 00086 { 00087 if(*datalen < buf->left) { 00088 memcpy(buf->ptr, *dataptr, *datalen); 00089 buf->ptr += *datalen; 00090 buf->left -= *datalen; 00091 *dataptr += *datalen; 00092 *datalen = 0; 00093 return BUF_NOT_FULL; 00094 } else if(*datalen == buf->left) { 00095 memcpy(buf->ptr, *dataptr, *datalen); 00096 buf->ptr += *datalen; 00097 buf->left = 0; 00098 *dataptr += *datalen; 00099 *datalen = 0; 00100 return BUF_FULL; 00101 } else { 00102 memcpy(buf->ptr, *dataptr, buf->left); 00103 buf->ptr += buf->left; 00104 *datalen -= buf->left; 00105 *dataptr += buf->left; 00106 buf->left = 0; 00107 return BUF_FULL; 00108 } 00109 } 00110 /*---------------------------------------------------------------------------*/ 00111 static u8_t 00112 buf_bufto(register struct psock_buf *buf, u8_t endmarker, 00113 register u8_t **dataptr, register u16_t *datalen) 00114 { 00115 u8_t c; 00116 while(buf->left > 0 && *datalen > 0) { 00117 c = *buf->ptr = **dataptr; 00118 ++*dataptr; 00119 ++buf->ptr; 00120 --*datalen; 00121 --buf->left; 00122 00123 if(c == endmarker) { 00124 return BUF_FOUND; 00125 } 00126 } 00127 00128 if(*datalen == 0) { 00129 return BUF_NOT_FOUND; 00130 } 00131 00132 while(*datalen > 0) { 00133 c = **dataptr; 00134 --*datalen; 00135 ++*dataptr; 00136 00137 if(c == endmarker) { 00138 return BUF_FOUND | BUF_FULL; 00139 } 00140 } 00141 00142 return BUF_FULL; 00143 } 00144 /*---------------------------------------------------------------------------*/ 00145 static char 00146 send_data(register struct psock *s) 00147 { 00148 if(s->state != STATE_DATA_SENT || uip_rexmit()) { 00149 if(s->sendlen > uip_mss()) { 00150 uip_send(s->sendptr, uip_mss()); 00151 } else { 00152 uip_send(s->sendptr, s->sendlen); 00153 } 00154 s->state = STATE_DATA_SENT; 00155 return 1; 00156 } 00157 return 0; 00158 } 00159 /*---------------------------------------------------------------------------*/ 00160 static char 00161 data_acked(register struct psock *s) 00162 { 00163 if(s->state == STATE_DATA_SENT && uip_acked()) { 00164 if(s->sendlen > uip_mss()) { 00165 s->sendlen -= uip_mss(); 00166 s->sendptr += uip_mss(); 00167 } else { 00168 s->sendptr += s->sendlen; 00169 s->sendlen = 0; 00170 } 00171 s->state = STATE_ACKED; 00172 return 1; 00173 } 00174 return 0; 00175 } 00176 /*---------------------------------------------------------------------------*/ 00177 PT_THREAD(psock_send(register struct psock *s, const char *buf, 00178 unsigned int len)) 00179 { 00180 PT_BEGIN(&s->psockpt); 00181 00182 /* Если в этом месте нет данных для отправки, то делаем немедленный выход. */ 00183 if(len == 0) { 00184 PT_EXIT(&s->psockpt); 00185 } 00186 00187 /* Сохраним длину и указатель на данные, которые будут отправлены. */ 00188 s->sendptr = (u8_t const*)buf; 00189 s->sendlen = len; 00190 00191 s->state = STATE_NONE; 00192 00193 /* Делаем цикл, пока отправляются все данные. Переменная s->sendlen 00194 обновляется функцией data_sent(). */ 00195 while(s->sendlen > 0) { 00196 00197 /* 00198 * Условие для этого PT_WAIT_UNTIL несколько хитрое: протопоток 00199 * будет ждать здесь, пока все данные не будут подтверждены 00200 * (data_acked() вернет true) и пока все данные не отправятся 00201 * (send_data() вернет true). Две функции data_acked() и 00202 * send_data() должны быть вызваны друг за другом, чтобы убедиться 00203 * в отправке всех данных. Таким образом используется оператор & 00204 * вместо &&, который привел бы только к вызову функции data_acked(), 00205 * когда она вернет false. 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 uip_appdata. */ 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 /* Здесь есть данные в буфере uip_appdata, которые еще не прочитаны 00257 функциями PSOCK_READ. */ 00258 return 1; 00259 } else if(s->state == STATE_READ) { 00260 /* Все данные в буфере uip_appdata были поглощены. */ 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, (u8_t*)psock->bufptr, psock->bufsize); 00277 00278 /* XXX: нужно добавить buf_checkmarker() перед циклом do{}, если 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, (u8_t*)psock->bufptr, psock->bufsize); 00304 00305 /* XXX: нужно добавить buf_checkmarker() перед циклом do{}, если 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, (u8_t*)buffer, buffersize); 00335 PT_INIT(&psock->pt); 00336 PT_INIT(&psock->psockpt); 00337 } 00338 /*---------------------------------------------------------------------------*/