Webserver basic for CDU

Dependencies:   mbed

Fork of EasyWebCR by Igor Skochinsky

Committer:
igorsk
Date:
Fri Jan 29 21:46:31 2010 +0000
Revision:
0:12b53511e212

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
igorsk 0:12b53511e212 1 /******************************************************************
igorsk 0:12b53511e212 2 ***** *****
igorsk 0:12b53511e212 3 ***** Name: tcpip.c *****
igorsk 0:12b53511e212 4 ***** Ver.: 1.0 *****
igorsk 0:12b53511e212 5 ***** Date: 07/05/2001 *****
igorsk 0:12b53511e212 6 ***** Auth: Andreas Dannenberg *****
igorsk 0:12b53511e212 7 ***** HTWK Leipzig *****
igorsk 0:12b53511e212 8 ***** university of applied sciences *****
igorsk 0:12b53511e212 9 ***** Germany *****
igorsk 0:12b53511e212 10 ***** adannenb@et.htwk-leipzig.de *****
igorsk 0:12b53511e212 11 ***** Func: implements the TCP/IP-stack and provides a *****
igorsk 0:12b53511e212 12 ***** simple API to the user *****
igorsk 0:12b53511e212 13 ***** *****
igorsk 0:12b53511e212 14 ******************************************************************/
igorsk 0:12b53511e212 15
igorsk 0:12b53511e212 16 // Modifications by Code Red Technologies for NXP LPC1768
igorsk 0:12b53511e212 17 // Throughout file, functions of form xxx8900() renamed xxx_EthMAC()
igorsk 0:12b53511e212 18 // Other changes commented in place
igorsk 0:12b53511e212 19
igorsk 0:12b53511e212 20 #include "tcpip.h"
igorsk 0:12b53511e212 21
igorsk 0:12b53511e212 22 //CodeRed - added header for LPC ethernet controller
igorsk 0:12b53511e212 23 #include "ethmac.h"
igorsk 0:12b53511e212 24 // CodeRed - added library string handling header
igorsk 0:12b53511e212 25 #include <string.h>
igorsk 0:12b53511e212 26
igorsk 0:12b53511e212 27 // CodeRed - added NXP LPC register definitions header
igorsk 0:12b53511e212 28 //#include "LPC17xx.h"
igorsk 0:12b53511e212 29
igorsk 0:12b53511e212 30 #include "mbed.h"
igorsk 0:12b53511e212 31
igorsk 0:12b53511e212 32 unsigned short MyIP[] = // "MYIP1.MYIP2.MYIP3.MYIP4"
igorsk 0:12b53511e212 33 {
igorsk 0:12b53511e212 34 MYIP_1 + (MYIP_2 << 8),
igorsk 0:12b53511e212 35 MYIP_3 + (MYIP_4 << 8)
igorsk 0:12b53511e212 36 };
igorsk 0:12b53511e212 37
igorsk 0:12b53511e212 38 unsigned short SubnetMask[] = // "SUBMASK1.SUBMASK2.SUBMASK3.SUBMASK4"
igorsk 0:12b53511e212 39 {
igorsk 0:12b53511e212 40 SUBMASK_1 + (SUBMASK_2 << 8),
igorsk 0:12b53511e212 41 SUBMASK_3 + (SUBMASK_4 << 8)
igorsk 0:12b53511e212 42 };
igorsk 0:12b53511e212 43
igorsk 0:12b53511e212 44 unsigned short GatewayIP[] = // "GWIP1.GWIP2.GWIP3.GWIP4"
igorsk 0:12b53511e212 45 {
igorsk 0:12b53511e212 46 GWIP_1 + (GWIP_2 << 8),
igorsk 0:12b53511e212 47 GWIP_3 + (GWIP_4 << 8)
igorsk 0:12b53511e212 48 };
igorsk 0:12b53511e212 49
igorsk 0:12b53511e212 50 // the next 3 buffers must be word-aligned!
igorsk 0:12b53511e212 51 // (here the 'RecdIPFrameLength' above does that)
igorsk 0:12b53511e212 52 unsigned short _TxFrame1[(ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + MAX_TCP_TX_DATA_SIZE)/2];
igorsk 0:12b53511e212 53 unsigned short _TxFrame2[(ETH_HEADER_SIZE + MAX_ETH_TX_DATA_SIZE)/2];
igorsk 0:12b53511e212 54 unsigned short _RxTCPBuffer[MAX_TCP_RX_DATA_SIZE/2]; // space for incoming TCP-data
igorsk 0:12b53511e212 55
igorsk 0:12b53511e212 56 unsigned short TxFrame1Size; // bytes to send in TxFrame1
igorsk 0:12b53511e212 57 unsigned char TxFrame2Size; // bytes to send in TxFrame2
igorsk 0:12b53511e212 58
igorsk 0:12b53511e212 59 unsigned char TransmitControl;
igorsk 0:12b53511e212 60 #define SEND_FRAME1 0x01
igorsk 0:12b53511e212 61 #define SEND_FRAME2 0x02
igorsk 0:12b53511e212 62
igorsk 0:12b53511e212 63 unsigned char TCPFlags;
igorsk 0:12b53511e212 64 #define TCP_ACTIVE_OPEN 0x01 // easyWEB shall initiate a connection
igorsk 0:12b53511e212 65 #define IP_ADDR_RESOLVED 0x02 // IP sucessfully resolved to MAC
igorsk 0:12b53511e212 66 #define TCP_TIMER_RUNNING 0x04
igorsk 0:12b53511e212 67 #define TIMER_TYPE_RETRY 0x08
igorsk 0:12b53511e212 68 #define TCP_CLOSE_REQUESTED 0x10
igorsk 0:12b53511e212 69
igorsk 0:12b53511e212 70 // easyWEB's internal variables
igorsk 0:12b53511e212 71 TTCPStateMachine TCPStateMachine; // perhaps the most important var at all ;-)
igorsk 0:12b53511e212 72 TLastFrameSent LastFrameSent; // retransmission type
igorsk 0:12b53511e212 73
igorsk 0:12b53511e212 74 unsigned short ISNGenHigh; // upper word of our Initial Sequence Number
igorsk 0:12b53511e212 75 unsigned long TCPSeqNr; // next sequence number to send
igorsk 0:12b53511e212 76 unsigned long TCPUNASeqNr; // last unaknowledged sequence number
igorsk 0:12b53511e212 77 // incremented AFTER sending data
igorsk 0:12b53511e212 78 unsigned long TCPAckNr; // next seq to receive and ack to send
igorsk 0:12b53511e212 79 // incremented AFTER receiving data
igorsk 0:12b53511e212 80 unsigned char TCPTimer; // inc'd each 262ms
igorsk 0:12b53511e212 81 unsigned char RetryCounter; // nr. of retransmissions
igorsk 0:12b53511e212 82
igorsk 0:12b53511e212 83 // properties of the just received frame
igorsk 0:12b53511e212 84 unsigned short RecdFrameLength; // EMAC reported frame length
igorsk 0:12b53511e212 85 unsigned short RecdFrameMAC[3]; // 48 bit MAC
igorsk 0:12b53511e212 86 unsigned short RecdFrameIP[2]; // 32 bit IP
igorsk 0:12b53511e212 87 unsigned short RecdIPFrameLength; // 16 bit IP packet length
igorsk 0:12b53511e212 88
igorsk 0:12b53511e212 89 // easyWEB-API global vars and flags
igorsk 0:12b53511e212 90 unsigned short TCPRxDataCount; // nr. of bytes rec'd
igorsk 0:12b53511e212 91 unsigned short TCPTxDataCount; // nr. of bytes to send
igorsk 0:12b53511e212 92
igorsk 0:12b53511e212 93 unsigned short TCPLocalPort; // TCP ports
igorsk 0:12b53511e212 94 unsigned short TCPRemotePort;
igorsk 0:12b53511e212 95
igorsk 0:12b53511e212 96 unsigned short RemoteMAC[3]; // MAC and IP of current TCP-session
igorsk 0:12b53511e212 97 unsigned short RemoteIP[2];
igorsk 0:12b53511e212 98
igorsk 0:12b53511e212 99 unsigned char SocketStatus;
igorsk 0:12b53511e212 100
igorsk 0:12b53511e212 101 void Start_SysTick10ms(void);
igorsk 0:12b53511e212 102
igorsk 0:12b53511e212 103 // Code Red - moved myMAC definition in from original cs8900.h
igorsk 0:12b53511e212 104 unsigned char MyMAC[6] = // "M1-M2-M3-M4-M5-M6"
igorsk 0:12b53511e212 105 {
igorsk 0:12b53511e212 106 MYMAC_6, MYMAC_5, MYMAC_4,
igorsk 0:12b53511e212 107 MYMAC_3, MYMAC_2, MYMAC_1
igorsk 0:12b53511e212 108 };
igorsk 0:12b53511e212 109
igorsk 0:12b53511e212 110 // easyWEB-API function
igorsk 0:12b53511e212 111 // initalizes the LAN-controller, reset flags, starts timer-ISR
igorsk 0:12b53511e212 112
igorsk 0:12b53511e212 113 void TCPLowLevelInit(void)
igorsk 0:12b53511e212 114 {
igorsk 0:12b53511e212 115 // CodeRed - comment out original 8900 specific code
igorsk 0:12b53511e212 116 /*
igorsk 0:12b53511e212 117 BCSCTL1 &= ~DIVA0; // ACLK = XT1 / 4 = 2 MHz
igorsk 0:12b53511e212 118 BCSCTL1 |= DIVA1;
igorsk 0:12b53511e212 119 TACTL = ID1 | ID0 | TASSEL0 | TAIE; // stop timer, use ACLK / 8 = 250 kHz, gen. int.
igorsk 0:12b53511e212 120 TACTL |= MC1; // start timer in continuous up-mode
igorsk 0:12b53511e212 121 _EINT(); // enable interrupts
igorsk 0:12b53511e212 122
igorsk 0:12b53511e212 123 Init8900();
igorsk 0:12b53511e212 124 */
igorsk 0:12b53511e212 125 LPC_GPIO1->FIODIR = 1 << 25; // P1.25 defined as Output (LED)
igorsk 0:12b53511e212 126
igorsk 0:12b53511e212 127 Start_SysTick10ms(); // Start SysTick timer running (10ms ticks)
igorsk 0:12b53511e212 128
igorsk 0:12b53511e212 129 Init_EthMAC();
igorsk 0:12b53511e212 130
igorsk 0:12b53511e212 131 TransmitControl = 0;
igorsk 0:12b53511e212 132 TCPFlags = 0;
igorsk 0:12b53511e212 133 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 134 SocketStatus = 0;
igorsk 0:12b53511e212 135 }
igorsk 0:12b53511e212 136
igorsk 0:12b53511e212 137 // easyWEB-API function
igorsk 0:12b53511e212 138 // does a passive open (listen on 'MyIP:TCPLocalPort' for an incoming
igorsk 0:12b53511e212 139 // connection)
igorsk 0:12b53511e212 140
igorsk 0:12b53511e212 141 void TCPPassiveOpen(void)
igorsk 0:12b53511e212 142 {
igorsk 0:12b53511e212 143 if (TCPStateMachine == CLOSED)
igorsk 0:12b53511e212 144 {
igorsk 0:12b53511e212 145 TCPFlags &= ~TCP_ACTIVE_OPEN; // let's do a passive open!
igorsk 0:12b53511e212 146 TCPStateMachine = LISTENING;
igorsk 0:12b53511e212 147 SocketStatus = SOCK_ACTIVE; // reset, socket now active
igorsk 0:12b53511e212 148 }
igorsk 0:12b53511e212 149 }
igorsk 0:12b53511e212 150
igorsk 0:12b53511e212 151 // easyWEB-API function
igorsk 0:12b53511e212 152 // does an active open (tries to establish a connection between
igorsk 0:12b53511e212 153 // 'MyIP:TCPLocalPort' and 'RemoteIP:TCPRemotePort')
igorsk 0:12b53511e212 154
igorsk 0:12b53511e212 155 void TCPActiveOpen(void)
igorsk 0:12b53511e212 156 {
igorsk 0:12b53511e212 157 if ((TCPStateMachine == CLOSED) || (TCPStateMachine == LISTENING))
igorsk 0:12b53511e212 158 {
igorsk 0:12b53511e212 159 TCPFlags |= TCP_ACTIVE_OPEN; // let's do an active open!
igorsk 0:12b53511e212 160 TCPFlags &= ~IP_ADDR_RESOLVED; // we haven't opponents MAC yet
igorsk 0:12b53511e212 161
igorsk 0:12b53511e212 162 PrepareARP_REQUEST(); // ask for MAC by sending a broadcast
igorsk 0:12b53511e212 163 LastFrameSent = ARP_REQUEST;
igorsk 0:12b53511e212 164 TCPStartRetryTimer();
igorsk 0:12b53511e212 165 SocketStatus = SOCK_ACTIVE; // reset, socket now active
igorsk 0:12b53511e212 166 }
igorsk 0:12b53511e212 167 }
igorsk 0:12b53511e212 168
igorsk 0:12b53511e212 169 // easyWEB-API function
igorsk 0:12b53511e212 170 // closes an open connection
igorsk 0:12b53511e212 171
igorsk 0:12b53511e212 172 void TCPClose(void)
igorsk 0:12b53511e212 173 {
igorsk 0:12b53511e212 174 switch (TCPStateMachine)
igorsk 0:12b53511e212 175 {
igorsk 0:12b53511e212 176 case LISTENING :
igorsk 0:12b53511e212 177 case SYN_SENT :
igorsk 0:12b53511e212 178 {
igorsk 0:12b53511e212 179 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 180 TCPFlags = 0;
igorsk 0:12b53511e212 181 SocketStatus = 0;
igorsk 0:12b53511e212 182 break;
igorsk 0:12b53511e212 183 }
igorsk 0:12b53511e212 184 case SYN_RECD :
igorsk 0:12b53511e212 185 case ESTABLISHED :
igorsk 0:12b53511e212 186 {
igorsk 0:12b53511e212 187 TCPFlags |= TCP_CLOSE_REQUESTED;
igorsk 0:12b53511e212 188 break;
igorsk 0:12b53511e212 189 }
igorsk 0:12b53511e212 190 }
igorsk 0:12b53511e212 191 }
igorsk 0:12b53511e212 192
igorsk 0:12b53511e212 193 // easyWEB-API function
igorsk 0:12b53511e212 194 // releases the receive-buffer and allows easyWEB to store new data
igorsk 0:12b53511e212 195 // NOTE: rx-buffer MUST be released periodically, else the other TCP
igorsk 0:12b53511e212 196 // get no ACKs for the data it sent
igorsk 0:12b53511e212 197
igorsk 0:12b53511e212 198 void TCPReleaseRxBuffer(void)
igorsk 0:12b53511e212 199 {
igorsk 0:12b53511e212 200 SocketStatus &= ~SOCK_DATA_AVAILABLE;
igorsk 0:12b53511e212 201 }
igorsk 0:12b53511e212 202
igorsk 0:12b53511e212 203 // easyWEB-API function
igorsk 0:12b53511e212 204 // transmitts data stored in 'TCP_TX_BUF'
igorsk 0:12b53511e212 205 // NOTE: * number of bytes to transmit must have been written to 'TCPTxDataCount'
igorsk 0:12b53511e212 206 // * data-count MUST NOT exceed 'MAX_TCP_TX_DATA_SIZE'
igorsk 0:12b53511e212 207
igorsk 0:12b53511e212 208 void TCPTransmitTxBuffer(void)
igorsk 0:12b53511e212 209 {
igorsk 0:12b53511e212 210 if ((TCPStateMachine == ESTABLISHED) || (TCPStateMachine == CLOSE_WAIT))
igorsk 0:12b53511e212 211 if (SocketStatus & SOCK_TX_BUF_RELEASED)
igorsk 0:12b53511e212 212 {
igorsk 0:12b53511e212 213 SocketStatus &= ~SOCK_TX_BUF_RELEASED; // occupy tx-buffer
igorsk 0:12b53511e212 214 TCPUNASeqNr += TCPTxDataCount; // advance UNA
igorsk 0:12b53511e212 215
igorsk 0:12b53511e212 216 TxFrame1Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount;
igorsk 0:12b53511e212 217 TransmitControl |= SEND_FRAME1;
igorsk 0:12b53511e212 218
igorsk 0:12b53511e212 219 LastFrameSent = TCP_DATA_FRAME;
igorsk 0:12b53511e212 220 TCPStartRetryTimer();
igorsk 0:12b53511e212 221 }
igorsk 0:12b53511e212 222 }
igorsk 0:12b53511e212 223
igorsk 0:12b53511e212 224 // CodeRed - New function to check if received frame
igorsk 0:12b53511e212 225 // was a broadcast message
igorsk 0:12b53511e212 226
igorsk 0:12b53511e212 227 // Reads the length of the received ethernet frame and checks if the
igorsk 0:12b53511e212 228 // destination address is a broadcast message or not
igorsk 0:12b53511e212 229 unsigned int BroadcastMessage(void)
igorsk 0:12b53511e212 230 {
igorsk 0:12b53511e212 231 unsigned short FrameDestination[3]; // to hold 48 bit MAC address
igorsk 0:12b53511e212 232
igorsk 0:12b53511e212 233 RecdFrameLength = StartReadingFrame();
igorsk 0:12b53511e212 234
igorsk 0:12b53511e212 235 // Read destination address
igorsk 0:12b53511e212 236 CopyFromFrame_EthMAC(&FrameDestination, 6);
igorsk 0:12b53511e212 237 // Save it for reply
igorsk 0:12b53511e212 238 CopyFromFrame_EthMAC(&RecdFrameMAC, 6);
igorsk 0:12b53511e212 239
igorsk 0:12b53511e212 240 if ((FrameDestination[0] == 0xFFFF) &&
igorsk 0:12b53511e212 241 (FrameDestination[1] == 0xFFFF) &&
igorsk 0:12b53511e212 242 (FrameDestination[2] == 0xFFFF)) {
igorsk 0:12b53511e212 243 return(1); // Broadcast message
igorsk 0:12b53511e212 244 } else {
igorsk 0:12b53511e212 245 return (0);
igorsk 0:12b53511e212 246 }
igorsk 0:12b53511e212 247 }
igorsk 0:12b53511e212 248
igorsk 0:12b53511e212 249
igorsk 0:12b53511e212 250 // easyWEB's 'main()'-function
igorsk 0:12b53511e212 251 // must be called from user program periodically (the often - the better)
igorsk 0:12b53511e212 252 // handles network, TCP/IP-stack and user events
igorsk 0:12b53511e212 253
igorsk 0:12b53511e212 254 void DoNetworkStuff(void)
igorsk 0:12b53511e212 255 {
igorsk 0:12b53511e212 256 // CodeRed - comment out original cs8900 code
igorsk 0:12b53511e212 257 /*
igorsk 0:12b53511e212 258 unsigned int ActRxEvent; // copy of cs8900's RxEvent-Register
igorsk 0:12b53511e212 259
igorsk 0:12b53511e212 260 Write8900(ADD_PORT, PP_RxEvent); // point to RxEvent
igorsk 0:12b53511e212 261 ActRxEvent = Read8900(DATA_PORT); // read, implied skip the last frame
igorsk 0:12b53511e212 262
igorsk 0:12b53511e212 263 if (ActRxEvent & RX_OK)
igorsk 0:12b53511e212 264 {
igorsk 0:12b53511e212 265 if (ActRxEvent & RX_IA) ProcessEthIAFrame();
igorsk 0:12b53511e212 266 if (ActRxEvent & RX_BROADCAST) ProcessEthBroadcastFrame();
igorsk 0:12b53511e212 267 }
igorsk 0:12b53511e212 268 */
igorsk 0:12b53511e212 269
igorsk 0:12b53511e212 270 // Check to see if packet received
igorsk 0:12b53511e212 271 if (CheckIfFrameReceived())
igorsk 0:12b53511e212 272 {
igorsk 0:12b53511e212 273 // Was it a broadcast message?
igorsk 0:12b53511e212 274 if (BroadcastMessage()) {
igorsk 0:12b53511e212 275 ProcessEthBroadcastFrame();
igorsk 0:12b53511e212 276 }
igorsk 0:12b53511e212 277 else {
igorsk 0:12b53511e212 278 ProcessEthIAFrame();
igorsk 0:12b53511e212 279 }
igorsk 0:12b53511e212 280 // now release ethernet controller buffer
igorsk 0:12b53511e212 281 StopReadingFrame();
igorsk 0:12b53511e212 282 }
igorsk 0:12b53511e212 283
igorsk 0:12b53511e212 284
igorsk 0:12b53511e212 285 // CodeRed - now back to original code
igorsk 0:12b53511e212 286
igorsk 0:12b53511e212 287 if (TCPFlags & TCP_TIMER_RUNNING)
igorsk 0:12b53511e212 288 if (TCPFlags & TIMER_TYPE_RETRY)
igorsk 0:12b53511e212 289 {
igorsk 0:12b53511e212 290 if (TCPTimer > RETRY_TIMEOUT)
igorsk 0:12b53511e212 291 {
igorsk 0:12b53511e212 292 TCPRestartTimer(); // set a new timeout
igorsk 0:12b53511e212 293
igorsk 0:12b53511e212 294 if (RetryCounter)
igorsk 0:12b53511e212 295 {
igorsk 0:12b53511e212 296 TCPHandleRetransmission(); // resend last frame
igorsk 0:12b53511e212 297 RetryCounter--;
igorsk 0:12b53511e212 298 }
igorsk 0:12b53511e212 299 else
igorsk 0:12b53511e212 300 {
igorsk 0:12b53511e212 301 TCPStopTimer();
igorsk 0:12b53511e212 302 TCPHandleTimeout();
igorsk 0:12b53511e212 303 }
igorsk 0:12b53511e212 304 }
igorsk 0:12b53511e212 305 }
igorsk 0:12b53511e212 306 else if (TCPTimer > FIN_TIMEOUT)
igorsk 0:12b53511e212 307 {
igorsk 0:12b53511e212 308 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 309 TCPFlags = 0; // reset all flags, stop retransmission...
igorsk 0:12b53511e212 310 SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags but data available
igorsk 0:12b53511e212 311 }
igorsk 0:12b53511e212 312
igorsk 0:12b53511e212 313 switch (TCPStateMachine)
igorsk 0:12b53511e212 314 {
igorsk 0:12b53511e212 315 case CLOSED :
igorsk 0:12b53511e212 316 case LISTENING :
igorsk 0:12b53511e212 317 {
igorsk 0:12b53511e212 318 if (TCPFlags & TCP_ACTIVE_OPEN) // stack has to open a connection?
igorsk 0:12b53511e212 319 if (TCPFlags & IP_ADDR_RESOLVED) // IP resolved?
igorsk 0:12b53511e212 320 if (!(TransmitControl & SEND_FRAME2)) // buffer free?
igorsk 0:12b53511e212 321 {
igorsk 0:12b53511e212 322 // CodeRed - change TAR -> TOTC to use LPC1768 clock
igorsk 0:12b53511e212 323 // TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | TAR; // set local ISN
igorsk 0:12b53511e212 324 TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | (LPC_TIM0->TC & 0xFFFF); // set local ISN
igorsk 0:12b53511e212 325 TCPUNASeqNr = TCPSeqNr;
igorsk 0:12b53511e212 326 TCPAckNr = 0; // we don't know what to ACK!
igorsk 0:12b53511e212 327 TCPUNASeqNr++; // count SYN as a byte
igorsk 0:12b53511e212 328 PrepareTCP_FRAME(TCP_CODE_SYN); // send SYN frame
igorsk 0:12b53511e212 329 LastFrameSent = TCP_SYN_FRAME;
igorsk 0:12b53511e212 330 TCPStartRetryTimer(); // we NEED a retry-timeout
igorsk 0:12b53511e212 331 TCPStateMachine = SYN_SENT;
igorsk 0:12b53511e212 332 }
igorsk 0:12b53511e212 333 break;
igorsk 0:12b53511e212 334 }
igorsk 0:12b53511e212 335 case SYN_RECD :
igorsk 0:12b53511e212 336 case ESTABLISHED :
igorsk 0:12b53511e212 337 {
igorsk 0:12b53511e212 338 if (TCPFlags & TCP_CLOSE_REQUESTED) // user has user initated a close?
igorsk 0:12b53511e212 339 if (!(TransmitControl & (SEND_FRAME2 | SEND_FRAME1))) // buffers free?
igorsk 0:12b53511e212 340 if (TCPSeqNr == TCPUNASeqNr) // all data ACKed?
igorsk 0:12b53511e212 341 {
igorsk 0:12b53511e212 342 TCPUNASeqNr++;
igorsk 0:12b53511e212 343 PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK);
igorsk 0:12b53511e212 344 LastFrameSent = TCP_FIN_FRAME;
igorsk 0:12b53511e212 345 TCPStartRetryTimer();
igorsk 0:12b53511e212 346 TCPStateMachine = FIN_WAIT_1;
igorsk 0:12b53511e212 347 }
igorsk 0:12b53511e212 348 break;
igorsk 0:12b53511e212 349 }
igorsk 0:12b53511e212 350 case CLOSE_WAIT :
igorsk 0:12b53511e212 351 {
igorsk 0:12b53511e212 352 if (!(TransmitControl & (SEND_FRAME2 | SEND_FRAME1))) // buffers free?
igorsk 0:12b53511e212 353 if (TCPSeqNr == TCPUNASeqNr) // all data ACKed?
igorsk 0:12b53511e212 354 {
igorsk 0:12b53511e212 355 TCPUNASeqNr++; // count FIN as a byte
igorsk 0:12b53511e212 356 PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); // we NEED a retry-timeout
igorsk 0:12b53511e212 357 LastFrameSent = TCP_FIN_FRAME; // time to say goodbye...
igorsk 0:12b53511e212 358 TCPStartRetryTimer();
igorsk 0:12b53511e212 359 TCPStateMachine = LAST_ACK;
igorsk 0:12b53511e212 360 }
igorsk 0:12b53511e212 361 break;
igorsk 0:12b53511e212 362 }
igorsk 0:12b53511e212 363 }
igorsk 0:12b53511e212 364
igorsk 0:12b53511e212 365 if (TransmitControl & SEND_FRAME2)
igorsk 0:12b53511e212 366 {
igorsk 0:12b53511e212 367 RequestSend(TxFrame2Size);
igorsk 0:12b53511e212 368
igorsk 0:12b53511e212 369 if (Rdy4Tx()) // NOTE: when using a very fast MCU, maybe
igorsk 0:12b53511e212 370 SendFrame2(); // the CS8900 isn't ready yet, include
igorsk 0:12b53511e212 371 else { // a kind of timer or counter here
igorsk 0:12b53511e212 372 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 373 SocketStatus = SOCK_ERR_ETHERNET; // indicate an error to user
igorsk 0:12b53511e212 374 TCPFlags = 0; // clear all flags, stop timers etc.
igorsk 0:12b53511e212 375 }
igorsk 0:12b53511e212 376
igorsk 0:12b53511e212 377 TransmitControl &= ~SEND_FRAME2; // clear tx-flag
igorsk 0:12b53511e212 378 }
igorsk 0:12b53511e212 379
igorsk 0:12b53511e212 380 if (TransmitControl & SEND_FRAME1)
igorsk 0:12b53511e212 381 {
igorsk 0:12b53511e212 382 PrepareTCP_DATA_FRAME(); // build frame w/ actual SEQ, ACK....
igorsk 0:12b53511e212 383 RequestSend(TxFrame1Size);
igorsk 0:12b53511e212 384
igorsk 0:12b53511e212 385 if (Rdy4Tx()) // CS8900 ready to accept our frame?
igorsk 0:12b53511e212 386 SendFrame1(); // (see note above)
igorsk 0:12b53511e212 387 else {
igorsk 0:12b53511e212 388 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 389 SocketStatus = SOCK_ERR_ETHERNET; // indicate an error to user
igorsk 0:12b53511e212 390 TCPFlags = 0; // clear all flags, stop timers etc.
igorsk 0:12b53511e212 391 }
igorsk 0:12b53511e212 392
igorsk 0:12b53511e212 393 TransmitControl &= ~SEND_FRAME1; // clear tx-flag
igorsk 0:12b53511e212 394 }
igorsk 0:12b53511e212 395 }
igorsk 0:12b53511e212 396
igorsk 0:12b53511e212 397 // easyWEB internal function
igorsk 0:12b53511e212 398 // handles an incoming broadcast frame
igorsk 0:12b53511e212 399
igorsk 0:12b53511e212 400 void ProcessEthBroadcastFrame(void)
igorsk 0:12b53511e212 401 {
igorsk 0:12b53511e212 402 // CodeRed - change from int to short
igorsk 0:12b53511e212 403 // unsigned int TargetIP[2];
igorsk 0:12b53511e212 404 unsigned short TargetIP[2];
igorsk 0:12b53511e212 405
igorsk 0:12b53511e212 406 // CodeRed - remove CS8900 specific code block
igorsk 0:12b53511e212 407 /*
igorsk 0:12b53511e212 408 // next two words MUST be read with High-Byte 1st (CS8900 AN181 Page 2)
igorsk 0:12b53511e212 409 ReadHB1ST8900(RX_FRAME_PORT); // ignore RxStatus Word
igorsk 0:12b53511e212 410 RecdFrameLength = ReadHB1ST8900(RX_FRAME_PORT);// get real length of frame
igorsk 0:12b53511e212 411
igorsk 0:12b53511e212 412 DummyReadFrame8900(6); // ignore DA (FF-FF-FF-FF-FF-FF)
igorsk 0:12b53511e212 413 CopyFromFrame8900(&RecdFrameMAC, 6); // store SA (for our answer)
igorsk 0:12b53511e212 414 // Code Red - end of CS8900 specific block
igorsk 0:12b53511e212 415 */
igorsk 0:12b53511e212 416
igorsk 0:12b53511e212 417 if (ReadFrameBE_EthMAC() == FRAME_ARP) // get frame type, check for ARP
igorsk 0:12b53511e212 418 if (ReadFrameBE_EthMAC() == HARDW_ETH10) // Ethernet frame
igorsk 0:12b53511e212 419 if (ReadFrameBE_EthMAC() == FRAME_IP) // check protocol
igorsk 0:12b53511e212 420 if (ReadFrameBE_EthMAC() == IP_HLEN_PLEN) // check HLEN, PLEN
igorsk 0:12b53511e212 421 if (ReadFrameBE_EthMAC() == OP_ARP_REQUEST)
igorsk 0:12b53511e212 422 {
igorsk 0:12b53511e212 423 DummyReadFrame_EthMAC(6); // ignore sender's hardware address
igorsk 0:12b53511e212 424 CopyFromFrame_EthMAC(&RecdFrameIP, 4); // read sender's protocol address
igorsk 0:12b53511e212 425 DummyReadFrame_EthMAC(6); // ignore target's hardware address
igorsk 0:12b53511e212 426 CopyFromFrame_EthMAC(&TargetIP, 4); // read target's protocol address
igorsk 0:12b53511e212 427 if (!memcmp(&MyIP, &TargetIP, 4)) // is it for us?
igorsk 0:12b53511e212 428 PrepareARP_ANSWER(); // yes->create ARP_ANSWER frame
igorsk 0:12b53511e212 429 }
igorsk 0:12b53511e212 430 }
igorsk 0:12b53511e212 431
igorsk 0:12b53511e212 432 // easyWEB internal function
igorsk 0:12b53511e212 433 // handles an incoming frame that passed CS8900's address filter
igorsk 0:12b53511e212 434 // (individual addressed = IA)
igorsk 0:12b53511e212 435
igorsk 0:12b53511e212 436 void ProcessEthIAFrame(void)
igorsk 0:12b53511e212 437 {
igorsk 0:12b53511e212 438 // CodeRed - change from int to short
igorsk 0:12b53511e212 439 //unsigned int TargetIP[2];
igorsk 0:12b53511e212 440 unsigned short TargetIP[2];
igorsk 0:12b53511e212 441 unsigned char ProtocolType;
igorsk 0:12b53511e212 442 // CodeRed - next few lines not needed for LPC1768 port
igorsk 0:12b53511e212 443 /*
igorsk 0:12b53511e212 444 // next two words MUST be read with High-Byte 1st (CS8900 AN181 Page 2)
igorsk 0:12b53511e212 445 ReadHB1ST_EthMAC(RX_FRAME_PORT); // ignore RxStatus Word
igorsk 0:12b53511e212 446 RecdFrameLength = ReadHB1ST_EthMAC(RX_FRAME_PORT);// get real length of frame
igorsk 0:12b53511e212 447
igorsk 0:12b53511e212 448 DummyReadFrame_EthMAC(6); // ignore DA
igorsk 0:12b53511e212 449 CopyFromFrame_EthMAC(&RecdFrameMAC, 6); // store SA (for our answer)
igorsk 0:12b53511e212 450 */
igorsk 0:12b53511e212 451 switch (ReadFrameBE_EthMAC()) // get frame type
igorsk 0:12b53511e212 452 {
igorsk 0:12b53511e212 453 case FRAME_ARP : // check for ARP
igorsk 0:12b53511e212 454 {
igorsk 0:12b53511e212 455 if ((TCPFlags & (TCP_ACTIVE_OPEN | IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN)
igorsk 0:12b53511e212 456 if (ReadFrameBE_EthMAC() == HARDW_ETH10) // check for the right prot. etc.
igorsk 0:12b53511e212 457 if (ReadFrameBE_EthMAC() == FRAME_IP)
igorsk 0:12b53511e212 458 if (ReadFrameBE_EthMAC() == IP_HLEN_PLEN)
igorsk 0:12b53511e212 459 if (ReadFrameBE_EthMAC() == OP_ARP_ANSWER)
igorsk 0:12b53511e212 460 {
igorsk 0:12b53511e212 461 TCPStopTimer(); // OK, now we've the MAC we wanted ;-)
igorsk 0:12b53511e212 462 CopyFromFrame_EthMAC(&RemoteMAC, 6); // extract opponents MAC
igorsk 0:12b53511e212 463 TCPFlags |= IP_ADDR_RESOLVED;
igorsk 0:12b53511e212 464 }
igorsk 0:12b53511e212 465 break;
igorsk 0:12b53511e212 466 }
igorsk 0:12b53511e212 467 case FRAME_IP : // check for IP-type
igorsk 0:12b53511e212 468 {
igorsk 0:12b53511e212 469 if ((ReadFrameBE_EthMAC() & 0xFF00 ) == IP_VER_IHL) // IPv4, IHL=5 (20 Bytes Header)
igorsk 0:12b53511e212 470 { // ignore Type Of Service
igorsk 0:12b53511e212 471 RecdIPFrameLength = ReadFrameBE_EthMAC(); // get IP frame's length
igorsk 0:12b53511e212 472 ReadFrameBE_EthMAC(); // ignore identification
igorsk 0:12b53511e212 473
igorsk 0:12b53511e212 474 if (!(ReadFrameBE_EthMAC() & (IP_FLAG_MOREFRAG | IP_FRAGOFS_MASK))) // only unfragm. frames
igorsk 0:12b53511e212 475 {
igorsk 0:12b53511e212 476 // CodeRed - add mask
igorsk 0:12b53511e212 477 // ProtocolType = ReadFrameBE_EthMAC() ; // get protocol, ignore TTL
igorsk 0:12b53511e212 478 ProtocolType = ReadFrameBE_EthMAC() & 0xFF ; // get protocol, ignore TTL
igorsk 0:12b53511e212 479 ReadFrameBE_EthMAC(); // ignore checksum
igorsk 0:12b53511e212 480 CopyFromFrame_EthMAC(&RecdFrameIP, 4); // get source IP
igorsk 0:12b53511e212 481 CopyFromFrame_EthMAC(&TargetIP, 4); // get destination IP
igorsk 0:12b53511e212 482
igorsk 0:12b53511e212 483 if (!memcmp(&MyIP, &TargetIP, 4)) // is it for us?
igorsk 0:12b53511e212 484 switch (ProtocolType) {
igorsk 0:12b53511e212 485 case PROT_ICMP : { ProcessICMPFrame(); break; }
igorsk 0:12b53511e212 486 case PROT_TCP : { ProcessTCPFrame(); break; }
igorsk 0:12b53511e212 487 case PROT_UDP : break; // not implemented!
igorsk 0:12b53511e212 488 }
igorsk 0:12b53511e212 489 }
igorsk 0:12b53511e212 490 }
igorsk 0:12b53511e212 491 break;
igorsk 0:12b53511e212 492 }
igorsk 0:12b53511e212 493 }
igorsk 0:12b53511e212 494 }
igorsk 0:12b53511e212 495
igorsk 0:12b53511e212 496 // easyWEB internal function
igorsk 0:12b53511e212 497 // we've just rec'd an ICMP-frame (Internet Control Message Protocol)
igorsk 0:12b53511e212 498 // check what to do and branch to the appropriate sub-function
igorsk 0:12b53511e212 499
igorsk 0:12b53511e212 500 void ProcessICMPFrame(void)
igorsk 0:12b53511e212 501 {
igorsk 0:12b53511e212 502 // CodeRed - change from int to short
igorsk 0:12b53511e212 503 //unsigned int ICMPTypeAndCode;
igorsk 0:12b53511e212 504 unsigned short ICMPTypeAndCode;
igorsk 0:12b53511e212 505
igorsk 0:12b53511e212 506 ICMPTypeAndCode = ReadFrameBE_EthMAC(); // get Message Type and Code
igorsk 0:12b53511e212 507 ReadFrameBE_EthMAC(); // ignore ICMP checksum
igorsk 0:12b53511e212 508
igorsk 0:12b53511e212 509 switch (ICMPTypeAndCode >> 8) { // check type
igorsk 0:12b53511e212 510 case ICMP_ECHO : // is echo request?
igorsk 0:12b53511e212 511 {
igorsk 0:12b53511e212 512 PrepareICMP_ECHO_REPLY(); // echo as much as we can...
igorsk 0:12b53511e212 513 break;
igorsk 0:12b53511e212 514 }
igorsk 0:12b53511e212 515 }
igorsk 0:12b53511e212 516 }
igorsk 0:12b53511e212 517
igorsk 0:12b53511e212 518 // easyWEB internal function
igorsk 0:12b53511e212 519 // we've just rec'd an TCP-frame (Transmission Control Protocol)
igorsk 0:12b53511e212 520 // this function mainly implements the TCP state machine according to RFC793
igorsk 0:12b53511e212 521
igorsk 0:12b53511e212 522 void ProcessTCPFrame(void)
igorsk 0:12b53511e212 523 {
igorsk 0:12b53511e212 524 // CodeRed - change from int to short
igorsk 0:12b53511e212 525 /* unsigned int TCPSegSourcePort; // segment's source port
igorsk 0:12b53511e212 526 unsigned int TCPSegDestPort; // segment's destination port
igorsk 0:12b53511e212 527 unsigned long TCPSegSeq; // segment's sequence number
igorsk 0:12b53511e212 528 unsigned long TCPSegAck; // segment's acknowledge number
igorsk 0:12b53511e212 529 unsigned int TCPCode; // TCP code and header length
igorsk 0:12b53511e212 530 unsigned char TCPHeaderSize; // real TCP header length
igorsk 0:12b53511e212 531 unsigned int NrOfDataBytes; // real number of data
igorsk 0:12b53511e212 532 */
igorsk 0:12b53511e212 533 unsigned short TCPSegSourcePort; // segment's source port
igorsk 0:12b53511e212 534 unsigned short TCPSegDestPort; // segment's destination port
igorsk 0:12b53511e212 535 unsigned long TCPSegSeq; // segment's sequence number
igorsk 0:12b53511e212 536 unsigned long TCPSegAck; // segment's acknowledge number
igorsk 0:12b53511e212 537 unsigned short TCPCode; // TCP code and header length
igorsk 0:12b53511e212 538 unsigned char TCPHeaderSize; // real TCP header length
igorsk 0:12b53511e212 539 unsigned short NrOfDataBytes; // real number of data
igorsk 0:12b53511e212 540
igorsk 0:12b53511e212 541
igorsk 0:12b53511e212 542 TCPSegSourcePort = ReadFrameBE_EthMAC(); // get ports
igorsk 0:12b53511e212 543 TCPSegDestPort = ReadFrameBE_EthMAC();
igorsk 0:12b53511e212 544
igorsk 0:12b53511e212 545 if (TCPSegDestPort != TCPLocalPort) return; // drop segment if port doesn't match
igorsk 0:12b53511e212 546
igorsk 0:12b53511e212 547 TCPSegSeq = (unsigned long)ReadFrameBE_EthMAC() << 16; // get segment sequence nr.
igorsk 0:12b53511e212 548 TCPSegSeq |= ReadFrameBE_EthMAC();
igorsk 0:12b53511e212 549
igorsk 0:12b53511e212 550 TCPSegAck = (unsigned long)ReadFrameBE_EthMAC() << 16; // get segment acknowledge nr.
igorsk 0:12b53511e212 551 TCPSegAck |= ReadFrameBE_EthMAC();
igorsk 0:12b53511e212 552
igorsk 0:12b53511e212 553 TCPCode = ReadFrameBE_EthMAC(); // get control bits, header length...
igorsk 0:12b53511e212 554
igorsk 0:12b53511e212 555 TCPHeaderSize = (TCPCode & DATA_OFS_MASK) >> 10; // header length in bytes
igorsk 0:12b53511e212 556 NrOfDataBytes = RecdIPFrameLength - IP_HEADER_SIZE - TCPHeaderSize; // seg. text length
igorsk 0:12b53511e212 557
igorsk 0:12b53511e212 558 if (NrOfDataBytes > MAX_TCP_RX_DATA_SIZE) return; // packet too large for us :...-(
igorsk 0:12b53511e212 559
igorsk 0:12b53511e212 560 if (TCPHeaderSize > TCP_HEADER_SIZE) // ignore options if any
igorsk 0:12b53511e212 561 DummyReadFrame_EthMAC(TCPHeaderSize - TCP_HEADER_SIZE);
igorsk 0:12b53511e212 562
igorsk 0:12b53511e212 563 switch (TCPStateMachine) // implement the TCP state machine
igorsk 0:12b53511e212 564 {
igorsk 0:12b53511e212 565 case CLOSED :
igorsk 0:12b53511e212 566 {
igorsk 0:12b53511e212 567 if (!(TCPCode & TCP_CODE_RST))
igorsk 0:12b53511e212 568 {
igorsk 0:12b53511e212 569 TCPRemotePort = TCPSegSourcePort;
igorsk 0:12b53511e212 570 memcpy(&RemoteMAC, &RecdFrameMAC, 6); // save opponents MAC and IP
igorsk 0:12b53511e212 571 memcpy(&RemoteIP, &RecdFrameIP, 4); // for later use
igorsk 0:12b53511e212 572
igorsk 0:12b53511e212 573 if (TCPCode & TCP_CODE_ACK) // make the reset sequence
igorsk 0:12b53511e212 574 { // acceptable to the other
igorsk 0:12b53511e212 575 TCPSeqNr = TCPSegAck; // TCP
igorsk 0:12b53511e212 576 PrepareTCP_FRAME(TCP_CODE_RST);
igorsk 0:12b53511e212 577 }
igorsk 0:12b53511e212 578 else
igorsk 0:12b53511e212 579 {
igorsk 0:12b53511e212 580 TCPSeqNr = 0;
igorsk 0:12b53511e212 581 TCPAckNr = TCPSegSeq + NrOfDataBytes;
igorsk 0:12b53511e212 582 if (TCPCode & (TCP_CODE_SYN | TCP_CODE_FIN)) TCPAckNr++;
igorsk 0:12b53511e212 583 PrepareTCP_FRAME(TCP_CODE_RST | TCP_CODE_ACK);
igorsk 0:12b53511e212 584 }
igorsk 0:12b53511e212 585 }
igorsk 0:12b53511e212 586 break;
igorsk 0:12b53511e212 587 }
igorsk 0:12b53511e212 588 case LISTENING :
igorsk 0:12b53511e212 589 {
igorsk 0:12b53511e212 590 if (!(TCPCode & TCP_CODE_RST)) // ignore segment containing RST
igorsk 0:12b53511e212 591 {
igorsk 0:12b53511e212 592 TCPRemotePort = TCPSegSourcePort;
igorsk 0:12b53511e212 593 memcpy(&RemoteMAC, &RecdFrameMAC, 6); // save opponents MAC and IP
igorsk 0:12b53511e212 594 memcpy(&RemoteIP, &RecdFrameIP, 4); // for later use
igorsk 0:12b53511e212 595
igorsk 0:12b53511e212 596 if (TCPCode & TCP_CODE_ACK) // reset a bad
igorsk 0:12b53511e212 597 { // acknowledgement
igorsk 0:12b53511e212 598 TCPSeqNr = TCPSegAck;
igorsk 0:12b53511e212 599 PrepareTCP_FRAME(TCP_CODE_RST);
igorsk 0:12b53511e212 600 }
igorsk 0:12b53511e212 601 else if (TCPCode & TCP_CODE_SYN)
igorsk 0:12b53511e212 602 {
igorsk 0:12b53511e212 603 TCPAckNr = TCPSegSeq + 1; // get remote ISN, next byte we expect
igorsk 0:12b53511e212 604 // CodeRed - change TAR -> TOTC to use LPC1768 clock
igorsk 0:12b53511e212 605 // TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | TAR; // set local ISN
igorsk 0:12b53511e212 606 TCPSeqNr = ((unsigned long)ISNGenHigh << 16) | (LPC_TIM0->TC & 0xFFFF); // set local ISN
igorsk 0:12b53511e212 607 TCPUNASeqNr = TCPSeqNr + 1; // one byte out -> increase by one
igorsk 0:12b53511e212 608 PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK);
igorsk 0:12b53511e212 609 LastFrameSent = TCP_SYN_ACK_FRAME;
igorsk 0:12b53511e212 610 TCPStartRetryTimer();
igorsk 0:12b53511e212 611 TCPStateMachine = SYN_RECD;
igorsk 0:12b53511e212 612 }
igorsk 0:12b53511e212 613 }
igorsk 0:12b53511e212 614 break;
igorsk 0:12b53511e212 615 }
igorsk 0:12b53511e212 616 case SYN_SENT :
igorsk 0:12b53511e212 617 {
igorsk 0:12b53511e212 618 if (memcmp(&RemoteIP, &RecdFrameIP, 4)) break; // drop segment if its IP doesn't belong
igorsk 0:12b53511e212 619 // to current session
igorsk 0:12b53511e212 620
igorsk 0:12b53511e212 621 if (TCPSegSourcePort != TCPRemotePort) break; // drop segment if port doesn't match
igorsk 0:12b53511e212 622
igorsk 0:12b53511e212 623 if (TCPCode & TCP_CODE_ACK) // ACK field significant?
igorsk 0:12b53511e212 624 if (TCPSegAck != TCPUNASeqNr) // is our ISN ACKed?
igorsk 0:12b53511e212 625 {
igorsk 0:12b53511e212 626 if (!(TCPCode & TCP_CODE_RST))
igorsk 0:12b53511e212 627 {
igorsk 0:12b53511e212 628 TCPSeqNr = TCPSegAck;
igorsk 0:12b53511e212 629 PrepareTCP_FRAME(TCP_CODE_RST);
igorsk 0:12b53511e212 630 }
igorsk 0:12b53511e212 631 break; // drop segment
igorsk 0:12b53511e212 632 }
igorsk 0:12b53511e212 633
igorsk 0:12b53511e212 634 if (TCPCode & TCP_CODE_RST) // RST??
igorsk 0:12b53511e212 635 {
igorsk 0:12b53511e212 636 if (TCPCode & TCP_CODE_ACK) // if ACK was acceptable, reset
igorsk 0:12b53511e212 637 { // connection
igorsk 0:12b53511e212 638 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 639 TCPFlags = 0; // reset all flags, stop retransmission...
igorsk 0:12b53511e212 640 SocketStatus = SOCK_ERR_CONN_RESET;
igorsk 0:12b53511e212 641 }
igorsk 0:12b53511e212 642 break; // drop segment
igorsk 0:12b53511e212 643 }
igorsk 0:12b53511e212 644
igorsk 0:12b53511e212 645 if (TCPCode & TCP_CODE_SYN) // SYN??
igorsk 0:12b53511e212 646 {
igorsk 0:12b53511e212 647 TCPAckNr = TCPSegSeq; // get opponents ISN
igorsk 0:12b53511e212 648 TCPAckNr++; // inc. by one...
igorsk 0:12b53511e212 649
igorsk 0:12b53511e212 650 if (TCPCode & TCP_CODE_ACK)
igorsk 0:12b53511e212 651 {
igorsk 0:12b53511e212 652 TCPStopTimer(); // stop retransmission, other TCP got our SYN
igorsk 0:12b53511e212 653 TCPSeqNr = TCPUNASeqNr; // advance our sequence number
igorsk 0:12b53511e212 654
igorsk 0:12b53511e212 655 PrepareTCP_FRAME(TCP_CODE_ACK); // ACK this ISN
igorsk 0:12b53511e212 656 TCPStateMachine = ESTABLISHED;
igorsk 0:12b53511e212 657 SocketStatus |= SOCK_CONNECTED;
igorsk 0:12b53511e212 658 SocketStatus |= SOCK_TX_BUF_RELEASED; // user may send data now :-)
igorsk 0:12b53511e212 659 }
igorsk 0:12b53511e212 660 else
igorsk 0:12b53511e212 661 {
igorsk 0:12b53511e212 662 TCPStopTimer();
igorsk 0:12b53511e212 663 PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); // our SYN isn't ACKed yet,
igorsk 0:12b53511e212 664 LastFrameSent = TCP_SYN_ACK_FRAME; // now continue with sending
igorsk 0:12b53511e212 665 TCPStartRetryTimer(); // SYN_ACK frames
igorsk 0:12b53511e212 666 TCPStateMachine = SYN_RECD;
igorsk 0:12b53511e212 667 }
igorsk 0:12b53511e212 668 }
igorsk 0:12b53511e212 669 break;
igorsk 0:12b53511e212 670 }
igorsk 0:12b53511e212 671 default :
igorsk 0:12b53511e212 672 {
igorsk 0:12b53511e212 673 if (memcmp(&RemoteIP, &RecdFrameIP, 4)) break; // drop segment if IP doesn't belong
igorsk 0:12b53511e212 674 // to current session
igorsk 0:12b53511e212 675
igorsk 0:12b53511e212 676 if (TCPSegSourcePort != TCPRemotePort) break; // drop segment if port doesn't match
igorsk 0:12b53511e212 677
igorsk 0:12b53511e212 678 if (TCPSegSeq != TCPAckNr) break; // drop if it's not the segment we expect
igorsk 0:12b53511e212 679
igorsk 0:12b53511e212 680 if (TCPCode & TCP_CODE_RST) // RST??
igorsk 0:12b53511e212 681 {
igorsk 0:12b53511e212 682 TCPStateMachine = CLOSED; // close the state machine
igorsk 0:12b53511e212 683 TCPFlags = 0; // reset all flags, stop retransmission...
igorsk 0:12b53511e212 684 SocketStatus = SOCK_ERR_CONN_RESET; // indicate an error to user
igorsk 0:12b53511e212 685 break;
igorsk 0:12b53511e212 686 }
igorsk 0:12b53511e212 687
igorsk 0:12b53511e212 688 if (TCPCode & TCP_CODE_SYN) // SYN??
igorsk 0:12b53511e212 689 {
igorsk 0:12b53511e212 690 PrepareTCP_FRAME(TCP_CODE_RST); // is NOT allowed here! send a reset,
igorsk 0:12b53511e212 691 TCPStateMachine = CLOSED; // close connection...
igorsk 0:12b53511e212 692 TCPFlags = 0; // reset all flags, stop retransmission...
igorsk 0:12b53511e212 693 SocketStatus = SOCK_ERR_REMOTE; // fatal error!
igorsk 0:12b53511e212 694 break; // ...and drop the frame
igorsk 0:12b53511e212 695 }
igorsk 0:12b53511e212 696
igorsk 0:12b53511e212 697 if (!(TCPCode & TCP_CODE_ACK)) break; // drop segment if the ACK bit is off
igorsk 0:12b53511e212 698
igorsk 0:12b53511e212 699 if (TCPSegAck == TCPUNASeqNr) // is our last data sent ACKed?
igorsk 0:12b53511e212 700 {
igorsk 0:12b53511e212 701 TCPStopTimer(); // stop retransmission
igorsk 0:12b53511e212 702 TCPSeqNr = TCPUNASeqNr; // advance our sequence number
igorsk 0:12b53511e212 703
igorsk 0:12b53511e212 704 switch (TCPStateMachine) // change state if necessary
igorsk 0:12b53511e212 705 {
igorsk 0:12b53511e212 706 case SYN_RECD : // ACK of our SYN?
igorsk 0:12b53511e212 707 {
igorsk 0:12b53511e212 708 TCPStateMachine = ESTABLISHED; // user may send data now :-)
igorsk 0:12b53511e212 709 SocketStatus |= SOCK_CONNECTED;
igorsk 0:12b53511e212 710 break;
igorsk 0:12b53511e212 711 }
igorsk 0:12b53511e212 712 case FIN_WAIT_1 : { TCPStateMachine = FIN_WAIT_2; break; } // ACK of our FIN?
igorsk 0:12b53511e212 713 case CLOSING : { TCPStateMachine = TIME_WAIT; break; } // ACK of our FIN?
igorsk 0:12b53511e212 714 case LAST_ACK : // ACK of our FIN?
igorsk 0:12b53511e212 715 {
igorsk 0:12b53511e212 716 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 717 TCPFlags = 0; // reset all flags, stop retransmission...
igorsk 0:12b53511e212 718 SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags but data available
igorsk 0:12b53511e212 719 break;
igorsk 0:12b53511e212 720 }
igorsk 0:12b53511e212 721 case TIME_WAIT :
igorsk 0:12b53511e212 722 {
igorsk 0:12b53511e212 723 PrepareTCP_FRAME(TCP_CODE_ACK); // ACK a retransmission of remote FIN
igorsk 0:12b53511e212 724 TCPRestartTimer(); // restart TIME_WAIT timeout
igorsk 0:12b53511e212 725 break;
igorsk 0:12b53511e212 726 }
igorsk 0:12b53511e212 727 }
igorsk 0:12b53511e212 728
igorsk 0:12b53511e212 729 if (TCPStateMachine == ESTABLISHED) // if true, give the frame buffer back
igorsk 0:12b53511e212 730 SocketStatus |= SOCK_TX_BUF_RELEASED; // to user
igorsk 0:12b53511e212 731 }
igorsk 0:12b53511e212 732
igorsk 0:12b53511e212 733 if ((TCPStateMachine == ESTABLISHED) || (TCPStateMachine == FIN_WAIT_1) || (TCPStateMachine == FIN_WAIT_2))
igorsk 0:12b53511e212 734 if (NrOfDataBytes) // data available?
igorsk 0:12b53511e212 735 if (!(SocketStatus & SOCK_DATA_AVAILABLE)) // rx data-buffer empty?
igorsk 0:12b53511e212 736 {
igorsk 0:12b53511e212 737 DummyReadFrame_EthMAC(6); // ignore window, checksum, urgent pointer
igorsk 0:12b53511e212 738 // CodeRed - removed unrequired &
igorsk 0:12b53511e212 739 // CopyFromFrame_EthMAC(&RxTCPBuffer, NrOfDataBytes);// fetch data and
igorsk 0:12b53511e212 740 CopyFromFrame_EthMAC(RxTCPBuffer, NrOfDataBytes);// fetch data and
igorsk 0:12b53511e212 741
igorsk 0:12b53511e212 742 TCPRxDataCount = NrOfDataBytes; // ...tell the user...
igorsk 0:12b53511e212 743 SocketStatus |= SOCK_DATA_AVAILABLE; // indicate the new data to user
igorsk 0:12b53511e212 744 TCPAckNr += NrOfDataBytes;
igorsk 0:12b53511e212 745 PrepareTCP_FRAME(TCP_CODE_ACK); // ACK rec'd data
igorsk 0:12b53511e212 746 }
igorsk 0:12b53511e212 747
igorsk 0:12b53511e212 748 if (TCPCode & TCP_CODE_FIN) // FIN??
igorsk 0:12b53511e212 749 {
igorsk 0:12b53511e212 750 switch (TCPStateMachine)
igorsk 0:12b53511e212 751 {
igorsk 0:12b53511e212 752 case SYN_RECD :
igorsk 0:12b53511e212 753 case ESTABLISHED :
igorsk 0:12b53511e212 754 {
igorsk 0:12b53511e212 755 TCPStateMachine = CLOSE_WAIT;
igorsk 0:12b53511e212 756 break;
igorsk 0:12b53511e212 757 }
igorsk 0:12b53511e212 758 case FIN_WAIT_1 :
igorsk 0:12b53511e212 759 { // if our FIN was ACKed, we automatically
igorsk 0:12b53511e212 760 TCPStateMachine = CLOSING; // enter FIN_WAIT_2 (look above) and therefore
igorsk 0:12b53511e212 761 SocketStatus &= ~SOCK_CONNECTED; // TIME_WAIT
igorsk 0:12b53511e212 762 break;
igorsk 0:12b53511e212 763 }
igorsk 0:12b53511e212 764 case FIN_WAIT_2 :
igorsk 0:12b53511e212 765 {
igorsk 0:12b53511e212 766 TCPStartTimeWaitTimer();
igorsk 0:12b53511e212 767 TCPStateMachine = TIME_WAIT;
igorsk 0:12b53511e212 768 SocketStatus &= ~SOCK_CONNECTED;
igorsk 0:12b53511e212 769 break;
igorsk 0:12b53511e212 770 }
igorsk 0:12b53511e212 771 case TIME_WAIT :
igorsk 0:12b53511e212 772 {
igorsk 0:12b53511e212 773 TCPRestartTimer();
igorsk 0:12b53511e212 774 break;
igorsk 0:12b53511e212 775 }
igorsk 0:12b53511e212 776 }
igorsk 0:12b53511e212 777 TCPAckNr++; // ACK remote's FIN flag
igorsk 0:12b53511e212 778 PrepareTCP_FRAME(TCP_CODE_ACK);
igorsk 0:12b53511e212 779 }
igorsk 0:12b53511e212 780 }
igorsk 0:12b53511e212 781 }
igorsk 0:12b53511e212 782 }
igorsk 0:12b53511e212 783
igorsk 0:12b53511e212 784 // easyWEB internal function
igorsk 0:12b53511e212 785 // prepares the TxFrame2-buffer to send an ARP-request
igorsk 0:12b53511e212 786
igorsk 0:12b53511e212 787 void PrepareARP_REQUEST(void)
igorsk 0:12b53511e212 788 {
igorsk 0:12b53511e212 789 // Ethernet
igorsk 0:12b53511e212 790
igorsk 0:12b53511e212 791 // CodeRed - added char cast
igorsk 0:12b53511e212 792 // memset(&TxFrame2[ETH_DA_OFS], 0xFF, 6);
igorsk 0:12b53511e212 793 memset(&TxFrame2[ETH_DA_OFS], (char)0xFF, 6); // we don't know opposites MAC!
igorsk 0:12b53511e212 794 memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);
igorsk 0:12b53511e212 795 // Code Red - int-> short
igorsk 0:12b53511e212 796 // *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP);
igorsk 0:12b53511e212 797 *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP);
igorsk 0:12b53511e212 798
igorsk 0:12b53511e212 799 // ARP
igorsk 0:12b53511e212 800
igorsk 0:12b53511e212 801 // CodeRed - int-> short
igorsk 0:12b53511e212 802 /* *(unsigned int *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10);
igorsk 0:12b53511e212 803 *(unsigned int *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 804 *(unsigned int *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN);
igorsk 0:12b53511e212 805 *(unsigned int *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_REQUEST);
igorsk 0:12b53511e212 806 */
igorsk 0:12b53511e212 807 *(unsigned short *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10);
igorsk 0:12b53511e212 808 *(unsigned short *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 809 *(unsigned short *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN);
igorsk 0:12b53511e212 810 *(unsigned short *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_REQUEST);
igorsk 0:12b53511e212 811
igorsk 0:12b53511e212 812 memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6);
igorsk 0:12b53511e212 813 memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4);
igorsk 0:12b53511e212 814 memset(&TxFrame2[ARP_TARGET_HA_OFS], 0x00, 6); // we don't know opposites MAC!
igorsk 0:12b53511e212 815
igorsk 0:12b53511e212 816 if (((RemoteIP[0] ^ MyIP[0]) & SubnetMask[0]) || ((RemoteIP[1] ^ MyIP[1]) & SubnetMask[1]))
igorsk 0:12b53511e212 817 memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &GatewayIP, 4); // IP not in subnet, use gateway
igorsk 0:12b53511e212 818 else
igorsk 0:12b53511e212 819 memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &RemoteIP, 4); // other IP is next to us...
igorsk 0:12b53511e212 820
igorsk 0:12b53511e212 821 TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE;
igorsk 0:12b53511e212 822 TransmitControl |= SEND_FRAME2;
igorsk 0:12b53511e212 823 }
igorsk 0:12b53511e212 824
igorsk 0:12b53511e212 825 // easyWEB internal function
igorsk 0:12b53511e212 826 // prepares the TxFrame2-buffer to send an ARP-answer (reply)
igorsk 0:12b53511e212 827
igorsk 0:12b53511e212 828 void PrepareARP_ANSWER(void)
igorsk 0:12b53511e212 829 {
igorsk 0:12b53511e212 830 // Ethernet
igorsk 0:12b53511e212 831 memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6);
igorsk 0:12b53511e212 832 memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);
igorsk 0:12b53511e212 833 // CodeRed - int-> short
igorsk 0:12b53511e212 834 // *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP);
igorsk 0:12b53511e212 835 *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP);
igorsk 0:12b53511e212 836
igorsk 0:12b53511e212 837 // ARP
igorsk 0:12b53511e212 838
igorsk 0:12b53511e212 839 // CodeRed - int-> short
igorsk 0:12b53511e212 840 /* *(unsigned int *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10);
igorsk 0:12b53511e212 841 *(unsigned int *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 842 *(unsigned int *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN);
igorsk 0:12b53511e212 843 *(unsigned int *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_ANSWER);
igorsk 0:12b53511e212 844 */
igorsk 0:12b53511e212 845 *(unsigned short *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10);
igorsk 0:12b53511e212 846 *(unsigned short *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 847 *(unsigned short *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN);
igorsk 0:12b53511e212 848 *(unsigned short *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_ANSWER);
igorsk 0:12b53511e212 849 memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6);
igorsk 0:12b53511e212 850 memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4);
igorsk 0:12b53511e212 851 memcpy(&TxFrame2[ARP_TARGET_HA_OFS], &RecdFrameMAC, 6);
igorsk 0:12b53511e212 852 memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &RecdFrameIP, 4);
igorsk 0:12b53511e212 853
igorsk 0:12b53511e212 854 TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE;
igorsk 0:12b53511e212 855 TransmitControl |= SEND_FRAME2;
igorsk 0:12b53511e212 856 }
igorsk 0:12b53511e212 857
igorsk 0:12b53511e212 858 // easyWEB internal function
igorsk 0:12b53511e212 859 // prepares the TxFrame2-buffer to send an ICMP-echo-reply
igorsk 0:12b53511e212 860
igorsk 0:12b53511e212 861 void PrepareICMP_ECHO_REPLY(void)
igorsk 0:12b53511e212 862 {
igorsk 0:12b53511e212 863 // CodeRed - int-> short
igorsk 0:12b53511e212 864 // unsigned int ICMPDataCount;
igorsk 0:12b53511e212 865 unsigned short ICMPDataCount;
igorsk 0:12b53511e212 866
igorsk 0:12b53511e212 867 if (RecdIPFrameLength > MAX_ETH_TX_DATA_SIZE) // don't overload TX-buffer
igorsk 0:12b53511e212 868 ICMPDataCount = MAX_ETH_TX_DATA_SIZE - IP_HEADER_SIZE - ICMP_HEADER_SIZE;
igorsk 0:12b53511e212 869 else
igorsk 0:12b53511e212 870 ICMPDataCount = RecdIPFrameLength - IP_HEADER_SIZE - ICMP_HEADER_SIZE;
igorsk 0:12b53511e212 871
igorsk 0:12b53511e212 872 // Ethernet
igorsk 0:12b53511e212 873 memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6);
igorsk 0:12b53511e212 874 memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);
igorsk 0:12b53511e212 875
igorsk 0:12b53511e212 876 // CodeRed - int-> short
igorsk 0:12b53511e212 877 // *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 878 *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 879
igorsk 0:12b53511e212 880 // IP
igorsk 0:12b53511e212 881
igorsk 0:12b53511e212 882 // CodeRed - int-> short
igorsk 0:12b53511e212 883 /* *(unsigned int *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL);
igorsk 0:12b53511e212 884 WriteWBE(&TxFrame2[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount);
igorsk 0:12b53511e212 885 *(unsigned int *)&TxFrame2[IP_IDENT_OFS] = 0;
igorsk 0:12b53511e212 886 *(unsigned int *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0;
igorsk 0:12b53511e212 887 *(unsigned int *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_ICMP);
igorsk 0:12b53511e212 888 *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 889 memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4);
igorsk 0:12b53511e212 890 memcpy(&TxFrame2[IP_DESTINATION_OFS], &RecdFrameIP, 4);
igorsk 0:12b53511e212 891 *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 892 */
igorsk 0:12b53511e212 893 *(unsigned short *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL);
igorsk 0:12b53511e212 894 WriteWBE(&TxFrame2[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount);
igorsk 0:12b53511e212 895 *(unsigned short *)&TxFrame2[IP_IDENT_OFS] = 0;
igorsk 0:12b53511e212 896 *(unsigned short *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0;
igorsk 0:12b53511e212 897 *(unsigned short *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_ICMP);
igorsk 0:12b53511e212 898 *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 899 memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4);
igorsk 0:12b53511e212 900 memcpy(&TxFrame2[IP_DESTINATION_OFS], &RecdFrameIP, 4);
igorsk 0:12b53511e212 901 *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 902
igorsk 0:12b53511e212 903 // ICMP
igorsk 0:12b53511e212 904
igorsk 0:12b53511e212 905 // CodeRed - int-> short
igorsk 0:12b53511e212 906 /* *(unsigned int *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8);
igorsk 0:12b53511e212 907 *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field
igorsk 0:12b53511e212 908
igorsk 0:12b53511e212 909 CopyFromFrame8900(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo...
igorsk 0:12b53511e212 910 *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 911 */
igorsk 0:12b53511e212 912 *(unsigned short *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8);
igorsk 0:12b53511e212 913 *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field
igorsk 0:12b53511e212 914
igorsk 0:12b53511e212 915 CopyFromFrame_EthMAC(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo...
igorsk 0:12b53511e212 916 *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 917
igorsk 0:12b53511e212 918
igorsk 0:12b53511e212 919 // ICMP
igorsk 0:12b53511e212 920
igorsk 0:12b53511e212 921 // Code Red - int-> short
igorsk 0:12b53511e212 922 /* *(unsigned int *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8);
igorsk 0:12b53511e212 923 *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field
igorsk 0:12b53511e212 924
igorsk 0:12b53511e212 925 CopyFromFrame8900(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo...
igorsk 0:12b53511e212 926 *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 927 */
igorsk 0:12b53511e212 928 *(unsigned short *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8);
igorsk 0:12b53511e212 929 *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = 0; // initialize checksum field
igorsk 0:12b53511e212 930
igorsk 0:12b53511e212 931 CopyFromFrame_EthMAC(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount); // get data to echo...
igorsk 0:12b53511e212 932 *(unsigned short *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 933
igorsk 0:12b53511e212 934
igorsk 0:12b53511e212 935 TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount;
igorsk 0:12b53511e212 936 TransmitControl |= SEND_FRAME2;
igorsk 0:12b53511e212 937 }
igorsk 0:12b53511e212 938
igorsk 0:12b53511e212 939 // easyWEB internal function
igorsk 0:12b53511e212 940 // prepares the TxFrame2-buffer to send a general TCP frame
igorsk 0:12b53511e212 941 // the TCPCode-field is passed as an argument
igorsk 0:12b53511e212 942
igorsk 0:12b53511e212 943 // CodeRed - int-> short
igorsk 0:12b53511e212 944 //void PrepareTCP_FRAME(unsigned int TCPCode)
igorsk 0:12b53511e212 945 void PrepareTCP_FRAME(unsigned short TCPCode)
igorsk 0:12b53511e212 946 {
igorsk 0:12b53511e212 947 // Ethernet
igorsk 0:12b53511e212 948 memcpy(&TxFrame2[ETH_DA_OFS], &RemoteMAC, 6);
igorsk 0:12b53511e212 949 memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);
igorsk 0:12b53511e212 950
igorsk 0:12b53511e212 951 // CodeRed - int-> short
igorsk 0:12b53511e212 952 // *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 953 *(unsigned short *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 954
igorsk 0:12b53511e212 955 // IP
igorsk 0:12b53511e212 956
igorsk 0:12b53511e212 957 // Code Red - int-> short
igorsk 0:12b53511e212 958 /* *(unsigned int *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D);
igorsk 0:12b53511e212 959
igorsk 0:12b53511e212 960 if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option
igorsk 0:12b53511e212 961 *(unsigned int *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE);
igorsk 0:12b53511e212 962 else
igorsk 0:12b53511e212 963 *(unsigned int *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE);
igorsk 0:12b53511e212 964
igorsk 0:12b53511e212 965 *(unsigned int *)&TxFrame2[IP_IDENT_OFS] = 0;
igorsk 0:12b53511e212 966 *(unsigned int *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0;
igorsk 0:12b53511e212 967 *(unsigned int *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);
igorsk 0:12b53511e212 968 *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 969 memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4);
igorsk 0:12b53511e212 970 memcpy(&TxFrame2[IP_DESTINATION_OFS], &RemoteIP, 4);
igorsk 0:12b53511e212 971 *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 972 */
igorsk 0:12b53511e212 973 *(unsigned short *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D);
igorsk 0:12b53511e212 974
igorsk 0:12b53511e212 975 if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option
igorsk 0:12b53511e212 976 *(unsigned short *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE);
igorsk 0:12b53511e212 977 else
igorsk 0:12b53511e212 978 *(unsigned short *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE);
igorsk 0:12b53511e212 979
igorsk 0:12b53511e212 980 *(unsigned short *)&TxFrame2[IP_IDENT_OFS] = 0;
igorsk 0:12b53511e212 981 *(unsigned short *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0;
igorsk 0:12b53511e212 982 *(unsigned short *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);
igorsk 0:12b53511e212 983 *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 984 memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4);
igorsk 0:12b53511e212 985 memcpy(&TxFrame2[IP_DESTINATION_OFS], &RemoteIP, 4);
igorsk 0:12b53511e212 986 *(unsigned short *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 987
igorsk 0:12b53511e212 988 // TCP
igorsk 0:12b53511e212 989 WriteWBE(&TxFrame2[TCP_SRCPORT_OFS], TCPLocalPort);
igorsk 0:12b53511e212 990 WriteWBE(&TxFrame2[TCP_DESTPORT_OFS], TCPRemotePort);
igorsk 0:12b53511e212 991
igorsk 0:12b53511e212 992 WriteDWBE(&TxFrame2[TCP_SEQNR_OFS], TCPSeqNr);
igorsk 0:12b53511e212 993 WriteDWBE(&TxFrame2[TCP_ACKNR_OFS], TCPAckNr);
igorsk 0:12b53511e212 994
igorsk 0:12b53511e212 995 // CodeRed - int-> short
igorsk 0:12b53511e212 996 /* *(unsigned int *)&TxFrame2[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept
igorsk 0:12b53511e212 997 *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = 0; // initalize checksum
igorsk 0:12b53511e212 998 *(unsigned int *)&TxFrame2[TCP_URGENT_OFS] = 0;
igorsk 0:12b53511e212 999
igorsk 0:12b53511e212 1000 if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option
igorsk 0:12b53511e212 1001 {
igorsk 0:12b53511e212 1002 *(unsigned int *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x6000 | TCPCode); // TCP header length = 24
igorsk 0:12b53511e212 1003 *(unsigned int *)&TxFrame2[TCP_DATA_OFS] = SWAPB(TCP_OPT_MSS); // MSS option
igorsk 0:12b53511e212 1004 *(unsigned int *)&TxFrame2[TCP_DATA_OFS + 2] = SWAPB(MAX_TCP_RX_DATA_SIZE);// max. length of TCP-data we accept
igorsk 0:12b53511e212 1005 *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1);
igorsk 0:12b53511e212 1006 TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE;
igorsk 0:12b53511e212 1007 }
igorsk 0:12b53511e212 1008 else
igorsk 0:12b53511e212 1009 {
igorsk 0:12b53511e212 1010 *(unsigned int *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCPCode); // TCP header length = 20
igorsk 0:12b53511e212 1011 *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1);
igorsk 0:12b53511e212 1012 TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE;
igorsk 0:12b53511e212 1013 }
igorsk 0:12b53511e212 1014 */
igorsk 0:12b53511e212 1015 *(unsigned short *)&TxFrame2[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept
igorsk 0:12b53511e212 1016 *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = 0; // initalize checksum
igorsk 0:12b53511e212 1017 *(unsigned short *)&TxFrame2[TCP_URGENT_OFS] = 0;
igorsk 0:12b53511e212 1018
igorsk 0:12b53511e212 1019 if (TCPCode & TCP_CODE_SYN) // if SYN, we want to use the MSS option
igorsk 0:12b53511e212 1020 {
igorsk 0:12b53511e212 1021 *(unsigned short *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x6000 | TCPCode); // TCP header length = 24
igorsk 0:12b53511e212 1022 *(unsigned short *)&TxFrame2[TCP_DATA_OFS] = SWAPB(TCP_OPT_MSS); // MSS option
igorsk 0:12b53511e212 1023 *(unsigned short *)&TxFrame2[TCP_DATA_OFS + 2] = SWAPB(MAX_TCP_RX_DATA_SIZE);// max. length of TCP-data we accept
igorsk 0:12b53511e212 1024 *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1);
igorsk 0:12b53511e212 1025 TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE;
igorsk 0:12b53511e212 1026 }
igorsk 0:12b53511e212 1027 else
igorsk 0:12b53511e212 1028 {
igorsk 0:12b53511e212 1029 *(unsigned short *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCPCode); // TCP header length = 20
igorsk 0:12b53511e212 1030 *(unsigned short *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1);
igorsk 0:12b53511e212 1031 TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE;
igorsk 0:12b53511e212 1032 }
igorsk 0:12b53511e212 1033 TransmitControl |= SEND_FRAME2;
igorsk 0:12b53511e212 1034 }
igorsk 0:12b53511e212 1035
igorsk 0:12b53511e212 1036 // easyWEB internal function
igorsk 0:12b53511e212 1037 // prepares the TxFrame1-buffer to send a payload-packet
igorsk 0:12b53511e212 1038
igorsk 0:12b53511e212 1039 void PrepareTCP_DATA_FRAME(void)
igorsk 0:12b53511e212 1040 {
igorsk 0:12b53511e212 1041 // Ethernet
igorsk 0:12b53511e212 1042 memcpy(&TxFrame1[ETH_DA_OFS], &RemoteMAC, 6);
igorsk 0:12b53511e212 1043 memcpy(&TxFrame1[ETH_SA_OFS], &MyMAC, 6);
igorsk 0:12b53511e212 1044 // Code Red - int-> short
igorsk 0:12b53511e212 1045 // *(unsigned int *)&TxFrame1[ETH_TYPE_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 1046 *(unsigned short *)&TxFrame1[ETH_TYPE_OFS] = SWAPB(FRAME_IP);
igorsk 0:12b53511e212 1047
igorsk 0:12b53511e212 1048 // IP
igorsk 0:12b53511e212 1049
igorsk 0:12b53511e212 1050 // CodeRed - int-> short
igorsk 0:12b53511e212 1051 /* *(unsigned int *)&TxFrame1[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D);
igorsk 0:12b53511e212 1052 WriteWBE(&TxFrame1[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount);
igorsk 0:12b53511e212 1053 *(unsigned int *)&TxFrame1[IP_IDENT_OFS] = 0;
igorsk 0:12b53511e212 1054 *(unsigned int *)&TxFrame1[IP_FLAGS_FRAG_OFS] = 0;
igorsk 0:12b53511e212 1055 *(unsigned int *)&TxFrame1[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);
igorsk 0:12b53511e212 1056 *(unsigned int *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 1057 memcpy(&TxFrame1[IP_SOURCE_OFS], &MyIP, 4);
igorsk 0:12b53511e212 1058 memcpy(&TxFrame1[IP_DESTINATION_OFS], &RemoteIP, 4);
igorsk 0:12b53511e212 1059 *(unsigned int *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 1060 */
igorsk 0:12b53511e212 1061 *(unsigned short *)&TxFrame1[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D);
igorsk 0:12b53511e212 1062 WriteWBE(&TxFrame1[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount);
igorsk 0:12b53511e212 1063 *(unsigned short *)&TxFrame1[IP_IDENT_OFS] = 0;
igorsk 0:12b53511e212 1064 *(unsigned short *)&TxFrame1[IP_FLAGS_FRAG_OFS] = 0;
igorsk 0:12b53511e212 1065 *(unsigned short *)&TxFrame1[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);
igorsk 0:12b53511e212 1066 *(unsigned short *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 1067 memcpy(&TxFrame1[IP_SOURCE_OFS], &MyIP, 4);
igorsk 0:12b53511e212 1068 memcpy(&TxFrame1[IP_DESTINATION_OFS], &RemoteIP, 4);
igorsk 0:12b53511e212 1069 *(unsigned short *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
igorsk 0:12b53511e212 1070
igorsk 0:12b53511e212 1071
igorsk 0:12b53511e212 1072 // TCP
igorsk 0:12b53511e212 1073 WriteWBE(&TxFrame1[TCP_SRCPORT_OFS], TCPLocalPort);
igorsk 0:12b53511e212 1074 WriteWBE(&TxFrame1[TCP_DESTPORT_OFS], TCPRemotePort);
igorsk 0:12b53511e212 1075
igorsk 0:12b53511e212 1076 WriteDWBE(&TxFrame1[TCP_SEQNR_OFS], TCPSeqNr);
igorsk 0:12b53511e212 1077 WriteDWBE(&TxFrame1[TCP_ACKNR_OFS], TCPAckNr);
igorsk 0:12b53511e212 1078 // CodeRed - int-> short
igorsk 0:12b53511e212 1079 /* *(unsigned int *)&TxFrame1[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCP_CODE_ACK); // TCP header length = 20
igorsk 0:12b53511e212 1080 *(unsigned int *)&TxFrame1[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept
igorsk 0:12b53511e212 1081 *(unsigned int *)&TxFrame1[TCP_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 1082 *(unsigned int *)&TxFrame1[TCP_URGENT_OFS] = 0;
igorsk 0:12b53511e212 1083 *(unsigned int *)&TxFrame1[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCPTxDataCount, 1);
igorsk 0:12b53511e212 1084 */
igorsk 0:12b53511e212 1085 *(unsigned short *)&TxFrame1[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCP_CODE_ACK); // TCP header length = 20
igorsk 0:12b53511e212 1086 *(unsigned short *)&TxFrame1[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE); // data bytes to accept
igorsk 0:12b53511e212 1087 *(unsigned short *)&TxFrame1[TCP_CHKSUM_OFS] = 0;
igorsk 0:12b53511e212 1088 *(unsigned short *)&TxFrame1[TCP_URGENT_OFS] = 0;
igorsk 0:12b53511e212 1089 *(unsigned short *)&TxFrame1[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCPTxDataCount, 1);
igorsk 0:12b53511e212 1090
igorsk 0:12b53511e212 1091 }
igorsk 0:12b53511e212 1092
igorsk 0:12b53511e212 1093 // easyWEB internal function
igorsk 0:12b53511e212 1094 // calculates the TCP/IP checksum. if 'IsTCP != 0', the TCP pseudo-header
igorsk 0:12b53511e212 1095 // will be included.
igorsk 0:12b53511e212 1096
igorsk 0:12b53511e212 1097 // CodeRed - int-> short
igorsk 0:12b53511e212 1098 //unsigned int CalcChecksum(void *Start, unsigned int Count, unsigned char IsTCP)
igorsk 0:12b53511e212 1099 unsigned short CalcChecksum(void *Start, unsigned short Count, unsigned char IsTCP)
igorsk 0:12b53511e212 1100 {
igorsk 0:12b53511e212 1101 // Code Red - added pStart
igorsk 0:12b53511e212 1102 unsigned short *pStart;
igorsk 0:12b53511e212 1103 unsigned long Sum = 0;
igorsk 0:12b53511e212 1104
igorsk 0:12b53511e212 1105 if (IsTCP) { // if we've a TCP frame...
igorsk 0:12b53511e212 1106 Sum += MyIP[0]; // ...include TCP pseudo-header
igorsk 0:12b53511e212 1107 Sum += MyIP[1];
igorsk 0:12b53511e212 1108 Sum += RemoteIP[0];
igorsk 0:12b53511e212 1109 Sum += RemoteIP[1];
igorsk 0:12b53511e212 1110 Sum += SwapBytes(Count); // TCP header length plus data length
igorsk 0:12b53511e212 1111 Sum += SWAPB(PROT_TCP);
igorsk 0:12b53511e212 1112 }
igorsk 0:12b53511e212 1113
igorsk 0:12b53511e212 1114 // Code Red - modified to correct expression
igorsk 0:12b53511e212 1115 /* while (Count > 1) { // sum words
igorsk 0:12b53511e212 1116 Sum += *((unsigned int *)Start)++;
igorsk 0:12b53511e212 1117 Count -= 2;
igorsk 0:12b53511e212 1118 }
igorsk 0:12b53511e212 1119
igorsk 0:12b53511e212 1120 if (Count) // add left-over byte, if any
igorsk 0:12b53511e212 1121 Sum += *(unsigned char *)Start;
igorsk 0:12b53511e212 1122 */
igorsk 0:12b53511e212 1123
igorsk 0:12b53511e212 1124 pStart = (unsigned short *)Start;
igorsk 0:12b53511e212 1125 while (Count > 1) { // sum words
igorsk 0:12b53511e212 1126 Sum += *pStart++;
igorsk 0:12b53511e212 1127 Count -= 2;
igorsk 0:12b53511e212 1128 }
igorsk 0:12b53511e212 1129
igorsk 0:12b53511e212 1130 if (Count) // add left-over byte, if any
igorsk 0:12b53511e212 1131 Sum += *(unsigned char *)pStart;
igorsk 0:12b53511e212 1132
igorsk 0:12b53511e212 1133
igorsk 0:12b53511e212 1134 while (Sum >> 16) // fold 32-bit sum to 16 bits
igorsk 0:12b53511e212 1135 Sum = (Sum & 0xFFFF) + (Sum >> 16);
igorsk 0:12b53511e212 1136
igorsk 0:12b53511e212 1137 return ~Sum;
igorsk 0:12b53511e212 1138 }
igorsk 0:12b53511e212 1139
igorsk 0:12b53511e212 1140 // easyWEB internal function
igorsk 0:12b53511e212 1141 // starts the timer as a retry-timer (used for retransmission-timeout)
igorsk 0:12b53511e212 1142
igorsk 0:12b53511e212 1143 void TCPStartRetryTimer(void)
igorsk 0:12b53511e212 1144 {
igorsk 0:12b53511e212 1145 TCPTimer = 0;
igorsk 0:12b53511e212 1146 RetryCounter = MAX_RETRYS;
igorsk 0:12b53511e212 1147 TCPFlags |= TCP_TIMER_RUNNING;
igorsk 0:12b53511e212 1148 TCPFlags |= TIMER_TYPE_RETRY;
igorsk 0:12b53511e212 1149 }
igorsk 0:12b53511e212 1150
igorsk 0:12b53511e212 1151 // easyWEB internal function
igorsk 0:12b53511e212 1152 // starts the timer as a 'TIME_WAIT'-timer (used to finish a TCP-session)
igorsk 0:12b53511e212 1153
igorsk 0:12b53511e212 1154 void TCPStartTimeWaitTimer(void)
igorsk 0:12b53511e212 1155 {
igorsk 0:12b53511e212 1156 TCPTimer = 0;
igorsk 0:12b53511e212 1157 TCPFlags |= TCP_TIMER_RUNNING;
igorsk 0:12b53511e212 1158 TCPFlags &= ~TIMER_TYPE_RETRY;
igorsk 0:12b53511e212 1159 }
igorsk 0:12b53511e212 1160
igorsk 0:12b53511e212 1161 // easyWEB internal function
igorsk 0:12b53511e212 1162 // restarts the timer
igorsk 0:12b53511e212 1163
igorsk 0:12b53511e212 1164 void TCPRestartTimer(void)
igorsk 0:12b53511e212 1165 {
igorsk 0:12b53511e212 1166 TCPTimer = 0;
igorsk 0:12b53511e212 1167 }
igorsk 0:12b53511e212 1168
igorsk 0:12b53511e212 1169 // easyWEB internal function
igorsk 0:12b53511e212 1170 // stopps the timer
igorsk 0:12b53511e212 1171
igorsk 0:12b53511e212 1172 void TCPStopTimer(void)
igorsk 0:12b53511e212 1173 {
igorsk 0:12b53511e212 1174 TCPFlags &= ~TCP_TIMER_RUNNING;
igorsk 0:12b53511e212 1175 }
igorsk 0:12b53511e212 1176
igorsk 0:12b53511e212 1177 // easyWEB internal function
igorsk 0:12b53511e212 1178 // if a retransmission-timeout occured, check which packet
igorsk 0:12b53511e212 1179 // to resend.
igorsk 0:12b53511e212 1180
igorsk 0:12b53511e212 1181 void TCPHandleRetransmission(void)
igorsk 0:12b53511e212 1182 {
igorsk 0:12b53511e212 1183 switch (LastFrameSent)
igorsk 0:12b53511e212 1184 {
igorsk 0:12b53511e212 1185 case ARP_REQUEST : { PrepareARP_REQUEST(); break; }
igorsk 0:12b53511e212 1186 case TCP_SYN_FRAME : { PrepareTCP_FRAME(TCP_CODE_SYN); break; }
igorsk 0:12b53511e212 1187 case TCP_SYN_ACK_FRAME : { PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); break; }
igorsk 0:12b53511e212 1188 case TCP_FIN_FRAME : { PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); break; }
igorsk 0:12b53511e212 1189 case TCP_DATA_FRAME : { TransmitControl |= SEND_FRAME1; break; }
igorsk 0:12b53511e212 1190 }
igorsk 0:12b53511e212 1191 }
igorsk 0:12b53511e212 1192
igorsk 0:12b53511e212 1193 // easyWEB internal function
igorsk 0:12b53511e212 1194 // if all retransmissions failed, close connection and indicate an error
igorsk 0:12b53511e212 1195
igorsk 0:12b53511e212 1196 void TCPHandleTimeout(void)
igorsk 0:12b53511e212 1197 {
igorsk 0:12b53511e212 1198 TCPStateMachine = CLOSED;
igorsk 0:12b53511e212 1199
igorsk 0:12b53511e212 1200 if ((TCPFlags & (TCP_ACTIVE_OPEN | IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN)
igorsk 0:12b53511e212 1201 SocketStatus = SOCK_ERR_ARP_TIMEOUT; // indicate an error to user
igorsk 0:12b53511e212 1202 else
igorsk 0:12b53511e212 1203 SocketStatus = SOCK_ERR_TCP_TIMEOUT;
igorsk 0:12b53511e212 1204
igorsk 0:12b53511e212 1205 TCPFlags = 0; // clear all flags
igorsk 0:12b53511e212 1206 }
igorsk 0:12b53511e212 1207
igorsk 0:12b53511e212 1208
igorsk 0:12b53511e212 1209 // CodeRed - TCPClockHandler() replaced
igorsk 0:12b53511e212 1210 /*
igorsk 0:12b53511e212 1211 // easyWEB internal function
igorsk 0:12b53511e212 1212 // function executed every 0.262s by the MCU. used for the
igorsk 0:12b53511e212 1213 // inital sequence number generator (ISN) and the TCP-timer
igorsk 0:12b53511e212 1214
igorsk 0:12b53511e212 1215 interrupt [TIMERA1_VECTOR] void TCPClockHandler(void)
igorsk 0:12b53511e212 1216 {
igorsk 0:12b53511e212 1217 if (TAIV == 10) // check for timer overflow, reset int.-flag
igorsk 0:12b53511e212 1218 {
igorsk 0:12b53511e212 1219 ISNGenHigh++; // upper 16 bits of initial sequence number
igorsk 0:12b53511e212 1220 TCPTimer++; // timer for retransmissions
igorsk 0:12b53511e212 1221 }
igorsk 0:12b53511e212 1222 }
igorsk 0:12b53511e212 1223 */
igorsk 0:12b53511e212 1224
igorsk 0:12b53511e212 1225 // easyWEB internal function
igorsk 0:12b53511e212 1226 // function executed every 0.210s by the MCU. used for the
igorsk 0:12b53511e212 1227 // inital sequence number generator (ISN) and the TCP-timer
igorsk 0:12b53511e212 1228
igorsk 0:12b53511e212 1229 void TCPClockHandler(void)
igorsk 0:12b53511e212 1230 {
igorsk 0:12b53511e212 1231 ISNGenHigh++; // upper 16 bits of initial sequence number
igorsk 0:12b53511e212 1232 TCPTimer++; // timer for retransmissions
igorsk 0:12b53511e212 1233 }
igorsk 0:12b53511e212 1234
igorsk 0:12b53511e212 1235
igorsk 0:12b53511e212 1236 // easyWEB internal function
igorsk 0:12b53511e212 1237 // transfers the contents of 'TxFrame1'-Buffer to the CS8900A
igorsk 0:12b53511e212 1238
igorsk 0:12b53511e212 1239 void SendFrame1(void)
igorsk 0:12b53511e212 1240 {
igorsk 0:12b53511e212 1241 // CodeRed - updated for LPC1768 port
igorsk 0:12b53511e212 1242 // CopyToFrame8900(&TxFrame1, TxFrame1Size);
igorsk 0:12b53511e212 1243 CopyToFrame_EthMAC(TxFrame1, TxFrame1Size);
igorsk 0:12b53511e212 1244 }
igorsk 0:12b53511e212 1245
igorsk 0:12b53511e212 1246 // easyWEB internal function
igorsk 0:12b53511e212 1247 // transfers the contents of 'TxFrame2'-Buffer to the CS8900A
igorsk 0:12b53511e212 1248
igorsk 0:12b53511e212 1249 void SendFrame2(void)
igorsk 0:12b53511e212 1250 {
igorsk 0:12b53511e212 1251 // CodeRed - updated for LPC1768 port
igorsk 0:12b53511e212 1252 // CopyToFrame8900(&TxFrame2, TxFrame2Size);
igorsk 0:12b53511e212 1253 CopyToFrame_EthMAC(TxFrame2, TxFrame2Size);
igorsk 0:12b53511e212 1254 }
igorsk 0:12b53511e212 1255
igorsk 0:12b53511e212 1256 // easyWEB internal function
igorsk 0:12b53511e212 1257 // help function to write a WORD in big-endian byte-order
igorsk 0:12b53511e212 1258 // to MCU-memory
igorsk 0:12b53511e212 1259
igorsk 0:12b53511e212 1260 // CodeRed - int->short
igorsk 0:12b53511e212 1261 //void WriteWBE(unsigned char *Add, unsigned int Data)
igorsk 0:12b53511e212 1262 void WriteWBE(unsigned char *Add, unsigned short Data)
igorsk 0:12b53511e212 1263 {
igorsk 0:12b53511e212 1264 *Add++ = Data >> 8;
igorsk 0:12b53511e212 1265 // Code Red - added cast
igorsk 0:12b53511e212 1266 // *Add = Data;
igorsk 0:12b53511e212 1267 *Add = (char)Data;
igorsk 0:12b53511e212 1268 }
igorsk 0:12b53511e212 1269
igorsk 0:12b53511e212 1270 // easyWEB internal function
igorsk 0:12b53511e212 1271 // help function to write a DWORD in big-endian byte-order
igorsk 0:12b53511e212 1272 // to MCU-memory
igorsk 0:12b53511e212 1273
igorsk 0:12b53511e212 1274 void WriteDWBE(unsigned char *Add, unsigned long Data)
igorsk 0:12b53511e212 1275 {
igorsk 0:12b53511e212 1276 *Add++ = Data >> 24;
igorsk 0:12b53511e212 1277 *Add++ = Data >> 16;
igorsk 0:12b53511e212 1278 *Add++ = Data >> 8;
igorsk 0:12b53511e212 1279 *Add = Data;
igorsk 0:12b53511e212 1280 }
igorsk 0:12b53511e212 1281
igorsk 0:12b53511e212 1282 // easyWEB internal function
igorsk 0:12b53511e212 1283 // help function to swap the byte order of a WORD
igorsk 0:12b53511e212 1284
igorsk 0:12b53511e212 1285 // CodeRed - int->short
igorsk 0:12b53511e212 1286 //unsigned int SwapBytes(unsigned int Data)
igorsk 0:12b53511e212 1287 unsigned short SwapBytes(unsigned short Data)
igorsk 0:12b53511e212 1288 {
igorsk 0:12b53511e212 1289 return (Data >> 8) | (Data << 8);
igorsk 0:12b53511e212 1290 }
igorsk 0:12b53511e212 1291