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

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [source/] [server.h] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jondawson
////////////////////////////////////////////////////////////////////////////////
2
//
3
//  CHIPS-2.0 TCP/IP SERVER
4
//
5
//  :Author: Jonathan P Dawson
6
//  :Date: 17/10/2013
7
//  :email: chips@jondawson.org.uk
8
//  :license: MIT
9
//  :Copyright: Copyright (C) Jonathan P Dawson 2013
10
//
11
//  A TCP/IP stack that supports a single socket connection.
12
//
13
////////////////////////////////////////////////////////////////////////////////
14
 
15
 
16
////////////////////////////////////////////////////////////////////////////////
17
// TCP-IP User Settings
18
//
19
 
20 4 jondawson
const unsigned local_mac_address_hi = 0x0001u;
21
const unsigned local_mac_address_med = 0x0203u;
22
const unsigned local_mac_address_lo = 0x0405u;
23
const unsigned local_ip_address_hi = 0xc0A8u;//192/168
24
const unsigned local_ip_address_lo = 0x0101u;//1/1
25
const unsigned local_port = 80u;//http
26 2 jondawson
 
27
////////////////////////////////////////////////////////////////////////////////
28
// TCP-IP GLOBALS
29
//
30
 
31
unsigned tx_packet[512];
32
 
33
////////////////////////////////////////////////////////////////////////////////
34
// Checksum calculation routines
35
//
36
 
37
//store checksum in a global variable
38
//unsigneds are 16 bits, so use an array of 2 to hold a 32 bit number
39
 
40
long unsigned checksum;
41
 
42
//Reset checksum before calculation
43
//
44
 
45
void reset_checksum(){
46
  checksum = 0;
47
}
48
 
49
//Add 16 bit data value to 32 bit checksum value
50
//
51
 
52
void add_checksum(unsigned data){
53
  checksum += data;
54
  if(checksum & 0x10000ul){
55
          checksum &= 0xffffu;
56
          checksum += 1;
57
  }
58
}
59
 
60
//Retrieve the calculated checksum
61
//
62
 
63
unsigned check_checksum(){
64
  return ~checksum;
65
}
66
 
67
////////////////////////////////////////////////////////////////////////////////
68
// UTILITY FUNCTIONS
69
//
70
 
71
unsigned calc_ack(unsigned ack[], unsigned seq[], unsigned length){
72
        //given a two word sequence number and a one word length
73
        //calculate a two word acknowledgement number
74
        //check whether we have new data or not
75
        unsigned new_ack_0;
76
        unsigned new_ack_1;
77
        unsigned return_value = 0;
78
        new_ack_0 = seq[0] + length;
79
        new_ack_1 = seq[1];
80
        if(new_ack_0 < length) new_ack_1 = new_ack_1 + 1;
81
 
82
        //Is this data we have allready acknowledged?
83
        if((new_ack_0 != ack[0]) || (new_ack_1 != ack[1])){
84
                ack[0] = new_ack_0;
85
                ack[1] = new_ack_1;
86
                return_value = 1;
87
        }
88
        return return_value;
89
}
90
 
91
////////////////////////////////////////////////////////////////////////////////
92
// Data Link Layer - Ethernet
93
//
94
 
95
void put_ethernet_packet(
96
                unsigned packet[],
97
                unsigned number_of_bytes,
98
                unsigned destination_mac_address_hi,
99
                unsigned destination_mac_address_med,
100
                unsigned destination_mac_address_lo,
101
                unsigned protocol){
102
 
103
        unsigned byte, index;
104
        report(number_of_bytes);
105
 
106
        //set up ethernet header
107
        packet[0] = destination_mac_address_hi;
108
        packet[1] = destination_mac_address_med;
109
        packet[2] = destination_mac_address_lo;
110
        packet[3] = local_mac_address_hi;
111
        packet[4] = local_mac_address_med;
112
        packet[5] = local_mac_address_lo;
113
        packet[6] = protocol;
114
 
115
        put_eth(number_of_bytes);
116
        index = 0;
117
        for(byte=0; byte<number_of_bytes; byte+=2){
118
                put_eth(packet[index]);
119
                index ++;
120
        }
121
}
122
 
