uIP 1.0
C:/asm/STM32-ethernet/ENC28J60prj/uip-master/uip/uip.h
См. документацию.
00001 /**
00002  * \addtogroup uip
00003  * @{
00004  */
00005 
00006 /**
00007  * \file
00008  * Заголовочный файл для стека uIP TCP/IP.
00009  * \author Adam Dunkels <adam@dunkels.com>
00010  *
00011  * Этот заголовочный файл стека uIP TCP/IP содержит определения нескольких
00012  * макросов C, которые используются программами uIP, а также внутренними
00013  * структурами uIP, структурами заголовка TCP/IP и декларациями фунций.
00014  *
00015  */
00016 
00017 
00018 /*
00019  * Copyright (c) 2001-2003, Adam Dunkels.
00020  * Все права зарезервированы. *
00021  * Повторное распространение, использование в исходном и двоичном виде,
00022  * с модификацией или без - разрешается, если выполняются следующие
00023  * условия:
00024  * 1. Распространение исходного кода должно сохранить вышеуказанную пометку
00025  *    копирайта, этот список условий и следующую правовую оговорку.
00026  * 2. Распространение исходного кода должно сохранить вышеуказанную пометку
00027  *    копирайта, этот список условий и следующую правовую оговорку в
00028  *    документации и/или других материалах, которые будут предоставлены
00029  *    вместе с распространяемыми материалами.
00030  * 3. Имя автора не может использоваться, чтобы подтвердить или продвинуть
00031  *    продукты, написанные с использованием этого программного обеспечения
00032  *    без специального на то разрешения.
00033  *
00034  * ЭТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ АВТОРОМ ``КАК ЕСТЬ'', БЕЗ
00035  * КАКОЙ-ЛИБО ЛЮБОЙ РАСШИРЕННОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ГАРАНТИИ, ВКЛЮЧАЯ,
00036  * НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ГАРАНТИИ ВЫСОКОГО СПРОСА И ПРИГОДНОСТИ
00037  * ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. АВТОР НИ ПРИ КАКИХ УСЛОВИЯХ НЕ ОТВЕТСТВЕНЕН
00038  * ЗА ЛЮБЫЕ УБЫТКИ - ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ОБРАЗЦОВЫЕ
00039  * ИЛИ ПОСЛЕДОВАТЕЛЬНЫЕ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ТРЕБОВАНИЯ
00040  * ЗАМЕНЫ ТОВАРА ИЛИ СЕРВИСА; ПОТЕРИ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ВЫГОДЫ;
00041  * ИЛИ ПРЕКРАЩЕНИЕ БИЗНЕСА), ОДНАКО ВЫЗВАННЫЕ ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ,
00042  * ЛИБО В КОНТРАКТЕ, ПРЯМОЙ ОТВЕТСТВЕННОСТИ, ЛИБО В НАРУШЕНИИ ЗАКОННЫХ ПРАВ
00043  * (ВКЛЮЧАЯ ТАК ИЛИ ИНАЧЕ НЕБРЕЖНОСТЬ), ВОЗНИКАЮЩИЕ ВСЕГДА ИЗ ИСПОЛЬЗОВАНИЯ
00044  * ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ БЫЛО ПРЕДУПРЕЖДЕНИЕ О ВОЗМОЖНОСТИ
00045  * ТАКОГО ПОВРЕЖДЕНИЯ.
00046  *
00047  * Этот файл является частью стека uIP TCP/IP.
00048  *
00049  * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $
00050  *
00051  */
00052 
00053 #ifndef __UIP_H__
00054 #define __UIP_H__
00055 
00056 #include "uipopt.h"
00057 
00058 /**
00059  * Представление адреса IP.
00060  *
00061  */
00062 typedef u16_t uip_ip4addr_t[2];
00063 typedef u16_t uip_ip6addr_t[8];
00064 #if UIP_CONF_IPV6
00065 typedef uip_ip6addr_t uip_ipaddr_t;
00066 #else /* UIP_CONF_IPV6 */
00067 typedef uip_ip4addr_t uip_ipaddr_t;
00068 #endif /* UIP_CONF_IPV6 */
00069 
00070 /*---------------------------------------------------------------------------*/
00071 /* Сначала приведены функции, которые должны вызываться из системы.
00072  * Инициализация, периодический таймер и приходящие пакеты обрабатываются
00073  * тремя следующими функциями.
00074  */
00075 
00076 /**
00077  * \defgroup uipconffunc Функции конфирурации uIP
00078  * @{
00079  *
00080  * Функции конфигурации uIP используются для установки во время выполнения
00081  * (run-time) параметров, таких как например адресов IP.
00082  */
00083 
00084 /**
00085  * Устанавливает IP-адрес хоста.
00086  *
00087  * Адрес IP представлен как 4-байтный массив, где первый октет адреса IP
00088  * помещается первым в 4-байтном массиве.
00089  *
00090  * Пример:
00091  \code
00092 
00093  uip_ipaddr_t addr;
00094 
00095  uip_ipaddr(&addr, 192,168,1,2);
00096  uip_sethostaddr(&addr);
00097  
00098  \endcode
00099  * \param addr Указатель на адрес IP типа uip_ipaddr_t;
00100  *
00101  * \sa uip_ipaddr()
00102  *
00103  * \hideinitializer
00104  */
00105 #define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
00106 
00107 /**
00108  * Получает IP-адрес хоста.
00109  *
00110  * Адрес IP представлен как 4-байтный массив, где первый октет адреса IP
00111  * помещается первым в 4-байтном массиве.
00112  *
00113  * Пример:
00114  \code
00115  uip_ipaddr_t hostaddr;
00116 
00117  uip_gethostaddr(&hostaddr);
00118  \endcode
00119  * \param addr Указатель на переменную uip_ipaddr_t, которая будет заполнена
00120  * текущим сконфигурированным IP-адресом.
00121  *
00122  * \hideinitializer
00123  */
00124 #define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)
00125 
00126 /**
00127  * Адрес IP шлюза (маршрутизатора) по умолчанию.
00128  *
00129  * \param addr Указатель на переменную uip_ipaddr_t, содержащую IP-адрес
00130  * для default router.
00131  *
00132  * \sa uip_ipaddr()
00133  *
00134  * \hideinitializer
00135  */
00136 #define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
00137 
00138 /**
00139  * Устанавливает маску подсети (netmask).
00140  *
00141  * \param addr Указатель на переменную uip_ipaddr_t, содержащую
00142  * значение маски подсети.
00143  *
00144  * \sa uip_ipaddr()
00145  *
00146  * \hideinitializer
00147  */
00148 #define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))
00149 
00150 
00151 /**
00152  * Получает IP-адрес шлюза по умолчанию.
00153  *
00154  * \param addr Указатель на переменную uip_ipaddr_t, которая будет
00155  * заполнена значением IP-адреса для default router.
00156  *
00157  * \hideinitializer
00158  */
00159 #define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
00160 
00161 /**
00162  * Получает маску подсети (netmask).
00163  *
00164  * \param addr Указатель на переменную uip_ipaddr_t, которая будет
00165  * заполнена значением маски подсети.
00166  *
00167  * \hideinitializer
00168  */
00169 #define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)
00170 
00171 /** @} */
00172 
00173 /**
00174  * \defgroup uipinit Функции инициализации uIP
00175  * @{
00176  *
00177  * Функции инициализации uIP используются для запуска uIP.
00178  */
00179 
00180 /**
00181  * Функция инициализации uIP.
00182  *
00183  * Эта функция должна быть вызвана в момент загрузки системы, чтобы
00184  * она проинициализировала стек uIP TCP/IP stack.
00185  */
00186 void uip_init(void);
00187 
00188 /**
00189  * Функция инициализации uIP.
00190  *
00191  * Эта функция должна быть вызвана в момент загрузки системы для 
00192  * установки изначального ip_id.
00193  */
00194 void uip_setipid(u16_t id);
00195 
00196 /** @} */
00197 
00198 /**
00199  * \defgroup uipdevfunc Функции драйвера устройства uIP
00200  * @{
00201  *
00202  * Эти функции используются сетевым драйвером устройства, который
00203  * работает совместно с uIP.
00204  */
00205 
00206 /**
00207  * Обрабатывает приходящий пакет.
00208  *
00209  * Эта функция должна быть вызвана, когда драйвер устройства принял
00210  * пакет через сеть. Пакет от драйвера устройства должен находиться
00211  * в буфере uip_buf, и длина пакета должна быть помещена в переменную
00212  * uip_len.
00213  *
00214  * Когда функция делает возврат, она может поместить исходящий пакет
00215  * в тот же буфер uip_buf. Если это так, то переменная uip_len 
00216  * устанавливается в значение длины этого пакета. Если нет пакета для
00217  * отправки, то значение переменной uip_len устанавливается равным 0.
00218  *
00219  * В коде ниже показан обычный способ вызова функции.
00220  \code
00221   uip_len = devicedriver_poll();
00222   if(uip_len > 0) {
00223     uip_input();
00224     if(uip_len > 0) {
00225       devicedriver_send();
00226     }
00227   }
00228  \endcode
00229  *
00230  * \note Если Вы пишете драйвер устройства uIP, которому нужен ARP
00231  * (Address Resolution Protocol), например когда uIP работает через
00232  * Ethernet, то Вам нужно перед вызовом этой функции вызвать
00233  * код uIP ARP:
00234  \code
00235   #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
00236   uip_len = ethernet_devicedrver_poll();
00237   if(uip_len > 0) {
00238     if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
00239       uip_arp_ipin();
00240       uip_input();
00241       if(uip_len > 0) {
00242         uip_arp_out();
00243         ethernet_devicedriver_send();
00244       }
00245     } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
00246       uip_arp_arpin();
00247       if(uip_len > 0) {
00248         ethernet_devicedriver_send();
00249       }
00250     }
00251  \endcode
00252  *
00253  * \hideinitializer
00254  */
00255 #define uip_input()        uip_process(UIP_DATA)
00256 
00257 /**
00258  * Периодическая обработка соединения, идентифицируемого по его номеру.
00259  *
00260  * Эта функция делает необходимые периодические обработки (таймеры,
00261  * поллинг) для соединения uIP TCP, и должна вызываться по срабатыванию
00262  * периодического таймера uIP. Она должна быть вызвана для каждого
00263  * соединения, назависимо от того - открыто это соединение или закрыто.
00264  *
00265  * Когда функция делает возврат, она может поместить в буфер пакета uIP
00266  * исходящий пакет, ожидающий отправки. Если это так, то переменная 
00267  * uip_len будет установлена в ненулевое значение. Чтобы отправить пакет,
00268  * должен быть вызван драйвер устройства.
00269  *
00270  * Обычно функция вызывается из цикла for() примерно так:
00271  \code
00272   for(i = 0; i < UIP_CONNS; ++i) {
00273     uip_periodic(i);
00274     if(uip_len > 0) {
00275       devicedriver_send();
00276     }
00277   }
00278  \endcode
00279  *
00280  * \note Если Вы пишете драйвер устройства uIP, которому нужен ARP
00281  * (Address Resolution Protocol), например когда uIP работает через
00282  * Ethernet, то Вам нужно вызвать функцию uip_arp_out() перед вызовом
00283  * драйвера устройства:
00284  \code
00285   for(i = 0; i < UIP_CONNS; ++i) {
00286     uip_periodic(i);
00287     if(uip_len > 0) {
00288       uip_arp_out();
00289       ethernet_devicedriver_send();
00290     }
00291   }
00292  \endcode
00293  *
00294  * \param conn Номер соединения, которое периодически опрашивается.
00295  *
00296  * \hideinitializer
00297  */
00298 #define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
00299                                 uip_process(UIP_TIMER); } while (0)
00300 
00301 /**
00302  *
00303  *
00304  */
00305 #define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
00306 
00307 /**
00308  * Выполняет периодические обработки соединения, идентифицируемого по
00309  * указателю на его структуру.
00310  *
00311  * То же самое, что и uip_periodic(), однако принимает в аргументе указатель
00312  * на реальную структуру uip_conn вместо целого числа. Эта функция может быть
00313  * использована для принудиельной периодической обработки отдельного соединения.
00314  *
00315  * \param conn Указатель на структуру uip_conn для обрабатываемого соединения.
00316  *
00317  * \hideinitializer
00318  */
00319 #define uip_periodic_conn(conn) do { uip_conn = conn; \
00320                                      uip_process(UIP_TIMER); } while (0)
00321 
00322 /**
00323  * Запрашивает отдельное соединение, которое должно быть опрошено.
00324  *
00325  * То же самое, что и uip_periodic_conn(), но не делает обработку по таймеру.
00326  * Приложение опрашивает появление новых данных.
00327  *
00328  * \param conn Указатель на структуру uip_conn для обрабатываемого
00329  * соединения.
00330  *
00331  * \hideinitializer
00332  */
00333 #define uip_poll_conn(conn) do { uip_conn = conn; \
00334                                  uip_process(UIP_POLL_REQUEST); } while (0)
00335 
00336 
00337 #if UIP_UDP
00338 /**
00339  * Периодическая обработка соединения UDP, идентифицированного по его номеру.
00340  *
00341  * Эта функция точно такая же, как и uip_periodic(), но для соединений
00342  * UDP. Она вызывается точно так же, как и функция uip_periodic():
00343  \code
00344   for(i = 0; i < UIP_UDP_CONNS; i++) {
00345     uip_udp_periodic(i);
00346     if(uip_len > 0) {
00347       devicedriver_send();
00348     }
00349   }
00350  \endcode
00351  *
00352  * \note Как и при использовании функции uip_periodic(), нужно позаботиться
00353  * taken о том, как использовать её при задействовании uIP вместе с ARP и Ethernet:
00354  \code
00355   for(i = 0; i < UIP_UDP_CONNS; i++) {
00356     uip_udp_periodic(i);
00357     if(uip_len > 0) {
00358       uip_arp_out();
00359       ethernet_devicedriver_send();
00360     }
00361   }
00362  \endcode
00363  *
00364  * \param conn Номер обрабатываемого соединения UDP.
00365  *
00366  * \hideinitializer
00367  */
00368 #define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
00369                                 uip_process(UIP_UDP_TIMER); } while (0)
00370 
00371 /**
00372  * Периодическая обработка соединения UDP, идентифицированного по указателю
00373  * на его структуру.
00374  *
00375  * То же самое, что и uip_udp_periodic(), но в качестве аргумента вместо
00376  * целого числа принимает указатель на реальную структуру uip_conn.
00377  * Эта функция может использоваться для принудительной периодической обработки
00378  * отдельного соединения.
00379  *
00380  * \param conn Указатель на структуру uip_udp_conn для обрабатываемого
00381  * соединения.
00382  *
00383  * \hideinitializer
00384  */
00385 #define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
00386                                          uip_process(UIP_UDP_TIMER); } while (0)
00387 
00388 
00389 #endif /* UIP_UDP */
00390 
00391 /**
00392  * Буфер пакета uIP.
00393  *
00394  * Массив uip_buf используется для того, чтобы хранить входящие и исходящие
00395  * пакеты. Драйвер устройства должен поместить в этот буфер приходящие данные.
00396  * Когда данные отправляются, драйвер устройства должен читать заголовки уровня
00397  * линка и заголовки TCP/IP из этого буфера. Размер заголовков уровня линка
00398  * конфигурируется дефайном UIP_LLH_LEN.
00399  *
00400  * \note Данные приложения должны быть помещены в этот буфер, так что драйвер
00401  * устройства должен читать их с места, указанного через указатель uip_appdata,
00402  * как это показано в следующем примере:
00403  \code
00404  void
00405  devicedriver_send(void)
00406  {
00407     hwsend(&uip_buf[0], UIP_LLH_LEN);
00408     if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
00409       hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
00410     } else {
00411       hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
00412       hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
00413     }
00414  }
00415  \endcode
00416  */
00417 extern u8_t uip_buf[UIP_BUFSIZE+2];
00418 
00419 /** @} */
00420 
00421 /*---------------------------------------------------------------------------*/
00422 /* Функции, которые используются программой приложения uIP. Открытие и
00423  * и закрытие соединений, отправка и прием данных и т. п. действия
00424  * обрбатываются следующими функциями.
00425 */
00426 /**
00427  * \defgroup uipappfunc Функции приложения uIP
00428  * @{
00429  *
00430  * Функции, используемые в приложении, работающем поверх uIP.
00431  */
00432 
00433 /**
00434  * Запуск прослушивания указанного порта.
00435  *
00436  * \note Поскольку эта функция ожидает номер порта с сетевым порядком байт,
00437  * то при необходимости должно быть применено преобразование HTONS() или htons().
00438  *
00439  \code
00440  uip_listen(HTONS(80));
00441  \endcode
00442  *
00443  * \param port 16-битный номер порта с сетевым порядком байт.
00444  */
00445 void uip_listen(u16_t port);
00446 
00447 /**
00448  * Остановить прослушивание указанного порта.
00449  *
00450  * \note Поскольку эта функция ожидает номер порта с сетевым порядком байт,
00451  * то при необходимости должно быть применено преобразование HTONS() или htons().
00452  *
00453  \code
00454  uip_unlisten(HTONS(80));
00455  \endcode
00456  *
00457  * \param port 16-битный номер порта с сетевым порядком байт.
00458  */
00459 void uip_unlisten(u16_t port);
00460 
00461 /**
00462  * Соединение с дальним хостом (remote host), используя TCP.
00463  *
00464  * Эта функция используется для запуска нового соединения с указанным портом
00465  * указанного хоста. Она выделяет новый идентификатор соединения,
00466  * устанавливает соединение в состояние SYN_SENT и устанавливает таймер
00467  * ретрансмиссии в 0. Это приведет к тому, что будет передан сегмент TCP SYN
00468  * в следующий раз, когда это соединение будет периодически обработано,
00469  * что будет сделано обычно через 0.5 секунд после вызова uip_connect().
00470  *
00471  * \note Эта функция доступна, только если активна поддержка активного открытого
00472  * соединения путем задания UIP_ACTIVE_OPEN на значение 1 в файле uipopt.h.
00473  *
00474  * \note Поскольку эта функция ожидает номер порта с сетевым порядком байт,
00475  * то при необходимости должно быть применено преобразование HTONS() или htons().
00476  *
00477  \code
00478  uip_ipaddr_t ipaddr;
00479 
00480  uip_ipaddr(&ipaddr, 192,168,1,2);
00481  uip_connect(&ipaddr, HTONS(80));
00482  \endcode
00483  *
00484  * \param ripaddr IP-адрес для remote hot.
00485  *
00486  * \param port 16-битный номер порта с сетевым порядком байт.
00487  *
00488  * \return Указатель на идентификатор соединения uI для нового соединения,
00489  * или NULL, если не может быть выделено новое соединение.
00490  *
00491  */
00492 struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
00493 
00494 
00495 
00496 /**
00497  * \internal
00498  *
00499  * Проверка - есть ли на соединении потерянные (например не подтвержденные)
00500  * данные.
00501  *
00502  * \param conn Указатель на структуру uip_conn для соединения.
00503  *
00504  * \hideinitializer
00505  */
00506 #define uip_outstanding(conn) ((conn)->len)
00507 
00508 /**
00509  * Посылает данные через текущее соединение.
00510  *
00511  * Эта функция используется для отправки одного сегмента данных TCP.
00512  * Могут отправлять данные только приложения, которые были вызваны из
00513  * uIP для обработки события.
00514  *
00515  * Количество данных, которое было на самом деле отправлено после вызова
00516  * этой функции, определяется максимальным количеством данны, которое
00517  * позволяет TCP. uIP автоматически будет урезать данные, так чтобы
00518  * было отправлено допустимое количество. Может быть использована
00519  * фукнция uip_mss(), чтобы запросить у uIP количество данных, которое
00520  * будет отправлено в действительности.
00521  *
00522  * \note Эта функция не дает гарантии, что посылаемые данные дойдут до
00523  * получателя. Если данные будут потеряны в сети, приложение будет вызвано
00524  * с установленным событием uip_rexmit(). Затем приложение заново отправит
00525  * данные, используя эту фукнцию.
00526  *
00527  * \param data Указатель на данные для отправки.
00528  *
00529  * \param len Максимальное количество данных для отправки.
00530  *
00531  * \hideinitializer
00532  */
00533 void uip_send(const void *data, int len);
00534 
00535 /**
00536  * Длина любых пришедшик данны, которые в настоящий момент доступны
00537  * (если доступны) в буфере uip_appdata.
00538  *
00539  * Перед этим может быть использована функция uip_data(), чтобы проверить,
00540  * есть ли вообще доступные данные.
00541  *
00542  * \hideinitializer
00543  */
00544 /*void uip_datalen(void);*/
00545 #define uip_datalen()       uip_len
00546 
00547 /**
00548  * Длина любых данные вне диапазона (out-of-band data, или urgent data,
00549  * т. е. данные, требующие срочной доставки), которые поступили 
00550  * на соединении.
00551  *
00552  * \note Чтобы эта функция была разрешена, должен быть установлен
00553  * конфигурационный параметр UIP_URGDATA.
00554  *
00555  * \hideinitializer
00556  */
00557 #define uip_urgdatalen()    uip_urglen
00558 
00559 /**
00560  * Закрывает текущее соединение.
00561  *
00562  * Эта функция должным образом закроет текущее соединение.
00563  *
00564  * \hideinitializer
00565  */
00566 #define uip_close()         (uip_flags = UIP_CLOSE)
00567 
00568 /**
00569  * Обрыв (Abort) текущего соединения.
00570  *
00571  * Эта функция оборвет (сбросит) текущее соедиение, что обычно используется,
00572  * когда случилась ошибка, что не дает право использовать функцию uip_close().
00573  *
00574  * \hideinitializer
00575  */
00576 #define uip_abort()         (uip_flags = UIP_ABORT)
00577 
00578 /**
00579  * Говорит посылающему данные хосту, что нужно остановить отправку данных.
00580  *
00581  * Эта функция закроет окно приема, чем приведет к остановке приема данных
00582  * для текущего соединения.
00583  *
00584  * \hideinitializer
00585  */
00586 #define uip_stop()          (uip_conn->tcpstateflags |= UIP_STOPPED)
00587 
00588 /**
00589  * Проверяет, было ли текущее соединение ранее остановлено вызовом uip_stop().
00590  *
00591  * \hideinitializer
00592  */
00593 #define uip_stopped(conn)   ((conn)->tcpstateflags & UIP_STOPPED)
00594 
00595 /**
00596  * Перезапускает текущее соединение, если оно было ранее остановлено
00597  * вызовом uip_stop().
00598  *
00599  * Эта функция снова откроет окно приема, что приведет к возобновлению
00600  * приема данных на текущем соединении.
00601  *
00602  * \hideinitializer
00603  */
00604 #define uip_restart()         do { uip_flags |= UIP_NEWDATA; \
00605                                    uip_conn->tcpstateflags &= ~UIP_STOPPED; \
00606                               } while(0)
00607 
00608 
00609 /* Проверки uIP, которые она может делать для того, чтобы определить,
00610    в каком состоянии находится соединение, и что должна делать функция
00611    приложения. */
00612 
00613 /**
00614  * Текущее соединение является соединением UDP?
00615  *
00616  * Эта функция проверяет, является ли текущее соединение соединением UDP.
00617  *
00618  * \hideinitializer
00619  *
00620  */
00621 #define uip_udpconnection() (uip_conn == NULL)
00622 
00623 /**
00624  * Есть ли новые данные?
00625  *
00626  * Вернет не 0, если для приложения имеются новые данные, которые 
00627  * представлены по указателю. Размер доступных данных можно узнать
00628  * по значению переменной uip_len.
00629  *
00630  * \hideinitializer
00631  */
00632 #define uip_newdata()   (uip_flags & UIP_NEWDATA)
00633 
00634 /**
00635  * Были ли подтверждены ранее отправленные данные?
00636  *
00637  * Вернет не 0, если ранее посланные данные были подтверждены стороной
00638  * remote host. Это означает, что приложение может послать новые данные.
00639  *
00640  * \hideinitializer
00641  */
00642 #define uip_acked()   (uip_flags & UIP_ACKDATA)
00643 
00644 /**
00645  * Соединение все еще установлено?
00646  *
00647  * Вернет не 0, если текущее соедиение еще работает, и подключено к
00648  * remote host. Это случится в обоих случаях, если соединение активно
00649  * открыто (вызовом uip_connect()) или пассивно открыто (вызовом
00650  * uip_listen()).
00651  *
00652  * \hideinitializer
00653  */
00654 #define uip_connected() (uip_flags & UIP_CONNECTED)
00655 
00656 /**
00657  * Было ли соединение закрыто на дальнем конце?
00658  *
00659  * Не 0, если соединение было закрыто по инициативе remote host.
00660  * Если это так, то приложение может сделать необходимые очистки.
00661  *
00662  * \hideinitializer
00663  */
00664 #define uip_closed()    (uip_flags & UIP_CLOSE)
00665 
00666 /**
00667  * Было ли соединение оборвано (aborted) на другом конце?
00668  *
00669  * Не 0, если текущее было оборвано (сброшено) по инициативе
00670  * remote host.
00671  *
00672  * \hideinitializer
00673  */
00674 #define uip_aborted()    (uip_flags & UIP_ABORT)
00675 
00676 /**
00677  * Истек ли таймаут на соединении?
00678  *
00679  * Не 0, если текущее соединение было оборвано из за слишком большого
00680  * количества ретрансмиссий.
00681  *
00682  * \hideinitializer
00683  */
00684 #define uip_timedout()    (uip_flags & UIP_TIMEDOUT)
00685 
00686 /**
00687  * Нужно ли отправить заново ранее посланные данные?
00688  *
00689  * Вернет не 0, если ранее отправленные данные были потеряны в сети,
00690  * в этом случае приложение должно заново их отправить (retransmit).
00691  * Приложение должно отправить точно те же данные, которые оно отправило
00692  * последний раз, используя функцию uip_send().
00693  *
00694  * \hideinitializer
00695  */
00696 #define uip_rexmit()     (uip_flags & UIP_REXMIT)
00697 
00698 /**
00699  * Соединение опрашивается от uIP?
00700  *
00701  * Не 0, если причина вызова приложения в том, что соединение было неактивно
00702  * некоторое время, и должно быть опрошено.
00703  *
00704  * Событие опроса (polling event) может быть использовано для отправки
00705  * данных без ожидания, что remote host отправит данные.
00706  *
00707  * \hideinitializer
00708  */
00709 #define uip_poll()       (uip_flags & UIP_POLL)
00710 
00711 /**
00712  * Получает максимальный начальный размер сегмента (MSS) текущего
00713  * соединения.
00714  *
00715  * \hideinitializer
00716  */
00717 #define uip_initialmss()             (uip_conn->initialmss)
00718 
00719 /**
00720  * Получает текущий максимальный размер сегмента, который может быть
00721  * отправлен через текущее соединение.
00722  *
00723  * Такущий максимальный размер сегмента, который можно отправить
00724  * на соединении, вычисляется на основе окна прием и MSS соединения
00725  * (которое также доступно через вызов uip_initialmss()).
00726  *
00727  * \hideinitializer
00728  */
00729 #define uip_mss()             (uip_conn->mss)
00730 
00731 /**
00732  * Устанавливает новое соединение UDP.
00733  *
00734  * Эта функция устанавливает новое соединение UDP. Функция автоматически
00735  * выделит неиспользуемый локальный порт для нового соединения. Однако может
00736  * быть выбран другой порт с помощью вызова uip_udp_bind() после того,
00737  * как была вызвана функция uip_udp_new().
00738  *
00739  * Пример:
00740  \code
00741  uip_ipaddr_t addr;
00742  struct uip_udp_conn *c;
00743  
00744  uip_ipaddr(&addr, 192,168,2,1);
00745  c = uip_udp_new(&addr, HTONS(12345));
00746  if(c != NULL) {
00747    uip_udp_bind(c, HTONS(12344));
00748  }
00749  \endcode
00750  * \param ripaddr IP-адрес для remote host.
00751  *
00752  * \param rport Номер порта remote host с сетевым порядком байт.
00753  *
00754  * \return Структура uip_udp_conn для нового соединения или NULL,
00755  * если не может быть выделено соединение.
00756  */
00757 struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
00758 
00759 /**
00760  * Удаляет соединение UDP.
00761  *
00762  * \param conn Указатель на структуру uip_udp_conn для соединения.
00763  *
00764  * \hideinitializer
00765  */
00766 #define uip_udp_remove(conn) (conn)->lport = 0
00767 
00768 /**
00769  * Привязка соединения UDP к локальному порту.
00770  *
00771  * \param conn Указатель на структуру uip_udp_conn для соединения.
00772  *
00773  * \param port Номер локального порта с сетевым порядком байт.
00774  *
00775  * \hideinitializer
00776  */
00777 #define uip_udp_bind(conn, port) (conn)->lport = port
00778 
00779 /**
00780  * Отправляет датаграмму UDP длиной len через текущее соединение.
00781  *
00782  * Эта функция может быть вызвана только в ответ на событие UDP (опроса
00783  * или поступления новых данных). Данные должны быть представлены в буфере
00784  * uip_buf, в том месте, на которое указывает указатель uip_appdata.
00785  *
00786  * \param len Длина данных в буфере uip_buf.
00787  *
00788  * \hideinitializer
00789  */
00790 #define uip_udp_send(len) uip_send((char *)uip_appdata, len)
00791 
00792 /** @} */
00793 
00794 /* Вспомогательные и конвертирующие функции uIP. */
00795 
00796 /**
00797  * \defgroup uipconvfunc Функции преобразований uIP
00798  * @{
00799  *
00800  * Эти функции могут использоваться для преобразования между разными
00801  * форматами данных, используемых в uIP.
00802  */
00803  
00804 /**
00805  * Конструирует адрес IP из 4 байт.
00806  *
00807  * Эта функция составляет IP-адрес того типа, который обрабатывает 
00808  * внутри себя uIP. Эта функция удобна, чтобы указать IP-адреса
00809  * для использования, например, с функцией uip_connect().
00810  *
00811  * Пример:
00812  \code
00813  uip_ipaddr_t ipaddr;
00814  struct uip_conn *c;
00815  
00816  uip_ipaddr(&ipaddr, 192,168,1,2);
00817  c = uip_connect(&ipaddr, HTONS(80));
00818  \endcode
00819  *
00820  * \param addr Указатель на переменную uip_ipaddr_t, которая будет
00821  * заполнена адресом IP.
00822  *
00823  * \param addr0 Первый октет адреса IP.
00824  * \param addr1 Второй октет адреса IP.
00825  * \param addr2 Третий октет адреса IP.
00826  * \param addr3 Четвертый октет адреса IP.
00827  *
00828  * \hideinitializer
00829  */
00830 #define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
00831                      ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
00832                      ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
00833                   } while(0)
00834 
00835 /**
00836  * Составляет адрес IPv6 из восьми 16-битных слов.
00837  *
00838  * Эта функция конструирует адрес IPv6.
00839  *
00840  * \hideinitializer
00841  */
00842 #define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
00843                      ((u16_t *)(addr))[0] = HTONS((addr0)); \
00844                      ((u16_t *)(addr))[1] = HTONS((addr1)); \
00845                      ((u16_t *)(addr))[2] = HTONS((addr2)); \
00846                      ((u16_t *)(addr))[3] = HTONS((addr3)); \
00847                      ((u16_t *)(addr))[4] = HTONS((addr4)); \
00848                      ((u16_t *)(addr))[5] = HTONS((addr5)); \
00849                      ((u16_t *)(addr))[6] = HTONS((addr6)); \
00850                      ((u16_t *)(addr))[7] = HTONS((addr7)); \
00851                   } while(0)
00852 
00853 /**
00854  * Копирует IP-адрес в другой IP-адрес.
00855  *
00856  * Копирует IP-адрес с одного места в другое.
00857  *
00858  * Пример:
00859  \code
00860  uip_ipaddr_t ipaddr1, ipaddr2;
00861 
00862  uip_ipaddr(&ipaddr1, 192,16,1,2);
00863  uip_ipaddr_copy(&ipaddr2, &ipaddr1);
00864  \endcode
00865  *
00866  * \param dest Место назначения копии.
00867  * \param src Исходные данные, откуда IP будет копироваться.
00868  *
00869  * \hideinitializer
00870  */
00871 #if !UIP_CONF_IPV6
00872 #define uip_ipaddr_copy(dest, src) do { \
00873                      ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
00874                      ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
00875                   } while(0)
00876 #else /* !UIP_CONF_IPV6 */
00877 #define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
00878 #endif /* !UIP_CONF_IPV6 */
00879 
00880 /**
00881  * Сравнение двух IP-адресов
00882  *
00883  * Сравнивает два IP-адреса.
00884  *
00885  * Пример:
00886  \code
00887  uip_ipaddr_t ipaddr1, ipaddr2;
00888 
00889  uip_ipaddr(&ipaddr1, 192,16,1,2);
00890  if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
00891     printf("They are the same");
00892  }
00893  \endcode
00894  *
00895  * \param addr1 Первый IP-адрес.
00896  * \param addr2 Второй IP-адрес.
00897  *
00898  * \hideinitializer
00899  */
00900 #if !UIP_CONF_IPV6
00901 #define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
00902                                       ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
00903 #else /* !UIP_CONF_IPV6 */
00904 #define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
00905 #endif /* !UIP_CONF_IPV6 */
00906 
00907 /**
00908  * Сравнение двух адресов IP с сетевой маской
00909  *
00910  * Сравнивает два адреса IP с сетевой маской. Маски используются, чтобы маскировать
00911  * биты, которые должны сравниваться.
00912  *
00913  * Пример:
00914  \code
00915  uip_ipaddr_t ipaddr1, ipaddr2, mask;
00916 
00917  uip_ipaddr(&mask, 255,255,255,0);
00918  uip_ipaddr(&ipaddr1, 192,16,1,2);
00919  uip_ipaddr(&ipaddr2, 192,16,1,3);
00920  if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
00921     printf("They are the same");
00922  }
00923  \endcode
00924  *
00925  * \param addr1 Первый IP-адрес.
00926  * \param addr2 Второй IP-адрес.
00927  * \param mask Сетевая маска.
00928  *
00929  * \hideinitializer
00930  */
00931 #define uip_ipaddr_maskcmp(addr1, addr2, mask) \
00932                           (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
00933                             (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
00934                            ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
00935                             (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
00936 
00937 
00938 /**
00939  * Маскирует сетевую часть адреса IP.
00940  *
00941  * Выделяет маской сетевую часть от IP-адреса, которая получается от адреса
00942  * и сетевой маски.
00943  *
00944  * Пример:
00945  \code
00946  uip_ipaddr_t ipaddr1, ipaddr2, netmask;
00947 
00948  uip_ipaddr(&ipaddr1, 192,16,1,2);
00949  uip_ipaddr(&netmask, 255,255,255,0);
00950  uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
00951  \endcode
00952  *
00953  * В предыдущем примере переменная "ipaddr2" будет содержать IP-адрес
00954  * 192.168.1.0.
00955  *
00956  * \param dest Место, куда будет помещен результат.
00957  * \param src Адрес IP.
00958  * \param mask Сетевая маска.
00959  *
00960  * \hideinitializer
00961  */
00962 #define uip_ipaddr_mask(dest, src, mask) do { \
00963                      ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
00964                      ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
00965                   } while(0)
00966 
00967 /**
00968  * Получение первого октета от адреса IP.
00969  *
00970  * Выбирает первый октет из IP-адреса.
00971  *
00972  * Пример:
00973  \code
00974  uip_ipaddr_t ipaddr;
00975  u8_t octet;
00976 
00977  uip_ipaddr(&ipaddr, 1,2,3,4);
00978  octet = uip_ipaddr1(&ipaddr);
00979  \endcode
00980  *
00981  * В предыдущем примере переменная "octet" будет содержать значение 1.
00982  *
00983  * \hideinitializer
00984  */
00985 #define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8)
00986 
00987 /**
00988  * Получение второго октета от адреса IP.
00989  *
00990  * Выбирает второй октет из IP-адреса.
00991  *
00992  * Пример:
00993  \code
00994  uip_ipaddr_t ipaddr;
00995  u8_t octet;
00996 
00997  uip_ipaddr(&ipaddr, 1,2,3,4);
00998  octet = uip_ipaddr2(&ipaddr);
00999  \endcode
01000  *
01001  * В предыдущем примере переменная "octet" будет содержать значение 2.
01002  *
01003  * \hideinitializer
01004  */
01005 #define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff)
01006 
01007 /**
01008  * Получение третьего октета от адреса IP.
01009  *
01010  * Выбирает третий октет из IP-адреса.
01011  *
01012  * Пример:
01013  \code
01014  uip_ipaddr_t ipaddr;
01015  u8_t octet;
01016 
01017  uip_ipaddr(&ipaddr, 1,2,3,4);
01018  octet = uip_ipaddr3(&ipaddr);
01019  \endcode
01020  *
01021  * В предыдущем примере переменная "octet" будет содержать значение 3.
01022  *
01023  * \hideinitializer
01024  */
01025 #define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8)
01026 
01027 /**
01028  * Получение четвертого октета от адреса IP.
01029  *
01030  * Выбирает четвертый октет из IP-адреса.
01031  *
01032  * Пример:
01033  \code
01034  uip_ipaddr_t ipaddr;
01035  u8_t octet;
01036 
01037  uip_ipaddr(&ipaddr, 1,2,3,4);
01038  octet = uip_ipaddr4(&ipaddr);
01039  \endcode
01040  *
01041  * В предыдущем примере переменная "octet" будет содержать значение 4.
01042  *
01043  * \hideinitializer
01044  */
01045 #define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff)
01046 
01047 /**
01048  * Преобразует 16-битное число с порядком байт хоста в число с 
01049  * сетевым порядком байт.
01050  *
01051  * Этот макрос главным образом используется для преобразования констант
01052  * номера порта. Для преобразования переменных в сетевой порядок байт
01053  * используйте вместо этого функцию htons().
01054  *
01055  * \hideinitializer
01056  */
01057 #ifndef HTONS
01058 #   if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
01059 #      define HTONS(n) (n)
01060 #   else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
01061 #      define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
01062 #   endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
01063 #else
01064 #error "HTONS already defined!"
01065 #endif /* HTONS */
01066 
01067 /**
01068  * Преобразует 16-битное число с порядком байт хоста в число с 
01069  * сетевым порядком байт.
01070  *
01071  * Этот функция главным образом используется для преобразования переменных
01072  * номера порта. Для преобразования констант в сетевой порядок байт
01073  * используйте вместо этого макрос HTONS().
01074  */
01075 #ifndef htons
01076 u16_t htons(u16_t val);
01077 #endif /* htons */
01078 #ifndef ntohs
01079 #define ntohs htons
01080 #endif
01081 
01082 /** @} */
01083 
01084 /**
01085  * Указатель на данные приложения, находящиеся в буфере пакета.
01086  *
01087  * Этот указатель указывает на данные приложения, когда вызывается функция
01088  * приложения. Если приложению нужно отправить данные, то оно может
01089  * использовать это пространство для записи туда данных перед вызовом
01090  * uip_send().
01091  */
01092 extern void *uip_appdata;
01093 
01094 #if UIP_URGDATA > 0
01095 /* u8_t *uip_urgdata:
01096  *
01097  * Этот указатель указывает на любые urgent data, которые были приняты.
01098  * Он представлен, если была разрешена компиляция поддержки urgent data
01099  * (UIP_URGDATA).
01100  */
01101 extern void *uip_urgdata;
01102 #endif /* UIP_URGDATA > 0 */
01103 
01104 
01105 /**
01106  * \defgroup uipdrivervars Переменные, используемые драйверами устройства uIP
01107  * @{
01108  *
01109  * uIP имеет несколько глобальных переменных, которе используются в драйверах
01110  * устройства для uIP.
01111  */
01112 
01113 /**
01114  * Длина пакета в буфере uip_buf.
01115  *
01116  * Глобальная переменная uip_len содержит длину пакета в буфере
01117  * uip_buf.
01118  *
01119  * Когда сетевой драйвер устройства вызывает функцию ввода uIP, переменная 
01120  * uip_len должна быть установлена на значение длины пакета в буфере
01121  * uip_buf.
01122  *
01123  * Когда отправляются пакеты, драйвер устройства должен использовать содержимое
01124  * переменной uip_len, чтобы определить длину уходящего пакета.
01125  *
01126  */
01127 extern u16_t uip_len;
01128 
01129 /** @} */
01130 
01131 #if UIP_URGDATA > 0
01132 extern u16_t uip_urglen, uip_surglen;
01133 #endif /* UIP_URGDATA > 0 */
01134 
01135 
01136 /**
01137  * Представление соединения TCP в стеке uIP.
01138  *
01139  * Структура uip_conn используется для идентификации соединения. Все поля
01140  * структуры, кроме одного, считаются для приложения полями только для 
01141  * чтения. Исключение составляет поле appstate, назначение которого - 
01142  * разрешить приложению сохранить свое состояние (например, файловые
01143  * указатели) для соединения. Тип этого поля конфигурируется в файле
01144  * заголовка "uipopt.h".
01145  */
01146 struct uip_conn {
01147   uip_ipaddr_t ripaddr;    /**< Адрес IP для remote host. */
01148   
01149   u16_t lport;             /**< Локальный порт TCP, с сетевым порядком байт. */
01150   u16_t rport;             /**< Локальная копия порта TCP дальней стороны
01151                                 соединения, с сетевым порядком байт. */
01152   
01153   u8_t rcv_nxt[4];         /**< Номер последоательности, который ожидается
01154                                 следующим для приема. */
01155   u8_t snd_nxt[4];         /**< Номер последовательности, который был нами
01156                                 отправлен последним. */
01157   u16_t len;               /**< Длина ранее отправленных данных. */
01158   u16_t mss;               /**< Текущий максимальный размер сегмента для
01159                                 соединения. */
01160   u16_t initialmss;        /**< Начальный максимальный размер сегмента для
01161                                 соединения. */
01162   u8_t sa;                 /**< Переменная состояния вычисления таймаута
01163                                 ретрансмиссии. */
01164   u8_t sv;                 /**< Переменная состояния вычисления таймаута
01165                                 ретрансмиссии. */
01166   u8_t rto;                /**< Таймаут ретрансмиссии. */
01167   u8_t tcpstateflags;      /**< Состояние и флаги TCP. */
01168   u8_t timer;              /**< Таймер ретрансмиссии. */
01169   u8_t nrtx;               /**< Количество ретрансмиссий, отправленных для
01170                                 последнего посланного сегмента. */
01171 
01172   /** Переменная состояния приложения. */
01173   uip_tcp_appstate_t appstate;
01174 };
01175 
01176 
01177 /**
01178  * Указатель на текущее соединение TCP.
01179  *
01180  * Указатель uip_conn может использоваться для доступа к текущему 
01181  * соединению TCP.
01182  */
01183 extern struct uip_conn *uip_conn;
01184 /* Массив, содержащий все соединения uIP. */
01185 extern struct uip_conn uip_conns[UIP_CONNS];
01186 /**
01187  * \addtogroup uiparch
01188  * @{
01189  */
01190 
01191 /**
01192  * 4-байтовый массив для вычисления 32-битного номера последовательности.
01193  */
01194 extern u8_t uip_acc32[4];
01195 
01196 /** @} */
01197 
01198 
01199 #if UIP_UDP
01200 /**
01201  * Представление соединения UDP в стеке uIP.
01202  */
01203 struct uip_udp_conn {
01204   uip_ipaddr_t ripaddr;    /**< Адрес IP дальнего участника соединения. */
01205   u16_t lport;             /**< Локальный номер порта с сетевым порядком байт. */
01206   u16_t rport;             /**< Номер порта дальнего участника соединения,
01207                                 с сетевым порядком байт. */
01208   u8_t  ttl;               /**< Время жизни по умолчанию (time-to-live). */
01209 
01210   /** Переменная состояния приложения. */
01211   uip_udp_appstate_t appstate;
01212 };
01213 
01214 /**
01215  * Текущее соединение UDP.
01216  */
01217 extern struct uip_udp_conn *uip_udp_conn;
01218 extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
01219 #endif /* UIP_UDP */
01220 
01221 /**
01222  * Структура содержит статистику TCP/IP, которая собирается, если значение
01223  * UIP_STATISTICS установлено в 1.
01224  *
01225  */
01226 struct uip_stats {
01227   struct {
01228     uip_stats_t drop;      /**< Количество отброшенных пакетов на слое IP. */
01229     uip_stats_t recv;      /**< Количество принятых пакетов на слое IP. */
01230     uip_stats_t sent;      /**< Количество отправленных пакетов на слое IP. */
01231     uip_stats_t vhlerr;    /**< Количество отброшенных пакетов по причине
01232                                 ошибочной версии IP или длины заголовка. */
01233     uip_stats_t hblenerr;  /**< Количество отброшенных пакетов по причине
01234                                 ошибочной длины IP, старший байт. */
01235     uip_stats_t lblenerr;  /**< Количество отброшенных пакетов по причине
01236                                 ошибочной длины IP, младший байт. */
01237     uip_stats_t fragerr;   /**< Количество отброшенных пакетов по той причине,
01238                                 что они были IP-фрагментами. */
01239     uip_stats_t chkerr;    /**< Количество отброшенных пакетов из-за ошибок
01240                                 контрольной суммы IP. */
01241     uip_stats_t protoerr;  /**< Количество отброшенных пакетов по той причине,
01242                                 что не были пакетами ICMP, UDP или TCP. */
01243   } ip;                    /**< Статистические данные IP. */
01244   struct {
01245     uip_stats_t drop;      /**< Количество отброшенных пакетов ICMP. */
01246     uip_stats_t recv;      /**< Количество принятых пакетов ICMP. */
01247     uip_stats_t sent;      /**< Количество отправленных пакетов ICMP. */
01248     uip_stats_t typeerr;   /**< Количество пакетов ICMP неправильного типа. */
01249   } icmp;                  /**< Статистические данные ICMP. */
01250   struct {
01251     uip_stats_t drop;      /**< Количество отброшенных сегментов TCP. */
01252     uip_stats_t recv;      /**< Количество принятых сегментов TCP. */
01253     uip_stats_t sent;      /**< Количество отправленных сегментов TCP. */
01254     uip_stats_t chkerr;    /**< Количество сегментов TCP с ошибкой
01255                                 в контрольной сумме. */
01256     uip_stats_t ackerr;    /**< Количество сегментов TCP с ошибочным
01257                                 номером ACK. */
01258     uip_stats_t rst;       /**< Количество принятых сегментов TCP RST (сброс). */
01259     uip_stats_t rexmit;    /**< Количество повторно отправленных сегментов TCP. */
01260     uip_stats_t syndrop;   /**< Количество отброшенных SYN-ов из-за слишком малого
01261                                 количества доступных соединений. */
01262     uip_stats_t synrst;    /**< Количество SYN-ов для закрытых портов,
01263                                 инициировавших RST. */
01264   } tcp;                   /**< Статистические данные TCP. */
01265 #if UIP_UDP
01266   struct {
01267     uip_stats_t drop;      /**< Количество отброшенных сегментов UDP. */
01268     uip_stats_t recv;      /**< Количество принятых сегментов UDP. */
01269     uip_stats_t sent;      /**< Количество отправленных сегментов UDP. */
01270     uip_stats_t chkerr;    /**< Количество сегментов UDP с ошибкой
01271                                 в контрольной сумме. */
01272   } udp;                   /**< Статистические данные UDP. */
01273 #endif /* UIP_UDP */
01274 };
01275 
01276 /**
01277  * Статистическая инфрмация uIP TCP/IP.
01278  *
01279  * Это переменная, в которой собирается статистика uIP TCP/IP.
01280  */
01281 extern struct uip_stats uip_stat;
01282 
01283 
01284 /*---------------------------------------------------------------------------*/
01285 /* Все, что находится ниже этой точки, задействовано внутри uIP и не должно
01286  * использоваться напрямую в приложении или в драйвере устройства.
01287  */
01288 /*---------------------------------------------------------------------------*/
01289 /* u8_t uip_flags:
01290  *
01291  * Когда вызывается функция приложения, uip_flags будет содержать флаги,
01292  * которые заданы в этом файле.
01293  */
01294 extern u8_t uip_flags;
01295 
01296 /* Следующие флаги могут быть установлены в глобальной переменной uip_flags
01297    перед вызовом функции обратного вызова приложения (application callback).
01298    Флаги UIP_ACKDATA, UIP_NEWDATA и UIP_CLOSE могут быть установлены в одно
01299    и то же время, в то время как другие являются взаимоисключающими.
01300    Обратите внимание на то, что эти флаги *НЕ ДОЛЖНЫ* быть исползованы
01301    напрямую, в обход специальных макросов и функций uIP. */
01302 
01303 #define UIP_ACKDATA   1    /* Показывает, что переданные данные были
01304                               подтверждены, и приложение может отправить
01305                               новые данные вместо ретрансмиссии ранее 
01306                               отправленных. */
01307 #define UIP_NEWDATA   2    /* Показывает, что дальний участник обмена
01308                               отправил нам новые данные. */
01309 #define UIP_REXMIT    4    /* Говорит приложению отправить заново данные,
01310                               которые были отправлены последний раз. */
01311 #define UIP_POLL      8    /* Используется для опроса приложения, чтобы
01312                               проверить, есть ли у приложения данные,
01313                               которые оно хотело бы отправить. */
01314 #define UIP_CLOSE     16   /* Участник обмена (remote host) закрыл соединение,
01315                               так что соединение завершилось. Или приложение
01316                               сигнализирует, что оно хотело бы завершить
01317                               соединение. */
01318 #define UIP_ABORT     32   /* Участник обмена (remote host) оборвал соединение,
01319                               так что соединение завершилось. Или приложение
01320                               сигнализирует, что оно хотело бы оборвать
01321                               соединение. */
01322 #define UIP_CONNECTED 64   /* У нас есть соединение от remote host, и для него
01323                               установлено новое соединение, или активное соединение
01324                               было успешно установлено. */
01325 
01326 #define UIP_TIMEDOUT  128  /* Соединение было оборвано (aborted) из-за слишком
01327                               большого количества повторных передач. */
01328 
01329 /* uip_process(flag):
01330  *
01331  * Действительная функция uIP, которая делает всю работу.
01332  */
01333 void uip_process(u8_t flag);
01334 
01335 /* Следующие флаги передаются в качестве аргумента для функции uip_process().
01336    Они используются для того, чтобы отличить друг от друга два случая вызова
01337    uip_process(). Вызов может быть либо по причине наличия принятых данных,
01338    которые должны быть обработаны, либо потому, что сработал периодический 
01339    таймер. Эти значения никогда не должны использоваться напрямую, только
01340    в макросах, которые определены в этом файле. */
01341  
01342 #define UIP_DATA          1   /* Говорит для uIP, что в буфере uip_buf
01343                                  есть поступившие данные. Длина данных
01344                                  сохранена в глобальной переменной uip_len. */
01345 #define UIP_TIMER         2   /* Говорит для uIP, что сработал периодический
01346                                  таймер. */
01347 #define UIP_POLL_REQUEST  3   /* Говорит для uIP, что должно быть опрошено
01348                                  соединение. */
01349 #define UIP_UDP_SEND_CONN 4   /* Говорит для uIP, что в буфере uip_buf 
01350                                  должна быть создана датаграмма UDP. */
01351 #if UIP_UDP
01352 #define UIP_UDP_TIMER     5
01353 #endif /* UIP_UDP */
01354 
01355 /* Состояния TCP, используемые в uip_conn->tcpstateflags. */
01356 #define UIP_CLOSED      0
01357 #define UIP_SYN_RCVD    1
01358 #define UIP_SYN_SENT    2
01359 #define UIP_ESTABLISHED 3
01360 #define UIP_FIN_WAIT_1  4
01361 #define UIP_FIN_WAIT_2  5
01362 #define UIP_CLOSING     6
01363 #define UIP_TIME_WAIT   7
01364 #define UIP_LAST_ACK    8
01365 #define UIP_TS_MASK     15
01366   
01367 #define UIP_STOPPED      16
01368 
01369 /* Заголовки TCP и IP. */
01370 struct uip_tcpip_hdr {
01371 #if UIP_CONF_IPV6
01372   /* Заголовок IPv6. */
01373   u8_t vtc,
01374     tcflow;
01375   u16_t flow;
01376   u8_t len[2];
01377   u8_t proto, ttl;
01378   uip_ip6addr_t srcipaddr, destipaddr;
01379 #else /* UIP_CONF_IPV6 */
01380   /* Заголовок IPv4. */
01381   u8_t vhl,
01382     tos,
01383     len[2],
01384     ipid[2],
01385     ipoffset[2],
01386     ttl,
01387     proto;
01388   u16_t ipchksum;
01389   u16_t srcipaddr[2],
01390     destipaddr[2];
01391 #endif /* UIP_CONF_IPV6 */
01392   
01393   /* Заголовок TCP. */
01394   u16_t srcport,
01395     destport;
01396   u8_t seqno[4],
01397     ackno[4],
01398     tcpoffset,
01399     flags,
01400     wnd[2];
01401   u16_t tcpchksum;
01402   u8_t urgp[2];
01403   u8_t optdata[4];
01404 };
01405 
01406 /* Заголовки ICMP и IP. */
01407 struct uip_icmpip_hdr {
01408 #if UIP_CONF_IPV6
01409   /* Заголовок IPv6. */
01410   u8_t vtc,
01411     tcf;
01412   u16_t flow;
01413   u8_t len[2];
01414   u8_t proto, ttl;
01415   uip_ip6addr_t srcipaddr, destipaddr;
01416 #else /* UIP_CONF_IPV6 */
01417   /* Заголовок IPv4. */
01418   u8_t vhl,
01419     tos,
01420     len[2],
01421     ipid[2],
01422     ipoffset[2],
01423     ttl,
01424     proto;
01425   u16_t ipchksum;
01426   u16_t srcipaddr[2],
01427     destipaddr[2];
01428 #endif /* UIP_CONF_IPV6 */
01429   
01430   /* Заголовок ICMP (echo). */
01431   u8_t type, icode;
01432   u16_t icmpchksum;
01433 #if !UIP_CONF_IPV6
01434   u16_t id, seqno;
01435 #else /* !UIP_CONF_IPV6 */
01436   u8_t flags, reserved1, reserved2, reserved3;
01437   u8_t icmp6data[16];
01438   u8_t options[1];
01439 #endif /* !UIP_CONF_IPV6 */
01440 };
01441 
01442 
01443 /* Заголовки UDP и IP. */
01444 struct uip_udpip_hdr {
01445 #if UIP_CONF_IPV6
01446   /* Заголовок IPv6. */
01447   u8_t vtc,
01448     tcf;
01449   u16_t flow;
01450   u8_t len[2];
01451   u8_t proto, ttl;
01452   uip_ip6addr_t srcipaddr, destipaddr;
01453 #else /* UIP_CONF_IPV6 */
01454   /* Заголовок IP. */
01455   u8_t vhl,
01456     tos,
01457     len[2],
01458     ipid[2],
01459     ipoffset[2],
01460     ttl,
01461     proto;
01462   u16_t ipchksum;
01463   u16_t srcipaddr[2],
01464     destipaddr[2];
01465 #endif /* UIP_CONF_IPV6 */
01466   
01467   /* Заголовок UDP. */
01468   u16_t srcport,
01469     destport;
01470   u16_t udplen;
01471   u16_t udpchksum;
01472 };
01473 
01474 
01475 
01476 /**
01477  * Размер пространства, доступного для данных пользователей в буфере \ref uip_buf.
01478  *
01479  * Этот макрос содержит доступное место для данных пользователя в буфере \ref
01480  * uip_buf. Макрос предназначен для проверки границ доступных для пользователя данных.
01481  *
01482  * Пример:
01483  \code
01484  snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
01485  \endcode
01486  *
01487  * \hideinitializer
01488  */
01489 #define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
01490 
01491 
01492 #define UIP_PROTO_ICMP  1
01493 #define UIP_PROTO_TCP   6
01494 #define UIP_PROTO_UDP   17
01495 #define UIP_PROTO_ICMP6 58
01496 
01497 /* Размеры для заголовков. */
01498 #if UIP_CONF_IPV6
01499 #define UIP_IPH_LEN    40
01500 #else /* UIP_CONF_IPV6 */
01501 #define UIP_IPH_LEN    20    /* Размер заголовка IP */
01502 #endif /* UIP_CONF_IPV6 */
01503 #define UIP_UDPH_LEN    8    /* Размер заголовка UDP */
01504 #define UIP_TCPH_LEN   20    /* Размер заголовка TCP */
01505 #define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)    /* Размер для
01506                                                           заголовка IP + UDP */
01507 #define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN)    /* Размер для
01508                                                           заголовка IP + TCP */
01509 #define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
01510 
01511 
01512 #if UIP_FIXEDADDR
01513 extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
01514 #else /* UIP_FIXEDADDR */
01515 extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
01516 #endif /* UIP_FIXEDADDR */
01517 
01518 
01519 
01520 /**
01521  * Представление 48-битного адреса Ethernet.
01522  */
01523 struct uip_eth_addr {
01524   u8_t addr[6];
01525 };
01526 
01527 /**
01528  * Вычисление контрольной суммы Internet для данных буфера.
01529  *
01530  * Контрольная сумма Internet - это поразрядное дополнение до 1 
01531  * суммы поразрядного дополнения всех 16-битных слов в буфере.
01532  *
01533  * См. RFC1071.
01534  *
01535  * \param buf Указатель на буфер, от которого вычисляется контрольная
01536  * сумма.
01537  *
01538  * \param len Длина буфера, от которого вычисляется контрольная
01539  * сумма.
01540  *
01541  * \return The Контрольная сумма Internet для буфера.
01542  */
01543 u16_t uip_chksum(u16_t *buf, u16_t len);
01544 
01545 /**
01546  * Вычисление контрольной суммы заголовка IP для заголовка пакета 
01547  * в буфере uip_buf.
01548  *
01549  * Контрольная сумма заголовка IP является контрольной суммой Internet
01550  * от 20 байт заголовка IP.
01551  *
01552  * \return Контрольная сумма заголовка IP для заголовка IP в 
01553  * в буфере uip_buf.
01554  */
01555 u16_t uip_ipchksum(void);
01556 
01557 /**
01558  * Вычисление контрольной суммы TCP для пакета в uip_buf и uip_appdata.
01559  *
01560  * Контрольная сумма TCP является контрольной суммой Internet от содержимого
01561  * данных сегмента TCP, и псевдозаголовка, определенного в RFC793.
01562  *
01563  * \return Контрольная сумма TCP сегмента TCP в uip_buf, на который
01564  * указывает uip_appdata.
01565  */
01566 u16_t uip_tcpchksum(void);
01567 
01568 /**
01569  * Вычисление контрольной суммы UDP для пакета в uip_buf и uip_appdata.
01570  *
01571  * Контрольная сумма UDP является контрольной суммой Internet от содержимого
01572  * данных сегмента UDP, и псевдозаголовка, определенного в RFC768.
01573  *
01574  * \return Контрольная сумма UDP сегмента UDP segment в uip_buf, на который
01575  * указывает uip_appdata.
01576  */
01577 u16_t uip_udpchksum(void);
01578 
01579 
01580 #endif /* __UIP_H__ */
01581 
01582 
01583 /** @} */