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:[email protected]
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:[email protected]]
Sent: Friday, December 09, 2011 3:50 PM
To: Kime, James
Cc: [email protected]; [email protected]
Subject: Re: CAN State Information
On 12/09/2011 02:41 PM, [email protected] 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
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core