Here is the patch.  It polls for messages at the end of the loop and repeats if 
needed.

diff -Naur b/libsocketcan.c a/libsocketcan.c
--- b/libsocketcan.c    2010-02-14 20:22:15.000000000 +0100
+++ a/libsocketcan.c    2011-12-12 11:10:40.000000000 +0100
@@ -32,6 +32,7 @@
 
 #include <linux/rtnetlink.h>
 #include <linux/netlink.h>
+#include <poll.h>
 
 #include <libsocketcan.h>
 
@@ -322,6 +323,13 @@
        char nlbuf[1024 * 8];
 
        int ret = -1;
+       int repeat = 0;
+
+       struct pollfd poll_msg = {
+               .fd = fd,
+               .events = 0x0001,
+               .revents = 0,
+       };
 
        struct iovec iov = {
                .iov_base = (void *)nlbuf,
@@ -352,126 +360,142 @@
                perror("Receive error");
                return ret;
        }
-       size_t u_msglen = (size_t) msglen;
-       /* Check to see if the buffers in msg get truncated */
-       if (msg.msg_namelen != sizeof(peer) ||
-           (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
-               fprintf(stderr, "Uhoh... truncated message.\n");
-               return ret;
-       }
-
-       for (nl_msg = (struct nlmsghdr *)nlbuf;
-            NLMSG_OK(nl_msg, u_msglen);
-            nl_msg = NLMSG_NEXT(nl_msg, u_msglen)) {
-               int type = nl_msg->nlmsg_type;
-               int len;
-               if (type != RTM_NEWLINK)
-                       continue;
-
-               struct ifinfomsg *ifi = NLMSG_DATA(nl_msg);
-               struct rtattr *tb[IFLA_MAX + 1];
-
-               len =
-                   nl_msg->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
-               parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-
-               if (strncmp
-                   ((char *)RTA_DATA(tb[IFLA_IFNAME]), name,
-                    sizeof(name)) != 0)
-                       continue;
-
-               if (tb[IFLA_LINKINFO])
-                       parse_rtattr_nested(linkinfo,
-                                           IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
-               else
-                       continue;
 
-               if (!linkinfo[IFLA_INFO_DATA]) {
-                       fprintf(stderr, "no link data found\n");
+    while(repeat == 0){
+               size_t u_msglen = (size_t) msglen;
+               /* Check to see if the buffers in msg get truncated */
+               if (msg.msg_namelen != sizeof(peer) ||
+                       (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
+                       fprintf(stderr, "Uhoh... truncated message.\n");
                        return ret;
                }
 
-               parse_rtattr_nested(can_attr, IFLA_CAN_MAX,
-                                   linkinfo[IFLA_INFO_DATA]);
-
-               switch (acquire) {
-               case GET_STATE:
-                       if (can_attr[IFLA_CAN_STATE]) {
-                               *((int *)res) = *((__u32 *)
-                                                 RTA_DATA(can_attr
-                                                          [IFLA_CAN_STATE]));
-                               ret = 0;
-                       } else {
-                               fprintf(stderr, "no state data found\n");
+               for (nl_msg = (struct nlmsghdr *)nlbuf;
+                       NLMSG_OK(nl_msg, u_msglen);
+                       nl_msg = NLMSG_NEXT(nl_msg, u_msglen)) {
+
+                       int type = nl_msg->nlmsg_type;
+                       int len;
+                       if (type != RTM_NEWLINK)
+                               continue;
+
+
+                       struct ifinfomsg *ifi = NLMSG_DATA(nl_msg);
+                       struct rtattr *tb[IFLA_MAX + 1];
+
+                       len =
+                               nl_msg->nlmsg_len - NLMSG_LENGTH(sizeof(struct 
ifaddrmsg));
+                       parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+                       if (strncmp
+                               ((char *)RTA_DATA(tb[IFLA_IFNAME]), name,
+                                sizeof(name)) != 0) {
+                               continue;
+                       }
+                       if (tb[IFLA_LINKINFO])
+                               parse_rtattr_nested(linkinfo,
+                                                       IFLA_INFO_MAX, 
tb[IFLA_LINKINFO]);
+                       else
+                               continue;
+
+                       if (!linkinfo[IFLA_INFO_DATA]) {
+                               fprintf(stderr, "no link data found\n");
+                               return ret;
                        }
 
-                       break;
-               case GET_RESTART_MS:
-                       if (can_attr[IFLA_CAN_RESTART_MS]) {
-                               *((__u32 *) res) = *((__u32 *)
-                                                    RTA_DATA(can_attr
-                                                             
[IFLA_CAN_RESTART_MS]));
-                               ret = 0;
-                       } else
-                               fprintf(stderr, "no restart_ms data found\n");
-
-                       break;
-               case GET_BITTIMING:
-                       if (can_attr[IFLA_CAN_BITTIMING]) {
-                               memcpy(res,
-                                      RTA_DATA(can_attr[IFLA_CAN_BITTIMING]),
-                                      sizeof(struct can_bittiming));
-                               ret = 0;
-                       } else
-                               fprintf(stderr, "no bittiming data found\n");
-
-                       break;
-               case GET_CTRLMODE:
-                       if (can_attr[IFLA_CAN_CTRLMODE]) {
-                               memcpy(res,
-                                      RTA_DATA(can_attr[IFLA_CAN_CTRLMODE]),
-                                      sizeof(struct can_ctrlmode));
-                               ret = 0;
-                       } else
-                               fprintf(stderr, "no ctrlmode data found\n");
-
-                       break;
-               case GET_CLOCK:
-                       if (can_attr[IFLA_CAN_CLOCK]) {
-                               memcpy(res,
-                                      RTA_DATA(can_attr[IFLA_CAN_CLOCK]),
-                                      sizeof(struct can_clock));
-                               ret = 0;
-                       } else
-                               fprintf(stderr,
-                                       "no clock parameter data found\n");
+                       parse_rtattr_nested(can_attr, IFLA_CAN_MAX,
+                                               linkinfo[IFLA_INFO_DATA]);
+
+                       switch (acquire) {
+                       case GET_STATE:
+                               if (can_attr[IFLA_CAN_STATE]) {
+                                       *((int *)res) = *((__u32 *)
+                                                         RTA_DATA(can_attr
+                                                                  
[IFLA_CAN_STATE]));
+                                       ret = 0;
+                               } else {
+                                       fprintf(stderr, "no state data 
found\n");
+                               }
 
-                       break;
-               case GET_BITTIMING_CONST:
-                       if (can_attr[IFLA_CAN_BITTIMING_CONST]) {
-                               memcpy(res,
-                                      
RTA_DATA(can_attr[IFLA_CAN_BITTIMING_CONST]),
-                                      sizeof(struct can_bittiming_const));
-                               ret = 0;
-                       } else
-                               fprintf(stderr, "no bittiming_const data 
found\n");
-
-                       break;
-               case GET_BERR_COUNTER:
-                       if (can_attr[IFLA_CAN_BERR_COUNTER]) {
-                               memcpy(res,
-                                      
RTA_DATA(can_attr[IFLA_CAN_BERR_COUNTER]),
-                                      sizeof(struct can_berr_counter));
-                               ret = 0;
-                       } else
-                               fprintf(stderr, "no berr_counter data found\n");
+                               break;
+                       case GET_RESTART_MS:
+                               if (can_attr[IFLA_CAN_RESTART_MS]) {
+                                       *((__u32 *) res) = *((__u32 *)
+                                                                
RTA_DATA(can_attr
+                                                                         
[IFLA_CAN_RESTART_MS]));
+                                       ret = 0;
+                               } else
+                                       fprintf(stderr, "no restart_ms data 
found\n");
+
+                               break;
+                       case GET_BITTIMING:
+                               if (can_attr[IFLA_CAN_BITTIMING]) {
+                                       memcpy(res,
+                                                  
RTA_DATA(can_attr[IFLA_CAN_BITTIMING]),
+                                                  sizeof(struct 
can_bittiming));
+                                       ret = 0;
+                               } else
+                                       fprintf(stderr, "no bittiming data 
found\n");
+
+                               break;
+                       case GET_CTRLMODE:
+                               if (can_attr[IFLA_CAN_CTRLMODE]) {
+                                       memcpy(res,
+                                                  
RTA_DATA(can_attr[IFLA_CAN_CTRLMODE]),
+                                                  sizeof(struct can_ctrlmode));
+                                       ret = 0;
+                               } else
+                                       fprintf(stderr, "no ctrlmode data 
found\n");
+
+                               break;
+                       case GET_CLOCK:
+                               if (can_attr[IFLA_CAN_CLOCK]) {
+                                       memcpy(res,
+                                                  
RTA_DATA(can_attr[IFLA_CAN_CLOCK]),
+                                                  sizeof(struct can_clock));
+                                       ret = 0;
+                               } else
+                                       fprintf(stderr,
+                                               "no clock parameter data 
found\n");
+
+                               break;
+                       case GET_BITTIMING_CONST:
+                               if (can_attr[IFLA_CAN_BITTIMING_CONST]) {
+                                       memcpy(res,
+                                                  
RTA_DATA(can_attr[IFLA_CAN_BITTIMING_CONST]),
+                                                  sizeof(struct 
can_bittiming_const));
+                                       ret = 0;
+                               } else
+                                       fprintf(stderr, "no bittiming_const 
data found\n");
+
+                               break;
+                       case GET_BERR_COUNTER:
+                               if (can_attr[IFLA_CAN_BERR_COUNTER]) {
+                                       memcpy(res,
+                                                  
RTA_DATA(can_attr[IFLA_CAN_BERR_COUNTER]),
+                                                  sizeof(struct 
can_berr_counter));
+                                       ret = 0;
+                               } else
+                                       fprintf(stderr, "no berr_counter data 
found\n");
 
-                       break;
+                               break;
 
-               default:
-                       fprintf(stderr, "unknown acquire mode\n");
+                       default:
+                               fprintf(stderr, "unknown acquire mode\n");
+                       }
                }
-       }
+
+               if((poll(&poll_msg,1,1))>0) {
+                       msglen = recvmsg(fd, &msg, 0);
+                       if (msglen <= 0) {
+                               perror("Receive error");
+                               return -1;
+                       }
+               }
+               else {
+                       repeat = 1;
+               }
+       }  //while(repeat == 0)
        return ret;
 }

Mit freundlichen Grüssen / Yours sincerely,

James Kime
Entwicklung / Development
--------------------------------------------
IXXAT Automation GmbH
Leibnizstr. 15, 88250 Weingarten, Germany
Phone +49-751-56146-181
Fax   +49-751-56146-29
mailto:k...@ixxat.de
http://www.ixxat.de
--------------------------------------------
PRIVILEGED AND CONFIDENTIAL.
Any unauthorized use or disclosure
is strictly prohibited.
--------------------------------------------
Sitz der Gesellschaft: Weingarten
Handelsregister Ulm HRB 551905
Geschäftsführer:
Dipl.-Ing. Christian Schlegel
--------------------------------------------


-----Original Message-----
From: Wolfgang Grandegger [mailto:w...@grandegger.com] 
Sent: Friday, December 09, 2011 3:50 PM
To: Kime, James
Cc: socketcan-core@lists.berlios.de; linux-...@vger.kernel.org
Subject: Re: CAN State Information

On 12/09/2011 02:41 PM, k...@ixxat.de wrote:
> I noticed that when libsocketcan calls send_dump_request() it returns a 
> message for me that has a length of 3424 with recvmsg().  This is not the 
> full message, if I add a loop into the routine to again receive, I receive a 
> second message this time with a length of 1424.  I added some prints into the 
> routine to output strings and sizes:
> 
> First read:
> nl_msg:-1073753668  u_msglen:3424
> lo
> nl_msg:-1073752676  u_msglen:2432
> eth0
> nl_msg:-1073751668  u_msglen:1424
> can0
> nl_msg:-1073750956  u_msglen:712
> can1
> 
> Second read:
> nl_msg:-1073753668  u_msglen:1424
> can2
> nl_msg:-1073752956  u_msglen:712
> can3
> 
> With this loop, it seems to work.  Does this make sense?

Yes, could you send a patch (showing your modifications)?

Wolfgang.
_______________________________________________
Socketcan-core mailing list
Socketcan-core@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/socketcan-core

Reply via email to