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

📄 tcp_ip.c

📁 Analog公司的ADSP_BF532上面实现以太网接口的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    *(WORD*)&TCP_TxFrame2[IP_FLAGS_FRAG_OFS] = 0;
    *(WORD*)&TCP_TxFrame2[IP_TTL_PROT_OFS] = swap_bytes((DEFAULT_TTL << 8) | PROT_TCP);
    *(WORD*)&TCP_TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;
    memcpy( &TCP_TxFrame2[IP_SOURCE_OFS], &TCP_Local_IP, 4);
    memcpy( &TCP_TxFrame2[IP_DESTINATION_OFS], &TCP_RemoteIP, 4);
    *(WORD*)&TCP_TxFrame2[IP_HEAD_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);

    // TCP
    *(WORD*)&TCP_TxFrame2[TCP_SRCPORT_OFS] = swap_bytes(TCP_LocalPort);
    *(WORD*)&TCP_TxFrame2[TCP_DESTPORT_OFS] = swap_bytes(TCP_RemotePort);

    WriteDWBE(&TCP_TxFrame2[TCP_SEQNR_OFS], TCP_Seq_Nr);
    WriteDWBE(&TCP_TxFrame2[TCP_ACKNR_OFS], TCP_Ack_Nr);

    // data bytes to accept
    *(WORD*)&TCP_TxFrame2[TCP_WINDOW_OFS] = swap_bytes(MAX_TCP_RX_SIZE);

    // initalize checksum
    *(WORD*)&TCP_TxFrame2[TCP_CHKSUM_OFS] = 0;
    *(WORD*)&TCP_TxFrame2[TCP_URGENT_OFS] = 0;

    // if SYN, we want to use the MSS option
    if (TCPCode & TCP_CODE_SYN)
    {
        // TCP header length = 24
        *(WORD*)&TCP_TxFrame2[TCP_DATA_CODE_OFS] = swap_bytes(0x6000 | TCPCode);

        // MSS option
        *(WORD*)&TCP_TxFrame2[TCP_DATA_OFS] = swap_bytes(TCP_OPT_MSS);

        // max. length of TCP-data we accept
        *(WORD*)&TCP_TxFrame2[TCP_DATA_OFS + 2] = swap_bytes(MAX_TCP_RX_SIZE);
        *(WORD*)&TCP_TxFrame2[TCP_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1);
        TCP_TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE;
    }
    else
    {
        // TCP header length = 20
        *(WORD*)&TCP_TxFrame2[TCP_DATA_CODE_OFS] = swap_bytes(0x5000 | TCPCode);
        *(WORD*)&TCP_TxFrame2[TCP_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1);
        TCP_TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE;
    }
    TCP_TransmitControl |= TCP_SEND_FRAME2;
}


