eth_proto.c
author Lluís Batlle <viric@viric.name>
Thu, 20 Mar 2014 16:33:27 +0100
changeset 97 eea77d5a624c
parent 88 a7f546938313
permissions -rw-r--r--
Merging the savefile branch. I hope it works; I even don't remember it.
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
87
be4ee314545c Making client and server use different ethernet protocols
viric@llimona
parents: 83
diff changeset
    13
#include "main.h"
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    14
#include "eth_linux.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,
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    19
    HEAD = 13
66
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;
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    34
    int port;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    35
} edata;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    36
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
    37
enum Control {
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    38
    SEND,
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    39
    ACK,
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
    40
    INIT
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    41
};
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    42
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    43
static char eth_buffer[MAXPACKET];
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    44
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    45
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
    46
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    47
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
    48
        int size)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    49
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    50
    *((unsigned int *) data) = htonl(seq);
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    51
    data[4] = (unsigned char) c;
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    52
    *((unsigned int *)(data+5)) = htonl(edata.port);
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    53
    *((unsigned int *)(data+5+4)) = htonl(size);
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    54
    return HEAD;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    55
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    56
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    57
static int parse_head(unsigned char *data, unsigned int *seq, enum Control *c,
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    58
        int *port, int *size)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    59
{
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    60
    *seq = ntohl( *((unsigned int*) data) );
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    61
    *c = data[4];
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    62
    if (port)
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    63
        *port = ntohl(*((unsigned int *)(data+5)));
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    64
    if (size)
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    65
        *size = ntohl(*((unsigned int *)(data+5+4)));
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    66
    return HEAD;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    67
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    68
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    69
int eth_proto_max_send()
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    70
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    71
    return MAXPACKET - HEAD;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    72
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    73
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    74
void eth_proto_init()
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    75
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    76
    edata.socket = -1;
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
    77
    edata.port = command_line.eth_port;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    78
    edata.seq_send = 0;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    79
    edata.seq_wait = 0;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    80
    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
    81
    edata.partner_set = 0;
66
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
int eth_proto_allow_sending()
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
    return edata.send_acked;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    87
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    88
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    89
static int seq_next(int val)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    90
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    91
    if (val >= 0 && val < MAXSEQ)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    92
        val = val + 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    93
    else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    94
        val = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    95
    return val;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    96
}
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    97
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    98
static int seq_before(int val)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
    99
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   100
    if (val > 0 && val < MAXSEQ)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   101
        val = val - 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   102
    else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   103
        val = MAXSEQ;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   104
    return val;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   105
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   106
87
be4ee314545c Making client and server use different ethernet protocols
viric@llimona
parents: 83
diff changeset
   107
