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

📄 tcpip.c

📁 msp430单片机
💻 C
📖 第 1 页 / 共 4 页
字号:

      if (TCPCode & TCP_CODE_RST)                // RST??
      {
        if (TCPCode & TCP_CODE_ACK)              // if ACK was acceptable, reset
        {                                        // connection
          TCPStateMachine = CLOSED;
          TCPFlags = 0;                          // reset all flags, stop retransmission...
          SocketStatus = SOCK_ERR_CONN_RESET;
        }
        break;                                   // drop segment
      }
        
      if (TCPCode & TCP_CODE_SYN)                // SYN??
      {
        TCPAckNr = TCPSegSeq;                    // get opponents ISN
        TCPAckNr++;                              // inc. by one...

        if (TCPCode & TCP_CODE_ACK)
        {
          TCPStopTimer();                        // stop retransmission, other TCP got our SYN
          TCPSeqNr = TCPUNASeqNr;                // advance our sequence number

          PrepareTCP_FRAME(TCPSeqNr, TCPAckNr, TCP_CODE_ACK);        // ACK this ISN
          TCPStateMachine = ESTABLISHED;
          SocketStatus |= SOCK_CONNECTED;
          SocketStatus |= SOCK_TX_BUF_RELEASED;  // user may send data now :-)
        }
        else
        {
          TCPStopTimer();
          PrepareTCP_FRAME(TCPSeqNr, TCPAckNr, TCP_CODE_SYN | TCP_CODE_ACK);   // our SYN isn't ACKed yet,
          LastFrameSent = TCP_SYN_ACK_FRAME;               // now continue with sending
          TCPStartRetryTimer();                            // SYN_ACK frames
          TCPStateMachine = SYN_RECD;
        }
      }
      break;
    default :
      // drop segment if IP doesn't belong to current session
      if ((RemoteIP[0] != RecdFrameIP[0]) || (RemoteIP[1] != RecdFrameIP[1]))
        break;      

      // drop segment if port doesn't match        
      if (TCPSegSourcePort != TCPRemotePort)
        break;     

      // drop segment if it doesn't fall into the receive window
      if ((TCPSegSeq < TCPAckNr) || (TCPSegSeq >= TCPAckNr + MAX_TCP_RX_DATA_SIZE))
        break;
            
      if (TCPCode & TCP_CODE_RST)                // RST??
      {
        TCPStateMachine = CLOSED;                // close the state machine
        TCPFlags = 0;                            // reset all flags, stop retransmission...
        SocketStatus = SOCK_ERR_CONN_RESET;      // indicate an error to user
        break;
      }

      if (TCPCode & TCP_CODE_SYN)                // SYN??
      {
        PrepareTCP_FRAME(TCPSegAck, 0, TCP_CODE_RST);  // is NOT allowed here! send a reset,
        TCPStateMachine = CLOSED;                // close connection...
        TCPFlags = 0;                            // reset all flags, stop retransmission...
        SocketStatus = SOCK_ERR_REMOTE;          // fatal error!
        break;                                   // ...and drop the frame
      }

      if (TCPSegSeq != TCPAckNr)                 // drop if it's not the segment we expect,
      {                                          // and send an ACK
        PrepareTCP_FRAME(TCPUNASeqNr, TCPAckNr, TCP_CODE_ACK);
        break;
      }

      if (!(TCPCode & TCP_CODE_ACK)) break;      // drop segment if the ACK bit is off

      if (TCPSegAck == TCPUNASeqNr)              // is our last data sent ACKed?
      {
        TCPStopTimer();                          // stop retransmission
        TCPSeqNr = TCPUNASeqNr;                  // advance our sequence number

        switch (TCPStateMachine)                 // change state if necessary
        {
          case SYN_RECD :                        // ACK of our SYN?
            TCPStateMachine = ESTABLISHED;       // user may send data now :-)
            SocketStatus |= SOCK_CONNECTED;
            break;
          case ESTABLISHED :
            SocketStatus |= SOCK_TX_BUF_RELEASED;  // give TX buffer back
            break;
          case FIN_WAIT_1 :                      // ACK of our FIN?
            TCPStateMachine = FIN_WAIT_2;

            /*
              The following code lines are not according to RFC793, but prevent from
              being stuck in the FIN_WAIT_2 state when no FIN packet within a certain
              timeframe will be received (RFC793 says there are two ways to leave this
              state: 1. FIN is received or 2. user closes/resets the connection)
            */

            TCPStartFinTimer();                  // start TIME_WAIT timeout
            break;
          case CLOSING :                         // ACK of our FIN?
            TCPStateMachine = TIME_WAIT;
            TCPStartFinTimer();                  // start TIME_WAIT timeout
            break;
          case LAST_ACK :                        // ACK of our FIN?
            TCPStateMachine = CLOSED;
            TCPFlags = 0;                        // reset all flags, stop retransmission...
            SocketStatus &= SOCK_DATA_AVAILABLE; // clear all flags but data available
            break;
          case TIME_WAIT :
            // ACK a retransmission of remote FIN
            PrepareTCP_FRAME(TCPSegAck, TCPAckNr, TCP_CODE_ACK);  
            TCPRestartTimer();                   // restart TIME_WAIT timeout
            break;
        }
      }

      if ((TCPStateMachine == ESTABLISHED) ||
          (TCPStateMachine == FIN_WAIT_1) ||
          (TCPStateMachine == FIN_WAIT_2))
        if (NrOfDataBytes)                                 // data available?
          if (!(SocketStatus & SOCK_DATA_AVAILABLE))       // rx data-buffer empty?
          {
            DummyReadFrame8900(6);                         // ignore window, checksum, urgent pointer
            CopyFromFrame8900(RxTCPBufferMem, NrOfDataBytes);  // fetch data and
            TCPRxDataCount = NrOfDataBytes;                // ...tell the user...
            SocketStatus |= SOCK_DATA_AVAILABLE;           // indicate the new data to user
            TCPAckNr += NrOfDataBytes;
            PrepareTCP_FRAME(TCPSegAck, TCPAckNr, TCP_CODE_ACK);  // ACK rec'd data
          }
          else
            break;                               // stop processing here, we cannot send an
                                                 // acknowledge packet as the received data
                                                 // could not be passed to the app layer
              
      if (TCPCode & TCP_CODE_FIN)                // FIN??
      {
        switch (TCPStateMachine)
        {
          case SYN_RECD :
          case ESTABLISHED :
            TCPStateMachine = CLOSE_WAIT;
            break;
          case FIN_WAIT_1 :                      
            TCPStateMachine = CLOSING;           // enter FIN_WAIT_2 (look above) and therefore
            SocketStatus &= ~SOCK_CONNECTED;     // TIME_WAIT
            break;
          case FIN_WAIT_2 :
            TCPStateMachine = TIME_WAIT;
            SocketStatus &= ~SOCK_CONNECTED;            
            TCPStartFinTimer();                  // start TIME_WAIT timeout
            break;
          case TIME_WAIT :
            TCPRestartTimer();                   // restart TIME_WAIT timeout
            break;
        }
        TCPAckNr++;                              // ACK remote's FIN flag
        
        PrepareTCP_FRAME(TCPSegAck, TCPAckNr, TCP_CODE_ACK);
      }
  }
}
//------------------------------------------------------------------------------
// easyWEB internal function
// prepares the TxFrame2-buffer to send an ARP-request
//------------------------------------------------------------------------------
static void PrepareARP_REQUEST(void)
{
  // Ethernet
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS) = 0xffff;  // we don't know opposites MAC!
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 2) = 0xffff;
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 4) = 0xffff;
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS) = MyMAC[0];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS + 2) = MyMAC[1];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS + 4) = MyMAC[2];
  ACCESS_UINT(TxFrame2Mem, ETH_TYPE_OFS) = SWAPB(FRAME_ARP);

  // ARP
  ACCESS_UINT(TxFrame2Mem, ARP_HARDW_OFS) = SWAPB(HARDW_ETH10);
  ACCESS_UINT(TxFrame2Mem, ARP_PROT_OFS) = SWAPB(FRAME_IP); 
  ACCESS_UINT(TxFrame2Mem, ARP_HLEN_PLEN_OFS) = SWAPB(IP_HLEN_PLEN);
  ACCESS_UINT(TxFrame2Mem, ARP_OPCODE_OFS) = SWAPB(OP_ARP_REQUEST);
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_HA_OFS) = MyMAC[0];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_HA_OFS + 2) = MyMAC[1];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_HA_OFS + 4) = MyMAC[2];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_IP_OFS) = MyIP[0];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_IP_OFS + 2) = MyIP[1];
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_HA_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_HA_OFS + 2) = 0;
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_HA_OFS + 4) = 0;
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS + 2) = 0;

  if (((RemoteIP[0] ^ MyIP[0]) & SubnetMask[0]) ||
      ((RemoteIP[1] ^ MyIP[1]) & SubnetMask[1]))
  {
    ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS) = GatewayIP[0];
    ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS + 2) = GatewayIP[1];
  }
  else
  {
    ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS) = RemoteIP[0];
    ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS + 2) = RemoteIP[1];
  }

  TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE;
  TransmitControl |= SEND_FRAME2;
}
//------------------------------------------------------------------------------
// easyWEB internal function
// prepares the TxFrame2-buffer to send an ARP-answer (reply)
//------------------------------------------------------------------------------
static void PrepareARP_ANSWER(void)
{
  // Ethernet
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS) = RecdFrameMAC[0];
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 2) = RecdFrameMAC[1];
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 4) = RecdFrameMAC[2];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS) = MyMAC[0];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS + 2) = MyMAC[1];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS + 4) = MyMAC[2];
  ACCESS_UINT(TxFrame2Mem, ETH_TYPE_OFS) = SWAPB(FRAME_ARP);

  // ARP
  ACCESS_UINT(TxFrame2Mem, ARP_HARDW_OFS) = SWAPB(HARDW_ETH10);
  ACCESS_UINT(TxFrame2Mem, ARP_PROT_OFS) = SWAPB(FRAME_IP); 
  ACCESS_UINT(TxFrame2Mem, ARP_HLEN_PLEN_OFS) = SWAPB(IP_HLEN_PLEN);
  ACCESS_UINT(TxFrame2Mem, ARP_OPCODE_OFS) = SWAPB(OP_ARP_ANSWER);
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_HA_OFS) = MyMAC[0];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_HA_OFS + 2) = MyMAC[1];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_HA_OFS + 4) = MyMAC[2];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_IP_OFS) = MyIP[0];
  ACCESS_UINT(TxFrame2Mem, ARP_SENDER_IP_OFS + 2) = MyIP[1];
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_HA_OFS) = RecdFrameMAC[0];
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_HA_OFS + 2) = RecdFrameMAC[1];
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_HA_OFS + 4) = RecdFrameMAC[2];
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS) = RecdFrameIP[0];
  ACCESS_UINT(TxFrame2Mem, ARP_TARGET_IP_OFS + 2) = RecdFrameIP[1];

  TxFrame2Size = ETH_HEADER_SIZE + ARP_FRAME_SIZE;
  TransmitControl |= SEND_FRAME2;
}
//------------------------------------------------------------------------------
// easyWEB internal function
// prepares the TxFrame2-buffer to send an ICMP-echo-reply
//------------------------------------------------------------------------------
static void 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
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS) = RecdFrameMAC[0];
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 2) = RecdFrameMAC[1];
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 4) = RecdFrameMAC[2];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS) = MyMAC[0];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS + 2) = MyMAC[1];
  ACCESS_UINT(TxFrame2Mem, ETH_SA_OFS + 4) = MyMAC[2];
  ACCESS_UINT(TxFrame2Mem, ETH_TYPE_OFS) = SWAPB(FRAME_IP);
  
  // IP   
  ACCESS_UINT(TxFrame2Mem, IP_VER_IHL_TOS_OFS) = SWAPB(IP_VER_IHL);
  ACCESS_UINT(TxFrame2Mem, IP_TOTAL_LENGTH_OFS) =
    __swap_bytes(IP_HEADER_SIZE + ICMP_HEADER_SIZE + ICMPDataCount);

⌨️ 快捷键说明

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