⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpip.c

📁 16位单片机接以太网芯片实现web功能。
💻 C
📖 第 1 页 / 共 3 页
字号:
}// easyWEB internal function// prepares the TxFrame2-buffer to send an ARP-answer (reply)void PrepareARP_ANSWER(void){  // Ethernet  memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6);  memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);  *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_ARP);  // ARP  *(unsigned int *)&TxFrame2[ARP_HARDW_OFS] = SWAPB(HARDW_ETH10);  *(unsigned int *)&TxFrame2[ARP_PROT_OFS] = SWAPB(FRAME_IP);  *(unsigned int *)&TxFrame2[ARP_HLEN_PLEN_OFS] = SWAPB(IP_HLEN_PLEN);  *(unsigned int *)&TxFrame2[ARP_OPCODE_OFS] = SWAPB(OP_ARP_ANSWER);  memcpy(&TxFrame2[ARP_SENDER_HA_OFS], &MyMAC, 6);  memcpy(&TxFrame2[ARP_SENDER_IP_OFS], &MyIP, 4);  memcpy(&TxFrame2[ARP_TARGET_HA_OFS], &RecdFrameMAC, 6);  memcpy(&TxFrame2[ARP_TARGET_IP_OFS], &RecdFrameIP, 4);  TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE;  TransmitControl |= SEND_FRAME2;}// easyWEB internal function// prepares the TxFrame2-buffer to send an ICMP-echo-replyvoid PrepareICMP_ECHO_REPLY(void){  unsigned int ICMPDataCount;  if (RecdIPFrameLength > MAX_ETH_TX_DATA_SIZE)                      // don't overload TX-buffer    ICMPDataCount = MAX_ETH_TX_DATA_SIZE - IP_HEADER_SIZE - ICMP_HEADER_SIZE;  else    ICMPDataCount = RecdIPFrameLength - IP_HEADER_SIZE - ICMP_HEADER_SIZE;  // Ethernet  memcpy(&TxFrame2[ETH_DA_OFS], &RecdFrameMAC, 6);  memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);  *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP);    // IP     *(unsigned int *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL);  WriteWBE(&TxFrame2[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount);  *(unsigned int *)&TxFrame2[IP_IDENT_OFS] = 0;  *(unsigned int *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0;  *(unsigned int *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_ICMP);  *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;  memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4);  memcpy(&TxFrame2[IP_DESTINATION_OFS], &RecdFrameIP, 4);  *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);  // ICMP  *(unsigned int *)&TxFrame2[ICMP_TYPE_CODE_OFS] = SWAPB(ICMP_ECHO_REPLY << 8);  *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = 0;                   // initialize checksum field  CopyFromFrame8900(&TxFrame2[ICMP_DATA_OFS], ICMPDataCount);        // get data to echo...  *(unsigned int *)&TxFrame2[ICMP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_DATA_OFS], ICMPDataCount + ICMP_HEADER_SIZE, 0);  TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount;  TransmitControl |= SEND_FRAME2;}// easyWEB internal function// prepares the TxFrame2-buffer to send a general TCP frame// the TCPCode-field is passed as an argumentvoid PrepareTCP_FRAME(unsigned int TCPCode){  // Ethernet  memcpy(&TxFrame2[ETH_DA_OFS], &RemoteMAC, 6);  memcpy(&TxFrame2[ETH_SA_OFS], &MyMAC, 6);  *(unsigned int *)&TxFrame2[ETH_TYPE_OFS] = SWAPB(FRAME_IP);    // IP     *(unsigned int *)&TxFrame2[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D);  if (TCPCode & TCP_CODE_SYN)                    // if SYN, we want to use the MSS option    *(unsigned int *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE);  else    *(unsigned int *)&TxFrame2[IP_TOTAL_LENGTH_OFS] = SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE);      *(unsigned int *)&TxFrame2[IP_IDENT_OFS] = 0;  *(unsigned int *)&TxFrame2[IP_FLAGS_FRAG_OFS] = 0;  *(unsigned int *)&TxFrame2[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);  *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;  memcpy(&TxFrame2[IP_SOURCE_OFS], &MyIP, 4);  memcpy(&TxFrame2[IP_DESTINATION_OFS], &RemoteIP, 4);  *(unsigned int *)&TxFrame2[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);  // TCP  WriteWBE(&TxFrame2[TCP_SRCPORT_OFS], TCPLocalPort);  WriteWBE(&TxFrame2[TCP_DESTPORT_OFS], TCPRemotePort);  WriteDWBE(&TxFrame2[TCP_SEQNR_OFS], TCPSeqNr);  WriteDWBE(&TxFrame2[TCP_ACKNR_OFS], TCPAckNr);  *(unsigned int *)&TxFrame2[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE);    // data bytes to accept  *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = 0;             // initalize checksum  *(unsigned int *)&TxFrame2[TCP_URGENT_OFS] = 0;  if (TCPCode & TCP_CODE_SYN)                    // if SYN, we want to use the MSS option  {    *(unsigned int *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x6000 | TCPCode);   // TCP header length = 24    *(unsigned int *)&TxFrame2[TCP_DATA_OFS] = SWAPB(TCP_OPT_MSS);             // MSS option    *(unsigned int *)&TxFrame2[TCP_DATA_OFS + 2] = SWAPB(MAX_TCP_RX_DATA_SIZE);// max. length of TCP-data we accept    *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1);    TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE;  }  else  {    *(unsigned int *)&TxFrame2[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCPCode);   // TCP header length = 20    *(unsigned int *)&TxFrame2[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1);    TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE;  }  TransmitControl |= SEND_FRAME2;}// easyWEB internal function// prepares the TxFrame1-buffer to send a payload-packetvoid PrepareTCP_DATA_FRAME(void){  // Ethernet  memcpy(&TxFrame1[ETH_DA_OFS], &RemoteMAC, 6);  memcpy(&TxFrame1[ETH_SA_OFS], &MyMAC, 6);  *(unsigned int *)&TxFrame1[ETH_TYPE_OFS] = SWAPB(FRAME_IP);    // IP     *(unsigned int *)&TxFrame1[IP_VER_IHL_TOS_OFS] = SWAPB(IP_VER_IHL | IP_TOS_D);  WriteWBE(&TxFrame1[IP_TOTAL_LENGTH_OFS], IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount);  *(unsigned int *)&TxFrame1[IP_IDENT_OFS] = 0;  *(unsigned int *)&TxFrame1[IP_FLAGS_FRAG_OFS] = 0;  *(unsigned int *)&TxFrame1[IP_TTL_PROT_OFS] = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);  *(unsigned int *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = 0;   memcpy(&TxFrame1[IP_SOURCE_OFS], &MyIP, 4);  memcpy(&TxFrame1[IP_DESTINATION_OFS], &RemoteIP, 4);  *(unsigned int *)&TxFrame1[IP_HEAD_CHKSUM_OFS] = CalcChecksum(&TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);  // TCP  WriteWBE(&TxFrame1[TCP_SRCPORT_OFS], TCPLocalPort);  WriteWBE(&TxFrame1[TCP_DESTPORT_OFS], TCPRemotePort);  WriteDWBE(&TxFrame1[TCP_SEQNR_OFS], TCPSeqNr);  WriteDWBE(&TxFrame1[TCP_ACKNR_OFS], TCPAckNr);  *(unsigned int *)&TxFrame1[TCP_DATA_CODE_OFS] = SWAPB(0x5000 | TCP_CODE_ACK);   // TCP header length = 20  *(unsigned int *)&TxFrame1[TCP_WINDOW_OFS] = SWAPB(MAX_TCP_RX_DATA_SIZE);       // data bytes to accept  *(unsigned int *)&TxFrame1[TCP_CHKSUM_OFS] = 0;   *(unsigned int *)&TxFrame1[TCP_URGENT_OFS] = 0;  *(unsigned int *)&TxFrame1[TCP_CHKSUM_OFS] = CalcChecksum(&TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCPTxDataCount, 1);}// easyWEB internal function// calculates the TCP/IP checksum. if 'IsTCP != 0', the TCP pseudo-header// will be included.unsigned int CalcChecksum(void *Start, unsigned int Count, unsigned char IsTCP){  unsigned long Sum = 0;  if (IsTCP) {                                   // if we've a TCP frame...    Sum += MyIP[0];                              // ...include TCP pseudo-header    Sum += MyIP[1];    Sum += RemoteIP[0];    Sum += RemoteIP[1];    Sum += SwapBytes(Count);                     // TCP header length plus data length    Sum += SWAPB(PROT_TCP);  }  while (Count > 1) {                            // sum words    Sum += *((unsigned int *)Start)++;    Count -= 2;  }  if (Count)                                     // add left-over byte, if any    Sum += *(unsigned char *)Start;    while (Sum >> 16)                              // fold 32-bit sum to 16 bits    Sum = (Sum & 0xFFFF) + (Sum >> 16);    return ~Sum;}// easyWEB internal function// starts the timer as a retry-timer (used for retransmission-timeout)void TCPStartRetryTimer(void){  TCPTimer = 0;  RetryCounter = MAX_RETRYS;  TCPFlags |= TCP_TIMER_RUNNING;  TCPFlags |= TIMER_TYPE_RETRY;}// easyWEB internal function// starts the timer as a 'TIME_WAIT'-timer (used to finish a TCP-session)void TCPStartTimeWaitTimer(void){  TCPTimer = 0;  TCPFlags |= TCP_TIMER_RUNNING;  TCPFlags &= ~TIMER_TYPE_RETRY;  }// easyWEB internal function// restarts the timervoid TCPRestartTimer(void){  TCPTimer = 0;}// easyWEB internal function// stopps the timervoid TCPStopTimer(void){  TCPFlags &= ~TCP_TIMER_RUNNING;}// easyWEB internal function// if a retransmission-timeout occured, check which packet// to resend.void TCPHandleRetransmission(void){  switch (LastFrameSent)  {    case ARP_REQUEST :       { PrepareARP_REQUEST(); break; }    case TCP_SYN_FRAME :     { PrepareTCP_FRAME(TCP_CODE_SYN); break; }    case TCP_SYN_ACK_FRAME : { PrepareTCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK); break; }    case TCP_FIN_FRAME :     { PrepareTCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK); break; }    case TCP_DATA_FRAME :    { TransmitControl |= SEND_FRAME1; break; }  }}// easyWEB internal function// if all retransmissions failed, close connection and indicate an errorvoid TCPHandleTimeout(void){  TCPStateMachine = CLOSED;  if ((TCPFlags & (TCP_ACTIVE_OPEN | IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN)    SocketStatus = SOCK_ERR_ARP_TIMEOUT;         // indicate an error to user  else    SocketStatus = SOCK_ERR_TCP_TIMEOUT;  TCPFlags = 0;                                  // clear all flags}// easyWEB internal function// function executed every 0.262s by the MCU. used for the// inital sequence number generator (ISN) and the TCP-timerinterrupt [TIMERA1_VECTOR] void TCPClockHandler(void){  if (TAIV == 10)                                // check for timer overflow, reset int.-flag  {    ISNGenHigh++;                                // upper 16 bits of initial sequence number    TCPTimer++;                                  // timer for retransmissions  }}// easyWEB internal function// transfers the contents of 'TxFrame1'-Buffer to the CS8900Avoid SendFrame1(void){  CopyToFrame8900(&TxFrame1, TxFrame1Size);}// easyWEB internal function// transfers the contents of 'TxFrame2'-Buffer to the CS8900Avoid SendFrame2(void){  CopyToFrame8900(&TxFrame2, TxFrame2Size);}// easyWEB internal function// help function to write a WORD in big-endian byte-order// to MCU-memoryvoid WriteWBE(unsigned char *Add, unsigned int Data){  *Add++ = Data >> 8;  *Add = Data;}// easyWEB internal function// help function to write a DWORD in big-endian byte-order// to MCU-memoryvoid WriteDWBE(unsigned char *Add, unsigned long Data){  *Add++ = Data >> 24;  *Add++ = Data >> 16;  *Add++ = Data >> 8;  *Add = Data;}// easyWEB internal function// help function to swap the byte order of a WORDunsigned int SwapBytes(unsigned int Data){  return (Data >> 8) | (Data << 8);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -