|
@@ -80,13 +80,15 @@ void nvcan::run()
|
|
|
struct sockaddr_can addr;
|
|
|
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval) + 3*sizeof(struct timespec) + sizeof(__u32))];
|
|
|
struct iovec iov;
|
|
|
- struct msghdr msg;
|
|
|
+ struct msghdr xmsghdr;
|
|
|
struct canfd_frame frame;
|
|
|
int nbytes, i, maxdlen;
|
|
|
struct ifreq ifr;
|
|
|
struct timeval tv, last_tv;
|
|
|
struct timeval timeout_config = { 0, 0 }, *timeout_current = 0;
|
|
|
|
|
|
+ struct cmsghdr *cmsg;
|
|
|
+
|
|
|
mfault->SetFaultState(0,0,"Initializing.");
|
|
|
|
|
|
for(i=0;i<currmax;i++)
|
|
@@ -113,6 +115,13 @@ void nvcan::run()
|
|
|
//CANFD Support
|
|
|
setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));
|
|
|
|
|
|
+ const int timestamp_on = 1;
|
|
|
+
|
|
|
+ if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMP,
|
|
|
+ ×tamp_on, sizeof(timestamp_on)) < 0) {
|
|
|
+ perror("setsockopt SO_TIMESTAMP");
|
|
|
+ }
|
|
|
+
|
|
|
if (bind(s[i], (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
|
|
mfault->SetFaultState(2,3,"bind error.");
|
|
|
emit SIG_CANOPENSTATE(false,-3,"bind error");
|
|
@@ -126,10 +135,10 @@ void nvcan::run()
|
|
|
emit SIG_CANOPENSTATE(true,0,"open can card successfully");
|
|
|
|
|
|
iov.iov_base = &frame;
|
|
|
- msg.msg_name = &addr;
|
|
|
- msg.msg_iov = &iov;
|
|
|
- msg.msg_iovlen = 1;
|
|
|
- msg.msg_control = &ctrlmsg;
|
|
|
+ xmsghdr.msg_name = &addr;
|
|
|
+ xmsghdr.msg_iov = &iov;
|
|
|
+ xmsghdr.msg_iovlen = 1;
|
|
|
+ xmsghdr.msg_control = &ctrlmsg;
|
|
|
|
|
|
qint64 nLastRecv = QDateTime::currentMSecsSinceEpoch();
|
|
|
int nRecvState = 0; // 0 Have Data 1 No Data;
|
|
@@ -165,11 +174,11 @@ void nvcan::run()
|
|
|
nLastRecv = QDateTime::currentMSecsSinceEpoch();
|
|
|
/* these settings may be modified by recvmsg() */
|
|
|
iov.iov_len = sizeof(frame);
|
|
|
- msg.msg_namelen = sizeof(addr);
|
|
|
- msg.msg_controllen = sizeof(ctrlmsg);
|
|
|
- msg.msg_flags = 0;
|
|
|
+ xmsghdr.msg_namelen = sizeof(addr);
|
|
|
+ xmsghdr.msg_controllen = sizeof(ctrlmsg);
|
|
|
+ xmsghdr.msg_flags = 0;
|
|
|
|
|
|
- nbytes = recvmsg(s[i], &msg, 0);
|
|
|
+ nbytes = recvmsg(s[i], &xmsghdr, 0);
|
|
|
|
|
|
if (nbytes < 0) {
|
|
|
// if ((errno == ENETDOWN) && !down_causes_exit) {
|
|
@@ -207,6 +216,37 @@ void nvcan::run()
|
|
|
msg.nLen = frame.len;
|
|
|
// if(msg.id == 0x1c2)qDebug("id = %08x",msg.id);
|
|
|
if((frame.len<=64)&&(frame.len>0))memcpy(msg.data,frame.data,frame.len);
|
|
|
+
|
|
|
+ msg.frecvtime = 0.0;
|
|
|
+ for (cmsg = CMSG_FIRSTHDR(&xmsghdr);
|
|
|
+ cmsg && (cmsg->cmsg_level == SOL_SOCKET);
|
|
|
+ cmsg = CMSG_NXTHDR(&xmsghdr,cmsg)) {
|
|
|
+ if (cmsg->cmsg_type == SO_TIMESTAMP) {
|
|
|
+ memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
|
|
|
+ } else if (cmsg->cmsg_type == SO_TIMESTAMPING) {
|
|
|
+
|
|
|
+ struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * stamp[0] is the software timestamp
|
|
|
+ * stamp[1] is deprecated
|
|
|
+ * stamp[2] is the raw hardware timestamp
|
|
|
+ * See chapter 2.1.2 Receive timestamps in
|
|
|
+ * linux/Documentation/networking/timestamping.txt
|
|
|
+ */
|
|
|
+ tv.tv_sec = stamp[2].tv_sec;
|
|
|
+ tv.tv_usec = stamp[2].tv_nsec/1000;
|
|
|
+
|
|
|
+ msg.frecvtime = tv.tv_usec;
|
|
|
+ msg.frecvtime = tv.tv_usec/((double)1e6);
|
|
|
+ msg.frecvtime = tv.tv_sec + msg.frecvtime;
|
|
|
+ std::cout<<" set frecvtime."<<std::endl;
|
|
|
+
|
|
|
+ } else if (cmsg->cmsg_type == SO_RXQ_OVFL)
|
|
|
+ std::cout<<" type is SO_RXQ_OVFL"<<std::endl;
|
|
|
+ // memcpy(&dropcnt[i], CMSG_DATA(cmsg), sizeof(__u32));
|
|
|
+ }
|
|
|
+
|
|
|
if(mMsgRecvBuf[i].size()<BUF_SIZE)
|
|
|
{
|
|
|
mMsgRecvBuf[i].push_back(msg);
|