123
//Get a packet from the ethernet interface
124
//Will reply to arp requests
125
//returns the number of bytes read which may be 0
126
unsigned get_ethernet_packet(unsigned packet[]){
127
 
128
        unsigned number_of_bytes, index;
129
        unsigned byte;
130
 
131
        if(!rdy_eth()) return 0;
132
 
133
        number_of_bytes = get_eth();
134
        index = 0;
135
        for(byte=0; byte<number_of_bytes; byte+=2){
136
                packet[index] = get_eth();
137
                index ++;
138
        }
139
 
140
        //Filter out packets not meant for us
141
        if(packet[0] != local_mac_address_hi && packet[0] != 0xffffu) return 0;
142
        if(packet[1] != local_mac_address_med && packet[1] != 0xffffu) return 0;
143
        if(packet[2] != local_mac_address_lo && packet[2] != 0xffffu) return 0;
144
 
145
        //Process ARP requests within the data link layer
146
        if (packet[6] == 0x0806){ //ARP
147
                //respond to requests
148
                if (packet[10] == 0x0001){
149
                        //construct and send an ARP response
150
                        tx_packet[7] = 0x0001; //HTYPE ethernet
151
                        tx_packet[8] = 0x0800; //PTYPE IPV4
152
                        tx_packet[9] = 0x0604; //HLEN, PLEN
153
                        tx_packet[10] = 0x0002; //OPER=REPLY
154
                        tx_packet[11] = local_mac_address_hi; //SENDER_HARDWARE_ADDRESS
155
                        tx_packet[12] = local_mac_address_med; //SENDER_HARDWARE_ADDRESS
156
                        tx_packet[13] = local_mac_address_lo; //SENDER_HARDWARE_ADDRESS
157
                        tx_packet[14] = local_ip_address_hi; //SENDER_PROTOCOL_ADDRESS
158
                        tx_packet[15] = local_ip_address_lo; //SENDER_PROTOCOL_ADDRESS
159
                        tx_packet[16] = packet[11]; //TARGET_HARDWARE_ADDRESS
160
                        tx_packet[17] = packet[12]; //
161
                        tx_packet[18] = packet[13]; //
162
                        tx_packet[19] = packet[14]; //TARGET_PROTOCOL_ADDRESS
163
                        tx_packet[20] = packet[15]; //
164
                        put_ethernet_packet(
165
                                tx_packet,
166
                                64,
167
                                packet[11],
168
                                packet[12],
169
                                packet[13],
170
                                0x0806);
171
                }
172
                return 0;
173
        }
174
        return number_of_bytes;
175
}
176
 
177
unsigned arp_ip_hi[16];
178
unsigned arp_ip_lo[16];
179
unsigned arp_mac_0[16];
180
unsigned arp_mac_1[16];
181
unsigned arp_mac_2[16];
182
unsigned arp_pounsigneder = 0;
183
 
184
//return the location of the ip address in the arp cache table
185
unsigned get_arp_cache(unsigned ip_hi, unsigned ip_lo){
186
 
187
        unsigned number_of_bytes;
188
        unsigned byte;
189
        unsigned packet[16];
190
        unsigned i;
191
 
192
        //Is the requested IP in the ARP cache?
193
        for(i=0; i<16; i++){
194
                if(arp_ip_hi[i] == ip_hi && arp_ip_lo[i] == ip_lo){
195
                        return i;
196
                }
197
        }
198
 
199
        //It is not, so send an arp request
200
        tx_packet[7] = 0x0001u; //HTYPE ethernet
201
        tx_packet[8] = 0x0800u; //PTYPE IPV4
202
        tx_packet[9] = 0x0604u; //HLEN, PLEN
203
        tx_packet[10] = 0x0001u; //OPER=REQUEST
204
        tx_packet[11] = local_mac_address_hi; //SENDER_HARDWARE_ADDRESS
205
        tx_packet[12] = local_mac_address_med; //SENDER_HARDWARE_ADDRESS
206
        tx_packet[13] = local_mac_address_lo; //SENDER_HARDWARE_ADDRESS
207
        tx_packet[14] = local_ip_address_hi; //SENDER_PROTOCOL_ADDRESS
208
        tx_packet[15] = local_ip_address_lo; //SENDER_PROTOCOL_ADDRESS
209
        tx_packet[19] = ip_hi; //TARGET_PROTOCOL_ADDRESS
210
        tx_packet[20] = ip_lo; //
211
        put_ethernet_packet(
212
                tx_packet,
213
                64u,
214
                0xffffu, //broadcast via ethernet
215
                0xffffu,
216
                0xffffu,
217
                0x0806u);
218
 
219
        //wait for a response
220
        while(1){
221
 
222
                number_of_bytes = get_eth();
223
                i = 0;
224
                for(byte=0; byte<number_of_bytes; byte+=2){
225
                        //only keep the part of the packet we care about
226
                        if(i < 16){
227
                                packet[i] = get_eth();
228
                        } else {
229
                                get_eth();
230
                        }
231
                        i++;
232
                }
233
 
234
                //Process ARP requests within the data link layer
235
                if (packet[6] == 0x0806 && packet[10] == 0x0002){
236
                        if (packet[14] == ip_hi && packet[15] == ip_lo){
237
                                arp_ip_hi[arp_pounsigneder] = ip_hi;
238
                                arp_ip_lo[arp_pounsigneder] = ip_lo;
239
                                arp_mac_0[arp_pounsigneder] = packet[11];
240
                                arp_mac_1[arp_pounsigneder] = packet[12];
241
                                arp_mac_2[arp_pounsigneder] = packet[13];
242
                                i = arp_pounsigneder;
243
                                arp_pounsigneder++;
244
                                if(arp_pounsigneder == 16) arp_pounsigneder = 0;
245
                                return i;
246
                        }
247
                }
248
        }
249
}
250
 
