uIP 1.0
C:/asm/STM32-ethernet/ENC28J60prj/uip-master/uip/psock.h
См. документацию.
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 /** @} */