OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [sw/] [boot-loader-ethmac/] [tcp.c] - Diff between revs 80 and 81

Show entire file | Details | Blame | View Log

Rev 80 Rev 81
Line 48... Line 48...
#include "timer.h"
#include "timer.h"
#include "utilities.h"
#include "utilities.h"
#include "packet.h"
#include "packet.h"
#include "tcp.h"
#include "tcp.h"
#include "telnet.h"
#include "telnet.h"
 
#include "serial.h"
 
 
 
 
/* Global variables */
/* Global variables */
int         tcp_checksum_errors_g = 0;
int         tcp_checksum_errors_g = 0;
socket_t*   first_socket_g;
socket_t*   first_socket_g = NULL;
socket_t*   socket1_g;
 
 
 
/* input argument is a pointer to the previous socket,
/* input argument is a pointer to the previous socket,
   if this is the first socket object, then it is NULL */
   if this is the first socket object, then it is NULL */
socket_t* new_socket(socket_t* prev)
socket_t* new_socket(socket_t* prev)
{
{
Line 78... Line 79...
        socket->tcp_buf[i]->ending_seq   = 0;
        socket->tcp_buf[i]->ending_seq   = 0;
        socket->tcp_buf[i]->len_bytes    = 0;
        socket->tcp_buf[i]->len_bytes    = 0;
        socket->tcp_buf[i]->ack_received = 0;
        socket->tcp_buf[i]->ack_received = 0;
        }
        }
 
 
    socket->telnet_txbuf = init_line_buffer(0x80000);
 
    socket->telnet_rxbuf = init_line_buffer(0x1000);
 
 
 
    socket->packets_sent = 0;
    socket->packets_sent = 0;
    socket->packets_received = 0;
    socket->packets_received = 0;
    socket->packets_resent = 0;
    socket->packets_resent = 0;
 
 
    socket->telnet_sent_opening_message = 0;
 
    socket->telnet_echo_mode = 0;
 
    socket->telnet_connection_state = TELNET_CLOSED;
 
    socket->telnet_options_sent = 0;
 
 
 
    socket->tcp_current_buf = 0;
    socket->tcp_current_buf = 0;
    socket->tcp_reset = 0;
    socket->tcp_reset = 0;
    socket->tcp_connection_state = TCP_CLOSED;
    socket->tcp_connection_state = TCP_CLOSED;
    socket->tcp_disconnect = 0;
    socket->tcp_disconnect = 0;
    socket->tcp_seq = 0x100;  /* should be random initial seq number for tcp */
    socket->tcp_tx_seq = 0x100;  /* should be random initial seq number for tcp */
    socket->tcp_last_seq = socket->tcp_seq;
    socket->tcp_rx_ack = 0;
    socket->tcp_last_ack = 0;
    socket->tcp_bytes_received = 0;
 
    socket->tcp_bytes_acked = 0;
 
 
    /* Chain the socket objects together */
    /* Chain the socket objects together */
    if (prev == NULL){
    if (prev == NULL){
        socket->first = socket;
        socket->first = socket;
        socket->id = 0;
        socket->id = 0;
Line 115... Line 108...
 
 
    return socket;
    return socket;
}
}
 
 
 
 
 
 
 
/* returns the socket id */
 
int listen_socket (unsigned int listen_port, app_t* app)
 
