uIP 1.0
C:/asm/STM32-ethernet/ENC28J60prj/uip-master/uip/uip-split.c
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: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $
00035  */
00036 
00037 #include <string.h>
00038 
00039 #include "uip-split.h"
00040 #include "uip.h"
00041 #include "uip-fw.h"
00042 #include "uip_arch.h"
00043 
00044 
00045 
00046 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00047 
00048 /*-----------------------------------------------------------------------------*/
00049 void
00050 uip_split_output(void)
00051 {
00052   u16_t tcplen, len1, len2;
00053 
00054   /* Будем пытаться разбить только сегменты TCP максимального размера. */
00055   if(BUF->proto == UIP_PROTO_TCP &&
00056      uip_len == UIP_BUFSIZE - UIP_LLH_LEN) {
00057 
00058     tcplen = uip_len - UIP_TCPIP_HLEN;
00059     /* Разделение сегмента на 2 частиo. Если длина оригинального пакета была
00060        нечетной, то второй пакет сделаем на 1 байт больше. */
00061     len1 = len2 = tcplen / 2;
00062     if(len1 + len2 < tcplen) {
00063       ++len2;
00064     }
00065 
00066     /* Создание первого пакета. Это делается изменением поля длины
00067        заголовка IP и обновлением контрольных сумм. */
00068     uip_len = len1 + UIP_TCPIP_HLEN;
00069 #if UIP_CONF_IPV6
00070     /* Для IPv6 длина поля IP не включает длину IP заголовка IPv6. */
00071     BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
00072     BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
00073 #else /* UIP_CONF_IPV6 */
00074     BUF->len[0] = uip_len >> 8;
00075     BUF->len[1] = uip_len & 0xff;
00076 #endif /* UIP_CONF_IPV6 */
00077     
00078     /* Пересчет контрольной суммы TCP. */
00079     BUF->tcpchksum = 0;
00080     BUF->tcpchksum = ~(uip_tcpchksum());
00081 
00082 #if !UIP_CONF_IPV6
00083     /* Пересчет контрольной суммы IP. */
00084     BUF->ipchksum = 0;
00085     BUF->ipchksum = ~(uip_ipchksum());
00086 #endif /* UIP_CONF_IPV6 */
00087     
00088     /* Передача первого пакета. */
00089     /*    uip_fw_output();*/
00090     tcpip_output();
00091 
00092     /* Теперь создадим второй пакет. Чтобы это сделать, недостаточно
00093        просто поменять поле длины, нужно также обновить номер 
00094        последовательности TCP и указать uip_appdata на новое место
00095        в памяти. Это место определяется из длины первого пакета (len1). */
00096     uip_len = len2 + UIP_TCPIP_HLEN;
00097 #if UIP_CONF_IPV6
00098     /* Для IPv6 длина поля IP не включает длину IP заголовка IPv6. */
00099     BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
00100     BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
00101 #else /* UIP_CONF_IPV6 */
00102     BUF->len[0] = uip_len >> 8;
00103     BUF->len[1] = uip_len & 0xff;
00104 #endif /* UIP_CONF_IPV6 */
00105     
00106     /*    uip_appdata += len1;*/
00107     memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);
00108 
00109     uip_add32(BUF->seqno, len1);
00110     BUF->seqno[0] = uip_acc32[0];
00111     BUF->seqno[1] = uip_acc32[1];
00112     BUF->seqno[2] = uip_acc32[2];
00113     BUF->seqno[3] = uip_acc32[3];
00114     
00115     /* Пересчет контрольной суммы TCP. */
00116     BUF->tcpchksum = 0;
00117     BUF->tcpchksum = ~(uip_tcpchksum());
00118 
00119 #if !UIP_CONF_IPV6
00120     /* Пересчет контрольной суммы IP. */
00121     BUF->ipchksum = 0;
00122     BUF->ipchksum = ~(uip_ipchksum());
00123 #endif /* UIP_CONF_IPV6 */
00124 
00125     /* Передача второго пакета. */
00126     /*    uip_fw_output();*/
00127     tcpip_output();
00128   } else {
00129     /*    uip_fw_output();*/
00130     tcpip_output();
00131   }
00132      
00133 }
00134 /*-----------------------------------------------------------------------------*/