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 2

Go to most recent revision | 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
unsigned local_mac_address_hi = 0x0001u;
21
unsigned local_mac_address_med = 0x0203u;
22
unsigned local_mac_address_lo = 0x0405u;
23
unsigned local_ip_address_hi = 0xc0A8u;//192/168
24
unsigned local_ip_address_lo = 0x0101u;//1/1
25
unsigned local_port = 80u;//http
26
 
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
 
305
        number_of_bytes = get_ethernet_packet(packet);
306
 
307
        if(number_of_bytes == 0) return 0;
308
        if(packet[6] != 0x0800) return 0;
309
        if(packet[15] != local_ip_address_hi) return 0;
310
        if(packet[16] != local_ip_address_lo) return 0;
311
        if((packet[11] & 0xff) == 1){//ICMP
312
                header_length = ((packet[7] >> 8) & 0xf) << 1;                   //in words
313
                payload_start = header_length + 7;                               //in words
314
                total_length = packet[8];                                        //in bytes
315
                payload_length = ((total_length+1) >> 1) - header_length;        //in words
316
                payload_end = payload_start + payload_length - 1;                //in words
317
 
318
                if(packet[payload_start] == 0x0800){//ping request
319
 
320
                        //copy icmp packet to response
321
                        to = 19;//assume that 17 and 18 are 0
322
                        reset_checksum();
323
                        for(from=payload_start+2; from<=payload_end; from++){
324
                                i = packet[from];
325
                                add_checksum(i);
326
                                tx_packet[to] = i;
327
                                to++;
328
                        }
329
                        tx_packet[17] = 0;//ping response
330
                        tx_packet[18] = check_checksum();
331
 
332
                        //send ping response
333
                        put_ip_packet(
334
                                tx_packet,
335
                                total_length,
336
                                1,//icmp
337
                                packet[13], //remote ip
338
                                packet[14]  //remote ip
339
                        );
340
                }
341
                return 0;
342
 
343
        }
344
        if((packet[11] & 0xff) != 6) return 0;//TCP
345
        return number_of_bytes;
346
}
347
 
348
////////////////////////////////////////////////////////////////////////////////
349
// Transport Layer - TCP
350
//
351
 
352
unsigned remote_ip_hi, remote_ip_lo;
353
 
354
unsigned tx_source=0;
355
unsigned tx_dest=0;
356
unsigned tx_seq[2];
357
unsigned next_tx_seq[2];
358
unsigned tx_ack[2];
359
unsigned tx_window=1460; //ethernet MTU - 40 bytes for TCP/IP header
360
 
361
unsigned tx_fin_flag=0;
362
unsigned tx_syn_flag=0;
363
unsigned tx_rst_flag=0;
364
unsigned tx_psh_flag=0;
365
unsigned tx_ack_flag=0;
366
unsigned tx_urg_flag=0;
367
 
368
unsigned rx_source=0;
369
unsigned rx_dest=0;
370
unsigned rx_seq[2];
371
unsigned rx_ack[2];
372
unsigned rx_window=0;
373
 
374
unsigned rx_fin_flag=0;
375
unsigned rx_syn_flag=0;
376
unsigned rx_rst_flag=0;
377
unsigned rx_psh_flag=0;
378
unsigned rx_ack_flag=0;
379
unsigned rx_urg_flag=0;
380
 
381
void put_tcp_packet(unsigned tx_packet [], unsigned tx_length){
382
 
383
        unsigned payload_start = 17;
384
        unsigned packet_length;
385
        unsigned index;
386
 
387
        //encode TCP header
388
        tx_packet[payload_start + 0] = tx_source;
389
        tx_packet[payload_start + 1] = tx_dest;
390
        tx_packet[payload_start + 2] = tx_seq[1];
391
        tx_packet[payload_start + 3] = tx_seq[0];
392
        tx_packet[payload_start + 4] = tx_ack[1];
393
        tx_packet[payload_start + 5] = tx_ack[0];
394
        tx_packet[payload_start + 6] = 0x5000; //5 long words
395
        tx_packet[payload_start + 7] = tx_window;
396
        tx_packet[payload_start + 8] = 0;
397
        tx_packet[payload_start + 9] = 0;
398
 
399
        //encode flags
400
        if(tx_fin_flag) tx_packet[payload_start + 6] |= 0x01;
401
        if(tx_syn_flag) tx_packet[payload_start + 6] |= 0x02;
402
        if(tx_rst_flag) tx_packet[payload_start + 6] |= 0x04;
403
        if(tx_psh_flag) tx_packet[payload_start + 6] |= 0x08;
404
        if(tx_ack_flag) tx_packet[payload_start + 6] |= 0x10;
405
        if(tx_urg_flag) tx_packet[payload_start + 6] |= 0x20;
406
 
407
        //calculate checksum
408
        //length of payload + header + pseudo_header in words
409
        reset_checksum();
410
        add_checksum(local_ip_address_hi);
411
        add_checksum(local_ip_address_lo);
412
        add_checksum(remote_ip_hi);
413
        add_checksum(remote_ip_lo);
414
        add_checksum(0x0006);
415
        add_checksum(tx_length+20);//tcp_header + tcp_payload in bytes
416
 
417
        packet_length = (tx_length + 20 + 1) >> 1;
418
        index = payload_start;
419
        for(i=0; i<packet_length; i++){
420
                add_checksum(tx_packet[index]);
421
                index++;
422
        }
423
        tx_packet[payload_start + 8] = check_checksum();
424
 
425
        put_ip_packet(
426
                tx_packet,
427
                tx_length + 40,
428
                6,//tcp
429
                remote_ip_hi, //remote ip
430
                remote_ip_lo  //remote ip
431
        );
432
}
433
 
