I have been using TCPnet for ST10 but I imagine my question applies cross-platform.
The documentation for udp_get_socket specifies that a user-defined listener callback should be registered as below:
#include <AR166.h> U8 udp_get_socket ( U8 tos, /* Type Of Service. */ U8 opt, /* Option to calculate or verify the checksum. */ U16 (*listener)( /* Function to call when TCPnet receives a data packet. */ U8 socket, /* Socket handle of the local machine. */ U8* remip, /* Pointer to IP address of remote machine. */ U16 port, /* Port number of remote machine. */ U8* buf, /* Pointer to buffer containing the received data. */ U16 len )); /* Number of bytes in the received data packet. */
I cannot find documentation about a few aspects of the listener function:
- Is it the responsibility of the udp_get_socket listener function to free the buffer memory, or does the listener caller take care of that? - What significance does the U16 return value of the listener function have? What does the caller do with the return value?
Thanks, Tony
"Is it the responsibility of the udp_get_socket listener function to free the buffer memory, or does the listener caller take care of that?"
When the UDP frame has been sent, TCPnet automatically de-allocates the memory used by the send buffer.
Taken from page:
http://www.keil.com/support/man/docs/rlarm/rlarm_udp_get_buf.htm
"What significance does the U16 return value of the listener function have? What does the caller do with the return value?"
Can't find the details concerning that at the moment. For a TCP connection, the manual states:
If the listener function returns 0, TCPnet rejects the incoming connection. You can thus define the listener function to selectively reject incoming connections from particular IP addresses.
but, since UDP cannot refuse a connection in the same way, I think the return value should always be zero. That's what I've always done and I've not found any problems with it.
I think that the example given in the manual supports that thought; i.e., it returns zero and there is no mention of anything else:
www.keil.com/.../rlarm_udp_get_socket.htm
IB Shy, thanks for your response.
My question was about the receive buffer, not the transmit. I have seen the documentation pertaining to udp_get_buf and udp_send, and I am confident that TCPnet de-allocates memory for transmit buffers. I have found no such documented assurance for receive buffers.
Logically, I could assume that returning from the listener function implies that the buffer has been processed and thus may be de-allocated, but I'd really like to know for sure. It is also implied by the absence of a udp_release_buf function to go with the udp_get_buf.
(Does that mean the only way in the TCPnet UDP API to free any buffer is to send it? What about the case if an error occurs in between your call to udp_get_buf and udp_send, such that the message shouldn't be sent?)
As far as the return value for the listener function, I've only seen zero used in all the examples, but those examples tend to be very simplistic.
- Tony
"My question was about the receive buffer, not the transmit."
My bad. Sorry.
I think details of what you're asking are going to be very thin (or, at best, well hidden). My understanding of receipt is that TCPnet allocates the buffer, passes it to the callback function and releases it automatically on return. If you need the data you must take a copy of it. If you don't want it you can ignore it. This is what I do and have never experienced 'out of memory' errors even after months of continuous use.
"(Does that mean the only way in the TCPnet UDP API to free any buffer is to send it? What about the case if an error occurs in between your call to udp_get_buf and udp_send, such that the message shouldn't be sent?)"
Not sure what sort of error you're really expecting there. Remember that TCPnet is expected to run within a single task, so I don't think detecting an error between the two actions would be necessary.
"As far as the return value for the listener function, I've only seen zero used in all the examples, but those examples tend to be very simplistic."
True - But, generally speaking, UDP communication is quite simplistic.
Shy, thanks for sharing your experience.
"I think details of what you're asking are going to be very thin (or, at best, well hidden)."
This is partly why I asked Keil for the source code, but they refused to supply it (thus far). I can at least ask them to revise their documentation.
"This is what I do and have never experienced 'out of memory' errors even after months of continuous use."
I hope that the ST10 and ARM implementations are comparable. What version(s) of ARM TCPnet were you using?
"Not sure what sort of error you're really expecting there. Remember that TCPnet is expected to run within a single task, so I don't think detecting an error between the two actions would be necessary."
A single task would be calling udp_get_buf, performing application-specific manipulation of the buffer, and then calling udp_send to send it. I didn't mean an error with TCPnet, but an error in the application-specific stuff. I'm also going to assume that even if udp_send returns __FALSE, it will have freed the buffer (assuming I passed a valid pointer).
"True - But, generally speaking, UDP communication is quite simplistic."
I'll always return zero then, based on your experience.
Tony
"This is partly why I asked Keil for the source code, but they refused to supply it (thus far)."
Been there. Done that. It is one of my real bugbears!
"What version(s) of ARM TCPnet were you using?"
Currently using version 4.23, but code has had the same (basic) structure since version 3.40.
"I'm also going to assume that even if udp_send returns __FALSE, it will have freed the buffer ..."
Without the source code or full documentation, I think that's about all we can do.
View all questions in Keil forum