PDA

View Full Version : UDP Ethernet connection



Roberto
May 8th, 2013, 05:37 AM
Hello,
I'm creating an UDP ethernet connection between XMC4500 (Relax Kit) and my Personal Computer
To do that, I used DAVE3 + App ETH003 (1.0.2)

I have a problem with the port number: I set the connection port to 8221 with htons, but the real connection is made on the 7456 port, which is equivalent to a swap of bytes of 8221

Could anyone help me?

Best Regards

Roberto.


this is my code snippet:


/* Thread Id Declrations*/
osThreadId lwip_thread_id;
osThreadId lwip_thread_udp_id;

/* Thread definitions */
osThreadDef(lwip_thread,0,1,0);
osThreadDef(udp_thread_entry,1,1,2048);
const u16_t RECEIVER_PORT_NUM = 8221;

#define DEST_IP_ADDR "172.30.10.31"

void udp_thread_entry(void const *argument)
{
int socket_fd;
struct sockaddr_in da,ra;
int sent_data;
int ret;
int recv_data; char data_buffer[80];
socklen_t fromlen;



socket_fd = socket(PF_INET, SOCK_DGRAM, 0);

if ( socket_fd < 0 )
{
printf("socket call failed");
return 1;
}

memset(&da, 0, sizeof(struct sockaddr_in));
da.sin_family = AF_INET;
da.sin_addr.s_addr = inet_addr(DEST_IP_ADDR);
da.sin_port = htons(RECEIVER_PORT_NUM);
da.sin_len = sizeof(struct sockaddr_in);

memset(&ra, 0, sizeof(struct sockaddr_in));
ra.sin_family = AF_INET;
ra.sin_addr.s_addr = INADDR_ANY;
ra.sin_port = htons(RECEIVER_PORT_NUM);

if (bind(socket_fd, (struct sockaddr *)&ra, sizeof(struct sockaddr_in)) == -1)
{
close(socket_fd);
}

while(1)
{


strcpy(data_buffer,"Hello World");
sent_data = sendto(socket_fd, data_buffer,strlen(data_buffer),0,(struct sockaddr*)&da,sizeof(da));
sent_data = errno;
osDelay(500);

fromlen =sizeof(ra);
recv_data = recvfrom(socket_fd,data_buffer,80,0,(struct sockaddr*)&ra, &fromlen);
if(recv_data > 0)
{

data_buffer[recv_data] = '\0';
printf("%s\n",data_buffer);

}
}
}

Travis
Jun 4th, 2013, 10:53 PM
Hi Roberto, Can you give this example a try.

Roberto
Jun 21st, 2013, 07:09 AM
Hi Travis,
using the socket connection, in my snippet code,
changing the code line

ra.sin_port = htons(RECEIVER_PORT_NUM);
with
ra.sin_port = (RECEIVER_PORT_NUM); //htons removed

The udp connection works fine.

Where am I wrong?

Just another thing.
I think there is a bug in the function
struct netbuf * netconn_recv(struct netconn *conn)

as generated by DAVE (ETH003. 1.0.2)
the line code
struct api_msg *msg = _MALLOC_API_MSG;
reserves memory but in case of UDP connection there is a memory leak
because there isn't the free(msg) line code before exit

Regards

Roberto

/**
* Receive data (in form of a netbuf containing a packet buffer) from a netconn
*
* @param conn the netconn from which to receive data
* @return a new netbuf containing received data or NULL on memory error or timeout
*/
struct netbuf *
netconn_recv(struct netconn *conn)
{
// struct api_msg msg;
struct api_msg *msg = _MALLOC_API_MSG;
struct netbuf *buf = NULL;
struct pbuf *p;
u16_t len;

LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return NULL;);

if (conn->recvmbox == SYS_MBOX_NULL) {
/* @todo: should calling netconn_recv on a TCP listen conn be fatal (ERR_CONN)?? */
/* TCP listen conns don't have a recvmbox! */
conn->err = ERR_CONN;
return NULL;
}

if (ERR_IS_FATAL(conn->err)) {
return NULL;
}

if (conn->type == NETCONN_TCP) {
#if LWIP_TCP
if (conn->state == NETCONN_LISTEN) {
/* @todo: should calling netconn_recv on a TCP listen conn be fatal?? */
conn->err = ERR_CONN;
return NULL;
}

buf = memp_malloc(MEMP_NETBUF);

if (buf == NULL) {
conn->err = ERR_MEM;
return NULL;
}

#if LWIP_SO_RCVTIMEO
if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
memp_free(MEMP_NETBUF, buf);
conn->err = ERR_TIMEOUT;
return NULL;
}
#else
sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, 0);
#endif /* LWIP_SO_RCVTIMEO*/

if (p != NULL) {
len = p->tot_len;
SYS_ARCH_DEC(conn->recv_avail, len);
} else {
len = 0;
}

/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);

/* If we are closed, we indicate that we no longer wish to use the socket */
if (p == NULL) {
memp_free(MEMP_NETBUF, buf);
/* Avoid to lose any previous error code */
if (conn->err == ERR_OK) {
conn->err = ERR_CLSD;
}
return NULL;
}

buf->p = p;
buf->ptr = p;
buf->port = 0;
buf->addr = NULL;


/* Let the stack know that we have taken the data. */
msg->function = do_recv;
msg->msg.conn = conn;
if (buf != NULL) {
msg->msg.msg.r.len = buf->p->tot_len;
} else {
msg->msg.msg.r.len = 1;
}

TCPIP_APIMSG(msg);
free(msg);
#endif /* LWIP_TCP */
} else {
#if (LWIP_UDP || LWIP_RAW)
#if LWIP_SO_RCVTIMEO
if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
buf = NULL;
}
#else
sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, 0);
#endif /* LWIP_SO_RCVTIMEO*/
if (buf!=NULL) {
SYS_ARCH_DEC(conn->recv_avail, buf->p->tot_len);
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
}
#endif /* (LWIP_UDP || LWIP_RAW) */
}

LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));

return buf;
}

Aaron Walsh
Jul 11th, 2013, 06:07 AM
Hi Travis,

Sorry but my Ethernet protocol knowledge is very small.

My application is quite simple, just 1 PC talking to 2 or 3 pcb's on a dedicated network.

I have read the UDP protocol does not guarantee to deliver data packets, is this correct for my type of network ?

Thank you.

Best regards
Aaron

Travis
Jul 11th, 2013, 11:33 PM
Hi Aaron,

Yes UDP is connectionless protocol. Pls see below for more info on TCP vs UDP

http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/

To my knowledge I think UDP is suitable for your needs. Sorry I might have missed out your important requirements.

Aaron Walsh
Jul 11th, 2013, 11:58 PM
Thank you Travis, very useful.
Best regards
Aaron