251
////////////////////////////////////////////////////////////////////////////////
252
// Network Layer - Internet Protocol
253
//
254
 
255
void put_ip_packet(unsigned packet[], unsigned total_length, unsigned protocol, unsigned ip_hi, unsigned ip_lo){
256
        unsigned number_of_bytes, i, arp_cache;
257
 
258
        //see if the requested IP address is in the arp cache
259
        arp_cache = get_arp_cache(ip_hi, ip_lo);
260
 
261
        //Form IP header
262
        packet[7] = 0x4500;              //Version 4 header length 5x32
263
        packet[8] = total_length;        //IP data + header
264
        packet[9] = 0x0000;              //Identification
265
        packet[10] = 0x4000;             //don't fragment
266
        packet[11] = 0xFF00u | protocol;  //ttl|protocol
267
        packet[12] = 0x0000;             //checksum
268
        packet[13] = local_ip_address_hi;//source_high
269
        packet[14] = local_ip_address_lo;//source_low
270
        packet[15] = ip_hi;              //dest_high
271
        packet[16] = ip_lo;              //dest_low
272
        number_of_bytes = total_length + 14;
273
 
274
        //calculate checksum
275
        reset_checksum();
276
        for(i=7; i<=16; i++){
277
                add_checksum(packet[i]);
278
        }
279
        packet[12] = check_checksum();
280
 
281
        //enforce minimum ethernet frame size
282
        if(number_of_bytes < 64){
283
                number_of_bytes = 64;
284
        }
285
 
286
        //send packet over ethernet
287
        put_ethernet_packet(
288
                packet,                  //packet
289
                number_of_bytes,         //number_of_bytes
290
                arp_mac_0[arp_cache],    //destination mac address
291
                arp_mac_1[arp_cache],    //
292
                arp_mac_2[arp_cache],    //
293
                0x0800);                 //protocol IPv4
294
}
295
 
296
unsigned get_ip_packet(unsigned packet[]){
297
        unsigned ip_payload;
298
        unsigned total_length;
299
        unsigned header_length;
300
        unsigned payload_start;
301
        unsigned payload_length;
302
        unsigned i, from, to;
303
        unsigned payload_end;
304 4 jondawson
        unsigned number_of_bytes;
305 2 jondawson
 
306
        number_of_bytes = get_ethernet_packet(packet);
307
 
308
        if(number_of_bytes == 0) return 0;
309
        if(packet[6] != 0x0800) return 0;
310
        if(packet[15] != local_ip_address_hi) return 0;
311
        if(packet[16] != local_ip_address_lo) return 0;
312
        if((packet[11] & 0xff) == 1){//ICMP
313
                header_length = ((packet[7] >> 8) & 0xf) << 1;                   //in words
314
                payload_start = header_length + 7;                               //in words
315
                total_length = packet[8];                                        //in bytes
316
                payload_length = ((total_length+1) >> 1) - header_length;        //in words
317
                payload_end = payload_start + payload_length - 1;                //in words
318
 
319
                if(packet[payload_start] == 0x0800){//ping request
320
 
321
                        //copy icmp packet to response
322
                        to = 19;//assume that 17 and 18 are 0
323
                        reset_checksum();
324
                        for(from=payload_start+2; from<=payload_end; from++){
325
                                i = packet[from];
326
                                add_checksum(i);
327
                                tx_packet[to] = i;
328
                                to++;
329
                        }
330
                        tx_packet[17] = 0;//ping response
331
                        tx_packet[18] = check_checksum();
332
 
333
                        //send ping response
334
                        put_ip_packet(
335
                                tx_packet,
336
                                total_length,
337
                                1,//icmp
338
                                packet[13], //remote ip
339
                                packet[14]  //remote ip
340
                        );
341
                }
342
                return 0;
343
 
344
        }
345
        if((packet[11] & 0xff) != 6) return 0;//TCP
346
        return number_of_bytes;
347
}
348
 
