I don't think you should follow my path (I started studying Lynx, then Bobcat. Bobcat07.zip was available on internet at that time and this text only internet browser was using a standard packet driver and wattcp 1.2).
I really needed a stack that compiles under msdos and under bare bios in real mode, but it's not your case.
I suffered a bit porting it to 32 bits for xbox1 and 64 bits for ps2. You should start with a 32 bits stack.
Maturion is hosting a mirrored version of original OpenXDK home page where Craig (its creator) wrote a todo list. In this list he talks about LWIP stack and gives an url :
http://www.sics.se/~adam/lwip/http://openxdk.maturion.de/todo.htmlIf wattcp is your thing, just grab wattcp32 (or watt-32) and bend it so it can accept my packet driver.
http://www.erickengelke.com/wattcp/lwip and wattcp or any other tcp/ip stack have necessarily a bottom that needs to be interfaced with a packet driver. And packet drivers are not over complex. The difficulty to write them is just the difficulty to find or guess the network adapter chipset registers documentation... They do always the same, send packet, receive packets... and packets are always around the same size, i.e 1500 bytes. So what requires lwip is probably not far from what requires wattcp or wattcp32... (mainly ring buffers and interrupts).
But the top of stacks show different high level apis... And I was happy to find plenty of samples for wattcp (http, ftp, pop, etc...).
Dunno for lwip, never tried it.
To help you, here is the function which gave me the most trouble...
A function that gives a correct 'pc ticks' value on xbox1 (for wattcp 16 bits)
QUOTE
unsigned long times(void *);
static longword pc_ticks_counter(void) //longword is unsigned 32 bits
{
static longword clk=0;
longword out;
out=times(0); //1000=1s
out=((out*1193L)>>16); //18.203735=1s (overflows after 1 hour)
//Try to guess if we got a clock overflow (0000ffff->00000000)
//Works well if we are called often (more often than every 15 mn)
if (((clk&0xffff)>=0xC000)&&(out<0x4000))
clk=(clk&0xffff0000)+out+0x10000; //18.203735=1s (overflows after 7 yrs)
else
clk=(clk&0xffff0000)+out; //18.203735=1s (overflows after 7 yrs)
return clk; //18.203735=1s (overflows after 7 yrs)
}
But since then, in Demo04 (main.c) I've found a much better way to detect exact processor clock :
QUOTE
unsigned int cpu_ticks(void)
{
unsigned int v;
__asm__ __volatile__ ("rdtsc":"=a" (v));
//edx:eax holds cpu ticks count after 'rdtsc'
return v;
}
However, typical algorithm in tcp/ip stacks deal with seconds and minutes rather than with microseconds for timeouts, and more important for the Van Jacobson algorithm (when you don't get replies for your sent packets, you DO NOT HAVE THE RIGHT to madly resend packets over internet, so a protocol exists that tells you to slow down the frequency of your resending) .
So, 'pc ticks' are just fine for the job and avoid too fast 32 bits counters overflows.
My notes about Van Jacobson algorithm (which was badly implemented in wattcp 1.2 16 bits, so I re-implemented it) :
QUOTE
Implementation of following algorithm is NECESSARY
(avoids congestion, improves performance)
Van Jacobson algorithm (from his book) :
Constants : alpha=1/8 beta=1/4 gamma=4 (for TCP)
RTT : Round Trip Time (time between sending and reply)
SRTT : Smoothed Round Trip Time (predicted RTT)
SRTT[K]=(1-alpha)*SRTT[K-1]+alpha*RTT[K]
ERR : Difference between prediction and reality
ERR[K]=RTT[K]-SRTT[K-1]
RTTVAR : Round Trip Time Variation (predicted error)
or SDEV : Smoothed Deviation
SDEV[K]=(1-beta)*SDEV[K-1]+beta*abs(ERR[K])
RTO : Retransmission Timeout
RTO[K]=SRTT[K]+gamma*SDEV[K]
Exponential smoothing algorithm (from rfc2988) :
1) G : timer granularity (<=100ms is better)
heartbeat : 2.5<2.5+G<3 seconds
2) First RTT measurement : R
SRTT=R
RTTVAR=R/2
RTO=SRTT+max(G,gamma*RTTVAR)
3) Next RTT measurements : R2
RTTVAR=(1-beta)*RTTVAR+beta*abs(SRTT-R2)
SRTT=(1-alpha)*SRTT+alpha*R2
(order is important)
4) if RTO<1s RTO=1s
5) if RTO>60s RTO=60s
Suggested sequence (from rfc2988) :
1) Start timeout detection with RTO
each time a packet containing data is sent
2) When all is done suspend timout detection
3) When ACK packet is received reset to RTO
4) If RTO timeout is detected, resend last packet,
double RTO value and detect next timout : RTO=RTO*2 (max 60s)
If happens too often, restart with first measurement R
Beside these timing problems, the stack was working good. No need to improve it.