eth_proto.c
author viric@llimona
Mon, 08 Oct 2007 12:59:27 +0200
changeset 79 7d316733d4b1
parent 67 d7405e4f12e1
child 83 76adae542b57
permissions -rw-r--r--
Added filterdes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
53
07500c5c53cb Adding license and web html.
viric@llimona
parents: 48
diff changeset
     1
/*
07500c5c53cb Adding license and web html.
viric@llimona
parents: 48
diff changeset
     2
    Terminal Mixer - multi-point multi-user access to terminal applications
07500c5c53cb Adding license and web html.
viric@llimona
parents: 48
diff changeset
     3
    Copyright (C) 2007  LluĂ­s Batlle i Rossell
07500c5c53cb Adding license and web html.
viric@llimona
parents: 48
diff changeset
     4
07500c5c53cb Adding license and web html.
viric@llimona
parents: 48
diff changeset
     5
    Please find the license in the provided COPYING file.
07500c5c53cb Adding license and web html.
viric@llimona
parents: 48
diff changeset
     6
*/
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     7
#include <netinet/in.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     8
#include <string.h>
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
     9
#include <assert.h>
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    10
#include <stdio.h>
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
    11
#include <errno.h>
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    12
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    13
#include "eth_linux.h"
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    14
#include "main.h"
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    15
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    16
enum {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    17
    MAXPACKET = 1500,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    18
    MAXSEQ = 100,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    19
    HEAD = 9
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    20
};
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    21
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    22
static struct
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    23
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    24
    int socket;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    25
    char partner[6];
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    26
    int partner_set;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    27
    int send_acked;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    28
    int send_retries_left;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    29
    unsigned int seq_send;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    30
    unsigned int seq_wait;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    31
    unsigned int wrong_recv;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    32
    char send_buffer[MAXPACKET];
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    33
    int send_buffer_size;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    34
} edata;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    35
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
    36