int eth_proto_open(enum Eth_type type)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   108
{
87
be4ee314545c Making client and server use different ethernet protocols
viric@llimona
parents: 83
diff changeset
   109
    edata.socket = eth_open(command_line.eth_device, type);
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   110
    if (edata.socket == -1)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   111
        error("Cannot open device %s", command_line.eth_device);
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   112
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   113
    if ( !command_line.is_server)
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   114
    {
65
107ab713b65b Error condition if eth server address not told on client.
viric@mandarina
parents: 62
diff changeset
   115
        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
   116
            error("You must specify the MAC you want to connect to.");
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   117
        eth_fill_mac(edata.partner, command_line.c_param.server_address);
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   118
        edata.partner_set = 1;
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   119
61
0b9daeb1cb1c Removing eth crc. The frames already have a 32bit crc.
viric@llimona
parents: 60
diff changeset
   120
        make_head(eth_buffer, edata.seq_send, INIT, 0);
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   121
        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
   122
        edata.seq_send = seq_next(edata.seq_send);
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   123
    }
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   124
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   125
    return edata.socket;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   126
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   127
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   128
int eth_proto_recv(char *data, int size)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   129
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   130
    int res;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   131
    int seq;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   132
    int data_length;
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
   133
    int port;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   134
    enum Control c;
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   135
    char partner[6];
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   136
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   137
    do {
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   138
            res = eth_recv(eth_buffer, sizeof(eth_buffer), partner);
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   139
            edata.partner_set = 1;
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   140
    } while(res < HEAD);
88
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
   141
    parse_head(eth_buffer, &seq, &c, &port, &data_length);
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
   142
    if (port != edata.port)
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
   143
        return -1; /* Nothing the parent should care about. Not a packet for us. */
a7f546938313 Adding port number on the ethernet protocol.
viric@llimona
parents: 87
diff changeset
   144
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   145
    /* We admit any first connection */
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   146
    if (seq == 0 && c == INIT)
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   147
    {
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   148
      edata.seq_wait = 1; /* next of the just receive 0 */
83
76adae542b57 Fixed a bug in the ethernet INIT packet.
lbatlle@npdl268.bpo.hp.com
parents: 67
diff changeset
   149
      edata.seq_send = 0; /* New partner we send to, so 0 sent */
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   150
      memcpy(edata.partner, partner, sizeof(edata.partner));
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   151
      return -1; /* Nothing the parent should care about */
46
bb76f8ca177d Allowing eth reconnections. Added DOCS.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
   152
    }
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   153
    if (c == SEND)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   154
    {
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   155
        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
   156
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   157
            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
   158
                    seq, edata.seq_wait);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   159
            edata.wrong_recv++;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   160
            return -1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   161
        }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   162
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   163
        if (seq == seq_before(edata.seq_wait))
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   164
            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
   165
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   166
        if (seq == edata.seq_wait)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   167
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   168
            if (data_length == 0)
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
                edata.partner_set = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   171
                edata.seq_wait = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   172
                edata.seq_send = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   173
                /* We should send ACK anyway */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   174
            }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   175
            else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   176
            {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   177
                memcpy(data, eth_buffer + HEAD, data_length);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   178
                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
   179
            }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   180
        }
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   181
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   182
        /* 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
   183
         * - We received the packed we expected
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   184
         * - 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
   185
         *   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
   186
        make_head(eth_buffer, seq, ACK, 0);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   187
        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
   188
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   189
    else if (c == ACK)
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   190
    {
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   191
        if (seq == edata.seq_send)
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   192
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   193
            edata.send_acked = 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   194
            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
   195
            unprogram_timeout();
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   196
        }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   197
        else
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
            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
   200
                    seq, edata.seq_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
        return -1; /* not data */
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   203
    }
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   204
    else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   205
        return -1;
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   206
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   207
    return data_length;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   208
}
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
static int eth_proto_link_send()
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   211
{
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   212
    int sent;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   213
    sent = eth_send(command_line.eth_device,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   214
            edata.partner,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   215
            edata.send_buffer,
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   216
            edata.send_buffer_size);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   217
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   218
    if (sent >= 0) /* expected */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   219
    {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   220
        edata.send_retries_left -= 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   221
        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
   222
        program_timeout(1);
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   223
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   224
    else /* strange case, data not 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
        sent = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   227
        edata.send_acked = 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   228
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   229
    return sent;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   230
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   231
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   232
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
   233
{
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   234
    int sent;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   235
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   236
    assert(edata.send_acked);
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   237
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   238
    if (!edata.partner_set)
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   239
    {
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   240
        if (edata.seq_send == 0 && !command_line.is_server
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   241
                && command_line.c_param.server_address != 0)
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   242
        {
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   243
            eth_fill_mac(edata.partner, command_line.c_param.server_address);
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   244
            edata.partner_set = 1;
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   245
        }
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   246
        else
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   247
            return 0;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   248
    }
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   249
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   250
    edata.send_retries_left = 3;
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
    /* Prepare packet */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   253
    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
   254
    memcpy(edata.send_buffer+HEAD, data, size);
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   255
    edata.send_buffer_size = size + HEAD;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   256
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   257
    sent = eth_proto_link_send();
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   258
    sent -= HEAD;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   259
    return sent;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   260
}
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   261
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   262
int eth_proto_process_timeouts()
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
    if (!edata.send_acked && did_timeout_happen())
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   265
    {
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   266
        unprogram_timeout();
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   267
        if (edata.send_retries_left > 0)
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   268
        {
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   269
            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
   270
            eth_proto_link_send();
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   271
        }
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   272
        else
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   273
        {
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   274
            /* The connection has been lost */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   275
            dump_line("Connection lost");
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   276
            edata.send_acked = 1;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   277
            edata.partner_set = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   278
            edata.seq_wait = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   279
            edata.seq_send = 0;
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   280
            return 0; /* FAIL */
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   281
        }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   282
    }
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 65
diff changeset
   283
    return 1; /* OK */
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   284
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   285
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   286
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
   287
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   288
  int res;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   289
  int imac[6];
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   290
  res = sscanf(str, "%x:%x:%x:%x:%x:%x",
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   291
      &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
   292
  if (res != 6)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   293
  {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   294
    error("Error parsing mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   295
      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
   296
  }
60
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   297
  mac[0] = imac[0];  mac[1] = imac[1];  mac[2] = imac[2];
18c24be2b1a6 Better ethernet protocol.
viric@llimona
parents: 53
diff changeset
   298
  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
   299
}