/******************************************************************************
 * TCP_IP_STACK: TCP_Prep_TCP_DATA_FRAME()
 *
 * Purpose:
 *  prepares the TxFrame1-buffer to send a payload-packet
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_Prep_TCP_DATA_FRAME()
{
    // Ethernet
    memcpy( &TCP_TxFrame1[ETH_DA_OFS], &TCP_RemoteMAC, 6);
    memcpy( &TCP_TxFrame1[ETH_SA_OFS], &TCP_MyMAC, 6);
    *(WORD*)&TCP_TxFrame1[ETH_TYPE_OFS] = FRAME_IP;

    // IP
    *(WORD*)&TCP_TxFrame1[IP_VER_IHL_TOS_OFS] = swap_bytes(IP_VER_IHL | IP_TOS_D);
    *(WORD*)&TCP_TxFrame1[IP_TOTAL_LENGTH_OFS] = swap_bytes( IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_Tx_Data_Count);
    *(WORD*)&TCP_TxFrame1[IP_IDENT_OFS] = 0;
    *(WORD*)&TCP_TxFrame1[IP_FLAGS_FRAG_OFS] = 0;
    *(WORD*)&TCP_TxFrame1[IP_TTL_PROT_OFS] = swap_bytes((DEFAULT_TTL << 8) | PROT_TCP);
    *(WORD*)&TCP_TxFrame1[IP_HEAD_CHKSUM_OFS] = 0;
    memcpy( &TCP_TxFrame1[IP_SOURCE_OFS], &TCP_Local_IP, 4);
    memcpy( &TCP_TxFrame1[IP_DESTINATION_OFS], &TCP_RemoteIP, 4);
    *(WORD*)&TCP_TxFrame1[IP_HEAD_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);

    // TCP
    *(WORD*)&TCP_TxFrame1[TCP_SRCPORT_OFS] = swap_bytes(TCP_LocalPort);
    *(WORD*)&TCP_TxFrame1[TCP_DESTPORT_OFS] = swap_bytes(TCP_RemotePort);

    WriteDWBE(&TCP_TxFrame1[TCP_SEQNR_OFS], TCP_Seq_Nr);
    WriteDWBE(&TCP_TxFrame1[TCP_ACKNR_OFS], TCP_Ack_Nr);

    // TCP header length = 20
    *(WORD*)&TCP_TxFrame1[TCP_DATA_CODE_OFS] = swap_bytes(0x5000 | TCP_CODE_ACK | TCP_CODE_PSH);

    // data bytes to accept
    *(WORD*)&TCP_TxFrame1[TCP_WINDOW_OFS] = swap_bytes(MAX_TCP_RX_SIZE);
    *(WORD*)&TCP_TxFrame1[TCP_CHKSUM_OFS] = 0;
    *(WORD*)&TCP_TxFrame1[TCP_URGENT_OFS] = 0;
    *(WORD*)&TCP_TxFrame1[TCP_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_Tx_Data_Count, 1);

}

/******************************************************************************
 * TCP_IP_STACK: CalcChecksum()
 *
 * Purpose:
 *  calculates the TCP/IP checksum. if 'IsTCP != 0', the TCP pseudo-header
 *  will be included.
 *
 * Actions:
 *
 *****************************************************************************/
MC WORD TCP_CalcChecksum(BYTE *Start, WORD Count, BYTE IsTCP)
{
    DWORD Sum = 0;

    // if we've a TCP frame...
    // ...include TCP pseudo-header
    if (IsTCP)
    {
        Sum += TCP_Local_IP[0];
        Sum += TCP_Local_IP[1];
        Sum += TCP_RemoteIP[0];
        Sum += TCP_RemoteIP[1];
        // TCP header length plus data length
        Sum += swap_bytes(Count);
        Sum += swap_bytes(PROT_TCP);
    }

    // sum words
    while (Count > 1)
    {
        //access data pointed to as WORD
        Sum += *(WORD*)Start;

        // increment pointer and decrement count
        Start += 2;
        Count -= 2;
    }

    // add left-over byte, if any
    if (Count)
        Sum += *(BYTE*)Start;

    // fold 32-bit sum to 16 bits
    while (Sum >> 16)
        Sum = (Sum & 0xFFFF) + (Sum >> 16);

    return ~Sum;
}


