Chen,
When NO_SYS=1, there is a lot more to do than you had to prior
just calling tcp_tick(). I use the following code to update the lwIP
timers. You can call this every mS (or to be more efficient, every 250mS
since that is the LCD of the all of the modulus operands). I essence,
this becomes your tcp_tick for lwIP. For the rest of your program, I’d
switch to the more standard socket interface in lwIP. The Rabbit stack
wasn’t really socket compatible as their naming might imply.
Bill
void lwipProcessTimers(
void )
{
void ip_reass_tmr(
void );
if( (lwip_mS %
TCP_TMR_INTERVAL) == 0 ) tcp_tmr();
if( (lwip_mS %
ARP_TMR_INTERVAL) == 0 ) etharp_tmr();
#if IP_REASSEMBLY
if( (lwip_mS %
IP_TMR_INTERVAL) == 0 ) ip_reass_tmr();
#endif
#if LWIP_AUTOIP
if( (lwip_mS %
AUTOIP_TMR_INTERVAL ) == 0 ) autoip_tmr();
#endif
#if LWIP_IGMP
if( (lwip_mS %
IGMP_TMR_INTERVAL ) == 0 ) igmp_tmr();
#endif
#if LWIP_DHCP
if( (lwip_mS %
DHCP_FINE_TIMER_MSECS ) == 0 ) dhcp_fine_tmr();
if( (lwip_mS %
(DHCP_COARSE_TIMER_SECS*1000) ) == 0 ) dhcp_coarse_tmr();
#endif
#if LWIP_DNS
if( (lwip_mS %
DNS_TMR_INTERVAL) == 0 ) dns_tmr();
#endif
}
From:
address@hidden
[mailto:address@hidden On Behalf
Of Chen
Sent: Thursday, February 05, 2009 8:53 AM
To: address@hidden
Subject: Re: Re: [lwip-users] Struggleing to build a TCP echo server
Simon,
Thanks to your reply, I am so new to the forum, I am not sure if this the right
way to to reply on the forum.
<<There is an example (very simple) HTTP server for the raw API in the
contrib module (there is also a port for unix and win32 for easy
development/debugging). The contrib module for lwIP 1.3.0 is availaible in the
download section at savannah or via CVS.>>
Could you show me how to get to the download section?
<<As you mentioned you used ATMEL sample projects: be aware ATMEL could
have an older version of lwIP, which is not really supported on this list. Oh,
and when using the raw API: be aware the functions may only be called from one
thread, the lwIP core is NOT thread safe (use sockets/netconn if you want
that).>>
ATMEL also has a working HTTP sample which I believed is based on lwIP version
1.3 , but I just can't figure out how to extract the pieces to construct a
telnet server from it.
Based on my previous experience with Dynamic C (see the end of this email for
the example), I assume I could build something similar from lwIP (btw, I still
couldn't find any sample using tcp_* under lwIP).
Based on your suggested reading, I struggle to come up something like this.
When running, it acted like a TCP black hole: I can open connection to port 23
once, JUST ONCE, and type until the socket is closed due to time out.
Problem:
1) From Ethereal, it accepted Telnet connection with SYN, ACK, and after that
it does nothing, never ACK to the incoming data anymore
2) I have no idea how to test number of data in the receive buffer
3) The state machine doesn't totally agree with Dynamic C's and I have no clue
how to deal with them due to lack of documentation
Could you be so kind to give me some pointers on this?
Thank you very very much for your time!
Regards,
Chen
>>>>>> My unsuccessful try under lwIP
>>>>>>
int len;
int i;
struct
netbuf *buf;
struct lwip_socket *sock;
struct tcp_pcb *ptel_pcb;
ptel_pcb = tcp_new();
tcp_bind(ptel_pcb, IP_ADDR_ANY,
23);
ptel_pcb =
tcp_listen(ptel_pcb);
tcp_accept(ptel_pcb, NULL);
while(1){
tcp_tmr();
switch(ptel_pcb->state){
case
CLOSED:
break;
case
LISTEN:
break;
case
SYN_SENT:
break;
case
SYN_RCVD:
break;
case
ESTABLISHED:
break;
case
FIN_WAIT_1:
break;
case
FIN_WAIT_2:
break;
case
CLOSE_WAIT:
break;
case
CLOSING:
break;
case
LAST_ACK:
break;
case
TIME_WAIT:
break;
}
>>>>>>>>>A working TCP Echo Server from
Dynamic C>>>>>>>>>>>>>
#define
VS_INIT 0 /*
closed or never opened */
#define
VS_LISTEN 1 /*
waiting for a connection */
#define
VS_OPENING 2 /*
wait while we open a connection */
#define
VS_OPEN 3 /*
we have a connection */
#define
VS_WAITCLOSE 4 /*
wait for the connection to be torn down */
typedef struct
{
int state;
tcp_Socket socket;
} VsState;
VsState vs_state;
void vs_init(VsState* vs_state)
{
vs_state->state=VS_INIT;
memcpy(&vs_info,&factory_defaults,sizeof(vs_info));
}
void vs_handler(VsState* state)
{
auto tcp_Socket* socket;
auto int ch, bytes_written;
auto int bytes_to_write;
socket=&state->socket;
if(state->state!=VS_INIT
&& tcp_tick(socket)==0) {
state->state=VS_INIT;
state->open_timeout=vs_info.open_timeout;
}
switch(state->state)
{
case
VS_INIT:
tcp_listen(socket,TCP_PORT,0,0,NULL,0);
state->state=VS_LISTEN;
break;
case
VS_LISTEN:
case
VS_OPENING:
if(sock_established(socket))
{
state->state=VS_OPEN;
sock_mode(socket,TCP_MODE_BINARY);
}
break;
case
VS_OPEN:
iread=sock_dataready(socket); //iread bytes are ready
to read
...
i=sock_read(socket, input, x
); //read x bytes to input[]
...
j=sock_tbleft(socket); //j
bytes available on output buffer
...
sock_fastwrite(socket,buffer,
y); //transmit y bytes from buffer[]
break;
case
VS_WAITCLOSE:
break;
default:
state->state=VS_INIT;
break;
}
}
void main()
{
sock_init();
vs_init(&vs_state);
while (1) {
tcp_tick(NULL); //this is similar to
tcp_tmr in lwIP, I think
vs_handler(&vs_state);
}
}