These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!
EMAC/Easy_Web/tcpip.c@0:bf7b9fba3924, 2011-03-20 (annotated)
- Committer:
- frank26080115
- Date:
- Sun Mar 20 05:38:56 2011 +0000
- Revision:
- 0:bf7b9fba3924
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
frank26080115 | 0:bf7b9fba3924 | 1 | /****************************************************************** |
frank26080115 | 0:bf7b9fba3924 | 2 | ***** ***** |
frank26080115 | 0:bf7b9fba3924 | 3 | ***** Name: tcpip.c ***** |
frank26080115 | 0:bf7b9fba3924 | 4 | ***** Ver.: 1.0 ***** |
frank26080115 | 0:bf7b9fba3924 | 5 | ***** Date: 07/05/2001 ***** |
frank26080115 | 0:bf7b9fba3924 | 6 | ***** Auth: Andreas Dannenberg ***** |
frank26080115 | 0:bf7b9fba3924 | 7 | ***** HTWK Leipzig ***** |
frank26080115 | 0:bf7b9fba3924 | 8 | ***** university of applied sciences ***** |
frank26080115 | 0:bf7b9fba3924 | 9 | ***** Germany ***** |
frank26080115 | 0:bf7b9fba3924 | 10 | ***** Func: implements the TCP/IP-stack and provides a ***** |
frank26080115 | 0:bf7b9fba3924 | 11 | ***** simple API to the user ***** |
frank26080115 | 0:bf7b9fba3924 | 12 | ***** ***** |
frank26080115 | 0:bf7b9fba3924 | 13 | ******************************************************************/ |
frank26080115 | 0:bf7b9fba3924 | 14 | |
frank26080115 | 0:bf7b9fba3924 | 15 | #include "tcpip.h" |
frank26080115 | 0:bf7b9fba3924 | 16 | #include "EMAC.h" // Keil: Line added |
frank26080115 | 0:bf7b9fba3924 | 17 | #include <string.h> // Keil: Line added |
frank26080115 | 0:bf7b9fba3924 | 18 | |
frank26080115 | 0:bf7b9fba3924 | 19 | // NXP: Include some header files that diifers from the origin |
frank26080115 | 0:bf7b9fba3924 | 20 | #include "lpc17xx_libcfg.h" |
frank26080115 | 0:bf7b9fba3924 | 21 | #include "lpc17xx_pinsel.h" |
frank26080115 | 0:bf7b9fba3924 | 22 | //#include "lpc17xx_emac.h" |
frank26080115 | 0:bf7b9fba3924 | 23 | #include "adc.h" |
frank26080115 | 0:bf7b9fba3924 | 24 | |
frank26080115 | 0:bf7b9fba3924 | 25 | /* For debugging... */ |
frank26080115 | 0:bf7b9fba3924 | 26 | #include "debug_frmwrk.h" |
frank26080115 | 0:bf7b9fba3924 | 27 | #include <stdio.h> |
frank26080115 | 0:bf7b9fba3924 | 28 | #define DB _DBG((uint8_t *)db_) |
frank26080115 | 0:bf7b9fba3924 | 29 | char db_[64]; |
frank26080115 | 0:bf7b9fba3924 | 30 | uint16_t _tickVal; |
frank26080115 | 0:bf7b9fba3924 | 31 | |
frank26080115 | 0:bf7b9fba3924 | 32 | #ifdef MCB_LPC_1768 |
frank26080115 | 0:bf7b9fba3924 | 33 | #define LED_PIN (1<<6) // P2.6 |
frank26080115 | 0:bf7b9fba3924 | 34 | #define LED2_MASK ((1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6)) |
frank26080115 | 0:bf7b9fba3924 | 35 | #define LED1_MASK ((1<<28) | (1<<29) | (1<<31)) |
frank26080115 | 0:bf7b9fba3924 | 36 | #elif defined(IAR_LPC_1768) |
frank26080115 | 0:bf7b9fba3924 | 37 | #define LED_PIN (1<<25) //P1.25 |
frank26080115 | 0:bf7b9fba3924 | 38 | #define LED2_MASK ((1<<4)) |
frank26080115 | 0:bf7b9fba3924 | 39 | #define LED1_MASK ((1<<25)) |
frank26080115 | 0:bf7b9fba3924 | 40 | #endif |
frank26080115 | 0:bf7b9fba3924 | 41 | |
frank26080115 | 0:bf7b9fba3924 | 42 | const unsigned char MyMAC[6] = // "M1-M2-M3-M4-M5-M6" |
frank26080115 | 0:bf7b9fba3924 | 43 | { |
frank26080115 | 0:bf7b9fba3924 | 44 | MYMAC_1, MYMAC_2, MYMAC_3, |
frank26080115 | 0:bf7b9fba3924 | 45 | MYMAC_4, MYMAC_5, MYMAC_6 |
frank26080115 | 0:bf7b9fba3924 | 46 | }; |
frank26080115 | 0:bf7b9fba3924 | 47 | |
frank26080115 | 0:bf7b9fba3924 | 48 | // NXP LowLevel initializing implementation |
frank26080115 | 0:bf7b9fba3924 | 49 | // System tick period definition (in microsecond) |
frank26080115 | 0:bf7b9fba3924 | 50 | #define SYSTICK_PERIOD 210000UL |
frank26080115 | 0:bf7b9fba3924 | 51 | |
frank26080115 | 0:bf7b9fba3924 | 52 | // System tick interrupt handler prototype |
frank26080115 | 0:bf7b9fba3924 | 53 | void SysTick_Handler (void); |
frank26080115 | 0:bf7b9fba3924 | 54 | |
frank26080115 | 0:bf7b9fba3924 | 55 | void LED_Init (void) |
frank26080115 | 0:bf7b9fba3924 | 56 | { |
frank26080115 | 0:bf7b9fba3924 | 57 | PINSEL_CFG_Type PinCfg; |
frank26080115 | 0:bf7b9fba3924 | 58 | |
frank26080115 | 0:bf7b9fba3924 | 59 | uint8_t temp; |
frank26080115 | 0:bf7b9fba3924 | 60 | #ifdef MCB_LPC_1768 |
frank26080115 | 0:bf7b9fba3924 | 61 | PinCfg.Funcnum = 0; |
frank26080115 | 0:bf7b9fba3924 | 62 | PinCfg.OpenDrain = 0; |
frank26080115 | 0:bf7b9fba3924 | 63 | PinCfg.Pinmode = 0; |
frank26080115 | 0:bf7b9fba3924 | 64 | PinCfg.Portnum = 2; |
frank26080115 | 0:bf7b9fba3924 | 65 | for (temp = 2; temp <= 6; temp++){ |
frank26080115 | 0:bf7b9fba3924 | 66 | PinCfg.Pinnum = temp; |
frank26080115 | 0:bf7b9fba3924 | 67 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 68 | } |
frank26080115 | 0:bf7b9fba3924 | 69 | |
frank26080115 | 0:bf7b9fba3924 | 70 | PinCfg.Funcnum = 0; |
frank26080115 | 0:bf7b9fba3924 | 71 | PinCfg.OpenDrain = 0; |
frank26080115 | 0:bf7b9fba3924 | 72 | PinCfg.Pinmode = 0; |
frank26080115 | 0:bf7b9fba3924 | 73 | PinCfg.Portnum = 1; |
frank26080115 | 0:bf7b9fba3924 | 74 | PinCfg.Pinnum = 28; |
frank26080115 | 0:bf7b9fba3924 | 75 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 76 | PinCfg.Pinnum = 29; |
frank26080115 | 0:bf7b9fba3924 | 77 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 78 | PinCfg.Pinnum = 31; |
frank26080115 | 0:bf7b9fba3924 | 79 | PINSEL_ConfigPin(&PinCfg); |
frank26080115 | 0:bf7b9fba3924 | 80 | |
frank26080115 | 0:bf7b9fba3924 | 81 | // Set direction to output |
frank26080115 | 0:bf7b9fba3924 | 82 | LPC_GPIO2->FIODIR |= LED2_MASK; |
frank26080115 | 0:bf7b9fba3924 | 83 | LPC_GPIO1->FIODIR |= LED1_MASK; |
frank26080115 | 0:bf7b9fba3924 | 84 | |
frank26080115 | 0:bf7b9fba3924 | 85 | /* Turn off all LEDs */ |
frank26080115 | 0:bf7b9fba3924 | 86 | LPC_GPIO2->FIOCLR = LED2_MASK; |
frank26080115 | 0:bf7b9fba3924 | 87 | LPC_GPIO1->FIOCLR = LED1_MASK; |
frank26080115 | 0:bf7b9fba3924 | 88 | #elif defined(IAR_LPC_1768) |
frank26080115 | 0:bf7b9fba3924 | 89 | LPC_GPIO0->FIODIR |= LED2_MASK; |
frank26080115 | 0:bf7b9fba3924 | 90 | LPC_GPIO1->FIODIR |= LED1_MASK; |
frank26080115 | 0:bf7b9fba3924 | 91 | |
frank26080115 | 0:bf7b9fba3924 | 92 | /* Turn off all LEDs */ |
frank26080115 | 0:bf7b9fba3924 | 93 | LPC_GPIO0->FIOSET = LED2_MASK; |
frank26080115 | 0:bf7b9fba3924 | 94 | LPC_GPIO1->FIOSET = LED1_MASK; |
frank26080115 | 0:bf7b9fba3924 | 95 | #endif |
frank26080115 | 0:bf7b9fba3924 | 96 | } |
frank26080115 | 0:bf7b9fba3924 | 97 | // easyWEB-API function |
frank26080115 | 0:bf7b9fba3924 | 98 | // initalizes the LAN-controller, reset flags, starts timer-ISR |
frank26080115 | 0:bf7b9fba3924 | 99 | |
frank26080115 | 0:bf7b9fba3924 | 100 | void TCPLowLevelInit(void) |
frank26080115 | 0:bf7b9fba3924 | 101 | { |
frank26080115 | 0:bf7b9fba3924 | 102 | // ADC initializing |
frank26080115 | 0:bf7b9fba3924 | 103 | ADC_init(); |
frank26080115 | 0:bf7b9fba3924 | 104 | |
frank26080115 | 0:bf7b9fba3924 | 105 | // Initialize LED for system tick timer |
frank26080115 | 0:bf7b9fba3924 | 106 | LED_Init(); |
frank26080115 | 0:bf7b9fba3924 | 107 | |
frank26080115 | 0:bf7b9fba3924 | 108 | /* Initialize debug via UART0 |
frank26080115 | 0:bf7b9fba3924 | 109 | * 115200bps |
frank26080115 | 0:bf7b9fba3924 | 110 | * 8 data bit |
frank26080115 | 0:bf7b9fba3924 | 111 | * No parity |
frank26080115 | 0:bf7b9fba3924 | 112 | * 1 stop bit |
frank26080115 | 0:bf7b9fba3924 | 113 | * No flow control |
frank26080115 | 0:bf7b9fba3924 | 114 | */ |
frank26080115 | 0:bf7b9fba3924 | 115 | debug_frmwrk_init(); |
frank26080115 | 0:bf7b9fba3924 | 116 | _DBG_("Hello NXP EMAC"); |
frank26080115 | 0:bf7b9fba3924 | 117 | |
frank26080115 | 0:bf7b9fba3924 | 118 | Init_EMAC(); |
frank26080115 | 0:bf7b9fba3924 | 119 | TransmitControl = 0; |
frank26080115 | 0:bf7b9fba3924 | 120 | TCPFlags = 0; |
frank26080115 | 0:bf7b9fba3924 | 121 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 122 | SocketStatus = 0; |
frank26080115 | 0:bf7b9fba3924 | 123 | |
frank26080115 | 0:bf7b9fba3924 | 124 | // NXP: Initialize System tick timer |
frank26080115 | 0:bf7b9fba3924 | 125 | // Generate interrupt each SYSTICK_PERIOD microsecond |
frank26080115 | 0:bf7b9fba3924 | 126 | if (SysTick_Config((4000000/1000000)*SYSTICK_PERIOD)){ |
frank26080115 | 0:bf7b9fba3924 | 127 | // Capture error |
frank26080115 | 0:bf7b9fba3924 | 128 | while (1); |
frank26080115 | 0:bf7b9fba3924 | 129 | } |
frank26080115 | 0:bf7b9fba3924 | 130 | _DBG_("Init LowLevelTCP complete!"); |
frank26080115 | 0:bf7b9fba3924 | 131 | sprintf(db_, "IP Address: %d.%d.%d.%d \n\r", MYIP_1, MYIP_2, MYIP_3, MYIP_4); |
frank26080115 | 0:bf7b9fba3924 | 132 | DB; |
frank26080115 | 0:bf7b9fba3924 | 133 | } |
frank26080115 | 0:bf7b9fba3924 | 134 | |
frank26080115 | 0:bf7b9fba3924 | 135 | // easyWEB-API function |
frank26080115 | 0:bf7b9fba3924 | 136 | // does a passive open (listen on 'MyIP:TCPLocalPort' for an incoming |
frank26080115 | 0:bf7b9fba3924 | 137 | // connection) |
frank26080115 | 0:bf7b9fba3924 | 138 | |
frank26080115 | 0:bf7b9fba3924 | 139 | void TCPPassiveOpen(void) |
frank26080115 | 0:bf7b9fba3924 | 140 | { |
frank26080115 | 0:bf7b9fba3924 | 141 | if (TCPStateMachine == CLOSED) |
frank26080115 | 0:bf7b9fba3924 | 142 | { |
frank26080115 | 0:bf7b9fba3924 | 143 | TCPFlags &= ~TCP_ACTIVE_OPEN; // let's do a passive open! |
frank26080115 | 0:bf7b9fba3924 | 144 | TCPStateMachine = LISTENING; |
frank26080115 | 0:bf7b9fba3924 | 145 | SocketStatus = SOCK_ACTIVE; // reset, socket now active |
frank26080115 | 0:bf7b9fba3924 | 146 | } |
frank26080115 | 0:bf7b9fba3924 | 147 | } |
frank26080115 | 0:bf7b9fba3924 | 148 | |
frank26080115 | 0:bf7b9fba3924 | 149 | // easyWEB-API function |
frank26080115 | 0:bf7b9fba3924 | 150 | // does an active open (tries to establish a connection between |
frank26080115 | 0:bf7b9fba3924 | 151 | // 'MyIP:TCPLocalPort' and 'RemoteIP:TCPRemotePort') |
frank26080115 | 0:bf7b9fba3924 | 152 | |
frank26080115 | 0:bf7b9fba3924 | 153 | void TCPActiveOpen(void) |
frank26080115 | 0:bf7b9fba3924 | 154 | { |
frank26080115 | 0:bf7b9fba3924 | 155 | if ((TCPStateMachine == CLOSED) || (TCPStateMachine == LISTENING)) |
frank26080115 | 0:bf7b9fba3924 | 156 | { |
frank26080115 | 0:bf7b9fba3924 | 157 | TCPFlags |= TCP_ACTIVE_OPEN; // let's do an active open! |
frank26080115 | 0:bf7b9fba3924 | 158 | TCPFlags &= ~IP_ADDR_RESOLVED; // we haven't opponents MAC yet |
frank26080115 | 0:bf7b9fba3924 | 159 | |
frank26080115 | 0:bf7b9fba3924 | 160 | PrepareARP_REQUEST(); // ask for MAC by sending a broadcast |
frank26080115 | 0:bf7b9fba3924 | 161 | LastFrameSent = ARP_REQUEST; |
frank26080115 | 0:bf7b9fba3924 | 162 | TCPStartRetryTimer(); |
frank26080115 | 0:bf7b9fba3924 | 163 | SocketStatus = SOCK_ACTIVE; // reset, socket now active |
frank26080115 | 0:bf7b9fba3924 | 164 | } |
frank26080115 | 0:bf7b9fba3924 | 165 | } |
frank26080115 | 0:bf7b9fba3924 | 166 | |
frank26080115 | 0:bf7b9fba3924 | 167 | // easyWEB-API function |
frank26080115 | 0:bf7b9fba3924 | 168 | // closes an open connection |
frank26080115 | 0:bf7b9fba3924 | 169 | |
frank26080115 | 0:bf7b9fba3924 | 170 | void TCPClose(void) |
frank26080115 | 0:bf7b9fba3924 | 171 | { |
frank26080115 | 0:bf7b9fba3924 | 172 | switch (TCPStateMachine) |
frank26080115 | 0:bf7b9fba3924 | 173 | { |
frank26080115 | 0:bf7b9fba3924 | 174 | case LISTENING : |
frank26080115 | 0:bf7b9fba3924 | 175 | case SYN_SENT : |
frank26080115 | 0:bf7b9fba3924 | 176 | { |
frank26080115 | 0:bf7b9fba3924 | 177 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 178 | TCPFlags = 0; |
frank26080115 | 0:bf7b9fba3924 | 179 | SocketStatus = 0; |
frank26080115 | 0:bf7b9fba3924 | 180 | break; |
frank26080115 | 0:bf7b9fba3924 | 181 | } |
frank26080115 | 0:bf7b9fba3924 | 182 | case SYN_RECD : |
frank26080115 | 0:bf7b9fba3924 | 183 | case ESTABLISHED : |
frank26080115 | 0:bf7b9fba3924 | 184 | { |
frank26080115 | 0:bf7b9fba3924 | 185 | TCPFlags |= TCP_CLOSE_REQUESTED; |
frank26080115 | 0:bf7b9fba3924 | 186 | break; |
frank26080115 | 0:bf7b9fba3924 | 187 | } |
frank26080115 | 0:bf7b9fba3924 | 188 | } |
frank26080115 | 0:bf7b9fba3924 | 189 | } |
frank26080115 | 0:bf7b9fba3924 | 190 | |
frank26080115 | 0:bf7b9fba3924 | 191 | // easyWEB-API function |
frank26080115 | 0:bf7b9fba3924 | 192 | // releases the receive-buffer and allows easyWEB to store new data |
frank26080115 | 0:bf7b9fba3924 | 193 | // NOTE: rx-buffer MUST be released periodically, else the other TCP |
frank26080115 | 0:bf7b9fba3924 | 194 | // get no ACKs for the data it sent |
frank26080115 | 0:bf7b9fba3924 | 195 | |
frank26080115 | 0:bf7b9fba3924 | 196 | void TCPReleaseRxBuffer(void) |
frank26080115 | 0:bf7b9fba3924 | 197 | { |
frank26080115 | 0:bf7b9fba3924 | 198 | SocketStatus &= ~SOCK_DATA_AVAILABLE; |
frank26080115 | 0:bf7b9fba3924 | 199 | } |
frank26080115 | 0:bf7b9fba3924 | 200 | |
frank26080115 | 0:bf7b9fba3924 | 201 | // easyWEB-API function |
frank26080115 | 0:bf7b9fba3924 | 202 | // transmitts data stored in 'TCP_TX_BUF' |
frank26080115 | 0:bf7b9fba3924 | 203 | // NOTE: * number of bytes to transmit must have been written to 'TCPTxDataCount' |
frank26080115 | 0:bf7b9fba3924 | 204 | // * data-count MUST NOT exceed 'MAX_TCP_TX_DATA_SIZE' |
frank26080115 | 0:bf7b9fba3924 | 205 | |
frank26080115 | 0:bf7b9fba3924 | 206 | void TCPTransmitTxBuffer(void) |
frank26080115 | 0:bf7b9fba3924 | 207 | { |
frank26080115 | 0:bf7b9fba3924 | 208 | if ((TCPStateMachine == ESTABLISHED) || (TCPStateMachine == CLOSE_WAIT)) |
frank26080115 | 0:bf7b9fba3924 | 209 | if (SocketStatus & SOCK_TX_BUF_RELEASED) |
frank26080115 | 0:bf7b9fba3924 | 210 | { |
frank26080115 | 0:bf7b9fba3924 | 211 | SocketStatus &= ~SOCK_TX_BUF_RELEASED; // occupy tx-buffer |
frank26080115 | 0:bf7b9fba3924 | 212 | TCPUNASeqNr += TCPTxDataCount; // advance UNA |
frank26080115 | 0:bf7b9fba3924 | 213 | |
frank26080115 | 0:bf7b9fba3924 | 214 | TxFrame1Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount; |
frank26080115 | 0:bf7b9fba3924 | 215 | TransmitControl |= SEND_FRAME1; |
frank26080115 | 0:bf7b9fba3924 | 216 | |
frank26080115 | 0:bf7b9fba3924 | 217 | LastFrameSent = TCP_DATA_FRAME; |
frank26080115 | 0:bf7b9fba3924 | 218 | TCPStartRetryTimer(); |
frank26080115 | 0:bf7b9fba3924 | 219 | } |
frank26080115 | 0:bf7b9fba3924 | 220 | } |
frank26080115 | 0:bf7b9fba3924 | 221 | |
frank26080115 | 0:bf7b9fba3924 | 222 | // Reads the length of the received ethernet frame and checks if the |
frank26080115 | 0:bf7b9fba3924 | 223 | // destination address is a broadcast message or not |
frank26080115 | 0:bf7b9fba3924 | 224 | unsigned int IsBroadcast(void) { |
frank26080115 | 0:bf7b9fba3924 | 225 | unsigned short RecdDestMAC[3]; // 48 bit MAC |
frank26080115 | 0:bf7b9fba3924 | 226 | |
frank26080115 | 0:bf7b9fba3924 | 227 | RecdFrameLength = StartReadFrame(); |
frank26080115 | 0:bf7b9fba3924 | 228 | |
frank26080115 | 0:bf7b9fba3924 | 229 | CopyFromFrame_EMAC(&RecdDestMAC, 6); // receive DA to see if it was a broadcast |
frank26080115 | 0:bf7b9fba3924 | 230 | CopyFromFrame_EMAC(&RecdFrameMAC, 6); // store SA (for our answer) |
frank26080115 | 0:bf7b9fba3924 | 231 | |
frank26080115 | 0:bf7b9fba3924 | 232 | if ((RecdDestMAC[0] == 0xFFFF) && |
frank26080115 | 0:bf7b9fba3924 | 233 | (RecdDestMAC[1] == 0xFFFF) && |
frank26080115 | 0:bf7b9fba3924 | 234 | (RecdDestMAC[2] == 0xFFFF)) { |
frank26080115 | 0:bf7b9fba3924 | 235 | return(1); |
frank26080115 | 0:bf7b9fba3924 | 236 | } else { |
frank26080115 | 0:bf7b9fba3924 | 237 | return (0); |
frank26080115 | 0:bf7b9fba3924 | 238 | } |
frank26080115 | 0:bf7b9fba3924 | 239 | } |
frank26080115 | 0:bf7b9fba3924 | 240 | |
frank26080115 | 0:bf7b9fba3924 | 241 | |
frank26080115 | 0:bf7b9fba3924 | 242 | // easyWEB's 'main()'-function |
frank26080115 | 0:bf7b9fba3924 | 243 | // must be called from user program periodically (the often - the better) |
frank26080115 | 0:bf7b9fba3924 | 244 | // handles network, TCP/IP-stack and user events |
frank26080115 | 0:bf7b9fba3924 | 245 | |
frank26080115 | 0:bf7b9fba3924 | 246 | void DoNetworkStuff(void) |
frank26080115 | 0:bf7b9fba3924 | 247 | { |
frank26080115 | 0:bf7b9fba3924 | 248 | if (CheckFrameReceived()) // Packet received |
frank26080115 | 0:bf7b9fba3924 | 249 | { |
frank26080115 | 0:bf7b9fba3924 | 250 | if (IsBroadcast()) { |
frank26080115 | 0:bf7b9fba3924 | 251 | ProcessEthBroadcastFrame(); |
frank26080115 | 0:bf7b9fba3924 | 252 | } else { |
frank26080115 | 0:bf7b9fba3924 | 253 | ProcessEthIAFrame(); |
frank26080115 | 0:bf7b9fba3924 | 254 | } |
frank26080115 | 0:bf7b9fba3924 | 255 | EndReadFrame(); // release buffer in ethernet controller |
frank26080115 | 0:bf7b9fba3924 | 256 | } |
frank26080115 | 0:bf7b9fba3924 | 257 | |
frank26080115 | 0:bf7b9fba3924 | 258 | if (TCPFlags & TCP_TIMER_RUNNING) |
frank26080115 | 0:bf7b9fba3924 | 259 | if (TCPFlags & TIMER_TYPE_RETRY) |
frank26080115 | 0:bf7b9fba3924 | 260 | { |
frank26080115 | 0:bf7b9fba3924 | 261 | if (TCPTimer > RETRY_TIMEOUT) |
frank26080115 | 0:bf7b9fba3924 | 262 | { |
frank26080115 | 0:bf7b9fba3924 | 263 | TCPRestartTimer(); // set a new timeout |
frank26080115 | 0:bf7b9fba3924 | 264 | |
frank26080115 | 0:bf7b9fba3924 | 265 | if (RetryCounter) |
frank26080115 | 0:bf7b9fba3924 | 266 | { |
frank26080115 | 0:bf7b9fba3924 | 267 | TCPHandleRetransmission(); // resend last frame |
frank26080115 | 0:bf7b9fba3924 | 268 | RetryCounter--; |
frank26080115 | 0:bf7b9fba3924 | 269 | } |
frank26080115 | 0:bf7b9fba3924 | 270 | else |
frank26080115 | 0:bf7b9fba3924 | 271 | { |
frank26080115 | 0:bf7b9fba3924 | 272 | TCPStopTimer(); |
frank26080115 | 0:bf7b9fba3924 | 273 | TCPHandleTimeout(); |
frank26080115 | 0:bf7b9fba3924 | 274 | } |
frank26080115 | 0:bf7b9fba3924 | 275 | } |
frank26080115 | 0:bf7b9fba3924 | 276 | } |
frank26080115 | 0:bf7b9fba3924 | 277 | else if (TCPTimer > FIN_TIMEOUT) |
frank26080115 | 0:bf7b9fba3924 | 278 | { |
frank26080115 | 0:bf7b9fba3924 | 279 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 280 | TCPFlags = 0; // reset all flags, stop retransmission... |
frank26080115 | 0:bf7b9fba3924 | 281 | SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags but data available |
frank26080115 | 0:bf7b9fba3924 | 282 | } |
frank26080115 | 0:bf7b9fba3924 | 283 | |
frank26080115 | 0:bf7b9fba3924 | 284 | switch (TCPStateMachine) |
frank26080115 | 0:bf7b9fba3924 | 285 | { |
frank26080115 | 0:bf7b9fba3924 | 286 | case CLOSED : |
frank26080115 | 0:bf7b9fba3924 | 287 | case LISTENING : |
frank26080115 | 0:bf7b9fba3924 | 288 | { |
frank26080115 | 0:bf7b9fba3924 | 289 | if (TCPFlags & TCP_ACTIVE_OPEN) // stack has to open a connection? |
frank26080115 | 0:bf7b9fba3924 | 290 | if (TCPFlags & IP_ADDR_RESOLVED) // IP resolved? |
frank26080115 | 0:bf7b9fba3924 | 291 | if (!(TransmitControl & SEND_FRAME2)) // buffer free? |
frank26080115 | 0:bf7b9fba3924 | 292 | { |
frank26080115 | 0:bf7b9fba3924 | 293 | TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | (SysTick->CURR & 0xFFFF); // NXP: changed from T0TC to SysTick->VAL; |
frank26080115 | 0:bf7b9fba3924 | 294 | // set local ISN |
frank26080115 | 0:bf7b9fba3924 | 295 | TCPUNASeqNr = TCPSeqNr; |
frank26080115 | 0:bf7b9fba3924 | 296 | TCPAckNr = 0; // we don't know what to ACK! |
frank26080115 | 0:bf7b9fba3924 | 297 | TCPUNASeqNr++; // count SYN as a byte |
frank26080115 | 0:bf7b9fba3924 | 298 | PrepareTCP_FRAME(TCP_CODE_SYN); // send SYN frame |
frank26080115 | 0:bf7b9fba3924 | 299 | LastFrameSent = TCP_SYN_FRAME; |
frank26080115 | 0:bf7b9fba3924 | 300 | TCPStartRetryTimer(); // we NEED a retry-timeout |
frank26080115 | 0:bf7b9fba3924 | 301 | TCPStateMachine = SYN_SENT; |
frank26080115 | 0:bf7b9fba3924 | 302 | } |
frank26080115 | 0:bf7b9fba3924 | 303 | break; |
frank26080115 | 0:bf7b9fba3924 | 304 | } |
frank26080115 | 0:bf7b9fba3924 | 305 | case SYN_RECD : |
frank26080115 | 0:bf7b9fba3924 | 306 | case ESTABLISHED : |
frank26080115 | 0:bf7b9fba3924 | 307 | { |
frank26080115 | 0:bf7b9fba3924 | 308 | if (TCPFlags & TCP_CLOSE_REQUESTED) // user has user initated a close? |
frank26080115 | 0:bf7b9fba3924 | 309 | if (!(TransmitControl & (SEND_FRAME2 | SEND_FRAME1))) // buffers free? |
frank26080115 | 0:bf7b9fba3924 | 310 | if (TCPSeqNr == TCPUNASeqNr) // all data ACKed? |
frank26080115 | 0:bf7b9fba3924 | 311 | { |
frank26080115 | 0:bf7b9fba3924 | 312 | TCPUNASeqNr++; |
frank26080115 | 0:bf7b9fba3924 | 313 | PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); |
frank26080115 | 0:bf7b9fba3924 | 314 | LastFrameSent = TCP_FIN_FRAME; |
frank26080115 | 0:bf7b9fba3924 | 315 | TCPStartRetryTimer(); |
frank26080115 | 0:bf7b9fba3924 | 316 | TCPStateMachine = FIN_WAIT_1; |
frank26080115 | 0:bf7b9fba3924 | 317 | } |
frank26080115 | 0:bf7b9fba3924 | 318 | break; |
frank26080115 | 0:bf7b9fba3924 | 319 | } |
frank26080115 | 0:bf7b9fba3924 | 320 | case CLOSE_WAIT : |
frank26080115 | 0:bf7b9fba3924 | 321 | { |
frank26080115 | 0:bf7b9fba3924 | 322 | if (!(TransmitControl & (SEND_FRAME2 | SEND_FRAME1))) // buffers free? |
frank26080115 | 0:bf7b9fba3924 | 323 | if (TCPSeqNr == TCPUNASeqNr) // all data ACKed? |
frank26080115 | 0:bf7b9fba3924 | 324 | { |
frank26080115 | 0:bf7b9fba3924 | 325 | TCPUNASeqNr++; // count FIN as a byte |
frank26080115 | 0:bf7b9fba3924 | 326 | PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); // we NEED a retry-timeout |
frank26080115 | 0:bf7b9fba3924 | 327 | LastFrameSent = TCP_FIN_FRAME; // time to say goodbye... |
frank26080115 | 0:bf7b9fba3924 | 328 | TCPStartRetryTimer(); |
frank26080115 | 0:bf7b9fba3924 | 329 | TCPStateMachine = LAST_ACK; |
frank26080115 | 0:bf7b9fba3924 | 330 | } |
frank26080115 | 0:bf7b9fba3924 | 331 | break; |
frank26080115 | 0:bf7b9fba3924 | 332 | } |
frank26080115 | 0:bf7b9fba3924 | 333 | } |
frank26080115 | 0:bf7b9fba3924 | 334 | |
frank26080115 | 0:bf7b9fba3924 | 335 | if (TransmitControl & SEND_FRAME2) |
frank26080115 | 0:bf7b9fba3924 | 336 | { |
frank26080115 | 0:bf7b9fba3924 | 337 | RequestSend(TxFrame2Size); |
frank26080115 | 0:bf7b9fba3924 | 338 | |
frank26080115 | 0:bf7b9fba3924 | 339 | if (Rdy4Tx()) { // NOTE: when using a very fast MCU, maybe |
frank26080115 | 0:bf7b9fba3924 | 340 | _DBG_("Send Frm2"); |
frank26080115 | 0:bf7b9fba3924 | 341 | SendFrame2(); // the EMAC isn't ready yet, include |
frank26080115 | 0:bf7b9fba3924 | 342 | } else { // a kind of timer or counter here |
frank26080115 | 0:bf7b9fba3924 | 343 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 344 | SocketStatus = SOCK_ERR_ETHERNET; // indicate an error to user |
frank26080115 | 0:bf7b9fba3924 | 345 | TCPFlags = 0; // clear all flags, stop timers etc. |
frank26080115 | 0:bf7b9fba3924 | 346 | } |
frank26080115 | 0:bf7b9fba3924 | 347 | |
frank26080115 | 0:bf7b9fba3924 | 348 | TransmitControl &= ~SEND_FRAME2; // clear tx-flag |
frank26080115 | 0:bf7b9fba3924 | 349 | } |
frank26080115 | 0:bf7b9fba3924 | 350 | |
frank26080115 | 0:bf7b9fba3924 | 351 | if (TransmitControl & SEND_FRAME1) |
frank26080115 | 0:bf7b9fba3924 | 352 | { |
frank26080115 | 0:bf7b9fba3924 | 353 | PrepareTCP_DATA_FRAME(); // build frame w/ actual SEQ, ACK.... |
frank26080115 | 0:bf7b9fba3924 | 354 | RequestSend(TxFrame1Size); |
frank26080115 | 0:bf7b9fba3924 | 355 | |
frank26080115 | 0:bf7b9fba3924 | 356 | if (Rdy4Tx()){ // EMAC ready to accept our frame? |
frank26080115 | 0:bf7b9fba3924 | 357 | _DBG_("Send Frm1"); |
frank26080115 | 0:bf7b9fba3924 | 358 | SendFrame1(); // (see note above) |
frank26080115 | 0:bf7b9fba3924 | 359 | } else { |
frank26080115 | 0:bf7b9fba3924 | 360 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 361 | SocketStatus = SOCK_ERR_ETHERNET; // indicate an error to user |
frank26080115 | 0:bf7b9fba3924 | 362 | TCPFlags = 0; // clear all flags, stop timers etc. |
frank26080115 | 0:bf7b9fba3924 | 363 | } |
frank26080115 | 0:bf7b9fba3924 | 364 | |
frank26080115 | 0:bf7b9fba3924 | 365 | TransmitControl &= ~SEND_FRAME1; // clear tx-flag |
frank26080115 | 0:bf7b9fba3924 | 366 | } |
frank26080115 | 0:bf7b9fba3924 | 367 | } |
frank26080115 | 0:bf7b9fba3924 | 368 | |
frank26080115 | 0:bf7b9fba3924 | 369 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 370 | // handles an incoming broadcast frame |
frank26080115 | 0:bf7b9fba3924 | 371 | |
frank26080115 | 0:bf7b9fba3924 | 372 | void ProcessEthBroadcastFrame(void) |
frank26080115 | 0:bf7b9fba3924 | 373 | { |
frank26080115 | 0:bf7b9fba3924 | 374 | unsigned short TargetIP[2]; |
frank26080115 | 0:bf7b9fba3924 | 375 | |
frank26080115 | 0:bf7b9fba3924 | 376 | if (ReadFrameBE_EMAC() == FRAME_ARP) // get frame type, check for ARP |
frank26080115 | 0:bf7b9fba3924 | 377 | if (ReadFrameBE_EMAC() == HARDW_ETH10) // Ethernet frame |
frank26080115 | 0:bf7b9fba3924 | 378 | if (ReadFrameBE_EMAC() == FRAME_IP) // check protocol |
frank26080115 | 0:bf7b9fba3924 | 379 | if (ReadFrameBE_EMAC() == IP_HLEN_PLEN) // check HLEN, PLEN |
frank26080115 | 0:bf7b9fba3924 | 380 | if (ReadFrameBE_EMAC() == OP_ARP_REQUEST) |
frank26080115 | 0:bf7b9fba3924 | 381 | { |
frank26080115 | 0:bf7b9fba3924 | 382 | DummyReadFrame_EMAC(6); // ignore sender's hardware address |
frank26080115 | 0:bf7b9fba3924 | 383 | CopyFromFrame_EMAC(&RecdFrameIP, 4); // read sender's protocol address |
frank26080115 | 0:bf7b9fba3924 | 384 | DummyReadFrame_EMAC(6); // ignore target's hardware address |
frank26080115 | 0:bf7b9fba3924 | 385 | CopyFromFrame_EMAC(&TargetIP, 4); // read target's protocol address |
frank26080115 | 0:bf7b9fba3924 | 386 | if (!memcmp(&MyIP, &TargetIP, 4)) // is it for us? |
frank26080115 | 0:bf7b9fba3924 | 387 | PrepareARP_ANSWER(); // yes->create ARP_ANSWER frame |
frank26080115 | 0:bf7b9fba3924 | 388 | } |
frank26080115 | 0:bf7b9fba3924 | 389 | } |
frank26080115 | 0:bf7b9fba3924 | 390 | |
frank26080115 | 0:bf7b9fba3924 | 391 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 392 | // handles an incoming frame that passed EMAC's address filter |
frank26080115 | 0:bf7b9fba3924 | 393 | // (individual addressed = IA) |
frank26080115 | 0:bf7b9fba3924 | 394 | |
frank26080115 | 0:bf7b9fba3924 | 395 | void ProcessEthIAFrame(void) |
frank26080115 | 0:bf7b9fba3924 | 396 | { |
frank26080115 | 0:bf7b9fba3924 | 397 | unsigned short TargetIP[2]; |
frank26080115 | 0:bf7b9fba3924 | 398 | unsigned char ProtocolType; |
frank26080115 | 0:bf7b9fba3924 | 399 | |
frank26080115 | 0:bf7b9fba3924 | 400 | switch (ReadFrameBE_EMAC()) // get frame type |
frank26080115 | 0:bf7b9fba3924 | 401 | { |
frank26080115 | 0:bf7b9fba3924 | 402 | case FRAME_ARP : // check for ARP |
frank26080115 | 0:bf7b9fba3924 | 403 | { |
frank26080115 | 0:bf7b9fba3924 | 404 | if ((TCPFlags & (TCP_ACTIVE_OPEN | IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN) |
frank26080115 | 0:bf7b9fba3924 | 405 | if (ReadFrameBE_EMAC() == HARDW_ETH10) // check for the right prot. etc. |
frank26080115 | 0:bf7b9fba3924 | 406 | if (ReadFrameBE_EMAC() == FRAME_IP) |
frank26080115 | 0:bf7b9fba3924 | 407 | if (ReadFrameBE_EMAC() == IP_HLEN_PLEN) |
frank26080115 | 0:bf7b9fba3924 | 408 | if (ReadFrameBE_EMAC() == OP_ARP_ANSWER) |
frank26080115 | 0:bf7b9fba3924 | 409 | { |
frank26080115 | 0:bf7b9fba3924 | 410 | TCPStopTimer(); // OK, now we've the MAC we wanted ;-) |
frank26080115 | 0:bf7b9fba3924 | 411 | CopyFromFrame_EMAC(&RemoteMAC, 6); // extract opponents MAC |
frank26080115 | 0:bf7b9fba3924 | 412 | TCPFlags |= IP_ADDR_RESOLVED; |
frank26080115 | 0:bf7b9fba3924 | 413 | } |
frank26080115 | 0:bf7b9fba3924 | 414 | break; |
frank26080115 | 0:bf7b9fba3924 | 415 | } |
frank26080115 | 0:bf7b9fba3924 | 416 | case FRAME_IP : // check for IP-type |
frank26080115 | 0:bf7b9fba3924 | 417 | { |
frank26080115 | 0:bf7b9fba3924 | 418 | if ((ReadFrameBE_EMAC() & 0xFF00 ) == IP_VER_IHL) // IPv4, IHL=5 (20 Bytes Header) |
frank26080115 | 0:bf7b9fba3924 | 419 | { // ignore Type Of Service |
frank26080115 | 0:bf7b9fba3924 | 420 | RecdIPFrameLength = ReadFrameBE_EMAC(); // get IP frame's length |
frank26080115 | 0:bf7b9fba3924 | 421 | ReadFrameBE_EMAC(); // ignore identification |
frank26080115 | 0:bf7b9fba3924 | 422 | |
frank26080115 | 0:bf7b9fba3924 | 423 | if (!(ReadFrameBE_EMAC() & (IP_FLAG_MOREFRAG | IP_FRAGOFS_MASK))) // only unfragm. frames |
frank26080115 | 0:bf7b9fba3924 | 424 | { |
frank26080115 | 0:bf7b9fba3924 | 425 | ProtocolType = ReadFrameBE_EMAC() & 0xFF; // get protocol, ignore TTL |
frank26080115 | 0:bf7b9fba3924 | 426 | ReadFrameBE_EMAC(); // ignore checksum |
frank26080115 | 0:bf7b9fba3924 | 427 | CopyFromFrame_EMAC(&RecdFrameIP, 4); // get source IP |
frank26080115 | 0:bf7b9fba3924 | 428 | CopyFromFrame_EMAC(&TargetIP, 4); // get destination IP |
frank26080115 | 0:bf7b9fba3924 | 429 | |
frank26080115 | 0:bf7b9fba3924 | 430 | if (!memcmp(&MyIP, &TargetIP, 4)) // is it for us? |
frank26080115 | 0:bf7b9fba3924 | 431 | switch (ProtocolType) { |
frank26080115 | 0:bf7b9fba3924 | 432 | case PROT_ICMP : { _DBG_("ICMP"); ProcessICMPFrame(); break; } |
frank26080115 | 0:bf7b9fba3924 | 433 | case PROT_TCP : { ProcessTCPFrame(); break; } |
frank26080115 | 0:bf7b9fba3924 | 434 | case PROT_UDP : break; // not implemented! |
frank26080115 | 0:bf7b9fba3924 | 435 | } |
frank26080115 | 0:bf7b9fba3924 | 436 | } |
frank26080115 | 0:bf7b9fba3924 | 437 | } |
frank26080115 | 0:bf7b9fba3924 | 438 | break; |
frank26080115 | 0:bf7b9fba3924 | 439 | } |
frank26080115 | 0:bf7b9fba3924 | 440 | } |
frank26080115 | 0:bf7b9fba3924 | 441 | } |
frank26080115 | 0:bf7b9fba3924 | 442 | |
frank26080115 | 0:bf7b9fba3924 | 443 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 444 | // we've just rec'd an ICMP-frame (Internet Control Message Protocol) |
frank26080115 | 0:bf7b9fba3924 | 445 | // check what to do and branch to the appropriate sub-function |
frank26080115 | 0:bf7b9fba3924 | 446 | |
frank26080115 | 0:bf7b9fba3924 | 447 | void ProcessICMPFrame(void) |
frank26080115 | 0:bf7b9fba3924 | 448 | { |
frank26080115 | 0:bf7b9fba3924 | 449 | unsigned short ICMPTypeAndCode; |
frank26080115 | 0:bf7b9fba3924 | 450 | |
frank26080115 | 0:bf7b9fba3924 | 451 | ICMPTypeAndCode = ReadFrameBE_EMAC(); // get Message Type and Code |
frank26080115 | 0:bf7b9fba3924 | 452 | ReadFrameBE_EMAC(); // ignore ICMP checksum |
frank26080115 | 0:bf7b9fba3924 | 453 | |
frank26080115 | 0:bf7b9fba3924 | 454 | switch (ICMPTypeAndCode >> 8) { // check type |
frank26080115 | 0:bf7b9fba3924 | 455 | case ICMP_ECHO : // is echo request? |
frank26080115 | 0:bf7b9fba3924 | 456 | { |
frank26080115 | 0:bf7b9fba3924 | 457 | PrepareICMP_ECHO_REPLY(); // echo as much as we can... |
frank26080115 | 0:bf7b9fba3924 | 458 | break; |
frank26080115 | 0:bf7b9fba3924 | 459 | } |
frank26080115 | 0:bf7b9fba3924 | 460 | } |
frank26080115 | 0:bf7b9fba3924 | 461 | } |
frank26080115 | 0:bf7b9fba3924 | 462 | |
frank26080115 | 0:bf7b9fba3924 | 463 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 464 | // we've just rec'd an TCP-frame (Transmission Control Protocol) |
frank26080115 | 0:bf7b9fba3924 | 465 | // this function mainly implements the TCP state machine according to RFC793 |
frank26080115 | 0:bf7b9fba3924 | 466 | |
frank26080115 | 0:bf7b9fba3924 | 467 | void ProcessTCPFrame(void) |
frank26080115 | 0:bf7b9fba3924 | 468 | { |
frank26080115 | 0:bf7b9fba3924 | 469 | unsigned short TCPSegSourcePort; // segment's source port |
frank26080115 | 0:bf7b9fba3924 | 470 | unsigned short TCPSegDestPort; // segment's destination port |
frank26080115 | 0:bf7b9fba3924 | 471 | unsigned long TCPSegSeq; // segment's sequence number |
frank26080115 | 0:bf7b9fba3924 | 472 | unsigned long TCPSegAck; // segment's acknowledge number |
frank26080115 | 0:bf7b9fba3924 | 473 | unsigned short TCPCode; // TCP code and header length |
frank26080115 | 0:bf7b9fba3924 | 474 | unsigned char TCPHeaderSize; // real TCP header length |
frank26080115 | 0:bf7b9fba3924 | 475 | unsigned short NrOfDataBytes; // real number of data |
frank26080115 | 0:bf7b9fba3924 | 476 | |
frank26080115 | 0:bf7b9fba3924 | 477 | TCPSegSourcePort = ReadFrameBE_EMAC(); // get ports |
frank26080115 | 0:bf7b9fba3924 | 478 | TCPSegDestPort = ReadFrameBE_EMAC(); |
frank26080115 | 0:bf7b9fba3924 | 479 | |
frank26080115 | 0:bf7b9fba3924 | 480 | if (TCPSegDestPort != TCPLocalPort) return; // drop segment if port doesn't match |
frank26080115 | 0:bf7b9fba3924 | 481 | |
frank26080115 | 0:bf7b9fba3924 | 482 | TCPSegSeq = (unsigned long)ReadFrameBE_EMAC() << 16; // get segment sequence nr. |
frank26080115 | 0:bf7b9fba3924 | 483 | TCPSegSeq |= ReadFrameBE_EMAC(); |
frank26080115 | 0:bf7b9fba3924 | 484 | |
frank26080115 | 0:bf7b9fba3924 | 485 | TCPSegAck = (unsigned long)ReadFrameBE_EMAC() << 16; // get segment acknowledge nr. |
frank26080115 | 0:bf7b9fba3924 | 486 | TCPSegAck |= ReadFrameBE_EMAC(); |
frank26080115 | 0:bf7b9fba3924 | 487 | |
frank26080115 | 0:bf7b9fba3924 | 488 | TCPCode = ReadFrameBE_EMAC(); // get control bits, header length... |
frank26080115 | 0:bf7b9fba3924 | 489 | |
frank26080115 | 0:bf7b9fba3924 | 490 | TCPHeaderSize = (TCPCode & DATA_OFS_MASK) >> 10; // header length in bytes |
frank26080115 | 0:bf7b9fba3924 | 491 | NrOfDataBytes = RecdIPFrameLength - IP_HEADER_SIZE - TCPHeaderSize; // seg. text length |
frank26080115 | 0:bf7b9fba3924 | 492 | |
frank26080115 | 0:bf7b9fba3924 | 493 | if (NrOfDataBytes > MAX_TCP_RX_DATA_SIZE) return; // packet too large for us :...-( |
frank26080115 | 0:bf7b9fba3924 | 494 | |
frank26080115 | 0:bf7b9fba3924 | 495 | if (TCPHeaderSize > TCP_HEADER_SIZE) // ignore options if any |
frank26080115 | 0:bf7b9fba3924 | 496 | DummyReadFrame_EMAC(TCPHeaderSize - TCP_HEADER_SIZE); |
frank26080115 | 0:bf7b9fba3924 | 497 | |
frank26080115 | 0:bf7b9fba3924 | 498 | switch (TCPStateMachine) // implement the TCP state machine |
frank26080115 | 0:bf7b9fba3924 | 499 | { |
frank26080115 | 0:bf7b9fba3924 | 500 | case CLOSED : |
frank26080115 | 0:bf7b9fba3924 | 501 | { |
frank26080115 | 0:bf7b9fba3924 | 502 | if (!(TCPCode & TCP_CODE_RST)) |
frank26080115 | 0:bf7b9fba3924 | 503 | { |
frank26080115 | 0:bf7b9fba3924 | 504 | TCPRemotePort = TCPSegSourcePort; |
frank26080115 | 0:bf7b9fba3924 | 505 | memcpy(&RemoteMAC, &RecdFrameMAC, 6); // save opponents MAC and IP |
frank26080115 | 0:bf7b9fba3924 | 506 | memcpy(&RemoteIP, &RecdFrameIP, 4); // for later use |
frank26080115 | 0:bf7b9fba3924 | 507 | |
frank26080115 | 0:bf7b9fba3924 | 508 | if (TCPCode & TCP_CODE_ACK) // make the reset sequence |
frank26080115 | 0:bf7b9fba3924 | 509 | { // acceptable to the other |
frank26080115 | 0:bf7b9fba3924 | 510 | TCPSeqNr = TCPSegAck; // TCP |
frank26080115 | 0:bf7b9fba3924 | 511 | PrepareTCP_FRAME(TCP_CODE_RST); |
frank26080115 | 0:bf7b9fba3924 | 512 | } |
frank26080115 | 0:bf7b9fba3924 | 513 | else |
frank26080115 | 0:bf7b9fba3924 | 514 | { |
frank26080115 | 0:bf7b9fba3924 | 515 | TCPSeqNr = 0; |
frank26080115 | 0:bf7b9fba3924 | 516 | TCPAckNr = TCPSegSeq + NrOfDataBytes; |
frank26080115 | 0:bf7b9fba3924 | 517 | if (TCPCode & (TCP_CODE_SYN | TCP_CODE_FIN)) TCPAckNr++; |
frank26080115 | 0:bf7b9fba3924 | 518 | PrepareTCP_FRAME(TCP_CODE_RST | TCP_CODE_ACK); |
frank26080115 | 0:bf7b9fba3924 | 519 | } |
frank26080115 | 0:bf7b9fba3924 | 520 | } |
frank26080115 | 0:bf7b9fba3924 | 521 | break; |
frank26080115 | 0:bf7b9fba3924 | 522 | } |
frank26080115 | 0:bf7b9fba3924 | 523 | case LISTENING : |
frank26080115 | 0:bf7b9fba3924 | 524 | { |
frank26080115 | 0:bf7b9fba3924 | 525 | if (!(TCPCode & TCP_CODE_RST)) // ignore segment containing RST |
frank26080115 | 0:bf7b9fba3924 | 526 | { |
frank26080115 | 0:bf7b9fba3924 | 527 | TCPRemotePort = TCPSegSourcePort; |
frank26080115 | 0:bf7b9fba3924 | 528 | memcpy(&RemoteMAC, &RecdFrameMAC, 6); // save opponents MAC and IP |
frank26080115 | 0:bf7b9fba3924 | 529 | memcpy(&RemoteIP, &RecdFrameIP, 4); // for later use |
frank26080115 | 0:bf7b9fba3924 | 530 | |
frank26080115 | 0:bf7b9fba3924 | 531 | if (TCPCode & TCP_CODE_ACK) // reset a bad |
frank26080115 | 0:bf7b9fba3924 | 532 | { // acknowledgement |
frank26080115 | 0:bf7b9fba3924 | 533 | TCPSeqNr = TCPSegAck; |
frank26080115 | 0:bf7b9fba3924 | 534 | PrepareTCP_FRAME(TCP_CODE_RST); |
frank26080115 | 0:bf7b9fba3924 | 535 | } |
frank26080115 | 0:bf7b9fba3924 | 536 | else if (TCPCode & TCP_CODE_SYN) |
frank26080115 | 0:bf7b9fba3924 | 537 | { |
frank26080115 | 0:bf7b9fba3924 | 538 | TCPAckNr = TCPSegSeq + 1; // get remote ISN, next byte we expect |
frank26080115 | 0:bf7b9fba3924 | 539 | TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | (SysTick->CURR & 0xFFFF); // Keil: changed from TAR to T0TC; |
frank26080115 | 0:bf7b9fba3924 | 540 | // set local ISN |
frank26080115 | 0:bf7b9fba3924 | 541 | TCPUNASeqNr = TCPSeqNr + 1; // one byte out -> increase by one |
frank26080115 | 0:bf7b9fba3924 | 542 | PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); |
frank26080115 | 0:bf7b9fba3924 | 543 | LastFrameSent = TCP_SYN_ACK_FRAME; |
frank26080115 | 0:bf7b9fba3924 | 544 | TCPStartRetryTimer(); |
frank26080115 | 0:bf7b9fba3924 | 545 | TCPStateMachine = SYN_RECD; |
frank26080115 | 0:bf7b9fba3924 | 546 | } |
frank26080115 | 0:bf7b9fba3924 | 547 | } |
frank26080115 | 0:bf7b9fba3924 | 548 | break; |
frank26080115 | 0:bf7b9fba3924 | 549 | } |
frank26080115 | 0:bf7b9fba3924 | 550 | case SYN_SENT : |
frank26080115 | 0:bf7b9fba3924 | 551 | { |
frank26080115 | 0:bf7b9fba3924 | 552 | if (memcmp(&RemoteIP, &RecdFrameIP, 4)) break; // drop segment if its IP doesn't belong |
frank26080115 | 0:bf7b9fba3924 | 553 | // to current session |
frank26080115 | 0:bf7b9fba3924 | 554 | |
frank26080115 | 0:bf7b9fba3924 | 555 | if (TCPSegSourcePort != TCPRemotePort) break; // drop segment if port doesn't match |
frank26080115 | 0:bf7b9fba3924 | 556 | |
frank26080115 | 0:bf7b9fba3924 | 557 | if (TCPCode & TCP_CODE_ACK) // ACK field significant? |
frank26080115 | 0:bf7b9fba3924 | 558 | if (TCPSegAck != TCPUNASeqNr) // is our ISN ACKed? |
frank26080115 | 0:bf7b9fba3924 | 559 | { |
frank26080115 | 0:bf7b9fba3924 | 560 | if (!(TCPCode & TCP_CODE_RST)) |
frank26080115 | 0:bf7b9fba3924 | 561 | { |
frank26080115 | 0:bf7b9fba3924 | 562 | TCPSeqNr = TCPSegAck; |
frank26080115 | 0:bf7b9fba3924 | 563 | PrepareTCP_FRAME(TCP_CODE_RST); |
frank26080115 | 0:bf7b9fba3924 | 564 | } |
frank26080115 | 0:bf7b9fba3924 | 565 | break; // drop segment |
frank26080115 | 0:bf7b9fba3924 | 566 | } |
frank26080115 | 0:bf7b9fba3924 | 567 | |
frank26080115 | 0:bf7b9fba3924 | 568 | if (TCPCode & TCP_CODE_RST) // RST?? |
frank26080115 | 0:bf7b9fba3924 | 569 | { |
frank26080115 | 0:bf7b9fba3924 | 570 | if (TCPCode & TCP_CODE_ACK) // if ACK was acceptable, reset |
frank26080115 | 0:bf7b9fba3924 | 571 | { // connection |
frank26080115 | 0:bf7b9fba3924 | 572 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 573 | TCPFlags = 0; // reset all flags, stop retransmission... |
frank26080115 | 0:bf7b9fba3924 | 574 | SocketStatus = SOCK_ERR_CONN_RESET; |
frank26080115 | 0:bf7b9fba3924 | 575 | } |
frank26080115 | 0:bf7b9fba3924 | 576 | break; // drop segment |
frank26080115 | 0:bf7b9fba3924 | 577 | } |
frank26080115 | 0:bf7b9fba3924 | 578 | |
frank26080115 | 0:bf7b9fba3924 | 579 | if (TCPCode & TCP_CODE_SYN) // SYN?? |
frank26080115 | 0:bf7b9fba3924 | 580 | { |
frank26080115 | 0:bf7b9fba3924 | 581 | TCPAckNr = TCPSegSeq; // get opponents ISN |
frank26080115 | 0:bf7b9fba3924 | 582 | TCPAckNr++; // inc. by one... |
frank26080115 | 0:bf7b9fba3924 | 583 | |
frank26080115 | 0:bf7b9fba3924 | 584 | if (TCPCode & TCP_CODE_ACK) |
frank26080115 | 0:bf7b9fba3924 | 585 | { |
frank26080115 | 0:bf7b9fba3924 | 586 | TCPStopTimer(); // stop retransmission, other TCP got our SYN |
frank26080115 | 0:bf7b9fba3924 | 587 | TCPSeqNr = TCPUNASeqNr; // advance our sequence number |
frank26080115 | 0:bf7b9fba3924 | 588 | |
frank26080115 | 0:bf7b9fba3924 | 589 | PrepareTCP_FRAME(TCP_CODE_ACK); // ACK this ISN |
frank26080115 | 0:bf7b9fba3924 | 590 | TCPStateMachine = ESTABLISHED; |
frank26080115 | 0:bf7b9fba3924 | 591 | SocketStatus |= SOCK_CONNECTED; |
frank26080115 | 0:bf7b9fba3924 | 592 | SocketStatus |= SOCK_TX_BUF_RELEASED; // user may send data now :-) |
frank26080115 | 0:bf7b9fba3924 | 593 | } |
frank26080115 | 0:bf7b9fba3924 | 594 | else |
frank26080115 | 0:bf7b9fba3924 | 595 | { |
frank26080115 | 0:bf7b9fba3924 | 596 | TCPStopTimer(); |
frank26080115 | 0:bf7b9fba3924 | 597 | PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); // our SYN isn't ACKed yet, |
frank26080115 | 0:bf7b9fba3924 | 598 | LastFrameSent = TCP_SYN_ACK_FRAME; // now continue with sending |
frank26080115 | 0:bf7b9fba3924 | 599 | TCPStartRetryTimer(); // SYN_ACK frames |
frank26080115 | 0:bf7b9fba3924 | 600 | TCPStateMachine = SYN_RECD; |
frank26080115 | 0:bf7b9fba3924 | 601 | } |
frank26080115 | 0:bf7b9fba3924 | 602 | } |
frank26080115 | 0:bf7b9fba3924 | 603 | break; |
frank26080115 | 0:bf7b9fba3924 | 604 | } |
frank26080115 | 0:bf7b9fba3924 | 605 | default : |
frank26080115 | 0:bf7b9fba3924 | 606 | { |
frank26080115 | 0:bf7b9fba3924 | 607 | if (memcmp(&RemoteIP, &RecdFrameIP, 4)) break; // drop segment if IP doesn't belong |
frank26080115 | 0:bf7b9fba3924 | 608 | // to current session |
frank26080115 | 0:bf7b9fba3924 | 609 | |
frank26080115 | 0:bf7b9fba3924 | 610 | if (TCPSegSourcePort != TCPRemotePort) break; // drop segment if port doesn't match |
frank26080115 | 0:bf7b9fba3924 | 611 | |
frank26080115 | 0:bf7b9fba3924 | 612 | if (TCPSegSeq != TCPAckNr) break; // drop if it's not the segment we expect |
frank26080115 | 0:bf7b9fba3924 | 613 | |
frank26080115 | 0:bf7b9fba3924 | 614 | if (TCPCode & TCP_CODE_RST) // RST?? |
frank26080115 | 0:bf7b9fba3924 | 615 | { |
frank26080115 | 0:bf7b9fba3924 | 616 | TCPStateMachine = CLOSED; // close the state machine |
frank26080115 | 0:bf7b9fba3924 | 617 | TCPFlags = 0; // reset all flags, stop retransmission... |
frank26080115 | 0:bf7b9fba3924 | 618 | SocketStatus = SOCK_ERR_CONN_RESET; // indicate an error to user |
frank26080115 | 0:bf7b9fba3924 | 619 | break; |
frank26080115 | 0:bf7b9fba3924 | 620 | } |
frank26080115 | 0:bf7b9fba3924 | 621 | |
frank26080115 | 0:bf7b9fba3924 | 622 | if (TCPCode & TCP_CODE_SYN) // SYN?? |
frank26080115 | 0:bf7b9fba3924 | 623 | { |
frank26080115 | 0:bf7b9fba3924 | 624 | PrepareTCP_FRAME(TCP_CODE_RST); // is NOT allowed here! send a reset, |
frank26080115 | 0:bf7b9fba3924 | 625 | TCPStateMachine = CLOSED; // close connection... |
frank26080115 | 0:bf7b9fba3924 | 626 | TCPFlags = 0; // reset all flags, stop retransmission... |
frank26080115 | 0:bf7b9fba3924 | 627 | SocketStatus = SOCK_ERR_REMOTE; // fatal error! |
frank26080115 | 0:bf7b9fba3924 | 628 | break; // ...and drop the frame |
frank26080115 | 0:bf7b9fba3924 | 629 | } |
frank26080115 | 0:bf7b9fba3924 | 630 | |
frank26080115 | 0:bf7b9fba3924 | 631 | if (!(TCPCode & TCP_CODE_ACK)) break; // drop segment if the ACK bit is off |
frank26080115 | 0:bf7b9fba3924 | 632 | |
frank26080115 | 0:bf7b9fba3924 | 633 | if (TCPSegAck == TCPUNASeqNr) // is our last data sent ACKed? |
frank26080115 | 0:bf7b9fba3924 | 634 | { |
frank26080115 | 0:bf7b9fba3924 | 635 | TCPStopTimer(); // stop retransmission |
frank26080115 | 0:bf7b9fba3924 | 636 | TCPSeqNr = TCPUNASeqNr; // advance our sequence number |
frank26080115 | 0:bf7b9fba3924 | 637 | |
frank26080115 | 0:bf7b9fba3924 | 638 | switch (TCPStateMachine) // change state if necessary |
frank26080115 | 0:bf7b9fba3924 | 639 | { |
frank26080115 | 0:bf7b9fba3924 | 640 | case SYN_RECD : // ACK of our SYN? |
frank26080115 | 0:bf7b9fba3924 | 641 | { |
frank26080115 | 0:bf7b9fba3924 | 642 | TCPStateMachine = ESTABLISHED; // user may send data now :-) |
frank26080115 | 0:bf7b9fba3924 | 643 | SocketStatus |= SOCK_CONNECTED; |
frank26080115 | 0:bf7b9fba3924 | 644 | break; |
frank26080115 | 0:bf7b9fba3924 | 645 | } |
frank26080115 | 0:bf7b9fba3924 | 646 | case FIN_WAIT_1 : { TCPStateMachine = FIN_WAIT_2; break; } // ACK of our FIN? |
frank26080115 | 0:bf7b9fba3924 | 647 | case CLOSING : { TCPStateMachine = TIME_WAIT; break; } // ACK of our FIN? |
frank26080115 | 0:bf7b9fba3924 | 648 | case LAST_ACK : // ACK of our FIN? |
frank26080115 | 0:bf7b9fba3924 | 649 | { |
frank26080115 | 0:bf7b9fba3924 | 650 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 651 | TCPFlags = 0; // reset all flags, stop retransmission... |
frank26080115 | 0:bf7b9fba3924 | 652 | SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags but data available |
frank26080115 | 0:bf7b9fba3924 | 653 | break; |
frank26080115 | 0:bf7b9fba3924 | 654 | } |
frank26080115 | 0:bf7b9fba3924 | 655 | case TIME_WAIT : |
frank26080115 | 0:bf7b9fba3924 | 656 | { |
frank26080115 | 0:bf7b9fba3924 | 657 | PrepareTCP_FRAME(TCP_CODE_ACK); // ACK a retransmission of remote FIN |
frank26080115 | 0:bf7b9fba3924 | 658 | TCPRestartTimer(); // restart TIME_WAIT timeout |
frank26080115 | 0:bf7b9fba3924 | 659 | break; |
frank26080115 | 0:bf7b9fba3924 | 660 | } |
frank26080115 | 0:bf7b9fba3924 | 661 | } |
frank26080115 | 0:bf7b9fba3924 | 662 | |
frank26080115 | 0:bf7b9fba3924 | 663 | if (TCPStateMachine == ESTABLISHED) // if true, give the frame buffer back |
frank26080115 | 0:bf7b9fba3924 | 664 | SocketStatus |= SOCK_TX_BUF_RELEASED; // to user |
frank26080115 | 0:bf7b9fba3924 | 665 | } |
frank26080115 | 0:bf7b9fba3924 | 666 | |
frank26080115 | 0:bf7b9fba3924 | 667 | if ((TCPStateMachine == ESTABLISHED) || (TCPStateMachine == FIN_WAIT_1) || (TCPStateMachine == FIN_WAIT_2)) |
frank26080115 | 0:bf7b9fba3924 | 668 | if (NrOfDataBytes) // data available? |
frank26080115 | 0:bf7b9fba3924 | 669 | if (!(SocketStatus & SOCK_DATA_AVAILABLE)) // rx data-buffer empty? |
frank26080115 | 0:bf7b9fba3924 | 670 | { |
frank26080115 | 0:bf7b9fba3924 | 671 | DummyReadFrame_EMAC(6); // ignore window, checksum, urgent pointer |
frank26080115 | 0:bf7b9fba3924 | 672 | CopyFromFrame_EMAC(RxTCPBuffer, NrOfDataBytes);// fetch data and |
frank26080115 | 0:bf7b9fba3924 | 673 | TCPRxDataCount = NrOfDataBytes; // ...tell the user... |
frank26080115 | 0:bf7b9fba3924 | 674 | SocketStatus |= SOCK_DATA_AVAILABLE; // indicate the new data to user |
frank26080115 | 0:bf7b9fba3924 | 675 | TCPAckNr += NrOfDataBytes; |
frank26080115 | 0:bf7b9fba3924 | 676 | PrepareTCP_FRAME(TCP_CODE_ACK); // ACK rec'd data |
frank26080115 | 0:bf7b9fba3924 | 677 | } |
frank26080115 | 0:bf7b9fba3924 | 678 | |
frank26080115 | 0:bf7b9fba3924 | 679 | if (TCPCode & TCP_CODE_FIN) // FIN?? |
frank26080115 | 0:bf7b9fba3924 | 680 | { |
frank26080115 | 0:bf7b9fba3924 | 681 | switch (TCPStateMachine) |
frank26080115 | 0:bf7b9fba3924 | 682 | { |
frank26080115 | 0:bf7b9fba3924 | 683 | case SYN_RECD : |
frank26080115 | 0:bf7b9fba3924 | 684 | case ESTABLISHED : |
frank26080115 | 0:bf7b9fba3924 | 685 | { |
frank26080115 | 0:bf7b9fba3924 | 686 | TCPStateMachine = CLOSE_WAIT; |
frank26080115 | 0:bf7b9fba3924 | 687 | break; |
frank26080115 | 0:bf7b9fba3924 | 688 | } |
frank26080115 | 0:bf7b9fba3924 | 689 | case FIN_WAIT_1 : |
frank26080115 | 0:bf7b9fba3924 | 690 | { // if our FIN was ACKed, we automatically |
frank26080115 | 0:bf7b9fba3924 | 691 | TCPStateMachine = CLOSING; // enter FIN_WAIT_2 (look above) and therefore |
frank26080115 | 0:bf7b9fba3924 | 692 | SocketStatus &= ~SOCK_CONNECTED; // TIME_WAIT |
frank26080115 | 0:bf7b9fba3924 | 693 | break; |
frank26080115 | 0:bf7b9fba3924 | 694 | } |
frank26080115 | 0:bf7b9fba3924 | 695 | case FIN_WAIT_2 : |
frank26080115 | 0:bf7b9fba3924 | 696 | { |
frank26080115 | 0:bf7b9fba3924 | 697 | TCPStartTimeWaitTimer(); |
frank26080115 | 0:bf7b9fba3924 | 698 | TCPStateMachine = TIME_WAIT; |
frank26080115 | 0:bf7b9fba3924 | 699 | SocketStatus &= ~SOCK_CONNECTED; |
frank26080115 | 0:bf7b9fba3924 | 700 | break; |
frank26080115 | 0:bf7b9fba3924 | 701 | } |
frank26080115 | 0:bf7b9fba3924 | 702 | case TIME_WAIT : |
frank26080115 | 0:bf7b9fba3924 | 703 | { |
frank26080115 | 0:bf7b9fba3924 | 704 | TCPRestartTimer(); |
frank26080115 | 0:bf7b9fba3924 | 705 | break; |
frank26080115 | 0:bf7b9fba3924 | 706 | } |
frank26080115 | 0:bf7b9fba3924 | 707 | } |
frank26080115 | 0:bf7b9fba3924 | 708 | TCPAckNr++; // ACK remote's FIN flag |
frank26080115 | 0:bf7b9fba3924 | 709 | PrepareTCP_FRAME(TCP_CODE_ACK); |
frank26080115 | 0:bf7b9fba3924 | 710 | } |
frank26080115 | 0:bf7b9fba3924 | 711 | } |
frank26080115 | 0:bf7b9fba3924 | 712 | } |
frank26080115 | 0:bf7b9fba3924 | 713 | } |
frank26080115 | 0:bf7b9fba3924 | 714 | |
frank26080115 | 0:bf7b9fba3924 | 715 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 716 | // prepares the TxFrame2-buffer to send an ARP-request |
frank26080115 | 0:bf7b9fba3924 | 717 | |
frank26080115 | 0:bf7b9fba3924 | 718 | void PrepareARP_REQUEST(void) |
frank26080115 | 0:bf7b9fba3924 | 719 | { |
frank26080115 | 0:bf7b9fba3924 | 720 | // Ethernet |
frank26080115 | 0:bf7b9fba3924 | 721 | memset(&TxFrame2[ETH_DA_OFS], (char)0xFF, 6); // we don't know opposites MAC! |
frank26080115 | 0:bf7b9fba3924 | 722 | memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 723 | *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP); |
frank26080115 | 0:bf7b9fba3924 | 724 | |
frank26080115 | 0:bf7b9fba3924 | 725 | // ARP |
frank26080115 | 0:bf7b9fba3924 | 726 | *(unsigned short *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10); |
frank26080115 | 0:bf7b9fba3924 | 727 | *(unsigned short *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP); |
frank26080115 | 0:bf7b9fba3924 | 728 | *(unsigned short *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN); |
frank26080115 | 0:bf7b9fba3924 | 729 | *(unsigned short *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_REQUEST); |
frank26080115 | 0:bf7b9fba3924 | 730 | memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 731 | memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 732 | memset(&TxFrame2[ARP_TARGET_HA_OFS], 0x00, 6); // we don't know opposites MAC! |
frank26080115 | 0:bf7b9fba3924 | 733 | |
frank26080115 | 0:bf7b9fba3924 | 734 | if (((RemoteIP[0] ^ MyIP[0]) & SubnetMask[0]) || ((RemoteIP[1] ^ MyIP[1]) & SubnetMask[1])) |
frank26080115 | 0:bf7b9fba3924 | 735 | memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &GatewayIP, 4); // IP not in subnet, use gateway |
frank26080115 | 0:bf7b9fba3924 | 736 | else |
frank26080115 | 0:bf7b9fba3924 | 737 | memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &RemoteIP, 4); // other IP is next to us... |
frank26080115 | 0:bf7b9fba3924 | 738 | |
frank26080115 | 0:bf7b9fba3924 | 739 | TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE; |
frank26080115 | 0:bf7b9fba3924 | 740 | TransmitControl |= SEND_FRAME2; |
frank26080115 | 0:bf7b9fba3924 | 741 | } |
frank26080115 | 0:bf7b9fba3924 | 742 | |
frank26080115 | 0:bf7b9fba3924 | 743 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 744 | // prepares the TxFrame2-buffer to send an ARP-answer (reply) |
frank26080115 | 0:bf7b9fba3924 | 745 | |
frank26080115 | 0:bf7b9fba3924 | 746 | void PrepareARP_ANSWER(void) |
frank26080115 | 0:bf7b9fba3924 | 747 | { |
frank26080115 | 0:bf7b9fba3924 | 748 | // Ethernet |
frank26080115 | 0:bf7b9fba3924 | 749 | memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 750 | memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 751 | *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP); |
frank26080115 | 0:bf7b9fba3924 | 752 | |
frank26080115 | 0:bf7b9fba3924 | 753 | // ARP |
frank26080115 | 0:bf7b9fba3924 | 754 | *(unsigned short *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10); |
frank26080115 | 0:bf7b9fba3924 | 755 | *(unsigned short *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP); |
frank26080115 | 0:bf7b9fba3924 | 756 | *(unsigned short *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN); |
frank26080115 | 0:bf7b9fba3924 | 757 | *(unsigned short *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_ANSWER); |
frank26080115 | 0:bf7b9fba3924 | 758 | memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 759 | memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 760 | memcpy(&TxFrame2[ARP_TARGET_HA_OFS], &RecdFrameMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 761 | memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &RecdFrameIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 762 | |
frank26080115 | 0:bf7b9fba3924 | 763 | TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE; |
frank26080115 | 0:bf7b9fba3924 | 764 | TransmitControl |= SEND_FRAME2; |
frank26080115 | 0:bf7b9fba3924 | 765 | } |
frank26080115 | 0:bf7b9fba3924 | 766 | |
frank26080115 | 0:bf7b9fba3924 | 767 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 768 | // prepares the TxFrame2-buffer to send an ICMP-echo-reply |
frank26080115 | 0:bf7b9fba3924 | 769 | |
frank26080115 | 0:bf7b9fba3924 | 770 | void PrepareICMP_ECHO_REPLY(void) |
frank26080115 | 0:bf7b9fba3924 | 771 | { |
frank26080115 | 0:bf7b9fba3924 | 772 | unsigned short ICMPDataCount; |
frank26080115 | 0:bf7b9fba3924 | 773 | |
frank26080115 | 0:bf7b9fba3924 | 774 | if (RecdIPFrameLength > MAX_ETH_TX_DATA_SIZE) // don't overload TX-buffer |
frank26080115 | 0:bf7b9fba3924 | 775 | ICMPDataCount = MAX_ETH_TX_DATA_SIZE - IP_HEADER_SIZE - ICMP_HEADER_SIZE; |
frank26080115 | 0:bf7b9fba3924 | 776 | else |
frank26080115 | 0:bf7b9fba3924 | 777 | ICMPDataCount = RecdIPFrameLength - IP_HEADER_SIZE - ICMP_HEADER_SIZE; |
frank26080115 | 0:bf7b9fba3924 | 778 | |
frank26080115 | 0:bf7b9fba3924 | 779 | // Ethernet |
frank26080115 | 0:bf7b9fba3924 | 780 | memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 781 | memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 782 | *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP); |
frank26080115 | 0:bf7b9fba3924 | 783 | |
frank26080115 | 0:bf7b9fba3924 | 784 | // IP |
frank26080115 | 0:bf7b9fba3924 | 785 | *(unsigned short *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL); |
frank26080115 | 0:bf7b9fba3924 | 786 | WriteWBE(&TxFrame2[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount); |
frank26080115 | 0:bf7b9fba3924 | 787 | *(unsigned short *)&TxFrame2[IP_IDENT_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 788 | *(unsigned short *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 789 | *(unsigned short *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_ICMP); |
frank26080115 | 0:bf7b9fba3924 | 790 | *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 791 | memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 792 | memcpy(&TxFrame2[IP_DESTINATION_OFS], &RecdFrameIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 793 | *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); |
frank26080115 | 0:bf7b9fba3924 | 794 | |
frank26080115 | 0:bf7b9fba3924 | 795 | // ICMP |
frank26080115 | 0:bf7b9fba3924 | 796 | *(unsigned short *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8); |
frank26080115 | 0:bf7b9fba3924 | 797 | *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field |
frank26080115 | 0:bf7b9fba3924 | 798 | |
frank26080115 | 0:bf7b9fba3924 | 799 | CopyFromFrame_EMAC(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo... |
frank26080115 | 0:bf7b9fba3924 | 800 | *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0); |
frank26080115 | 0:bf7b9fba3924 | 801 | |
frank26080115 | 0:bf7b9fba3924 | 802 | TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount; |
frank26080115 | 0:bf7b9fba3924 | 803 | TransmitControl |= SEND_FRAME2; |
frank26080115 | 0:bf7b9fba3924 | 804 | } |
frank26080115 | 0:bf7b9fba3924 | 805 | |
frank26080115 | 0:bf7b9fba3924 | 806 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 807 | // prepares the TxFrame2-buffer to send a general TCP frame |
frank26080115 | 0:bf7b9fba3924 | 808 | // the TCPCode-field is passed as an argument |
frank26080115 | 0:bf7b9fba3924 | 809 | |
frank26080115 | 0:bf7b9fba3924 | 810 | void PrepareTCP_FRAME(unsigned short TCPCode) |
frank26080115 | 0:bf7b9fba3924 | 811 | { |
frank26080115 | 0:bf7b9fba3924 | 812 | // Ethernet |
frank26080115 | 0:bf7b9fba3924 | 813 | memcpy(&TxFrame2[ETH_DA_OFS], &RemoteMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 814 | memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 815 | *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP); |
frank26080115 | 0:bf7b9fba3924 | 816 | |
frank26080115 | 0:bf7b9fba3924 | 817 | // IP |
frank26080115 | 0:bf7b9fba3924 | 818 | *(unsigned short *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D); |
frank26080115 | 0:bf7b9fba3924 | 819 | |
frank26080115 | 0:bf7b9fba3924 | 820 | if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option |
frank26080115 | 0:bf7b9fba3924 | 821 | *(unsigned short *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE); |
frank26080115 | 0:bf7b9fba3924 | 822 | else |
frank26080115 | 0:bf7b9fba3924 | 823 | *(unsigned short *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE); |
frank26080115 | 0:bf7b9fba3924 | 824 | |
frank26080115 | 0:bf7b9fba3924 | 825 | *(unsigned short *)&TxFrame2[IP_IDENT_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 826 | *(unsigned short *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 827 | *(unsigned short *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP); |
frank26080115 | 0:bf7b9fba3924 | 828 | *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 829 | memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 830 | memcpy(&TxFrame2[IP_DESTINATION_OFS], &RemoteIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 831 | *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); |
frank26080115 | 0:bf7b9fba3924 | 832 | |
frank26080115 | 0:bf7b9fba3924 | 833 | // TCP |
frank26080115 | 0:bf7b9fba3924 | 834 | WriteWBE(&TxFrame2[TCP_SRCPORT_OFS], TCPLocalPort); |
frank26080115 | 0:bf7b9fba3924 | 835 | WriteWBE(&TxFrame2[TCP_DESTPORT_OFS], TCPRemotePort); |
frank26080115 | 0:bf7b9fba3924 | 836 | |
frank26080115 | 0:bf7b9fba3924 | 837 | WriteDWBE(&TxFrame2[TCP_SEQNR_OFS], TCPSeqNr); |
frank26080115 | 0:bf7b9fba3924 | 838 | WriteDWBE(&TxFrame2[TCP_ACKNR_OFS], TCPAckNr); |
frank26080115 | 0:bf7b9fba3924 | 839 | |
frank26080115 | 0:bf7b9fba3924 | 840 | *(unsigned short *)&TxFrame2[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept |
frank26080115 | 0:bf7b9fba3924 | 841 | *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = 0; // initalize checksum |
frank26080115 | 0:bf7b9fba3924 | 842 | *(unsigned short *)&TxFrame2[TCP_URGENT_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 843 | |
frank26080115 | 0:bf7b9fba3924 | 844 | if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option |
frank26080115 | 0:bf7b9fba3924 | 845 | { |
frank26080115 | 0:bf7b9fba3924 | 846 | *(unsigned short *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x6000 | TCPCode); // TCP header length = 24 |
frank26080115 | 0:bf7b9fba3924 | 847 | *(unsigned short *)&TxFrame2[TCP_DATA_OFS] = SWAPB(TCP_OPT_MSS); // MSS option |
frank26080115 | 0:bf7b9fba3924 | 848 | *(unsigned short *)&TxFrame2[TCP_DATA_OFS + 2] = SWAPB(MAX_TCP_RX_DATA_SIZE);// max. length of TCP-data we accept |
frank26080115 | 0:bf7b9fba3924 | 849 | *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1); |
frank26080115 | 0:bf7b9fba3924 | 850 | TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE; |
frank26080115 | 0:bf7b9fba3924 | 851 | } |
frank26080115 | 0:bf7b9fba3924 | 852 | else |
frank26080115 | 0:bf7b9fba3924 | 853 | { |
frank26080115 | 0:bf7b9fba3924 | 854 | *(unsigned short *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCPCode); // TCP header length = 20 |
frank26080115 | 0:bf7b9fba3924 | 855 | *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1); |
frank26080115 | 0:bf7b9fba3924 | 856 | TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE; |
frank26080115 | 0:bf7b9fba3924 | 857 | } |
frank26080115 | 0:bf7b9fba3924 | 858 | |
frank26080115 | 0:bf7b9fba3924 | 859 | TransmitControl |= SEND_FRAME2; |
frank26080115 | 0:bf7b9fba3924 | 860 | } |
frank26080115 | 0:bf7b9fba3924 | 861 | |
frank26080115 | 0:bf7b9fba3924 | 862 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 863 | // prepares the TxFrame1-buffer to send a payload-packet |
frank26080115 | 0:bf7b9fba3924 | 864 | |
frank26080115 | 0:bf7b9fba3924 | 865 | void PrepareTCP_DATA_FRAME(void) |
frank26080115 | 0:bf7b9fba3924 | 866 | { |
frank26080115 | 0:bf7b9fba3924 | 867 | // Ethernet |
frank26080115 | 0:bf7b9fba3924 | 868 | memcpy(&TxFrame1[ETH_DA_OFS], &RemoteMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 869 | memcpy(&TxFrame1[ETH_SA_OFS], &MyMAC, 6); |
frank26080115 | 0:bf7b9fba3924 | 870 | *(unsigned short *)&TxFrame1[ETH_TYPE_OFS] = SWAPB(FRAME_IP); |
frank26080115 | 0:bf7b9fba3924 | 871 | |
frank26080115 | 0:bf7b9fba3924 | 872 | // IP |
frank26080115 | 0:bf7b9fba3924 | 873 | *(unsigned short *)&TxFrame1[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D); |
frank26080115 | 0:bf7b9fba3924 | 874 | WriteWBE(&TxFrame1[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount); |
frank26080115 | 0:bf7b9fba3924 | 875 | *(unsigned short *)&TxFrame1[IP_IDENT_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 876 | *(unsigned short *)&TxFrame1[IP_FLAGS_FRAG_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 877 | *(unsigned short *)&TxFrame1[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP); |
frank26080115 | 0:bf7b9fba3924 | 878 | *(unsigned short *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 879 | memcpy(&TxFrame1[IP_SOURCE_OFS], &MyIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 880 | memcpy(&TxFrame1[IP_DESTINATION_OFS], &RemoteIP, 4); |
frank26080115 | 0:bf7b9fba3924 | 881 | *(unsigned short *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0); |
frank26080115 | 0:bf7b9fba3924 | 882 | |
frank26080115 | 0:bf7b9fba3924 | 883 | // TCP |
frank26080115 | 0:bf7b9fba3924 | 884 | WriteWBE(&TxFrame1[TCP_SRCPORT_OFS], TCPLocalPort); |
frank26080115 | 0:bf7b9fba3924 | 885 | WriteWBE(&TxFrame1[TCP_DESTPORT_OFS], TCPRemotePort); |
frank26080115 | 0:bf7b9fba3924 | 886 | |
frank26080115 | 0:bf7b9fba3924 | 887 | WriteDWBE(&TxFrame1[TCP_SEQNR_OFS], TCPSeqNr); |
frank26080115 | 0:bf7b9fba3924 | 888 | WriteDWBE(&TxFrame1[TCP_ACKNR_OFS], TCPAckNr); |
frank26080115 | 0:bf7b9fba3924 | 889 | *(unsigned short *)&TxFrame1[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCP_CODE_ACK); // TCP header length = 20 |
frank26080115 | 0:bf7b9fba3924 | 890 | *(unsigned short *)&TxFrame1[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept |
frank26080115 | 0:bf7b9fba3924 | 891 | *(unsigned short *)&TxFrame1[TCP_CHKSUM_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 892 | *(unsigned short *)&TxFrame1[TCP_URGENT_OFS] = 0; |
frank26080115 | 0:bf7b9fba3924 | 893 | *(unsigned short *)&TxFrame1[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCPTxDataCount, 1); |
frank26080115 | 0:bf7b9fba3924 | 894 | } |
frank26080115 | 0:bf7b9fba3924 | 895 | |
frank26080115 | 0:bf7b9fba3924 | 896 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 897 | // calculates the TCP/IP checksum. if 'IsTCP != 0', the TCP pseudo-header |
frank26080115 | 0:bf7b9fba3924 | 898 | // will be included. |
frank26080115 | 0:bf7b9fba3924 | 899 | |
frank26080115 | 0:bf7b9fba3924 | 900 | unsigned short CalcChecksum(void *Start, unsigned short Count, unsigned char IsTCP) |
frank26080115 | 0:bf7b9fba3924 | 901 | { |
frank26080115 | 0:bf7b9fba3924 | 902 | unsigned long Sum = 0; |
frank26080115 | 0:bf7b9fba3924 | 903 | unsigned short * piStart; // Keil: Pointer added to correct expression |
frank26080115 | 0:bf7b9fba3924 | 904 | |
frank26080115 | 0:bf7b9fba3924 | 905 | if (IsTCP) { // if we've a TCP frame... |
frank26080115 | 0:bf7b9fba3924 | 906 | Sum += MyIP[0]; // ...include TCP pseudo-header |
frank26080115 | 0:bf7b9fba3924 | 907 | Sum += MyIP[1]; |
frank26080115 | 0:bf7b9fba3924 | 908 | Sum += RemoteIP[0]; |
frank26080115 | 0:bf7b9fba3924 | 909 | Sum += RemoteIP[1]; |
frank26080115 | 0:bf7b9fba3924 | 910 | Sum += SwapBytes(Count); // TCP header length plus data length |
frank26080115 | 0:bf7b9fba3924 | 911 | Sum += SWAPB(PROT_TCP); |
frank26080115 | 0:bf7b9fba3924 | 912 | } |
frank26080115 | 0:bf7b9fba3924 | 913 | |
frank26080115 | 0:bf7b9fba3924 | 914 | piStart = Start; // Keil: Line added |
frank26080115 | 0:bf7b9fba3924 | 915 | while (Count > 1) { // sum words |
frank26080115 | 0:bf7b9fba3924 | 916 | // Sum += *((unsigned short *)Start)++; // Keil: Line replaced with following line |
frank26080115 | 0:bf7b9fba3924 | 917 | Sum += *piStart++; |
frank26080115 | 0:bf7b9fba3924 | 918 | Count -= 2; |
frank26080115 | 0:bf7b9fba3924 | 919 | } |
frank26080115 | 0:bf7b9fba3924 | 920 | |
frank26080115 | 0:bf7b9fba3924 | 921 | if (Count) // add left-over byte, if any |
frank26080115 | 0:bf7b9fba3924 | 922 | // Sum += *(unsigned char *)Start; // Keil: Line replaced with following line |
frank26080115 | 0:bf7b9fba3924 | 923 | Sum += *(unsigned char *)piStart; |
frank26080115 | 0:bf7b9fba3924 | 924 | |
frank26080115 | 0:bf7b9fba3924 | 925 | while (Sum >> 16) // fold 32-bit sum to 16 bits |
frank26080115 | 0:bf7b9fba3924 | 926 | Sum = (Sum & 0xFFFF) + (Sum >> 16); |
frank26080115 | 0:bf7b9fba3924 | 927 | |
frank26080115 | 0:bf7b9fba3924 | 928 | return ~Sum; |
frank26080115 | 0:bf7b9fba3924 | 929 | } |
frank26080115 | 0:bf7b9fba3924 | 930 | |
frank26080115 | 0:bf7b9fba3924 | 931 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 932 | // starts the timer as a retry-timer (used for retransmission-timeout) |
frank26080115 | 0:bf7b9fba3924 | 933 | |
frank26080115 | 0:bf7b9fba3924 | 934 | void TCPStartRetryTimer(void) |
frank26080115 | 0:bf7b9fba3924 | 935 | { |
frank26080115 | 0:bf7b9fba3924 | 936 | TCPTimer = 0; |
frank26080115 | 0:bf7b9fba3924 | 937 | RetryCounter = MAX_RETRYS; |
frank26080115 | 0:bf7b9fba3924 | 938 | TCPFlags |= TCP_TIMER_RUNNING; |
frank26080115 | 0:bf7b9fba3924 | 939 | TCPFlags |= TIMER_TYPE_RETRY; |
frank26080115 | 0:bf7b9fba3924 | 940 | } |
frank26080115 | 0:bf7b9fba3924 | 941 | |
frank26080115 | 0:bf7b9fba3924 | 942 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 943 | // starts the timer as a 'TIME_WAIT'-timer (used to finish a TCP-session) |
frank26080115 | 0:bf7b9fba3924 | 944 | |
frank26080115 | 0:bf7b9fba3924 | 945 | void TCPStartTimeWaitTimer(void) |
frank26080115 | 0:bf7b9fba3924 | 946 | { |
frank26080115 | 0:bf7b9fba3924 | 947 | TCPTimer = 0; |
frank26080115 | 0:bf7b9fba3924 | 948 | TCPFlags |= TCP_TIMER_RUNNING; |
frank26080115 | 0:bf7b9fba3924 | 949 | TCPFlags &= ~TIMER_TYPE_RETRY; |
frank26080115 | 0:bf7b9fba3924 | 950 | } |
frank26080115 | 0:bf7b9fba3924 | 951 | |
frank26080115 | 0:bf7b9fba3924 | 952 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 953 | // restarts the timer |
frank26080115 | 0:bf7b9fba3924 | 954 | |
frank26080115 | 0:bf7b9fba3924 | 955 | void TCPRestartTimer(void) |
frank26080115 | 0:bf7b9fba3924 | 956 | { |
frank26080115 | 0:bf7b9fba3924 | 957 | TCPTimer = 0; |
frank26080115 | 0:bf7b9fba3924 | 958 | } |
frank26080115 | 0:bf7b9fba3924 | 959 | |
frank26080115 | 0:bf7b9fba3924 | 960 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 961 | // stopps the timer |
frank26080115 | 0:bf7b9fba3924 | 962 | |
frank26080115 | 0:bf7b9fba3924 | 963 | void TCPStopTimer(void) |
frank26080115 | 0:bf7b9fba3924 | 964 | { |
frank26080115 | 0:bf7b9fba3924 | 965 | TCPFlags &= ~TCP_TIMER_RUNNING; |
frank26080115 | 0:bf7b9fba3924 | 966 | } |
frank26080115 | 0:bf7b9fba3924 | 967 | |
frank26080115 | 0:bf7b9fba3924 | 968 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 969 | // if a retransmission-timeout occured, check which packet |
frank26080115 | 0:bf7b9fba3924 | 970 | // to resend. |
frank26080115 | 0:bf7b9fba3924 | 971 | |
frank26080115 | 0:bf7b9fba3924 | 972 | void TCPHandleRetransmission(void) |
frank26080115 | 0:bf7b9fba3924 | 973 | { |
frank26080115 | 0:bf7b9fba3924 | 974 | switch (LastFrameSent) |
frank26080115 | 0:bf7b9fba3924 | 975 | { |
frank26080115 | 0:bf7b9fba3924 | 976 | case ARP_REQUEST : { PrepareARP_REQUEST(); break; } |
frank26080115 | 0:bf7b9fba3924 | 977 | case TCP_SYN_FRAME : { PrepareTCP_FRAME(TCP_CODE_SYN); break; } |
frank26080115 | 0:bf7b9fba3924 | 978 | case TCP_SYN_ACK_FRAME : { PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); break; } |
frank26080115 | 0:bf7b9fba3924 | 979 | case TCP_FIN_FRAME : { PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); break; } |
frank26080115 | 0:bf7b9fba3924 | 980 | case TCP_DATA_FRAME : { TransmitControl |= SEND_FRAME1; break; } |
frank26080115 | 0:bf7b9fba3924 | 981 | } |
frank26080115 | 0:bf7b9fba3924 | 982 | } |
frank26080115 | 0:bf7b9fba3924 | 983 | |
frank26080115 | 0:bf7b9fba3924 | 984 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 985 | // if all retransmissions failed, close connection and indicate an error |
frank26080115 | 0:bf7b9fba3924 | 986 | |
frank26080115 | 0:bf7b9fba3924 | 987 | void TCPHandleTimeout(void) |
frank26080115 | 0:bf7b9fba3924 | 988 | { |
frank26080115 | 0:bf7b9fba3924 | 989 | TCPStateMachine = CLOSED; |
frank26080115 | 0:bf7b9fba3924 | 990 | |
frank26080115 | 0:bf7b9fba3924 | 991 | if ((TCPFlags & (TCP_ACTIVE_OPEN | IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN) |
frank26080115 | 0:bf7b9fba3924 | 992 | SocketStatus = SOCK_ERR_ARP_TIMEOUT; // indicate an error to user |
frank26080115 | 0:bf7b9fba3924 | 993 | else |
frank26080115 | 0:bf7b9fba3924 | 994 | SocketStatus = SOCK_ERR_TCP_TIMEOUT; |
frank26080115 | 0:bf7b9fba3924 | 995 | |
frank26080115 | 0:bf7b9fba3924 | 996 | TCPFlags = 0; // clear all flags |
frank26080115 | 0:bf7b9fba3924 | 997 | } |
frank26080115 | 0:bf7b9fba3924 | 998 | |
frank26080115 | 0:bf7b9fba3924 | 999 | |
frank26080115 | 0:bf7b9fba3924 | 1000 | /* |
frank26080115 | 0:bf7b9fba3924 | 1001 | * NXP: old TCPClockHandler() function is replaced with this function |
frank26080115 | 0:bf7b9fba3924 | 1002 | */ |
frank26080115 | 0:bf7b9fba3924 | 1003 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 1004 | // function executed every 0.210s by the CPU. used for the |
frank26080115 | 0:bf7b9fba3924 | 1005 | // inital sequence number generator (ISN) and the TCP-timer |
frank26080115 | 0:bf7b9fba3924 | 1006 | void SysTick_Handler (void) { /* SysTick Interrupt Handler (1ms) */ |
frank26080115 | 0:bf7b9fba3924 | 1007 | ISNGenHigh++; // upper 16 bits of initial sequence number |
frank26080115 | 0:bf7b9fba3924 | 1008 | TCPTimer++; // timer for retransmissions |
frank26080115 | 0:bf7b9fba3924 | 1009 | _tickVal = (++_tickVal) & 0x03; |
frank26080115 | 0:bf7b9fba3924 | 1010 | if (!_tickVal){ |
frank26080115 | 0:bf7b9fba3924 | 1011 | #ifdef MCB_LPC_1768 |
frank26080115 | 0:bf7b9fba3924 | 1012 | LPC_GPIO2->FIOPIN ^= LED_PIN; |
frank26080115 | 0:bf7b9fba3924 | 1013 | #elif defined(IAR_LPC_1768) |
frank26080115 | 0:bf7b9fba3924 | 1014 | LPC_GPIO1->FIOPIN ^= LED_PIN; |
frank26080115 | 0:bf7b9fba3924 | 1015 | #endif |
frank26080115 | 0:bf7b9fba3924 | 1016 | } |
frank26080115 | 0:bf7b9fba3924 | 1017 | } |
frank26080115 | 0:bf7b9fba3924 | 1018 | |
frank26080115 | 0:bf7b9fba3924 | 1019 | |
frank26080115 | 0:bf7b9fba3924 | 1020 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 1021 | // transfers the contents of 'TxFrame1'-Buffer to the EMAC |
frank26080115 | 0:bf7b9fba3924 | 1022 | |
frank26080115 | 0:bf7b9fba3924 | 1023 | void SendFrame1(void) |
frank26080115 | 0:bf7b9fba3924 | 1024 | { |
frank26080115 | 0:bf7b9fba3924 | 1025 | CopyToFrame_EMAC(TxFrame1, TxFrame1Size); |
frank26080115 | 0:bf7b9fba3924 | 1026 | } |
frank26080115 | 0:bf7b9fba3924 | 1027 | |
frank26080115 | 0:bf7b9fba3924 | 1028 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 1029 | // transfers the contents of 'TxFrame2'-Buffer to the EMAC |
frank26080115 | 0:bf7b9fba3924 | 1030 | |
frank26080115 | 0:bf7b9fba3924 | 1031 | void SendFrame2(void) |
frank26080115 | 0:bf7b9fba3924 | 1032 | { |
frank26080115 | 0:bf7b9fba3924 | 1033 | CopyToFrame_EMAC(TxFrame2, TxFrame2Size); |
frank26080115 | 0:bf7b9fba3924 | 1034 | } |
frank26080115 | 0:bf7b9fba3924 | 1035 | |
frank26080115 | 0:bf7b9fba3924 | 1036 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 1037 | // help function to write a WORD in big-endian byte-order |
frank26080115 | 0:bf7b9fba3924 | 1038 | // to MCU-memory |
frank26080115 | 0:bf7b9fba3924 | 1039 | |
frank26080115 | 0:bf7b9fba3924 | 1040 | void WriteWBE(unsigned char *Add, unsigned short Data) |
frank26080115 | 0:bf7b9fba3924 | 1041 | { |
frank26080115 | 0:bf7b9fba3924 | 1042 | *Add++ = Data >> 8; |
frank26080115 | 0:bf7b9fba3924 | 1043 | *Add = (char)Data; |
frank26080115 | 0:bf7b9fba3924 | 1044 | } |
frank26080115 | 0:bf7b9fba3924 | 1045 | |
frank26080115 | 0:bf7b9fba3924 | 1046 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 1047 | // help function to write a DWORD in big-endian byte-order |
frank26080115 | 0:bf7b9fba3924 | 1048 | // to MCU-memory |
frank26080115 | 0:bf7b9fba3924 | 1049 | |
frank26080115 | 0:bf7b9fba3924 | 1050 | void WriteDWBE(unsigned char *Add, unsigned long Data) |
frank26080115 | 0:bf7b9fba3924 | 1051 | { |
frank26080115 | 0:bf7b9fba3924 | 1052 | *Add++ = Data >> 24; |
frank26080115 | 0:bf7b9fba3924 | 1053 | *Add++ = Data >> 16; |
frank26080115 | 0:bf7b9fba3924 | 1054 | *Add++ = Data >> 8; |
frank26080115 | 0:bf7b9fba3924 | 1055 | *Add = (char)Data; |
frank26080115 | 0:bf7b9fba3924 | 1056 | } |
frank26080115 | 0:bf7b9fba3924 | 1057 | |
frank26080115 | 0:bf7b9fba3924 | 1058 | // easyWEB internal function |
frank26080115 | 0:bf7b9fba3924 | 1059 | // help function to swap the byte order of a WORD |
frank26080115 | 0:bf7b9fba3924 | 1060 | |
frank26080115 | 0:bf7b9fba3924 | 1061 | unsigned short SwapBytes(unsigned short Data) |
frank26080115 | 0:bf7b9fba3924 | 1062 | { |
frank26080115 | 0:bf7b9fba3924 | 1063 | return (Data >> 8) | (Data << 8); |
frank26080115 | 0:bf7b9fba3924 | 1064 | } |
frank26080115 | 0:bf7b9fba3924 | 1065 |