434
unsigned rx_length, rx_start;
435
 
436
unsigned get_tcp_packet(unsigned rx_packet []){
437
 
438
        unsigned number_of_bytes, header_length, payload_start, total_length, payload_length, payload_end, tcp_header_length;
439
 
440
        number_of_bytes = get_ip_packet(rx_packet);
441
 
442
        //decode lengths from the IP header
443
        header_length = ((rx_packet[7] >> 8) & 0xf) << 1;                   //in words
444
        payload_start = header_length + 7;                                  //in words
445
 
446
        total_length = rx_packet[8];                                        //in bytes
447
        payload_length = total_length - (header_length << 1);               //in bytes
448
        tcp_header_length = ((rx_packet[payload_start + 6] & 0xf000u)>>10); //in bytes
449
        rx_length = payload_length - tcp_header_length;                     //in bytes
450
        rx_start = payload_start + (tcp_header_length >> 1);                //in words
451
 
452
        //decode TCP header
453
        rx_source = rx_packet[payload_start + 0];
454
        rx_dest   = rx_packet[payload_start + 1];
455
        rx_seq[1] = rx_packet[payload_start + 2];
456
        rx_seq[0] = rx_packet[payload_start + 3];
457
        rx_ack[1] = rx_packet[payload_start + 4];
458
        rx_ack[0] = rx_packet[payload_start + 5];
459
        rx_window = rx_packet[payload_start + 7];
460
 
461
        //decode flags
462
        rx_fin_flag = rx_packet[payload_start + 6] & 0x01;
463
        rx_syn_flag = rx_packet[payload_start + 6] & 0x02;
464
        rx_rst_flag = rx_packet[payload_start + 6] & 0x04;
465
        rx_psh_flag = rx_packet[payload_start + 6] & 0x08;
466
        rx_ack_flag = rx_packet[payload_start + 6] & 0x10;
467
        rx_urg_flag = rx_packet[payload_start + 6] & 0x20;
468
 
469
        return number_of_bytes;
470
}
471
 
472
void application_put_data(unsigned packet[], unsigned start, unsigned length){
473
        unsigned i, index;
474
 
475
        index = start;
476
        put_socket(length);
477
        for(i=0; i<length; i+=2){
478
                put_socket(packet[index]);
479
                index++;
480
        }
481
}
482
 
483
unsigned application_get_data(unsigned packet[], unsigned start){
484
        unsigned i, index, length;
485
 
486
        if(!ready_socket()){
487
                return 0;
488
        }
489
 
490
        index = start;
491
        length = get_socket();
492
        for(i=0; i<length; i+=2){
493
                packet[index] = get_socket();
494
                index++;
495
        }
496
        return length;
497
}
498
 