{
 
    socket_t* socket;
 
 
 
    /* Add a new socket to the end of the list */
 
    if (first_socket_g == NULL) {
 
        trace("first_socket_g == NULL");
 
        first_socket_g = new_socket(NULL);
 
        socket = first_socket_g;
 
    }
 
    else {
 
        socket = first_socket_g;
 
        for(;;){
 
            if (socket->next!=NULL)
 
                socket=socket->next;
 
            else
 
                break;
 
            }
 
        socket = new_socket(socket);
 
    }
 
 
 
    socket->listen_port = listen_port;
 
    socket->tcp_connection_state = TCP_LISTENING;
 
 
 
    /* Assign the telnet object */
 
    socket->app = app;
 
    /* cross link, so can find the socket object when have pointer to the telnet object */
 
    socket->app->socket = socket;
 
 
 
    trace("new socket %d listening", socket->id);
 
 
 
    return socket->id;
 
}
 
 
 
 
 
 
/* All received tcp packets with dset ip == me arrive here */
/* All received tcp packets with dset ip == me arrive here */
void parse_tcp_packet(char * buf, packet_t* rx_packet)
void parse_tcp_packet(char * buf, packet_t* rx_packet)
{
{
    int i;
    int i;
    int ptr;
    int ptr;
Line 147... Line 178...
    rx_packet->tcp_seq         = buf[4]<<24|buf[5]<<16|buf[6]<<8|buf[7];
    rx_packet->tcp_seq         = buf[4]<<24|buf[5]<<16|buf[6]<<8|buf[7];
    rx_packet->tcp_ack         = buf[8]<<24|buf[9]<<16|buf[10]<<8|buf[11];
    rx_packet->tcp_ack         = buf[8]<<24|buf[9]<<16|buf[10]<<8|buf[11];
    rx_packet->tcp_flags       = buf[13];
    rx_packet->tcp_flags       = buf[13];
    rx_packet->tcp_window_size = buf[14]<<8|buf[15];
    rx_packet->tcp_window_size = buf[14]<<8|buf[15];
 
 
 
    // trace("client tcp rx window %d bytes",
 
    //     (rx_packet->tcp_window_size)<<rx_packet->tcp_window_scale);
 
 
    /* only interested in telnet packet to dest port xx */
 
    if (rx_packet->tcp_dst_port != 23) {
 
        return;
 
    }
 
 
 
    if (rx_packet->tcp_hdr_len > 20) {
    if (rx_packet->tcp_hdr_len > 20) {
        /* Get the source time stamp */
        /* Get the source time stamp */
        parse_tcp_options(buf, rx_packet);
        parse_tcp_options(buf, rx_packet);
        }
        }
 
 
 
 
 
    /* only interested in telnet packet to dest port xx */
 
    //if (rx_packet->tcp_dst_port != 23) {
 
    //    return;
 
    //}
 
 
 
 
    /*  --------------------------------------------------
    /*  --------------------------------------------------
        Assign the received packet to a socket
        Assign the received packet to a socket
        -------------------------------------------------- */
        -------------------------------------------------- */
    /*  seach for an open socket that matches the tcp connection */
    /*  seach for an open socket that matches the tcp connection */
    socket = first_socket_g;
    socket = first_socket_g;
 
    if (socket == NULL) {
 
        trace("first socket is null");
 
        return;
 
    }
 
 
 
 
 
    /* Search for an already open socket */
    for(;;){
    for(;;){
        if (socket->tcp_connection_state != TCP_CLOSED &&
        if ((socket->tcp_connection_state == TCP_PENDING ||
 
             socket->tcp_connection_state == TCP_OPEN)      &&
            socket->rx_packet->tcp_src_port == rx_packet->tcp_src_port) {
            socket->rx_packet->tcp_src_port == rx_packet->tcp_src_port) {
            found=1;
            found=1;
            break;
            break;
            }
            }
        if (socket->next!=NULL)
        if (socket->next!=NULL)
Line 177... Line 220...
        else
        else
            break;
            break;
        }
        }
 
 
 
 
    /* Search for an available closed soeckt to reuse */
    /* Search for a listening socket */
    if (!found){
    if (!found){
        socket = first_socket_g;
        socket = first_socket_g;
 
        trace("search for listening socket");
 
 
        for(;;){
        for(;;){
            if (socket->tcp_connection_state == TCP_CLOSED) {
            if (socket->tcp_connection_state == TCP_LISTENING) {
 
                if (socket->listen_port == rx_packet->tcp_dst_port)  {
                found=1;
                found=1;
                break;
                break;
                }
                }
 
                }
            if (socket->next!=NULL)
            if (socket->next!=NULL)
                socket=socket->next;
                socket=socket->next;
            else
            else
                break;
                break;
            }
            }
        }
        }
 
 
 
 
    /* All available sockets being used. Add a new one to the end of the chain */
    /* All available sockets being used. Add a new one to the end of the chain */
    if (!found) {
    if (!found) {
        socket = new_socket(socket);
        trace("not found");
 
        return;
    }
    }
 
 
 
 
    /* Copy the rx_packet structure into the socket */
    /* Copy the rx_packet structure into the socket */
    memcpy(socket->rx_packet, rx_packet, sizeof(packet_t));
    memcpy(socket->rx_packet, rx_packet, sizeof(packet_t));
 
 
    tcp_response(buf, socket);
    tcp_response(buf, socket);
}
}
Line 217... Line 264...
    while (ptr < rx_packet->tcp_hdr_len-1) {
    while (ptr < rx_packet->tcp_hdr_len-1) {
        switch (buf[ptr]) {
        switch (buf[ptr]) {
            case 0:  ptr=rx_packet->tcp_hdr_len; break; // end of options
            case 0:  ptr=rx_packet->tcp_hdr_len; break; // end of options
            case 1:  ptr++; break;
            case 1:  ptr++; break;
            case 2:  ptr = ptr + buf[ptr+1]; break;  // max segment size
            case 2:  ptr = ptr + buf[ptr+1]; break;  // max segment size
            case 3:  ptr = ptr + buf[ptr+1]; break;  // Window Scale
            case 3:
 
                // Window Scale
 
                trace("%s:L%d window scale bytes %d, 0x%x", buf[ptr+1], buf[ptr+2]);
 
                rx_packet->tcp_window_scale = buf[ptr+2];
 
                ptr = ptr + buf[ptr+1];
 
                break;
 
 
            case 4:  ptr = ptr + buf[ptr+1]; break;  // SACK Permitted
            case 4:  ptr = ptr + buf[ptr+1]; break;  // SACK Permitted
            case 5:  ptr = ptr + buf[ptr+1]; break;  // SACK
            case 5:  ptr = ptr + buf[ptr+1]; break;  // SACK
            case 8:
            case 8:
                // Time Stamp Option
                // Time Stamp Option
                rx_packet->tcp_src_time_stamp = buf[ptr+2]<<24|buf[ptr+3]<<16|buf[ptr+4]<<8|buf[ptr+5];
                rx_packet->tcp_src_time_stamp = buf[ptr+2]<<24|buf[ptr+3]<<16|buf[ptr+4]<<8|buf[ptr+5];
Line 239... Line 292...
 
 
 
 
void tcp_response(char * buf, socket_t* socket)
void tcp_response(char * buf, socket_t* socket)
{
{
    socket->packets_received++;
    socket->packets_received++;
 
    trace("tcp_response");
 
 
    /* Mark the ack in the tcp tx packet buffer so the tx packet does not get resent */
    /* Mark the ack in the tcp tx packet buffer so the tx packet does not get resent */
    if (socket->rx_packet->tcp_flags & 0x10) // ack flag set ?
    if (socket->rx_packet->tcp_flags & 0x10) // ack flag set ?
        tcp_ack(socket);
        tcp_ack(socket);
 
 
Line 252... Line 306...
        // Reset the connection
        // Reset the connection
        socket->tcp_disconnect = 1;
        socket->tcp_disconnect = 1;
        }
        }
 
 
    // open a connection
    // open a connection
    else if (socket->tcp_connection_state == TCP_CLOSED) {
    else if (socket->tcp_connection_state == TCP_LISTENING) {
 
 
        if (socket->rx_packet->tcp_flags & 0x02) { // SYN
        if (socket->rx_packet->tcp_flags & 0x02) { // SYN
 
            trace("tcp_open");
            // Open connection
            // Open connection
            tcp_open(socket);
            tcp_open(socket);
            socket->tcp_connection_state = TCP_PENDING;
            socket->tcp_connection_state = TCP_PENDING;
            }
            }
 
 
Line 271... Line 326...
    // Sent the first ack packet to establish a connection.
    // Sent the first ack packet to establish a connection.
    // Have just received the second packet from the server
    // Have just received the second packet from the server
    else if (socket->tcp_connection_state == TCP_PENDING) {
    else if (socket->tcp_connection_state == TCP_PENDING) {
        /* Add 1 to the sequence number as a special case to open
        /* Add 1 to the sequence number as a special case to open
           the connection */
           the connection */
        socket->tcp_seq++;
        socket->tcp_tx_seq++;
        socket->tcp_connection_state = TCP_OPEN;
        socket->tcp_connection_state = TCP_OPEN;
        }
        }
 
 
 
 
    // connection is already open
    // connection is already open
    else {
    else {
 
 
        /* contains tcp payload */
        /* contains tcp payload */
        if (socket->rx_packet->tcp_payload_len != 0) {
        if (socket->rx_packet->tcp_payload_len != 0) {
 
 
 
            socket->tcp_bytes_received += socket->rx_packet->tcp_payload_len;
 
            trace("socket %d received total %d bytes", socket->id, socket->tcp_bytes_received);
 
 
            /* Ack the packet only if the payload length is non-zero */
            /* Ack the packet only if the payload length is non-zero */
            tcp_reply(socket, NULL, 0);
            tcp_reply(socket, NULL, 0);
 
 
            /* Process the tcp contents */
            /* Process the tcp contents */
            if (socket->rx_packet->tcp_dst_port == TELNET_PORT)
            if (socket->rx_packet->tcp_dst_port == TELNET_PORT)
Line 295... Line 354...
}
}
 
 
 
 
void tcp_disconnect(socket_t * socket)
void tcp_disconnect(socket_t * socket)
{
{
 
    telnet_t* telnet;
 
 
    if (socket->tcp_connection_state != TCP_CLOSED) {
    if (socket->tcp_connection_state != TCP_CLOSED) {
        socket->tcp_connection_state = TCP_CLOSED;
        socket->tcp_connection_state = TCP_CLOSED;
        socket->telnet_connection_state = TELNET_CLOSED;
 
        socket->telnet_options_sent = 0;
 
        socket->telnet_sent_opening_message = 0;
 
        tcp_reply(socket, NULL, 0);
        tcp_reply(socket, NULL, 0);
 
 
 
        /* app level disconnect function */
 
        switch(socket->app->type) {
 
            case APP_TELNET: telnet_disconnect(socket->app);
 
                              break;
 
            default:
 
                trace("Unknown app type");
 
        }
        socket->tcp_disconnect = 0;
        socket->tcp_disconnect = 0;
        socket->telnet_echo_mode = 0;  // reset this setting
 
    }
    }
}
}
 
 
 
 
 
 
Line 329... Line 394...
void tcp_open(socket_t* socket)
void tcp_open(socket_t* socket)
{
{
 
 
    int i, j;
    int i, j;
    unsigned short header_checksum;
    unsigned short header_checksum;
    mac_ip_t target;
 
    int ip_length;
    int ip_length;
    char * buf;
    char * buf;
 
 
 
 
    buf = socket->tcp_buf[socket->tcp_current_buf]->buf;
    buf = socket->tcp_buf[socket->tcp_current_buf]->buf;
 
 
 
    strncpy(&socket->dest_ip,  socket->rx_packet->src_ip, 4);
    target.mac[0] = socket->rx_packet->src_mac[0];
    strncpy(&socket->dest_mac, socket->rx_packet->src_mac, 6);
    target.mac[1] = socket->rx_packet->src_mac[1];
 
    target.mac[2] = socket->rx_packet->src_mac[2];
 
    target.mac[3] = socket->rx_packet->src_mac[3];
 
    target.mac[4] = socket->rx_packet->src_mac[4];
 
    target.mac[5] = socket->rx_packet->src_mac[5];
 
    target.ip[0]  = socket->rx_packet->src_ip[0];
 
    target.ip[1]  = socket->rx_packet->src_ip[1];
 
    target.ip[2]  = socket->rx_packet->src_ip[2];
 
    target.ip[3]  = socket->rx_packet->src_ip[3];
 
 
 
 
 
    /* Include 20 bytes of tcp options */
    /* Include 20 bytes of tcp options */
    ip_length = 20+20+20; /* 20 bytes ip header, 20 bytes tcp header, 20 bytes tcp options */
    ip_length = 20+20+20; /* 20 bytes ip header, 20 bytes tcp header, 20 bytes tcp options */
 
 
 
    /* fill in the information about the packet about to be sent */
    socket->tcp_buf[socket->tcp_current_buf]->payload_valid = 1;
    socket->tcp_buf[socket->tcp_current_buf]->payload_valid = 1;
    socket->tcp_buf[socket->tcp_current_buf]->ack_received = 0;
    socket->tcp_buf[socket->tcp_current_buf]->ack_received = 0;
    socket->tcp_buf[socket->tcp_current_buf]->starting_seq = tcp_header(&buf[34], socket, 0, TCP_NEW);
    socket->tcp_buf[socket->tcp_current_buf]->starting_seq = tcp_header(&buf[34], socket, 0, TCP_NEW);
    socket->tcp_buf[socket->tcp_current_buf]->ending_seq   = socket->tcp_buf[socket->tcp_current_buf]->starting_seq + 1;
    socket->tcp_buf[socket->tcp_current_buf]->ending_seq   = socket->tcp_buf[socket->tcp_current_buf]->starting_seq + 1;
    set_timer(&socket->tcp_buf[socket->tcp_current_buf]->resend_time, 500);
 
 
 
    ip_header(&buf[14], &target, ip_length, 6); /* 20 byes of tcp  options, bytes 14 to 33, ip_proto = 6, TCP*/
 
    ethernet_header(buf, &target, 0x0800);  /* bytes 0 to 13*/
 
 
 
    socket->tcp_buf[socket->tcp_current_buf]->len_bytes = 14+ip_length;
    socket->tcp_buf[socket->tcp_current_buf]->len_bytes = 14+ip_length;
 
    set_timer(&socket->tcp_buf[socket->tcp_current_buf]->resend_time, 500);
 
 
    strncpy((char*)ETHMAC_TX_BUFFER, buf, socket->tcp_buf[socket->tcp_current_buf]->len_bytes);
    ip_header(&buf[14], &socket->dest_ip, ip_length, 6); /* 20 byes of tcp  options, bytes 14 to 33, ip_proto = 6, TCP*/
 
    ethernet_header(buf, &socket->dest_mac, 0x0800);  /* bytes 0 to 13*/
 
 
    tx_packet(socket->tcp_buf[socket->tcp_current_buf]->len_bytes);  // MAC header, IP header, TCP header, TCP options
    /* transmit an ethernet frame */
 
    //trace("tx_packet buf 0x%d, len %d",
 
    //    (unsigned int)buf, socket->tcp_buf[socket->tcp_current_buf]->len_bytes);
 
    ethmac_tx_packet(buf, socket->tcp_buf[socket->tcp_current_buf]->len_bytes);
    socket->packets_sent++;
    socket->packets_sent++;
 
 
 
 
    /* Pick the next tx buffer to use */
    /* Pick the next tx buffer to use */
    if (socket->tcp_current_buf == TCP_TX_BUFFERS-1)
    if (socket->tcp_current_buf == TCP_TX_BUFFERS-1)
Line 382... Line 436...
 
 
void tcp_reply(socket_t* socket, char* telnet_payload, int telnet_payload_length)
void tcp_reply(socket_t* socket, char* telnet_payload, int telnet_payload_length)
{
{
 
 
    int i, j;
    int i, j;
    mac_ip_t target;
 
    int ip_length;
    int ip_length;
    char * buf;
    char * buf;
 
 
 
 
    buf = socket->tcp_buf[socket->tcp_current_buf]->buf;
    buf = socket->tcp_buf[socket->tcp_current_buf]->buf;
 
 
    target.mac[0] = socket->rx_packet->src_mac[0];
 
    target.mac[1] = socket->rx_packet->src_mac[1];
 
    target.mac[2] = socket->rx_packet->src_mac[2];
 
    target.mac[3] = socket->rx_packet->src_mac[3];
 
    target.mac[4] = socket->rx_packet->src_mac[4];
 
    target.mac[5] = socket->rx_packet->src_mac[5];
 
    target.ip[0]  = socket->rx_packet->src_ip[0];
 
    target.ip[1]  = socket->rx_packet->src_ip[1];
 
    target.ip[2]  = socket->rx_packet->src_ip[2];
 
    target.ip[3]  = socket->rx_packet->src_ip[3];
 
 
 
    ip_length = 20+20 + telnet_payload_length;
    ip_length = 20+20 + telnet_payload_length;
 
 
    /* Copy the payload into the transmit buffer */
    /* Copy the payload into the transmit buffer */
    if (telnet_payload_length != 0) {
    if (telnet_payload_length != 0) {
        for (i=14+ip_length-telnet_payload_length, j=0; i<14+ip_length;i++,j++) {
        for (i=14+ip_length-telnet_payload_length, j=0; i<14+ip_length;i++,j++) {
Line 414... Line 455...
    if (telnet_payload_length)
    if (telnet_payload_length)
        socket->tcp_buf[socket->tcp_current_buf]->payload_valid = 1;
        socket->tcp_buf[socket->tcp_current_buf]->payload_valid = 1;
    else
    else
        socket->tcp_buf[socket->tcp_current_buf]->payload_valid = 0;
        socket->tcp_buf[socket->tcp_current_buf]->payload_valid = 0;
 
 
 
    /* fill in the information about the packet about to be sent */
    socket->tcp_buf[socket->tcp_current_buf]->ack_received = 0;
    socket->tcp_buf[socket->tcp_current_buf]->ack_received = 0;
    socket->tcp_buf[socket->tcp_current_buf]->starting_seq = tcp_header(&buf[34], socket, telnet_payload_length, TCP_NORMAL);
    socket->tcp_buf[socket->tcp_current_buf]->starting_seq = tcp_header(&buf[34], socket, telnet_payload_length, TCP_NORMAL);
    socket->tcp_buf[socket->tcp_current_buf]->ending_seq   = socket->tcp_buf[socket->tcp_current_buf]->starting_seq + telnet_payload_length;
    socket->tcp_buf[socket->tcp_current_buf]->ending_seq   = socket->tcp_buf[socket->tcp_current_buf]->starting_seq + telnet_payload_length;
    set_timer(&socket->tcp_buf[socket->tcp_current_buf]->resend_time, 500);
 
 
 
    ip_header(&buf[14], &target, ip_length, 6); /* 20 byes of tcp  options, bytes 14 to 33, ip_proto = 6, TCP*/
 
    ethernet_header(buf, &target, 0x0800);  /*bytes 0 to 13*/
 
 
 
    socket->tcp_buf[socket->tcp_current_buf]->len_bytes = 14+ip_length;
    socket->tcp_buf[socket->tcp_current_buf]->len_bytes = 14+ip_length;
 
    set_timer(&socket->tcp_buf[socket->tcp_current_buf]->resend_time, 500);
 
 
    strncpy((char*)ETHMAC_TX_BUFFER, buf, socket->tcp_buf[socket->tcp_current_buf]->len_bytes);
    /* Create the IP header */
 
    /* 20 byes of tcp  options, bytes 14 to 33, ip_proto = 6, TCP*/
 
    ip_header(&buf[14], &socket->dest_ip, ip_length, 6); /* 20 byes of tcp  options, bytes 14 to 33, ip_proto = 6, TCP*/
 
    ethernet_header(buf, &socket->dest_mac, 0x0800);  /* bytes 0 to 13*/
 
 
    tx_packet(socket->tcp_buf[socket->tcp_current_buf]->len_bytes);  // MAC header, IP header, TCP header, TCP options
    /* transmit an ethernet frame */
 
    ethmac_tx_packet(buf, socket->tcp_buf[socket->tcp_current_buf]->len_bytes);
    socket->packets_sent++;
    socket->packets_sent++;
 
 
 
 
    /* Pick the next tx buffer to use */
    /* Pick the next tx buffer to use */
    if (socket->tcp_current_buf == TCP_TX_BUFFERS-1)
    if (socket->tcp_current_buf == TCP_TX_BUFFERS-1)
Line 439... Line 481...
        socket->tcp_current_buf++;
        socket->tcp_current_buf++;
}
}
 
 
 
 
 
 
 
 
/* Find the packets lower than or equal to seq and mark them as acked */
/* Find the packets lower than or equal to seq and mark them as acked */
void tcp_ack(socket_t* socket)
void tcp_ack(socket_t* socket)
{
{
    int i, ack_valid;
    int i, ack_valid;
    unsigned int ack      = socket->rx_packet->tcp_ack;
    unsigned int ack      = socket->rx_packet->tcp_ack;
    unsigned int last_ack = socket->tcp_last_ack;
    unsigned int last_ack = socket->tcp_rx_ack;
 
 
    for (i=0;i<TCP_TX_BUFFERS;i=i+1) {
    for (i=0;i<TCP_TX_BUFFERS;i=i+1) {
        if (socket->tcp_buf[i]->payload_valid) {
        if (socket->tcp_buf[i]->payload_valid) {
 
 
            if (ack > last_ack) {
            if (ack > last_ack) {
Line 469... Line 510...
                if (socket->tcp_buf[i]->ending_seq == ack) break;
                if (socket->tcp_buf[i]->ending_seq == ack) break;
                }
                }
            }
            }
        }
        }
 
 
   socket->tcp_last_ack = ack;
   socket->tcp_rx_ack = ack;
}
}
 
 
 
 
/* Check if any tcp packets need to be re-transmitted */
/* Check if any tcp packets need to be re-transmitted */
void tcp_retransmit(socket_t* socket)
void tcp_retransmit(socket_t* socket)
Line 491... Line 532...
                socket->packets_resent++;
                socket->packets_resent++;
 
 
                /* Disable ethmac_int interrupt */
                /* Disable ethmac_int interrupt */
                *(unsigned int *) ( ADR_AMBER_IC_IRQ0_ENABLECLR ) = 0x100;
                *(unsigned int *) ( ADR_AMBER_IC_IRQ0_ENABLECLR ) = 0x100;
 
 
                strncpy((char*)ETHMAC_TX_BUFFER, socket->tcp_buf[i]->buf, socket->tcp_buf[i]->len_bytes);
                /* transmit an ethernet frame */
                tx_packet(socket->tcp_buf[i]->len_bytes);  // MAC header, IP header, TCP header, TCP options
                ethmac_tx_packet(socket->tcp_buf[i]->buf, socket->tcp_buf[i]->len_bytes);
                socket->packets_sent++;
                socket->packets_sent++;
 
 
 
 
                /* Enable ethmac_int interrupt */
                /* Enable ethmac_int interrupt */
                *(unsigned int *) ( ADR_AMBER_IC_IRQ0_ENABLESET ) = 0x100;
                *(unsigned int *) ( ADR_AMBER_IC_IRQ0_ENABLESET ) = 0x100;
Line 525... Line 566...
    buf[2] = socket->rx_packet->tcp_src_port >>8;
    buf[2] = socket->rx_packet->tcp_src_port >>8;
    buf[3] = socket->rx_packet->tcp_src_port &0xff;
    buf[3] = socket->rx_packet->tcp_src_port &0xff;
 
 
    /* Sequence Number */
    /* Sequence Number */
    /* Increment the sequence number for the next packet */
    /* Increment the sequence number for the next packet */
    starting_seq = socket->tcp_seq;
    starting_seq = socket->tcp_tx_seq;
    socket->tcp_last_seq = socket->tcp_seq;
    socket->tcp_tx_seq += payload_length;
    socket->tcp_seq += payload_length;
 
 
 
 
 
    buf[4] =  starting_seq>>24;
    buf[4] =  starting_seq>>24;
    buf[5] = (starting_seq>>16)&0xff;
    buf[5] = (starting_seq>>16)&0xff;
    buf[6] = (starting_seq>>8)&0xff;
    buf[6] = (starting_seq>>8)&0xff;
    buf[7] =  starting_seq&0xff;
    buf[7] =  starting_seq&0xff;
 
 
 
 
    /* Ack Number */
    /* Ack Number */
    if (options == TCP_NEW)
    if (options == TCP_NEW) {
        ack_num = socket->rx_packet->tcp_seq + 1;
        ack_num = socket->rx_packet->tcp_seq + 1;
 
        socket->tcp_rx_init_seq = socket->rx_packet->tcp_seq;
 
    }
    else if (socket->rx_packet->tcp_flags & 0x01) // FIN
    else if (socket->rx_packet->tcp_flags & 0x01) // FIN
        // +1 to the final ack
        // +1 to the final ack
        ack_num = socket->rx_packet->tcp_seq + 1;
        ack_num = socket->rx_packet->tcp_seq + 1;
    else
    else
        ack_num = socket->rx_packet->tcp_seq + socket->rx_packet->tcp_payload_len;
        ack_num = socket->rx_packet->tcp_seq + socket->rx_packet->tcp_payload_len;
 
 
 
    socket->tcp_rx_seq= ack_num;
 
    //trace("socket %d received seq %d",
 
    //    socket->id, socket->tcp_rx_seq - socket->tcp_rx_init_seq);
 
 
 
 
    buf[8]  =  ack_num>>24;
    buf[8]  =  ack_num>>24;
    buf[9]  = (ack_num>>16)&0xff;
    buf[9]  = (ack_num>>16)&0xff;
    buf[10] = (ack_num>>8)&0xff;
    buf[10] = (ack_num>>8)&0xff;
    buf[11] =  ack_num&0xff;
    buf[11] =  ack_num&0xff;
 
 
Line 665... Line 712...
 
 
/* handle tcp connections and process buffers
/* handle tcp connections and process buffers
   Poll all sockets in turn for activity */
   Poll all sockets in turn for activity */
void process_tcp(socket_t* socket)
void process_tcp(socket_t* socket)
{
{
 
    telnet_t* telnet;
 
 
    /* Check if any tcp packets need to be re-transmitted */
    /* Check if any tcp packets need to be re-transmitted */
    tcp_retransmit(socket);
    tcp_retransmit(socket);
 
 
    /* Handle exit command */
    /* Handle exit command */
    if (socket->tcp_disconnect && socket->tcp_connection_state == TCP_OPEN) {
    if (socket->tcp_disconnect && socket->tcp_connection_state == TCP_OPEN) {
 
        trace("calling tcp disconnect %d",
 
            socket->tcp_rx_seq - socket->tcp_rx_init_seq);
        tcp_disconnect(socket);
        tcp_disconnect(socket);
        }
        }
 
 
    /* Reset connection */
    /* Reset connection */
    else if (socket->tcp_reset) {
    else if (socket->tcp_reset) {
        socket->tcp_connection_state = TCP_CLOSED;
        socket->tcp_connection_state = TCP_CLOSED;
        socket->telnet_connection_state = TELNET_CLOSED;
 
        socket->telnet_options_sent = 0;
        telnet = (telnet_t*) socket->app->telnet;
 
        telnet->connection_state = TELNET_CLOSED;
 
        telnet->options_sent = 0;
 
 
        tcp_reply(socket, NULL, 0);
        tcp_reply(socket, NULL, 0);
        socket->tcp_reset = 0;
        socket->tcp_reset = 0;
        }
        }
 
 
    /* handle telnet messages */
    /* handle telnet messages */
    else if (socket->tcp_connection_state == TCP_OPEN){
    else if (socket->tcp_connection_state == TCP_OPEN){
        process_telnet(socket);
 
 
        /* app level process function */
 
        switch(socket->app->type) {
 
            case APP_TELNET: process_telnet(socket);
 
                             break;
 
            default:
 
                trace("Unknown app type");
    }
    }
}
}
 
}
 
 
 
 
 
 
 
void process_sockets()
 
{
 
    socket_t* socket;
 
 
 
    /* handle tcp connections and process buffers */
 
    /* Poll all sockets in turn for activity */
 
    socket = first_socket_g;
 
    for(;;){
 
        process_tcp(socket);
 
        if (socket->next!=NULL)
 
            socket=socket->next;
 
        else
 
            break;
 
        }
 
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.