/******************************************************************************
 * TCP_IP_STACK: TCP_StartRetryTimer()
 *
 * Purpose:
 *  starts the timer as a retry-timer (used for retransmission-timeout)
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_StartRetryTimer()
{
    TCP_Timer = 0;
    TCP_RetryCounter = TCP_MAX_RETRIES;
    TCP_Flags |= TCP_TIMER_RUNNING;
    TCP_Flags |= TCP_TIMER_TYPE_RETRY;
}


/******************************************************************************
 * TCP_IP_STACK: TCP_StartTimeWaitTimer()
 *
 * Purpose:
 *  starts the timer as a 'TIME_WAIT'-timer (used to finish a TCP-session)
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_StartTimeWaitTimer()
{
    TCP_Timer = 0;
    TCP_Flags |= TCP_TIMER_RUNNING;
    TCP_Flags &= ~TCP_TIMER_TYPE_RETRY;
}


/******************************************************************************
 * TCP_IP_STACK: TCP_RestartTimer()
 *
 * Purpose:
 *  restarts the timer
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_RestartTimer()
{
    TCP_Timer = 0;
}


/******************************************************************************
 * TCP_IP_STACK: TCP_StopTimer()
 *
 * Purpose:
 *  stops the timer
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_StopTimer()
{
    TCP_Flags &= ~TCP_TIMER_RUNNING;
}


/******************************************************************************
 * TCP_IP_STACK: TCP_HandleRetransmission()
 *
 * Purpose:
 *  if a retransmission-timeout occured, check which packet to resend.
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_HandleRetransmission()
{
    switch (TCP_LastFrameSent)
    {
        case ARP_REQUEST :
        {
            TCP_Prep_ARP_REQUEST();
            break;
        }
        case TCP_SYN_FRAME :
        {
            TCP_Prep_TCP_FRAME(TCP_CODE_SYN);
            break;
        }
        case TCP_SYN_ACK_FRAME :
        {
            TCP_Prep_TCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK);
            break;
        }
        case TCP_FIN_FRAME :
        {
            TCP_Prep_TCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK);
            break;
        }
        case TCP_DATA_FRAME :
        {
            TCP_TransmitControl |= TCP_SEND_FRAME1;
            break;
        }
    }
}


/******************************************************************************
 * TCP_IP_STACK: TCP_HandleTimeout()
 *
 * Purpose:
 *  if all retransmissions failed, close connection and indicate an error
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_HandleTimeout()
{
    TCP_StateMachine = CLOSED;

    if ((TCP_Flags & (TCP_ACTIVE_OPEN | TCP_IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN)

        // indicate an error to user
        TCP_SocketStatus = TCP_SOCK_ERR_ARP_TIMEOUT;
    else
        TCP_SocketStatus = TCP_SOCK_ERR_TCP_TIMEOUT;

    // clear all flags
    TCP_Flags = 0;
}


/******************************************************************************
 * TCP_IP_STACK: TCP_Copy_Frame()
 *
 * Purpose:
 *  Copies prepared frame to LAN transmit buffer
 *
 * Actions:
 *
 *****************************************************************************/
MC void TCP_Copy_Frame(WORD length, BYTE *Frame)
{
#ifndef USE_16_BITS
    DWORD *data_src = (DWORD*) Frame;
    DWORD *data_dst = LAN_tx_packet.data;
    int i;

    LAN_tx_packet.length = length;
    LAN_tx_packet.busy = 1;
    for (i=0; i<=(length>>2); i++)
        *data_dst++ = *data_src++;
    return;
#else
    WORD *data_src = (WORD*) Frame;
    WORD *data_dst = LAN_tx_packet.data;
    int i;

    LAN_tx_packet.length = length;
    LAN_tx_packet.busy = 1;
    for (i=0; i<=(length>>1); i++)
        *data_dst++ = *data_src++;
    return;
#endif
}

/******************************************************************************
 * TCP_IP_STACK: swap_bytes()
 *
 * Purpose:
 *  swaps lower 8bits with higher 8bits and vice versa
 *
 * Actions:
 *
 *****************************************************************************/
inline WORD swap_bytes(DWORD in)
{
    return ((in&0xff)<<8) | ((in&0xff00)>>8);
#if 0
    WORD rval;
    asm("r5 = %1.l (z); %1 >>=8; r5 <<=8; %0 = r5 |%1;"
        : "=D" (rval)
        : "D" (in)
        : "r5");
    return rval;
#endif
}


/******************************************************************************
 * TCP_IP_STACK: WriteDWBE()
 *
 * Purpose:
 *  swaps lower 8bits with higher 8bits and vice versa
 *
 * Actions:
 *
 *****************************************************************************/
inline void WriteDWBE(BYTE* Add, DWORD Data)
{
    *Add++ = Data >> 24;
    *Add++ = Data >> 16;
    *Add++ = Data >> 8;
    *Add = Data;
}

/******************************************************************************
 * TCP_IP_STACK: get_cyles()
 *
 * Purpose:
 *  returns --XXXX-- out of CYCLES register for ISN Generation
 *
 * Actions:
 *
 *****************************************************************************/
inline WORD get_cycles()
{
    WORD rval;
    asm("%0 = CYCLES; %0 >>= 9;"
        : "=D" (rval)
        :
        : );
    return rval;
}

// end-of-file

⌨️ 快捷键说明

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