// Good packet, so call the packet handling function.
comm_udp_rx_packet(rx_header, g->data2); // g->data2 points to the data
part in the udp datagram
}
}
// The whole UDP RX traffic is handled in this function,
// so I don't add any data to the socket buffer for future use
return 1;
}
---=== Some info from the documentation ===---
Callback function parameters:
Event:
UDP_DH_INDATA - Normal received data
UDP_DH_ICMPMSG - ICMP message received for this socket
ll_Gather: (documented in NET.LIB)
typedef struct {
byte iface; // Destination interface
byte spare;
word len1; // Length of root data section
void * data1; // UDP header
word len2; // Length of first xmem section
long data2; // UDP data - xmem physical address
word len3; // Length of second xmem section
long data3; // not used
} ll_Gather;
_udp_datagram_info: (documented in udp_peek)
typedef struct {
longword remip; // Remote host IP address
word remport; // Remote host port number
int len; // Length of datagram
byte flags; // Bit mask (defined below)
byte iface; // Interface number
} _udp_datagram_info;
The flags field may have one of the following values:
UDI_ICMP_ERROR - This is an ICMP error entry.
UDI_TOS_MASK - Type-of-service bit mask.
UDI_BROADCAST_LL - Received on broadcast link layer address.
UDI_BROADCAST_IP - Received on broadcast network (IP) address.
This callback function should return:
0 - to continue with normal processing (i.e., add the datagram to the socket
buffer)
1 - to indicate that the datagram has been processed and should not be added
to the socket buffer
Reply by Steve Trigero●July 31, 20122012-07-31
The function udp_recvfrom() stuffs the ip and port values from the received
datagram
into the ip and port function arguments. That way, if the message requires a
response
I can respond to the specific ip and port of the host device.
steve
From: Jeff Powell >To: r...
>Sent: Tuesday, July 31, 2012 2:01 PM
>Subject: Re: [rabbit-semi] Help with UDP data handler
>
>Thanks that's a good idea. I may deploy this approach in my application.
Could you tell me how you are getting the remote IP and PORT for the recvfrom
call?
>
>Thanks.
>On 07/31/2012 12:29 PM, Steve Trigero wrote:
>
>
>>I can't tell you what you might doing wrong, but I can offer
>>some suggestions based on how I did something similar.
>>I did not use the callback feature. It seems to me there are
>>too many messages flying around to use this feature reliably.
>>
>>I open several UDP sockets listening for broadcast messages.
>>
>> for(i=0;i
>> udp_extopen(&udpcon[i].socket,
>> IF_DEFAULT,
>> UDP_BROADCAST_PORT,
>> -1,-1,NULL,0,0);
>> }
>>In the main loop I call a function that checks each socket for
>>a received message. If a message with data is found, the data
>>is copied to a buffer and passed to a paring routine.
>>
>>// Look for incoming packets. for( s=0;s
>>UdpParse( &udpcon[s]);
>>}
>>
>>Occasionally, my program sends its own broadcast status.
>>When it does, it opens a UDP port, sends the message, then
>>closes the port.
>>
>>// Open a Broadcast socket if( !udp_extopen( &udpsock.socket, IF_DEFAULT,
UDP_BROADCAST_PORT-1, -1, UDP_BROADCAST_PORT, NULL, 0, 0) ) return;// Oops! //
Build a status message FormatUDPStatusMsg( udpsock.buf); // Send it... udp_send(
&udpsock.socket, udpsock.buf, strlen(udpsock.buf) ); udp_close(
&udpsock.socket);
>>
>>This works well in our system.
>>
>>>
>>>From: Jeff Powell mailto:j...@yahoo.com
>>>To: r...
>>>Sent: Monday, July 30, 2012 8:57 AM
>>>Subject: [rabbit-semi] Help with UDP data handler
>>>
>>>
>>>
>>>I posted this as part of a different question and nobody answered so I
>>>will try again as it's own topic.
>>>
>>>I have opened a udp socket with a datahandler.
>>>I opened a second udp socket for sending multicast data when values
change.
>>>I get a connection, read from client, write back to client.
>>>I get another connection. It does not go to the datahandler.
>>>The main loop runs and multicast data continues to send properly.
>>>
>>>What am I missing?
>>>
>>>-- code --
>>>if (!udp_open(&tsock, LOCAL_PORT, 0, 0, dataHandler))
>>>{
>>>printf("udp_lst_open failed!\n");
>>>exit(0);
>>>}
>>>else
>>>{
>>>printf("Listener %s:%d\n",MY_IP_ADDRESS,LOCAL_PORT);
>>>}
>>>if (!udp_open(&usock, MBUS_PORT, resolve(MBUS_ADDRESS), MBUS_PORT,
>>>NULL))
>>>{
>>>printf("udp_open failed!\n");
>>>exit(0);
>>>}
>>>
>>>...
>>>
>>>while (1)
>>>{
>>>idleProcessing(); // where values are processed and
>>>multicast data is sent as needed.
>>>tcp_tick(NULL);
>>>}
>>>
>>>...
>>>
>>>int dataHandler(int event, udp_Socket *s, ll_Gather *g,
>>>_udp_datagram_info *udi)
>>>{
>>>int status;
>>>char cip[20];
>>>CARDMSG_S *pkt;
>>>if(handleUdp) // stops recursion, does not effect
>>>handler death
>>>return 1;
>>>handleUdp=1;
>>>if(event == UDP_DH_ICMPMSG) // from the example
>>>{
>>>return 1;
>>>}
>>>memset(&replyMsg, 0, sizeof (REPLYMSG_S));
>>>xmem2root(pktbuf, g->data2, g->len2);
>>>if(g->len3>0)
>>>xmem2root(pktbuf+g->len2, g->data3, g->len3);
>>>pkt=(CARDMSG_S*) &pktbuf;
>>>inet_ntoa( cip, udi->remip);
>>>printf("%s:%u Slot %d Type %d Device %d Offset %x Width %x Data %lx
>>>%lx\n", cip, udi->remport, pkt->cSlot, pkt->cOperation, pkt->cDevice,
>>>pkt->cOffset, pkt->cDataWidth, pkt->sData.longs[1], pkt->sData.longs[0] );
>>>status = process_packet(pktbuf);
>>>replyMsg.eStatus = status;
>>>printf("Status: %x\n", status);
>>>udp_sendto(s, (char*) &replyMsg, sizeof(REPLYMSG_S), udi->remip,
>>>udi->remport); // straight from the
>>>// even tried this but it does not help either. Returns 1 for NULL or
>>>bytes recv'd for the incoming socket.
>>>printf("Sent response %u\n", tcp_tick(NULL));
>>>handleUdp=0;
>>>return 1;
>>>}
>>>
>>>
>>>
>>>
Reply by Jeff Powell●July 31, 20122012-07-31
Thanks that's a good idea. I may deploy this approach in my application.
Could you tell me how you are getting the remote IP and PORT for the
recvfrom call?
Thanks.
On 07/31/2012 12:29 PM, Steve Trigero wrote: > I can't tell you what you might doing wrong, but
I can offer
> some suggestions based on how I did something similar.
> I did not use the callback feature. It seems to me there are
> too many messages flying around to use this feature reliably.
> I open several UDP sockets listening for broadcast messages.
> for(i=0;i
> udp_extopen(&udpcon[i].socket,
> IF_DEFAULT,
> UDP_BROADCAST_PORT,
> -1,-1,NULL,0,0);
> }
> In the main loop I call a function that checks each socket for
> a received message. If a message with data is found, the data
> is copied to a buffer and passed to a paring routine.
> // Look for incoming packets.
> for (s=0; s
>
> if (!udp_peek(&udpcon[s].socket,NULL ) ){
> continue; // No packets...
> }
>
> numBytes = udp_recvfrom(&udpcon[s].socket,
> udpcon[s].buf,
> sizeof(udpcon[s].buf),
> &udpcon[s].ip,
> &udpcon[s].port );
> if (numBytes < 1 ){
> continue; // No data...
> }
> udpcon[s].buf[numBytes] = NUL;
> UdpParse(&udpcon[s] );
> }
> Occasionally, my program sends its own broadcast status.
> When it does, it opens a UDP port, sends the message, then
> closes the port.
> // Open a Broadcast socket
> if (!udp_extopen(&udpsock.socket,IF_DEFAULT,UDP_BROADCAST_PORT-1,
> -1,UDP_BROADCAST_PORT,NULL,0,0 ) )
> return; // Oops!
>
> // Build a status message
> FormatUDPStatusMsg(udpsock.buf );
>
> // Send it...
> udp_send(&udpsock.socket,udpsock.buf,strlen(udpsock.buf) );
> udp_close(&udpsock.socket );
> This works well in our system.
>
> *From:* Jeff Powell
> *To:* r...
> *Sent:* Monday, July 30, 2012 8:57 AM
> *Subject:* [rabbit-semi] Help with UDP data handler
>
> I posted this as part of a different question and nobody answered
> so I
> will try again as it's own topic.
>
> I have opened a udp socket with a datahandler.
> I opened a second udp socket for sending multicast data when
> values change.
> I get a connection, read from client, write back to client.
> I get another connection. It does not go to the datahandler.
> The main loop runs and multicast data continues to send properly.
>
> What am I missing?
>
> -- code --
> if (!udp_open(&tsock, LOCAL_PORT, 0, 0, dataHandler))
> {
> printf("udp_lst_open failed!\n");
> exit(0);
> }
> else
> {
> printf("Listener %s:%d\n",MY_IP_ADDRESS,LOCAL_PORT);
> }
> if (!udp_open(&usock, MBUS_PORT, resolve(MBUS_ADDRESS), MBUS_PORT,
> NULL))
> {
> printf("udp_open failed!\n");
> exit(0);
> }
>
> ...
>
> while (1)
> {
> idleProcessing(); // where values are processed and
> multicast data is sent as needed.
> tcp_tick(NULL);
> }
>
> ...
>
> int dataHandler(int event, udp_Socket *s, ll_Gather *g,
> _udp_datagram_info *udi)
> {
> int status;
> char cip[20];
> CARDMSG_S *pkt;
> if(handleUdp) // stops recursion, does not effect
> handler death
> return 1;
> handleUdp=1;
> if(event == UDP_DH_ICMPMSG) // from the example
> {
> return 1;
> }
> memset(&replyMsg, 0, sizeof (REPLYMSG_S));
> xmem2root(pktbuf, g->data2, g->len2);
> if(g->len3>0)
> xmem2root(pktbuf+g->len2, g->data3, g->len3);
> pkt=(CARDMSG_S*) &pktbuf;
> inet_ntoa( cip, udi->remip);
> printf("%s:%u Slot %d Type %d Device %d Offset %x Width %x Data %lx
> %lx\n", cip, udi->remport, pkt->cSlot, pkt->cOperation, pkt->cDevice,
> pkt->cOffset, pkt->cDataWidth, pkt->sData.longs[1],
> pkt->sData.longs[0] );
> status = process_packet(pktbuf);
> replyMsg.eStatus = status;
> printf("Status: %x\n", status);
> udp_sendto(s, (char*) &replyMsg, sizeof(REPLYMSG_S), udi->remip,
> udi->remport); // straight from the
> // even tried this but it does not help either. Returns 1 for NULL or
> bytes recv'd for the incoming socket.
> printf("Sent response %u\n", tcp_tick(NULL));
> handleUdp=0;
> return 1;
> }
Reply by Steve Trigero●July 31, 20122012-07-31
I can't tell you what you might doing wrong, but I can offer
some suggestions based on how I did something similar.
I did not use the callback feature. It seems to me there are
too many messages flying around to use this feature reliably.
I open several UDP sockets listening for broadcast messages.
In the main loop I call a function that checks each socket for
a received message. If a message with data is found, the data
is copied to a buffer and passed to a paring routine.
// Look for incoming packets. for( s=0;s
UdpParse( &udpcon[s]);
}
Occasionally, my program sends its own broadcast status.
When it does, it opens a UDP port, sends the message, then
closes the port.
// Open a Broadcast socket if( !udp_extopen( &udpsock.socket, IF_DEFAULT,
UDP_BROADCAST_PORT-1, -1, UDP_BROADCAST_PORT, NULL, 0, 0) ) return;// Oops! //
Build a status message FormatUDPStatusMsg( udpsock.buf); // Send it... udp_send(
&udpsock.socket, udpsock.buf, strlen(udpsock.buf) ); udp_close(
&udpsock.socket);
This works well in our system.
>From: Jeff Powell
>To: r...
>Sent: Monday, July 30, 2012 8:57 AM
>Subject: [rabbit-semi] Help with UDP data handler
>
>I posted this as part of a different question and nobody answered so I
>will try again as it's own topic.
>
>I have opened a udp socket with a datahandler.
>I opened a second udp socket for sending multicast data when values change.
>I get a connection, read from client, write back to client.
>I get another connection. It does not go to the datahandler.
>The main loop runs and multicast data continues to send properly.
>
>What am I missing?
>
>-- code --
>if (!udp_open(&tsock, LOCAL_PORT, 0, 0, dataHandler))
>{
>printf("udp_lst_open failed!\n");
>exit(0);
>}
>else
>{
>printf("Listener %s:%d\n",MY_IP_ADDRESS,LOCAL_PORT);
>}
>if (!udp_open(&usock, MBUS_PORT, resolve(MBUS_ADDRESS), MBUS_PORT,
>NULL))
>{
>printf("udp_open failed!\n");
>exit(0);
>}
>
>...
>
>while (1)
>{
>idleProcessing(); // where values are processed and
>multicast data is sent as needed.
>tcp_tick(NULL);
>}
>
>...
>
>int dataHandler(int event, udp_Socket *s, ll_Gather *g,
>_udp_datagram_info *udi)
>{
>int status;
>char cip[20];
>CARDMSG_S *pkt;
>if(handleUdp) // stops recursion, does not effect
>handler death
>return 1;
>handleUdp=1;
>if(event == UDP_DH_ICMPMSG) // from the example
>{
>return 1;
>}
>memset(&replyMsg, 0, sizeof (REPLYMSG_S));
>xmem2root(pktbuf, g->data2, g->len2);
>if(g->len3>0)
>xmem2root(pktbuf+g->len2, g->data3, g->len3);
>pkt=(CARDMSG_S*) &pktbuf;
>inet_ntoa( cip, udi->remip);
>printf("%s:%u Slot %d Type %d Device %d Offset %x Width %x Data %lx
>%lx\n", cip, udi->remport, pkt->cSlot, pkt->cOperation, pkt->cDevice,
>pkt->cOffset, pkt->cDataWidth, pkt->sData.longs[1], pkt->sData.longs[0] );
>status = process_packet(pktbuf);
>replyMsg.eStatus = status;
>printf("Status: %x\n", status);
>udp_sendto(s, (char*) &replyMsg, sizeof(REPLYMSG_S), udi->remip,
>udi->remport); // straight from the
>// even tried this but it does not help either. Returns 1 for NULL or
>bytes recv'd for the incoming socket.
>printf("Sent response %u\n", tcp_tick(NULL));
>handleUdp=0;
>return 1;
>}
>
Reply by Jeff Powell●July 30, 20122012-07-30
I posted this as part of a different question and nobody answered so I
will try again as it's own topic.
I have opened a udp socket with a datahandler.
I opened a second udp socket for sending multicast data when values change.
I get a connection, read from client, write back to client.
I get another connection. It does not go to the datahandler.
The main loop runs and multicast data continues to send properly.