349
////////////////////////////////////////////////////////////////////////////////
350
// Transport Layer - TCP
351
//
352
 
353
unsigned remote_ip_hi, remote_ip_lo;
354
 
355
unsigned tx_source=0;
356
unsigned tx_dest=0;
357
unsigned tx_seq[2];
358
unsigned next_tx_seq[2];
359
unsigned tx_ack[2];
360
unsigned tx_window=1460; //ethernet MTU - 40 bytes for TCP/IP header
361
 
362
unsigned tx_fin_flag=0;
363
unsigned tx_syn_flag=0;
364
unsigned tx_rst_flag=0;
365
unsigned tx_psh_flag=0;
366
unsigned tx_ack_flag=0;
367
unsigned tx_urg_flag=0;
368
 
369
unsigned rx_source=0;
370
unsigned rx_dest=0;
371
unsigned rx_seq[2];
372
unsigned rx_ack[2];
373
unsigned rx_window=0;
374
 
375
unsigned rx_fin_flag=0;
376
unsigned rx_syn_flag=0;
377
unsigned rx_rst_flag=0;
378
unsigned rx_psh_flag=0;
379
unsigned rx_ack_flag=0;
380
unsigned rx_urg_flag=0;
381
 
382
void put_tcp_packet(unsigned tx_packet [], unsigned tx_length){
383
 
384
        unsigned payload_start = 17;
385
        unsigned packet_length;
386
        unsigned index;
387 4 jondawson
        unsigned i;
388 2 jondawson
 
389
        //encode TCP header
390
        tx_packet[payload_start + 0] = tx_source;
391
        tx_packet[payload_start + 1] = tx_dest;
392
        tx_packet[payload_start + 2] = tx_seq[1];
393
        tx_packet[payload_start + 3] = tx_seq[0];
394
        tx_packet[payload_start + 4] = tx_ack[1];
395
        tx_packet[payload_start + 5] = tx_ack[0];
396
        tx_packet[payload_start + 6] = 0x5000; //5 long words
397
        tx_packet[payload_start + 7] = tx_window;
398
        tx_packet[payload_start + 8] = 0;
399
        tx_packet[payload_start + 9] = 0;
400
 
401
        //encode flags
402
        if(tx_fin_flag) tx_packet[payload_start + 6] |= 0x01;
403
        if(tx_syn_flag) tx_packet[payload_start + 6] |= 0x02;
404
        if(tx_rst_flag) tx_packet[payload_start + 6] |= 0x04;
405
        if(tx_psh_flag) tx_packet[payload_start + 6] |= 0x08;
406
        if(tx_ack_flag) tx_packet[payload_start + 6] |= 0x10;
407
        if(tx_urg_flag) tx_packet[payload_start + 6] |= 0x20;
408
 
409
        //calculate checksum
410
        //length of payload + header + pseudo_header in words
411
        reset_checksum();
412
        add_checksum(local_ip_address_hi);
413
        add_checksum(local_ip_address_lo);
414
        add_checksum(remote_ip_hi);
415
        add_checksum(remote_ip_lo);
416
        add_checksum(0x0006);
417
        add_checksum(tx_length+20);//tcp_header + tcp_payload in bytes
418
 
419
        packet_length = (tx_length + 20 + 1) >> 1;
420
        index = payload_start;
421
        for(i=0; i<packet_length; i++){
422
                add_checksum(tx_packet[index]);
423
                index++;
424
        }
425
        tx_packet[payload_start + 8] = check_checksum();
426
 
427
        put_ip_packet(
428
                tx_packet,
429
                tx_length + 40,
430
                6,//tcp
431
                remote_ip_hi, //remote ip
432
                remote_ip_lo  //remote ip
433
        );
434
}
435
 
436
unsigned rx_length, rx_start;
437
 
