Igor Skochinsky
/
EasyWebCR
code_red's port of EasyWeb server for LPC1768, made to compile with mbed's online compiler.
tcpip.c@0:12b53511e212, 2010-01-29 (annotated)
- Committer:
- igorsk
- Date:
- Fri Jan 29 21:46:31 2010 +0000
- Revision:
- 0:12b53511e212
Who changed what in which revision?
User | Revision | Line number | New 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 |