FreeRTOS_recv always return 1

rasty1 wrote on Thursday, November 19, 2015:

I write TCP/IP wrapper for CLI and see that FreeRTOS_recv always return 1. Even if multiply characters are read from the socket.
What do i miss?
Link to screen capture from debugger - https://rslutsker-gmail.tinytake.com/sf/Mzg2OTY5XzIxNjc4MTE
Best regards
Rasty

rtel wrote on Thursday, November 19, 2015:

As a sanity check I just tried the echo client, which contains the following code:

xReturned = FreeRTOS_recv( xSocket,								
						&( pcReceivedString[ xReceivedBytes ] ),
						 lStringLength - xReceivedBytes,		
						 0 );									

…and xReturned had the expected value.

Can you show the declaration of cLocalBuffer.
What happens if you memset cLocalBuffer to 0 before calling FreeRTOS_recv()? Maybe you just have old data in the buffer.

Regards.

heinbali01 wrote on Friday, November 20, 2015:

And in addition :

void vTelnetSession()
{
    for( ;; )
    {
    /* Declare it volatile to make sure
    the debugger shows the correct value. */
    volatile long lBytes;

        lBytes = FreeRTOS_recv( xSocket, cBuffer, sizeof( cBuffer ), 0 );
        if( ( lBytes == 0 ) || ( lBytes == -pdFREERTOS_ERRNO_EAGAIN ) )
        {
            /* Time-out was reached. Make sure that
            'FREERTOS_SO_RCVTIMEO' has a reasonable value. */
            continue;
        }
        if( lBytes < 0 )
        {
            /* You may want to look-up the type of error.
            Normally you'd see -pdFREERTOS_ERRNO_ENOTCONN */
            break;
        }
        for( lIndex = 0; lIndex < lBytes; lIndex++ )
        {
            cInChar = cBuffer[ lIndex ];
            ...
        }
    }
    FreeRTOS_closesocket( xSocket );
}

All +TCP i/o functions have the following result codes:

  • Positive : number of bytes sent or received
  • Zero or -EAGAIN ( == -EWOULDBLOCK ) : a timeout was reached, nothing was sent or received
  • Other negative values: see defined ERRNO values

Regards.

rasty1 wrote on Friday, November 20, 2015:

telnet client sends entire line when I hit Enter. In rcv buffer i see “help\n” that is what I type, but ret is “1” instead of expected 5 bytes.
If I read byte after byte I get all the data, characher each call.
I’ll wipe buffer and double check it with tcpdump next week.
Thank you for the support.

heinbali01 wrote on Saturday, November 21, 2015:

First some remarks that have nothing to do with your “FreeRTOS_recv always return 1” problem. I had another look at the FreeRTOSIPConfig.h that you posted earlier:

#define ipconfigARP_CACHE_ENTRIES                6

That is may too little: it will only have 6 ARP entries. If you have many connections, there will often be unnecessary ARP lookup’s because ealier entries were overwritten.

#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS   96

That is a lot. I would use that in a Xilinx Zynq, which has 1 GB of RAM available. In CPU’s with less RAM, 36 descriptors will be more than enough:

#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS   36

While developing, it is always good to keep an eye on the actual usage of network buffer descriptors, such as in this code:

    {
        uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
        if( uxLastMinBufferCount != uxCurrentCount )
        {
            /* The logging produced below may be helpful
            while tuning +TCP: see how many buffers are in use. */
            uxLastMinBufferCount = uxCurrentCount;
            FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
                uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
        }
    }

TCP stream buffer size:

/* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed
maximum size.  Define the size of Rx buffer for TCP sockets. */
#define ipconfigTCP_RX_BUF_LEN            ( 0x4000 )
/* Define the size of Tx buffer for TCP sockets. */
#define ipconfigTCP_TX_BUF_LEN            ( 0x4000 )

That gives a RX (and TX) stream buffer of 16384 bytes. If you would omit to call recv(), the socket will receive up to that amount of bytes.
Note that you can always overwrite these default buffer sizes for individual sockets.

Back to the "FreeRTOS_recv always return 1" problem:

It would be interesting to see a PCAP of the communication.
And maybe the code that creates a socket, binds and listens, calls to FreeRTOS_setsockopt()? If it is complete enough I can run it in a Xilinx Zynq (have no uBlaze here :frowning: )

Regards,
Hein

rasty1 wrote on Sunday, November 22, 2015:

Hi
I reconfirm the problem
https://rslutsker-gmail.tinytake.com/sf/Mzg5NjU2XzIxODAwOTA
I put a breakpoint immidiately after receive and get complete line (“help\n”), but number of bytes read from the socket is “1”.
Please look into packet #17 at the pcap dump.

I attached also TCP code. It is still under construction :slight_smile:

rasty1 wrote on Sunday, November 22, 2015:

Another interesting observation.
I check what happens if remote would close connection.
I expected that FreeRTOS_recv would return any negative number, instead it keeps returning “1”.

rtel wrote on Sunday, November 22, 2015:

I have just created a little TCP interface for the CLI, and when I type
“help” and the rx buffer contains help\n, FreeRTOS_recv() is correctly
returning 5. I will post the code when I have tested it a bit (other
stuff doing now).

heinbali01 wrote on Sunday, November 22, 2015:

Another interesting observation.
I check what happens if remote would close connection.
I expected that FreeRTOS_recv would return any negative number,
instead it keeps returning “1”.

FreeRTOS_recv() will only return a negative value ( usually -pdFREERTOS_ERRNO_ENOTCONN ) when the RX stream buffer is empty.

It is even possible that a TCP connection comes in, bytes are being received, and the connection is closed, before your application has had a chance to call FreeRTOS_accept(). This happens often in a FTP server when small files are being received.
In such cases, FreeRTOS_recv() will return a positive number as long as there is data to read.

socketclose.pcap

This PCAP already looks better than ublaze.pcap: now therr is a normal and complete TCP conversation. There has been 1 retransmission.

TCPCommandServer.c

Here above I posted some code. Why did not you try it out? It would have solved your problem.

Look at this code:

while (lBytes = FreeRTOS_recv( xSocket, ( void * ) cLocalBuffer, sizeof( cLocalBuffer ) /*RS returns 1 no matter how many chars are in the buffer*/, 0 )!= FREERTOS_SOCKET_ERROR)
{
}

Doesn’t your compiler issue a warning about this expression? Think of the C priorities within expressions.

it says:

while( lBytes = ( FreeRTOS_recv() != FREERTOS_SOCKET_ERROR ) )

And therefore lBytes can either become 0 or 1.

Could you try out the code that I posted here above?

Regards,
Hein

rasty1 wrote on Sunday, November 22, 2015:

Doesn’t your compiler issue a warning about this expression? Think of the C priorities within expressions.
Yes, pretty stupid error. Thank you very much for you help.
Now it works as expected.