enum Control {
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    37
    SEND,
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    38
    ACK,
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
    39
    INIT
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    40
};
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    41
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    42
static char eth_buffer[MAXPACKET];
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    44
static void eth_fill_mac(unsigned char *mac, const char *str);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    45
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    46
static int make_head(unsigned char *data, unsigned int seq, enum Control c,
61
0b9daeb1cb1c Removing eth crc. The frames already have a 32bit crc.
viric@llimona
parents: 60
diff changeset
    47
        int size)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    48
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    49
    *((unsigned int *) data) = htonl(seq);
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    50
    data[4] = (unsigned char) c;
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    51
    *((unsigned int *)(data+5)) = htonl(size);
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    52
    return HEAD;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    53
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    54
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    55
static int parse_head(unsigned char *data, unsigned int *seq, enum Control *c,
61
0b9daeb1cb1c Removing eth crc. The frames already have a 32bit crc.
viric@llimona
parents: 60
diff changeset
    56
        int *size)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    57
{
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    58
    *seq = ntohl( *((unsigned int*) data) );
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    59
    *c = data[4];
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    60
    if (size)
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    61
        *size = ntohl(*((unsigned int *)(data+5)));
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    62
    return HEAD;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    63
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    64
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    65
int eth_proto_max_send()
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    66
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    67
    return MAXPACKET - HEAD;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    68
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    69
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    70
void eth_proto_init()
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    71
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    72
    edata.socket = -1;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    73
    edata.seq_send = 0;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    74
    edata.seq_wait = 0;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    75
    edata.send_acked = 1; /* Fine at the beginning, as if the last data was acked */
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    76
    edata.partner_set = 0;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    77
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    78
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    79
int eth_proto_allow_sending()
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    80
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    81
    return edata.send_acked;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    82
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    83
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    84
static int seq_next(int val)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    85
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    86
    if (val >= 0 && val < MAXSEQ)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    87
        val = val + 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    88
    else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    89
        val = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    90
    return val;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    91
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    92
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    93
static int seq_before(int val)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    94
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    95
    if (val > 0 && val < MAXSEQ)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    96
        val = val - 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    97
    else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    98
        val = MAXSEQ;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    99
    return val;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   100
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   101
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   102
int eth_proto_open()
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   103
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   104
    edata.socket = eth_open(command_line.eth_device);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   105
    if (edata.socket == -1)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   106
        error("Cannot open device %s", command_line.eth_device);
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   107
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   108
    if ( !command_line.is_server)
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   109
    {
65
107ab713b65b Error condition if eth server address not told on client.
viric@mandarina
parents: 62
diff changeset
   110
        if (command_line.c_param.server_address == 0)
107ab713b65b Error condition if eth server address not told on client.
viric@mandarina
parents: 62
diff changeset
   111
            error("You must specify the MAC you want to connect to.");
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   112
        eth_fill_mac(edata.partner, command_line.c_param.server_address);
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   113
        edata.partner_set = 1;
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   114
61
0b9daeb1cb1c Removing eth crc. The frames already have a 32bit crc.
viric@llimona
parents: 60
diff changeset
   115
        make_head(eth_buffer, edata.seq_send, INIT, 0);
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   116
        eth_send(command_line.eth_device, edata.partner, eth_buffer, HEAD);
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   117
        edata.seq_send = seq_next(edata.seq_send);
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   118
    }
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   119
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   120
    return edata.socket;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   121
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   122
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   123
int eth_proto_recv(char *data, int size)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   124
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   125
    int res;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   126
    int seq;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   127
    int data_length;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   128
    enum Control c;
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   129
    char partner[6];
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   130
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   131
    do {
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   132
            res = eth_recv(eth_buffer, sizeof(eth_buffer), partner);
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   133
            edata.partner_set = 1;
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   134
    } while(res < HEAD);
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   135
    parse_head(eth_buffer, &seq, &c, &data_length);
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   136
    /* We admit any first connection */
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   137
    if (seq == 0 && c == INIT)
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   138
    {
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   139
      edata.seq_wait = 1; /* next of the just receive 0 */
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   140
      memcpy(edata.partner, partner, sizeof(edata.partner));
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   141
      return -1; /* Nothing the parent should care about */
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   142
    }
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   143
    if (c == SEND)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   144
    {
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   145
        if (seq != edata.seq_wait && seq != seq_before(edata.seq_wait))
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   146
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   147
            dump_line("Wrong data packet seq received. Recvd: %i Expected: %i\n",
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   148
                    seq, edata.seq_wait);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   149
            edata.wrong_recv++;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   150
            return -1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   151
        }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   152
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   153
        if (seq == seq_before(edata.seq_wait))
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   154
            dump_line("Repeated data seq received: %i\n", seq);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   155
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   156
        if (seq == edata.seq_wait)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   157
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   158
            if (data_length == 0)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   159
            {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   160
                edata.partner_set = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   161
                edata.seq_wait = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   162
                edata.seq_send = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   163
                /* We should send ACK anyway */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   164
            }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   165
            else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   166
            {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   167
                memcpy(data, eth_buffer + HEAD, data_length);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   168
                edata.seq_wait = seq_next(edata.seq_wait);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   169
            }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   170
        }
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   171
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   172
        /* Ack the packed we received. In these conditions:
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   173
         * - We received the packed we expected
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   174
         * - We received a repeat of the old packet. The
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   175
         *   ACK was lost probably, so we resend it */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   176
        make_head(eth_buffer, seq, ACK, 0);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   177
        eth_send(command_line.eth_device, edata.partner, eth_buffer, HEAD);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   178
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   179
    else if (c == ACK)
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   180
    {
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   181
        if (seq == edata.seq_send)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   182
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   183
            edata.send_acked = 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   184
            edata.seq_send = seq_next(edata.seq_send);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   185
            unprogram_timeout();
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   186
        }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   187
        else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   188
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   189
            dump_line("Wrong ack received. Recvd: %i Expected: %i\n",
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   190
                    seq, edata.seq_send);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   191
        }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   192
        return -1; /* not data */
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   193
    }
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   194
    else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   195
        return -1;
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   196
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   197
    return data_length;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   198
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   199
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   200
static int eth_proto_link_send()
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   201
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   202
    int sent;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   203
    sent = eth_send(command_line.eth_device,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   204
            edata.partner,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   205
            edata.send_buffer,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   206
            edata.send_buffer_size);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   207
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   208
    if (sent >= 0) /* expected */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   209
    {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   210
        edata.send_retries_left -= 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   211
        edata.send_acked = 0;
67
d7405e4f12e1 The timeout should be always handled. Now we use pselect in the loops.
viric@mandarina
parents: 66
diff changeset
   212
        program_timeout(1);
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   213
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   214
    else /* strange case, data not sent */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   215
    {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   216
        sent = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   217
        edata.send_acked = 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   218
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   219
    return sent;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   220
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   221
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   222
int eth_proto_send(const char *data, int size)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   223
{
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   224
    int sent;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   225
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   226
    assert(edata.send_acked);
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   227
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   228
    if (!edata.partner_set)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   229
    {
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   230
        if (edata.seq_send == 0 && !command_line.is_server
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   231
                && command_line.c_param.server_address != 0)
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   232
        {
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   233
            eth_fill_mac(edata.partner, command_line.c_param.server_address);
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   234
            edata.partner_set = 1;
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   235
        }
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   236
        else
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   237
            return 0;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   238
    }
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   239
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   240
    edata.send_retries_left = 3;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   241
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   242
    /* Prepare packet */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   243
    make_head(edata.send_buffer, edata.seq_send, SEND, size);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   244
    memcpy(edata.send_buffer+HEAD, data, size);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   245
    edata.send_buffer_size = size + HEAD;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   246
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   247
    sent = eth_proto_link_send();
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   248
    sent -= HEAD;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   249
    return sent;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   250
}
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   251
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   252
int eth_proto_process_timeouts()
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   253
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   254
    if (!edata.send_acked && did_timeout_happen())
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   255
    {
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   256
        unprogram_timeout();
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   257
        if (edata.send_retries_left > 0)
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   258
        {
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   259
            dump_line("Retrying. Left:%i\n", edata.send_retries_left);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   260
            eth_proto_link_send();
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   261
        }
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   262
        else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   263
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   264
            /* The connection has been lost */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   265
            dump_line("Connection lost");
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   266
            edata.send_acked = 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   267
            edata.partner_set = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   268
            edata.seq_wait = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   269
            edata.seq_send = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   270
            return 0; /* FAIL */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   271
        }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   272
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   273
    return 1; /* OK */
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   274
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   275
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   276
static void eth_fill_mac(unsigned char *mac, const char *str)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   277
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   278
  int res;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   279
  int imac[6];
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   280
  res = sscanf(str, "%x:%x:%x:%x:%x:%x",
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   281
      &imac[0], &imac[1], &imac[2], &imac[3], &imac[4], &imac[5]);
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   282
  if (res != 6)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   283
  {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   284
    error("Error parsing mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   285
      imac[0], imac[1], imac[2], imac[3], imac[4], imac[5]);
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   286
  }
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   287
  mac[0] = imac[0];  mac[1] = imac[1];  mac[2] = imac[2];
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   288
  mac[3] = imac[3];  mac[4] = imac[4];  mac[5] = imac[5];
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   289
}