438
unsigned get_tcp_packet(unsigned rx_packet []){
439
 
440
        unsigned number_of_bytes, header_length, payload_start, total_length, payload_length, payload_end, tcp_header_length;
441
 
442
        number_of_bytes = get_ip_packet(rx_packet);
443
 
444
        //decode lengths from the IP header
445
        header_length = ((rx_packet[7] >> 8) & 0xf) << 1;                   //in words
446
        payload_start = header_length + 7;                                  //in words
447
 
448
        total_length = rx_packet[8];                                        //in bytes
449
        payload_length = total_length - (header_length << 1);               //in bytes
450
        tcp_header_length = ((rx_packet[payload_start + 6] & 0xf000u)>>10); //in bytes
451
        rx_length = payload_length - tcp_header_length;                     //in bytes
452
        rx_start = payload_start + (tcp_header_length >> 1);                //in words
453
 
454
        //decode TCP header
455
        rx_source = rx_packet[payload_start + 0];
456
        rx_dest   = rx_packet[payload_start + 1];
457
        rx_seq[1] = rx_packet[payload_start + 2];
458
        rx_seq[0] = rx_packet[payload_start + 3];
459
        rx_ack[1] = rx_packet[payload_start + 4];
460
        rx_ack[0] = rx_packet[payload_start + 5];
461
        rx_window = rx_packet[payload_start + 7];
462
 
463
        //decode flags
464
        rx_fin_flag = rx_packet[payload_start + 6] & 0x01;
465
        rx_syn_flag = rx_packet[payload_start + 6] & 0x02;
466
        rx_rst_flag = rx_packet[payload_start + 6] & 0x04;
467
        rx_psh_flag = rx_packet[payload_start + 6] & 0x08;
468
        rx_ack_flag = rx_packet[payload_start + 6] & 0x10;
469
        rx_urg_flag = rx_packet[payload_start + 6] & 0x20;
470
 
471
        return number_of_bytes;
472
}
473
 
474
void application_put_data(unsigned packet[], unsigned start, unsigned length){
475
        unsigned i, index;
476
 
477
        index = start;
478
        put_socket(length);
479
        for(i=0; i<length; i+=2){
480
                put_socket(packet[index]);
481
                index++;
482
        }
483
}
484
 
485
unsigned application_get_data(unsigned packet[], unsigned start){
486
        unsigned i, index, length;
487
 
488
        if(!ready_socket()){
489
                return 0;
490
        }
491
 
492
        index = start;
493
        length = get_socket();
494
        for(i=0; i<length; i+=2){
495
                packet[index] = get_socket();
496
                index++;
497
        }
498
        return length;
499
}
500
 
