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

📄 tcpip.c

📁 msp430单片机
💻 C
📖 第 1 页 / 共 4 页
字号:
  ACCESS_UINT(TxFrame2Mem, IP_IDENT_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, IP_FLAGS_FRAG_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, IP_TTL_PROT_OFS) = SWAPB((DEFAULT_TTL << 8) | PROT_ICMP);
  ACCESS_UINT(TxFrame2Mem, IP_HEAD_CHKSUM_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, IP_SOURCE_OFS) = MyIP[0];
  ACCESS_UINT(TxFrame2Mem, IP_SOURCE_OFS + 2) = MyIP[1];
  ACCESS_UINT(TxFrame2Mem, IP_DESTINATION_OFS) = RecdFrameIP[0];
  ACCESS_UINT(TxFrame2Mem, IP_DESTINATION_OFS + 2) = RecdFrameIP[1];
  ACCESS_UINT(TxFrame2Mem, IP_HEAD_CHKSUM_OFS) = 
    CalcChecksum((unsigned char *)TxFrame2Mem + IP_VER_IHL_TOS_OFS, IP_HEADER_SIZE, 0);

  // ICMP
  ACCESS_UINT(TxFrame2Mem, ICMP_TYPE_CODE_OFS) = SWAPB(ICMP_ECHO_REPLY << 8);
  ACCESS_UINT(TxFrame2Mem, ICMP_CHKSUM_OFS) = 0;                // initialize checksum field
  CopyFromFrame8900((unsigned char *)TxFrame2Mem + ICMP_DATA_OFS, ICMPDataCount);  // get data to echo...
  ACCESS_UINT(TxFrame2Mem, ICMP_CHKSUM_OFS) = 
    CalcChecksum((unsigned char *)TxFrame2Mem + 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 argument
//------------------------------------------------------------------------------
static void PrepareTCP_FRAME(unsigned long seqnr, unsigned long acknr,
  unsigned int TCPCode)
{
  // Ethernet
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS) = RemoteMAC[0];
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 2) = RemoteMAC[1];
  ACCESS_UINT(TxFrame2Mem, ETH_DA_OFS + 4) = RemoteMAC[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);

  if (TCPCode & TCP_CODE_SYN)                    // if SYN, we want to use the MSS option
    ACCESS_UINT(TxFrame2Mem, IP_TOTAL_LENGTH_OFS) =
      SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE);
  else
    ACCESS_UINT(TxFrame2Mem, IP_TOTAL_LENGTH_OFS) =
      SWAPB(IP_HEADER_SIZE + TCP_HEADER_SIZE);

  ACCESS_UINT(TxFrame2Mem, IP_IDENT_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, IP_FLAGS_FRAG_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, IP_TTL_PROT_OFS) = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);
  ACCESS_UINT(TxFrame2Mem, IP_HEAD_CHKSUM_OFS) = 0;
  ACCESS_UINT(TxFrame2Mem, IP_SOURCE_OFS) = MyIP[0];
  ACCESS_UINT(TxFrame2Mem, IP_SOURCE_OFS + 2) = MyIP[1];
  ACCESS_UINT(TxFrame2Mem, IP_DESTINATION_OFS) = RemoteIP[0];
  ACCESS_UINT(TxFrame2Mem, IP_DESTINATION_OFS + 2) = RemoteIP[1];
  ACCESS_UINT(TxFrame2Mem, IP_HEAD_CHKSUM_OFS) = 
    CalcChecksum((unsigned char *)TxFrame2Mem + IP_VER_IHL_TOS_OFS,
      IP_HEADER_SIZE, 0);
  
  // TCP
  ACCESS_UINT(TxFrame2Mem, TCP_SRCPORT_OFS) = __swap_bytes(TCPLocalPort);
  ACCESS_UINT(TxFrame2Mem, TCP_DESTPORT_OFS) = __swap_bytes(TCPRemotePort);

  WriteDWBE((unsigned char *)TxFrame2Mem + TCP_SEQNR_OFS, seqnr);
  WriteDWBE((unsigned char *)TxFrame2Mem + TCP_ACKNR_OFS, acknr);

  ACCESS_UINT(TxFrame2Mem, TCP_WINDOW_OFS) = SWAPB(MAX_TCP_RX_DATA_SIZE);    // data bytes to accept
  ACCESS_UINT(TxFrame2Mem, TCP_CHKSUM_OFS) = 0;  // initalize checksum
  ACCESS_UINT(TxFrame2Mem, TCP_URGENT_OFS) = 0;

  if (TCPCode & TCP_CODE_SYN)                    // if SYN, we want to use the MSS option
  {
    ACCESS_UINT(TxFrame2Mem, TCP_DATA_CODE_OFS) = SWAPB(0x6000 | TCPCode);   // TCP header length = 24
    ACCESS_UINT(TxFrame2Mem, TCP_DATA_OFS) = SWAPB(TCP_OPT_MSS);             // MSS option
    ACCESS_UINT(TxFrame2Mem, TCP_DATA_OFS + 2) = SWAPB(MAX_TCP_RX_DATA_SIZE);// max. length of TCP-data we accept
    ACCESS_UINT(TxFrame2Mem, TCP_CHKSUM_OFS) =
      CalcChecksum((unsigned char *)TxFrame2Mem + 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
  {
    ACCESS_UINT(TxFrame2Mem, TCP_DATA_CODE_OFS) = SWAPB(0x5000 | TCPCode);   // TCP header length = 20
    ACCESS_UINT(TxFrame2Mem, TCP_CHKSUM_OFS) =
      CalcChecksum((unsigned char *)TxFrame2Mem + 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-packet
//------------------------------------------------------------------------------
static void PrepareTCP_DATA_FRAME(void)
{
  // Ethernet
  ACCESS_UINT(TxFrame1Mem, ETH_DA_OFS) = RemoteMAC[0];
  ACCESS_UINT(TxFrame1Mem, ETH_DA_OFS + 2) = RemoteMAC[1];
  ACCESS_UINT(TxFrame1Mem, ETH_DA_OFS + 4) = RemoteMAC[2];
  ACCESS_UINT(TxFrame1Mem, ETH_SA_OFS) = MyMAC[0];
  ACCESS_UINT(TxFrame1Mem, ETH_SA_OFS + 2) = MyMAC[1];
  ACCESS_UINT(TxFrame1Mem, ETH_SA_OFS + 4) = MyMAC[2];
  ACCESS_UINT(TxFrame1Mem, ETH_TYPE_OFS) = SWAPB(FRAME_IP);
  
  // IP   
  ACCESS_UINT(TxFrame1Mem, IP_VER_IHL_TOS_OFS) = SWAPB(IP_VER_IHL);
  ACCESS_UINT(TxFrame1Mem, IP_TOTAL_LENGTH_OFS) =
    __swap_bytes(IP_HEADER_SIZE + TCP_HEADER_SIZE + TCPTxDataCount);
  ACCESS_UINT(TxFrame1Mem, IP_IDENT_OFS) = 0;
  ACCESS_UINT(TxFrame1Mem, IP_FLAGS_FRAG_OFS) = 0;
  ACCESS_UINT(TxFrame1Mem, IP_TTL_PROT_OFS) = SWAPB((DEFAULT_TTL << 8) | PROT_TCP);
  ACCESS_UINT(TxFrame1Mem, IP_HEAD_CHKSUM_OFS) = 0;
  ACCESS_UINT(TxFrame1Mem, IP_SOURCE_OFS) = MyIP[0];
  ACCESS_UINT(TxFrame1Mem, IP_SOURCE_OFS + 2) = MyIP[1];
  ACCESS_UINT(TxFrame1Mem, IP_DESTINATION_OFS) = RemoteIP[0];
  ACCESS_UINT(TxFrame1Mem, IP_DESTINATION_OFS + 2) = RemoteIP[1];
  ACCESS_UINT(TxFrame1Mem, IP_HEAD_CHKSUM_OFS) = 
    CalcChecksum((unsigned char *)TxFrame1Mem + IP_VER_IHL_TOS_OFS,
      IP_HEADER_SIZE, 0);

  // TCP
  ACCESS_UINT(TxFrame1Mem, TCP_SRCPORT_OFS) = __swap_bytes(TCPLocalPort);
  ACCESS_UINT(TxFrame1Mem, TCP_DESTPORT_OFS) = __swap_bytes(TCPRemotePort);

  WriteDWBE((unsigned char *)TxFrame1Mem + TCP_SEQNR_OFS, TCPSeqNr);
  WriteDWBE((unsigned char *)TxFrame1Mem + TCP_ACKNR_OFS, TCPAckNr);
  
  ACCESS_UINT(TxFrame1Mem, TCP_DATA_CODE_OFS) = SWAPB(0x5000 | TCP_CODE_ACK);  // TCP header length = 20
  ACCESS_UINT(TxFrame1Mem, TCP_WINDOW_OFS) = SWAPB(MAX_TCP_RX_DATA_SIZE);  // data bytes to accept
  ACCESS_UINT(TxFrame1Mem, TCP_CHKSUM_OFS) = 0;  // initalize checksum
  ACCESS_UINT(TxFrame1Mem, TCP_URGENT_OFS) = 0;
  ACCESS_UINT(TxFrame1Mem, TCP_CHKSUM_OFS) =
    CalcChecksum((unsigned char *)TxFrame1Mem + 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.
//------------------------------------------------------------------------------
static unsigned int CalcChecksum(void *Start, unsigned int Count,
  unsigned char IsTCP)
{
  unsigned long Sum = 0;
  unsigned int *pStart = Start;

  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 += __swap_bytes(Count);                  // TCP header length plus data length
    Sum += SWAPB(PROT_TCP);
  }

  while (Count > 1)                              // sum words
  {                            
    Sum += *pStart++;
    Count -= 2;
  }

  if (Count)                                     // add left-over byte, if any
    Sum += *(unsigned char *)pStart;
  
  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)
//------------------------------------------------------------------------------
static 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)
//------------------------------------------------------------------------------
static void TCPStartFinTimer(void)
{
  TCPTimer = 0;
  TCPFlags |= TCP_TIMER_RUNNING;
  TCPFlags &= ~TIMER_TYPE_RETRY;  
}
//------------------------------------------------------------------------------
// easyWEB internal function
// restarts the timer
//------------------------------------------------------------------------------
static void TCPRestartTimer(void)
{
  TCPTimer = 0;
}
//------------------------------------------------------------------------------
// easyWEB internal function
// stopps the timer
//------------------------------------------------------------------------------
static void TCPStopTimer(void)
{
  TCPFlags &= ~TCP_TIMER_RUNNING;
}
//------------------------------------------------------------------------------
// easyWEB internal function
// if a retransmission-timeout occured, check which packet
// to resend.
//------------------------------------------------------------------------------
static void TCPHandleRetransmission(void)
{
  switch (LastFrameSent)
  {
    case ARP_REQUEST :
      PrepareARP_REQUEST();
      break;
    case TCP_SYN_FRAME :
      PrepareTCP_FRAME(TCPSeqNr, TCPAckNr, TCP_CODE_SYN);
      break;
    case TCP_SYN_ACK_FRAME :
      PrepareTCP_FRAME(TCPSeqNr, TCPAckNr, TCP_CODE_SYN | TCP_CODE_ACK);
      break; 
    case TCP_FIN_FRAME :
      PrepareTCP_FRAME(TCPSeqNr, TCPAckNr, 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 error
//------------------------------------------------------------------------------
static void 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-timer
//------------------------------------------------------------------------------
#pragma vector = TIMERA1_VECTOR
__interrupt 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
  }
}

⌨️ 快捷键说明

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