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.h,v 1.3 2006/06/12 08:00:30 adam Exp $ 00035 */ 00036 00037 /** 00038 * \defgroup psock Библиотека protosocket-ов. 00039 * @{ 00040 * 00041 * Библиотека protosocket-ов предоставляет интерфейс к стеку uIP, который работает 00042 * похоже на традиционный интерфейс сокетов BSD. В отличие от программ, написанных 00043 * для обычного интерфейса uIP, управляемого событиями, программы на 00044 * protosocket-библиотеке выполнются последовательно и требуют явно реализованных 00045 * машин состояний. 00046 * 00047 * Protosocket-ы работают только с соединениями TCP. 00048 * 00049 * Protosocket-библиотека использует \ref pt protothread-ы для предоставления 00050 * последовательного потока выполнения. Это делате protosocket-ы нересурсоемкими 00051 * в плане расхода памяти, однако подразумевается, что protosocket-ы наследуют 00052 * фуциональные ограничения protothread-ов. Каждый protosocket живет только 00053 * в пределах одной функции. Автоматические переменные (хранящиеся в стеке) 00054 * не сохраняются между вызовами функций protosocket-библиотеки. 00055 * 00056 * \note Поскольку protosocket-библиотека использует protothread-ы, локальные 00057 * переменные не всегда будут сохранены между вызовами функции 00058 * protosocket-библиотеки. Так что рекомендуется использовать локальные 00059 * переменные с большой осторожностью. 00060 * 00061 * Protosocket-библиотека предоставляет функции для отправки данных без 00062 * разборки с повторными передачами и подтверждениями, как и с функциями для 00063 * чтения данных с разборкой разбиения данных больше чем через 1 сегмент TCP. 00064 * 00065 * Поскольку каждый протосокет запускается как protothread, то protosocket 00066 * стартует с вызова PSOCK_BEGIN() в начале функции, в которой используется 00067 * protosocket. Аналогично, protosocket protothread может быть прерван 00068 * вызовом PSOCK_EXIT(). 00069 * 00070 */ 00071 00072 /** 00073 * \file 00074 * Заголовочный файл библиотеки протосокетов 00075 * \author 00076 * Adam Dunkels <adam@sics.se> 00077 * 00078 */ 00079 00080 #ifndef __PSOCK_H__ 00081 #define __PSOCK_H__ 00082 00083 #include "uipopt.h" 00084 #include "pt.h" 00085 00086 /* 00087 * Структура, которая содержит состояние буфера. 00088 * 00089 * В этой структуре находится состояние буфера uIP. Структура не имеет 00090 * элементов, видимых для пользователя, но используется функциями, 00091 * предоставленными библиотекой. 00092 * 00093 */ 00094 struct psock_buf { 00095 u8_t *ptr; 00096 unsigned short left; 00097 }; 00098 00099 /** 00100 * Представление протосокета. 00101 * 00102 * Структура протосокета является непрозрачной, в ней нет полей, 00103 * которые видит пользователь. 00104 */ 00105 struct psock { 00106 struct pt pt, psockpt; /* Протосокеты используют функции psock 00107 и функцию, которая работает внутри 00108 функций psock. */ 00109 const u8_t *sendptr; /* Указатель на следующие отправляемые данные. */ 00110 u8_t *readptr; /* Указатель на следующие данные для чтения. */ 00111 00112 char *bufptr; /* Указатель на буфер, используемый для буферизации 00113 приходящих данных. */ 00114 00115 u16_t sendlen; /* Количество байт, которое осталось отправить. */ 00116 u16_t readlen; /* Количество байт, которое осталось прочитать. */ 00117 00118 struct psock_buf buf; /* Структура, которая содержит состояние входного 00119 буфера. */ 00120 unsigned int bufsize; /* Размер входного буфера. */ 00121 00122 unsigned char state; /* Состояние протосокета. */ 00123 }; 00124 00125 void psock_init(struct psock *psock, char *buffer, unsigned int buffersize); 00126 /** 00127 * Инициализирует протосокет. 00128 * 00129 * Этот макрос инициализирует протосокет, и должен быть вызван перед 00130 * протосокета. Инициализация таке указывает входной буфер для 00131 * протосокета. 00132 * 00133 * \param psock (struct psock *) Указатель на протосокет, который будет 00134 * инициализирован. 00135 * 00136 * \param buffer (char *) Указатель на входной буфер для протосокета. 00137 * 00138 * \param buffersize (unsigned int) Размер входного буфера. 00139 * 00140 * \hideinitializer 00141 */ 00142 #define PSOCK_INIT(psock, buffer, buffersize) \ 00143 psock_init(psock, buffer, buffersize) 00144 00145 /** 00146 * Запускает в фукнции протопоток протосокета. 00147 * 00148 * Этот макрос запускает протопоток, ассоциированный с протосокетом, 00149 * и он должен быть использован перед тем, как будет вызвана другая 00150 * фукнция протосокета. 00151 * 00152 * \param psock (struct psock *) Указатель на протосокет, который будет 00153 * запущен. 00154 * 00155 * \hideinitializer 00156 */ 00157 #define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt)) 00158 00159 PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len)); 00160 /** 00161 * Отправление данных. 00162 * 00163 * Этот макрос посылает данные через протосокет. Протопоток протосокета 00164 * блокируется, пока все данные не будут отправлены, и не станет известно, 00165 * что данные приняты на дальнем конце соединения TCP. 00166 * 00167 * \param psock (struct psock *) A pointer to the protosocket over which 00168 * data is to be sent. 00169 * 00170 * \param data (char *) Указатель на протосокет, через который будут 00171 * отправлены данные. 00172 * 00173 * \param datalen (unsigned int) Длина отправляемых данных. 00174 * 00175 * \hideinitializer 00176 */ 00177 #define PSOCK_SEND(psock, data, datalen) \ 00178 PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen)) 00179 00180 /** 00181 * \brief Отправляет строку, завершающуюся нулем (null-terminated 00182 * string). 00183 * \param psock Указатель на протосокет. 00184 * \param str Строка для отправки. 00185 * 00186 * Эта функция посылвает null-terminated строку через 00187 * протосокет. 00188 * 00189 * \hideinitializer 00190 */ 00191 #define PSOCK_SEND_STR(psock, str) \ 00192 PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str))) 00193 00194 PT_THREAD(psock_generator_send(struct psock *psock, 00195 unsigned short (*f)(void *), void *arg)); 00196 00197 /** 00198 * \brief Генерация данных с помощью функции и отправка их 00199 * \param psock Указатель на протосокет. 00200 * \param generator Указатель на функцию генератора. 00201 * \param arg Аргумент для функции генератора. 00202 * 00203 * Эта функция генерирует данные и посылает их через 00204 * протосокет. Это может использоваться для динамической 00205 * генерации данных для передачи, вместо того, чтобы 00206 * генерировать данные в буфере заранее. Эта функция 00207 * снижает необходимость в буферной памяти. Функция 00208 * генератора реализована приложением, и указатель на 00209 * функцию предоставляется в аргументе, когда делается 00210 * вызов PSOCK_GENERATOR_SEND(). 00211 * 00212 * Функция генератора должна поместить сгенерированные 00213 * данные напрямую в буфер uip_appdata, и возвратить 00214 * длину сгенерированных данных. Функция генератора 00215 * вызывается слоем протосокета, когда данные посылаются 00216 * первый раз, и каждый раз, когда требуется ретрансмиссия. 00217 * 00218 * \hideinitializer 00219 */ 00220 #define PSOCK_GENERATOR_SEND(psock, generator, arg) \ 00221 PT_WAIT_THREAD(&((psock)->pt), \ 00222 psock_generator_send(psock, generator, arg)) 00223 00224 00225 /** 00226 * Закрытие протосокета. 00227 * 00228 * Этот макрос закрывает протосокет, и может быть вызван только из 00229 * протопотока, в котором живет протосокет. 00230 * 00231 * \param psock (struct psock *) Указатель на протосокет, который 00232 * будет закрыт. 00233 * 00234 * \hideinitializer 00235 */ 00236 #define PSOCK_CLOSE(psock) uip_close() 00237 00238 PT_THREAD(psock_readbuf(struct psock *psock)); 00239 /** 00240 * Чтение данных, пока буфер не заполнится. 00241 * 00242 * Этот марос будет блокироватьс выполнение протопотока на ожидании 00243 * данных, и читать данные во входной буфер, указанный вызовом 00244 * PSOCK_INIT(). Дата читаются, пока буфер не заполнится. 00245 * 00246 * \param psock (struct psock *) Указатель на протосокет, из которого 00247 * читаются данные. 00248 * 00249 * \hideinitializer 00250 */ 00251 #define PSOCK_READBUF(psock) \ 00252 PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock)) 00253 00254 PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); 00255 /** 00256 * Читает данные, пока не попадется указанный символ. 00257 * 00258 * Этот макрос заблокирует выполнение на ожидании нужного символа, и читаемые 00259 * данные будут попадать во входной буфер, указанный вызовом PSOCK_INIT(). 00260 * Данные будут читаться в буфер, пока во входом потоке данных не появится 00261 * указанный символ. 00262 * 00263 * \param psock (struct psock *) Указатель на protosocket с которого должны 00264 * читаться данные. 00265 * 00266 * \param c (char) Символ, на котором должно быть остановлено чтение. 00267 * 00268 * \hideinitializer 00269 */ 00270 #define PSOCK_READTO(psock, c) \ 00271 PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c)) 00272 00273 /** 00274 * Длина данных, котррые были прочитаны ранее. 00275 * 00276 * Этот макрос возвращает длину данных, которые были прочитаны ранее 00277 * с использованием PSOCK_READTO() или PSOCK_READ(). 00278 * 00279 * \param psock (struct psock *) Указатель на протосокет, содержащий 00280 * данные. 00281 * 00282 * \hideinitializer 00283 */ 00284 #define PSOCK_DATALEN(psock) psock_datalen(psock) 00285 00286 u16_t psock_datalen(struct psock *psock); 00287 00288 /** 00289 * Выход из протопотока протосокета. 00290 * 00291 * Этот макрос прерывает протопоток протосокета и должен почти всегда 00292 * использоваться в сочетании с PSOCK_CLOSE(). 00293 * 00294 * \sa PSOCK_CLOSE_EXIT() 00295 * 00296 * \param psock (struct psock *) Указатель на протосокет. 00297 * 00298 * \hideinitializer 00299 */ 00300 #define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt)) 00301 00302 /** 00303 * Закрывает протосокет и делает выход из протопотока протосокета. 00304 * 00305 * Этот макрос закрывает протосокет и делает выход из протопотока 00306 * протосокета. 00307 * 00308 * \param psock (struct psock *) Указатель на протосокет. 00309 * 00310 * \hideinitializer 00311 */ 00312 #define PSOCK_CLOSE_EXIT(psock) \ 00313 do { \ 00314 PSOCK_CLOSE(psock); \ 00315 PSOCK_EXIT(psock); \ 00316 } while(0) 00317 00318 /** 00319 * Декларирует конец протопотока протосокета. 00320 * 00321 * Этот макрос используется, чтобы декларировать, где находится 00322 * конец протопотока протосокета. Макрос должен всегда использоваться 00323 * совместно с соответствующим макросом PSOCK_BEGIN(). 00324 * 00325 * \param psock (struct psock *) Указатель на протосокет. 00326 * 00327 * \hideinitializer 00328 */ 00329 #define PSOCK_END(psock) PT_END(&((psock)->pt)) 00330 00331 char psock_newdata(struct psock *s); 00332 00333 /** 00334 * Проверяет - поступили ли новые данные на протосокет. 00335 * 00336 * Этот макрос используется совместно с макросом PSOCK_WAIT_UNTIL() 00337 * для проверки - поступили ли данные на протосокет. 00338 * 00339 * \param psock (struct psock *) Указатель на протосокет. 00340 * 00341 * \hideinitializer 00342 */ 00343 #define PSOCK_NEWDATA(psock) psock_newdata(psock) 00344 00345 /** 00346 * Ожидание, пока условие не станет true. 00347 * 00348 * Этот макрос блокирует протопоток, пока указанное условие не станет 00349 * true. Макрос PSOCK_NEWDATA() может использоваться для проверки, 00350 * поступили ли новые данные, когда протосокет находится в ожидании. 00351 * 00352 * Обычно этот макрос используется так: 00353 * 00354 \code 00355 PT_THREAD(thread(struct psock *s, struct timer *t)) 00356 { 00357 PSOCK_BEGIN(s); 00358 00359 PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); 00360 00361 if(PSOCK_NEWDATA(s)) { 00362 PSOCK_READTO(s, '\n'); 00363 } else { 00364 handle_timed_out(s); 00365 } 00366 00367 PSOCK_END(s); 00368 } 00369 \endcode 00370 * 00371 * \param psock (struct psock *) Указатель на протосокет. 00372 * \param condition Условие, которое ждет блокировка. 00373 * 00374 * \hideinitializer 00375 */ 00376 #define PSOCK_WAIT_UNTIL(psock, condition) \ 00377 PT_WAIT_UNTIL(&((psock)->pt), (condition)); 00378 00379 #define PSOCK_WAIT_THREAD(psock, condition) \ 00380 PT_WAIT_THREAD(&((psock)->pt), (condition)) 00381 00382 #endif /* __PSOCK_H__ */ 00383 00384 /** @} */