501
void server()
502
{
503
        unsigned rx_packet[1024];
504
        unsigned tx_packet[1024];
505
        unsigned tx_start = 27;
506
 
507
        unsigned new_rx_data = 0;
508
        unsigned new_tx_data = 0;
509
        unsigned tx_length;
510
        unsigned timeout;
511
        unsigned resend_wait;
512
        unsigned bytes;
513
        unsigned last_state;
514
        unsigned new_rx_data;
515
 
516 4 jondawson
        const unsigned listen           = 0;
517
        const unsigned open             = 1;
518
        const unsigned send             = 2;
519
        const unsigned wait_acknowledge = 3;
520
        const unsigned close            = 4;
521 2 jondawson
        unsigned state = listen;
522
 
523
        tx_seq[0] = 0;
524
        tx_seq[1] = 0;
525
 
526
        while(1){
527
 
528
                if(timeout){
529
                        timeout--;
530
                } else {
531
                        timeout = 120; //2 mins @100 MHz
532
                        state = listen;
533
                        tx_syn_flag = 0;
534
                        tx_fin_flag = 0;
535
                        tx_ack_flag = 0;
536
                        tx_rst_flag = 1;
537
                        put_tcp_packet(tx_packet, 0);//send reset packet
538
                }
539
 
540
                // (optionaly) send something
541
                switch(state){
542 4 jondawson
                    case listen:
543 2 jondawson
                        tx_rst_flag = 0;
544
                        tx_syn_flag = 0;
545
                        tx_fin_flag = 0;
546
                        tx_ack_flag = 0;
547
                        break;
548 4 jondawson
                    case open:
549 2 jondawson
                        // set remote ip/port
550
                        remote_ip_hi = rx_packet[13];
551
                        remote_ip_lo = rx_packet[14];
552
                        tx_dest = rx_source;
553
                        tx_source = local_port;
554
                        // send syn_ack
555
                        calc_ack(tx_ack, rx_seq, 1);
556
                        tx_syn_flag = 1;
557
                        tx_ack_flag = 1;
558
                        put_tcp_packet(tx_packet, 0);
559
                        break;
560 4 jondawson
                    case send:
561 2 jondawson
                        // application -> tcp
562
                        tx_length = application_get_data(tx_packet, tx_start);
563
                        tx_seq[0] = next_tx_seq[0];
564
                        tx_seq[1] = next_tx_seq[1];
565
                        calc_ack(next_tx_seq, tx_seq, tx_length);
566
                        tx_syn_flag = 0;
567
                        tx_ack_flag = 1;
568
                        put_tcp_packet(tx_packet, tx_length);
569
                        break;
570 4 jondawson
                    case wait_acknowledge:
571 2 jondawson
                        // resend until acknowledge recieved
572
                        put_tcp_packet(tx_packet, tx_length);
573
                        break;
574 4 jondawson
                    case close:
575 2 jondawson
                        // send fin ack
576
                        tx_fin_flag = 1;
577
                        tx_ack_flag = 1;
578
                        calc_ack(tx_ack, rx_seq, 1);
579
                        put_tcp_packet(tx_packet, 0);
580
                        break;
581
                }
582
 
583
                // repeatedly check for responses
584
                for(resend_wait = 10000; resend_wait; resend_wait--){ //1 second @ 100MHz
585
                        bytes = get_tcp_packet(rx_packet);
586
                        if(bytes && (rx_dest == local_port)){
587
                                //Once connection is established ignore other connection attempts
588
                                if(state != listen && rx_source != tx_dest) continue;
589
                                new_rx_data = 0;
590
                                last_state = state;
591
                                switch(state){
592
 
593
                                    // If a syn packet is recieved, wait for an ack
594 4 jondawson
                                    case listen:
595 2 jondawson
                                        if(rx_syn_flag) state = open;
596
                                        else{
597
                                                tx_rst_flag = 1;
598
                                                put_tcp_packet(tx_packet, 0);//send reset packet
599
                                        }
600
                                        break;
601
 
602
                                    // If an ack is recieved the connection is established
603 4 jondawson
                                    case open:
604 2 jondawson
                                        if(rx_ack_flag){
605
                                                tx_seq[1] = rx_ack[1];
606
                                                tx_seq[0] = rx_ack[0];
607
                                                next_tx_seq[1] = rx_ack[1];
608
                                                next_tx_seq[0] = rx_ack[0];
609
                                                state = send;
610
                                        }
611
                                        break;
612
 
613
                                    // Send some data
614 4 jondawson
                                    case send:
615 2 jondawson
                                        new_rx_data = calc_ack(tx_ack, rx_seq, rx_length);
616
                                        if(rx_fin_flag){
617
                                                state = close;
618
                                        } else if( tx_length ){
619
                                                state = wait_acknowledge;
620
                                        }
621
                                        break;
622
 
623
                                    // Wait until data is acknowledged before sending some more.
624 4 jondawson
                                    case wait_acknowledge:
625 2 jondawson
 
626
                                        new_rx_data = calc_ack(tx_ack, rx_seq, rx_length);
627
                                        if(rx_fin_flag){
628
                                                state = close;
629
                                        } else if(  rx_ack_flag &&
630
                                                    (next_tx_seq[1] == rx_ack[1]) &&
631
                                                    (next_tx_seq[0] == rx_ack[0])){
632
                                                state = send;
633
                                        }
634
 
635
                                        break;
636
 
637
                                    // wait for fin/ack.
638 4 jondawson
                                    case close:
639 2 jondawson
                                        if(rx_ack_flag) state = listen;
640
                                        break;
641
                                }
642
 
643
                                if(rx_rst_flag) state = listen;
644
 
645
                                // Transfer any new data to the application
646
                                if(new_rx_data){
647
                                        application_put_data(rx_packet, rx_start, rx_length);
648
                                        //Ack can go in next transmission.
649
                                        if(state == last_state) put_tcp_packet(tx_packet, tx_length);
650
                                }
651
 
652
                                if(state == send && ready_socket()){
653
                                        break;
654
                                }
655
 
656
                                if(state != last_state){
657
                                        timeout = 120;
658
                                        break;
659
                                }
660
 
661
                        } else {
662
                                wait_clocks(10000);//100 us @100 MHz
663
                        }
664
                }
665
        }
666
}

powered by: WebSVN 2.1.0

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