View previous topic :: View next topic |
Author |
Message |
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
CCS TCP/IP stack bug? |
Posted: Wed Feb 18, 2009 11:15 am |
|
|
Hello,
I use the CCS TCP/IP stack on a server application with the 18F66J60.
I connect PC to board with "TCP_client.exe", send text, the board respond with another text and I close "TCP_client.exe".
No problem.... excepted that it works only 4 times.
At the 5th time, the "TCP_client.exe" can be connected, but the PIC doesn't receive the text that I send.
It's always at the 5th connection that this happens, even if I don't send any text during the 4 previous connection (so it's not a buffer problem).
It works fine if I reset the board between each connection.
Is there any bug on the CCS TCP/IP stack which could make this happen?
Thanks for any help,
Franck. |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Wed Feb 18, 2009 12:57 pm |
|
|
I made some progress:
After 4 connection/disconnection, the function TCPListen() return INVALID_SOCKET. It's normal since I have defined MAX_SOCKETS to 5.
So it looks like I don't free the sockets when the PC application is disconnected.
The code is the CCS example:
Code: | void MyTCPTask() {
static TICKTYPE lastTick[NUM_LISTEN_SOCKETS];
static TCP_SOCKET socket[NUM_LISTEN_SOCKETS]={INVALID_SOCKET};
static enum {
MYTCP_STATE_NEW=0,
MYTCP_STATE_LISTENING=1,
MYTCP_STATE_CONNECTED=2,
MYTCP_STATE_DISCONNECT=3,
MYTCP_STATE_FORCE_DISCONNECT=4
} state[NUM_LISTEN_SOCKETS]={0};
TICKTYPE currTick;
int8 dis;
int8 i;
currTick=TickGet();
for (i=0;i<NUM_LISTEN_SOCKETS;i++) {
switch (state[i]) {
case MYTCP_STATE_NEW:
socket[i]=TCPListen(EXAMPLE_TCP_PORT);
if (socket[i]!=INVALID_SOCKET) {
state[i]=MYTCP_STATE_LISTENING;
}
break;
case MYTCP_STATE_LISTENING:
if (TCPIsConnected(socket[i])) {
state[i]=MYTCP_STATE_CONNECTED;
lastTick[i]=currTick;
}
break;
case MYTCP_STATE_CONNECTED:
if (TCPIsConnected(socket[i])) {
if (TickGetDiff(currTick,lastTick[i]) > ((int16)TICKS_PER_SECOND * 300)) {
state[i]=MYTCP_STATE_DISCONNECT;
lastTick[i]=currTick;
}
else {
dis=TCPConnectedTask(socket[i],i);
if (dis) {
state[i]=MYTCP_STATE_DISCONNECT;
lastTick[i]=currTick;
}
}
}
else {
state[i]=MYTCP_STATE_FORCE_DISCONNECT;
}
break;
case MYTCP_STATE_DISCONNECT:
if (TCPIsPutReady(socket[i])) {
state[i]=MYTCP_STATE_FORCE_DISCONNECT;
}
else if (TickGetDiff(currTick, lastTick[i]) > (TICKS_PER_SECOND * 10)) {
state[i]=MYTCP_STATE_FORCE_DISCONNECT;
}
break;
case MYTCP_STATE_FORCE_DISCONNECT:
TCPDisconnect(socket[i]);
state[i]=MYTCP_STATE_NEW;
break;
}
}
} |
Is there anything I can do free the sockets when the PC application is disconnected?
Thanks for any help,
Franck. |
|
|
eskimobob
Joined: 07 Feb 2009 Posts: 40
|
Re: CCS TCP/IP stack bug? |
Posted: Wed Feb 18, 2009 1:46 pm |
|
|
Edit: Oops, I took so long posting a reply that you came to the same conclusion as me. I'd suggest looking into the source code for TCP_client.c (supplied along with the examples) and figure out why it is not closing the sockets.
My original reply below
Franck26 wrote: | No problem.... excepted that it works only 4 times. |
Presumably you are using example ex13b.c for this along with the TCP_client.exe program that CCS supply.
In the example, there are by default a maximum of 2 sockets opened. Have you changed this?
The reason I ask is I wonder whether TCP_client.exe is not closing the sockets correctly and therefore you are running out of sockets to connect to.
Franck26 wrote: | Is there any bug on the CCS TCP/IP stack which could make this happen? |
Unfortunately I have found a couple of bugs in the examples so far so there are possibly more and possibly others in the stack itself
If you confirm that you are using the example, ex13b.c, I will try it here and see if I get the same effect. |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Wed Feb 18, 2009 4:13 pm |
|
|
Hi Eskimobob,
Thanks for your help .
Yes I'm using the CCS example ex13b.c. I didn't change the define value.
It would be great if you could run this example and tell me if you have the same problem.
Thanks in advance .
Franck. |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Thu Feb 19, 2009 12:30 am |
|
|
Looking at my code, the MYTCP_STATE_FORCE_DISCONNECT should be changing the state to MYTCP_STATE_LISTENING not MYTCP_STATE_NEW. In any case, I only call TCPListen on each socket once at startup, and never again. _________________ Andrew |
|
|
eskimobob
Joined: 07 Feb 2009 Posts: 40
|
|
Posted: Thu Feb 19, 2009 8:28 am |
|
|
Hi Franck26,
I have tried the example and I get the same problem as you. I have investigated and have a possible solution - see my explanation below:
When TCPListen is called, it will search through the available sockets (which is up to 5 by default) to find one that has a state of TCP_CLOSED.
If it finds one then it sets it as a listening socket by setting state to TCP_LISTEN. It defines this as a server socket.
If it does not find a socket in state TCP_CLOSED then it assumes they are all used and returns INVALID_SOCKET which means you get "SOCKET ERROR" in the example.
When you disconnect from the socket, TCPDisconnect is called and this calls the CloseSocket function in TCP.c. The close socket function checks to see whether the socket is a server socket or not. If it is not a server socket then it changes the socket state to TCP_CLOSED and the socket is therefore freed up for reuse. However, if it is a server socket then it sets the socket state to TCP_LISTEN.
Now, in the example code, when you call TCPListen again, this time TCPListen will find that this particular socket is marked as TCP_LISTEN and therefore it cannot use it. After this happens a few times, there are no more sockets in the TCP_CLOSED state because they are all in the TCP_LISTEN state.
The offending bit of code seems to be in tcp.c Line 1529 in function CloseSocket:
Code: |
if ( ps->Flags.bServer )
{
ps->smState = TCP_LISTEN;
}
else
{
ps->smState = TCP_CLOSED;
}
|
If you this so that the socket is always set to TCP_CLOSED then regardless of whether you have a server socket or not, it works.
Code: |
ps->smState = TCP_CLOSED;
|
This works and I can open and close the socket repeatedly without any problem. Will be interesting to hear what you find if you try the same fix.
I don't know that this is definietly the right solution without spending more time investigating what the code is supposed to do
I will send CCS a bug report covering this and see what they say. It is sad to find what appears to be another bug in the CCS TCP-IP info (whether it is in TCP.c or ex13b.c) |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Thu Feb 19, 2009 11:46 am |
|
|
Hi Eskimobob and Andrewg,
Your both solution works for me !!!
Both code solution are doing the same, but I'm wondering which one is the most appropriate...
Anyway, thanks a lot to both of you.
Just another small problem that I have on my board: the Ethernet LED doesn't work ...
I've got the #FUSES ETHLED set and SetLEDConfig(0x047A).
Do they work on your application?
Is there a trick?
Thanks,
Franck. |
|
|
eskimobob
Joined: 07 Feb 2009 Posts: 40
|
|
Posted: Thu Feb 19, 2009 12:55 pm |
|
|
Franck26 wrote: | Do they work on your application? |
Hello Franck,
I am confused by your original post:
Franck26 wrote: | I use the CCS TCP/IP stack on a server application with the 18F66J60. |
I have the board with the PIC18F67J60 chip. Is this what you have?
If it is, you should change the SetLEDConfig to:
SetLEDConfig(0x0472);
The Ethernet LEDs work for me |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Thu Feb 19, 2009 2:35 pm |
|
|
Hello Esquimobo,
My CCS board with a PIC18F67J60 seems dead: micro OK but no Ethernet connection. Or maybe the Ethernet cable I use doesn't have the good connection... Do I need a special cable?
I use another board with a layout similar but with a PIC18F66J60 and it works, excepted the LED .
Anyway, I'll try the LED config you gave me tomorrow and hopefully it will be finished for this project !!!
I'll let you know.
Thanks,
Franck. |
|
|
eskimobob
Joined: 07 Feb 2009 Posts: 40
|
|
Posted: Thu Feb 19, 2009 2:51 pm |
|
|
Franck26 wrote: | Do I need a special cable? |
Depends how you connect it. If you connect to a router/switch/hub then a normal cable will be fine. If you connect directly to the LAN on your PC then you will need a crossover cable |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Thu Feb 19, 2009 4:23 pm |
|
|
Crossover cable... It must be the problem!!!
Thanks,
Franck. |
|
|
eskimobob
Joined: 07 Feb 2009 Posts: 40
|
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Fri Feb 20, 2009 12:12 pm |
|
|
Nothing better for the LED.
I tried SetLEDConfig(0x0472), SetLEDConfig(0x047A) (to have a Pulse stretch of 139ms), and even SetLEDConfig(0x088A) to have both LED on all the time...
Both pin are configured as output.
The only way to light up those LED is to set directly the port output.
I'll try on Monday with the CCS Ethernet board and a crossover cable.
Good weekend,
Franck. |
|
|
eskimobob
Joined: 07 Feb 2009 Posts: 40
|
|
Posted: Sat Feb 21, 2009 10:54 am |
|
|
andrewg wrote: | Looking at my code, the MYTCP_STATE_FORCE_DISCONNECT should be changing the state to MYTCP_STATE_LISTENING not MYTCP_STATE_NEW. In any case, I only call TCPListen on each socket once at startup, and never again. |
Franck,
I have looked into this a bit more and I think Andrew is correct.
The example ex13b.c has the mistake rather than tcp.c. Instead of case MYTCP_STATE_FORCE_DISCONNECT setting state to MYTCP_STATE_NEW, it should set it to MYTCP_STATE_LISTENING.
Hope this helps |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Mon Feb 23, 2009 4:20 am |
|
|
Hi Eskimobob,
I've got the crossover cable, so I have been able to connect the CCS board.
But the LED are not working neither with this board .
I use the example 13b, the only thing that I change is the IP address, and I connect with TCP_client.exe.
I send a long string, the string display on the LCD, but none of the LED are lighting up...
Same thing when I press the button A4, to send a string from the board to the PC.
Can you confirm that you don't do anything else, like some magic...
Thanks, for your help.
Franck. |
|
|
|