499
void server()
500
{
501
        unsigned rx_packet[1024];
502
        unsigned tx_packet[1024];
503
        unsigned tx_start = 27;
504
 
505
        unsigned new_rx_data = 0;
506
        unsigned new_tx_data = 0;
507
        unsigned tx_length;
508
        unsigned timeout;
509
        unsigned resend_wait;
510
        unsigned bytes;
511
        unsigned last_state;
512
        unsigned new_rx_data;
513
 
514
        unsigned listen           = 0;
515
        unsigned open             = 1;
516
        unsigned send             = 2;
517
        unsigned wait_acknowledge = 3;
518
        unsigned close            = 4;
519
        unsigned state = listen;
520
 
521
        tx_seq[0] = 0;
522
        tx_seq[1] = 0;
523
 
524
        while(1){
525
 
526
                if(timeout){
527
                        timeout--;
528
                } else {
529
                        timeout = 120; //2 mins @100 MHz
530
                        state = listen;
531
                        tx_syn_flag = 0;
532
                        tx_fin_flag = 0;
533
                        tx_ack_flag = 0;
534
                        tx_rst_flag = 1;
535
                        put_tcp_packet(tx_packet, 0);//send reset packet
536
                }
537
 
538
                // (optionaly) send something
539
                switch(state){
540
                    case 0:
541
                        tx_rst_flag = 0;
542
                        tx_syn_flag = 0;
543
                        tx_fin_flag = 0;
544
                        tx_ack_flag = 0;
545
                        break;
546
                    case 1:
547
                        // set remote ip/port
548
                        remote_ip_hi = rx_packet[13];
549
                        remote_ip_lo = rx_packet[14];
550
                        tx_dest = rx_source;
551
                        tx_source = local_port;
552
                        // send syn_ack
553
                        calc_ack(tx_ack, rx_seq, 1);
554
                        tx_syn_flag = 1;
555
                        tx_ack_flag = 1;
556
                        put_tcp_packet(tx_packet, 0);
557
                        break;
558
                    case 2:
559
                        // application -> tcp
560
                        tx_length = application_get_data(tx_packet, tx_start);
561
                        tx_seq[0] = next_tx_seq[0];
562
                        tx_seq[1] = next_tx_seq[1];
563
                        calc_ack(next_tx_seq, tx_seq, tx_length);
564
                        tx_syn_flag = 0;
565
                        tx_ack_flag = 1;
566
                        put_tcp_packet(tx_packet, tx_length);
567
                        break;
568
                    case 3:
569
                        // resend until acknowledge recieved
570
                        put_tcp_packet(tx_packet, tx_length);
571
                        break;
572
                    case 4:
573
                        // send fin ack
574
                        tx_fin_flag = 1;
575
                        tx_ack_flag = 1;
576
                        calc_ack(tx_ack, rx_seq, 1);
577
                        put_tcp_packet(tx_packet, 0);
578
                        break;
579
                }
580
 
581
                // repeatedly check for responses
582
                for(resend_wait = 10000; resend_wait; resend_wait--){ //1 second @ 100MHz
583
                        bytes = get_tcp_packet(rx_packet);
584
                        if(bytes && (rx_dest == local_port)){
585
                                //Once connection is established ignore other connection attempts
586
                                if(state != listen && rx_source != tx_dest) continue;
587
                                new_rx_data = 0;
588
                                last_state = state;
589
                                switch(state){
590
 
591
                                    // If a syn packet is recieved, wait for an ack
592
                                    case 0:
593
                                        if(rx_syn_flag) state = open;
594
                                        else{
595
                                                tx_rst_flag = 1;
596
                                                put_tcp_packet(tx_packet, 0);//send reset packet
597
                                        }
598
                                        break;
599
 
600
                                    // If an ack is recieved the connection is established
601
                                    case 1:
602
                                        if(rx_ack_flag){
603
                                                tx_seq[1] = rx_ack[1];
604
                                                tx_seq[0] = rx_ack[0];
605
                                                next_tx_seq[1] = rx_ack[1];
606
                                                next_tx_seq[0] = rx_ack[0];
607
                                                state = send;
608
                                        }
609
                                        break;
610
 
611
                                    // Send some data
612
                                    case 2:
613
                                        new_rx_data = calc_ack(tx_ack, rx_seq, rx_length);
614
                                        if(rx_fin_flag){
615
                                                state = close;
616
                                        } else if( tx_length ){
617
                                                state = wait_acknowledge;
618
                                        }
619
                                        break;
620
 
621
                                    // Wait until data is acknowledged before sending some more.
622
                                    case 3:
623
 
624
                                        new_rx_data = calc_ack(tx_ack, rx_seq, rx_length);
625
                                        if(rx_fin_flag){
626
                                                state = close;
627
                                        } else if(  rx_ack_flag &&
628
                                                    (next_tx_seq[1] == rx_ack[1]) &&
629
                                                    (next_tx_seq[0] == rx_ack[0])){
630
                                                state = send;
631
                                        }
632
 
633
                                        break;
634
 
635
                                    // wait for fin/ack.
636
                                    case 4:
637
                                        if(rx_ack_flag) state = listen;
638
                                        break;
639
                                }
640
 
641
                                if(rx_rst_flag) state = listen;
642
 
643
                                // Transfer any new data to the application
644
                                if(new_rx_data){
645
                                        application_put_data(rx_packet, rx_start, rx_length);
646
                                        //Ack can go in next transmission.
647
                                        if(state == last_state) put_tcp_packet(tx_packet, tx_length);
648
                                }
649
 
650
                                if(state == send && ready_socket()){
651
                                        break;
652
                                }
653
 
654
                                if(state != last_state){
655
                                        timeout = 120;
656
                                        break;
657
                                }
658
 
659
                        } else {
660
                                wait_clocks(10000);//100 us @100 MHz
661
                        }
662
                }
663
        }
664
}

powered by: WebSVN 2.1.0

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