#include "nvcan.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for hardware timestamps - since Linux 2.6.30 */ #ifndef SO_TIMESTAMPING #define SO_TIMESTAMPING 37 #endif /* from #include - since Linux 2.6.30 */ #define SOF_TIMESTAMPING_SOFTWARE (1<<4) #define SOF_TIMESTAMPING_RX_SOFTWARE (1<<3) #define SOF_TIMESTAMPING_RAW_HARDWARE (1<<6) #define MAXSOCK 16 /* max. number of CAN interfaces given on the cmdline */ #define MAXIFNAMES 30 /* size of receive name index to omit ioctls */ #define MAXCOL 6 /* number of different colors for colorized output */ #define ANYDEV "any" /* name of interface to receive from any CAN interface */ #define ANL "\r\n" /* newline in ASC mode */ #define SILENT_INI 42 /* detect user setting on commandline */ #define SILENT_OFF 0 /* no silent mode */ #define SILENT_ANI 1 /* silent mode with animation */ #define SILENT_ON 2 /* silent mode (completely silent) */ #include #define BUF_SIZE 1000 std::string CANNAME[] = {"can0","can1"}; nvcan::nvcan() { // qDebug("nvcan"); // connect(this,SIGNAL(SIG_CANOPENSTATE(bool,int,const char*)),this,SLOT(onMsg(bool,int,const char*))); mfault = new iv::Ivfault("can_agx"); mivlog = new iv::Ivlog("can_agx"); } void nvcan::run() { int currmax = 2; fd_set rdfs; int s[MAXSOCK]; int ret; struct sockaddr_can addr; char ctrlmsg[CMSG_SPACE(sizeof(struct timeval) + 3*sizeof(struct timespec) + sizeof(__u32))]; struct iovec iov; struct msghdr msg; 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; for(i=0;iverbose("open can succesfully."); 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; while((!QThread::isInterruptionRequested())&&(mbCANOpen)) { FD_ZERO(&rdfs); for (i=0; ierror("%s interface down", CANNAME[i].data()); mfault->SetFaultState(1, 0, "interface down"); emit SIG_CANOPENSTATE(false,-5,"can card down"); fprintf(stderr, "%s: interface down\n", CANNAME[i].data()); return; } continue; // perror("read"); // return 1; } if ((size_t)nbytes == CAN_MTU) maxdlen = CAN_MAX_DLEN; else if ((size_t)nbytes == CANFD_MTU) maxdlen = CANFD_MAX_DLEN; else { mivlog->warn("read incomplete message"); continue; } // qDebug("receive msg."); mMutex.lock(); basecan_msg msg; msg.id = frame.can_id&0x1fffffff; if((frame.can_id&0x80000000)!= 0)msg.isExtern = true; else msg.isExtern = false; if((frame.can_id&0x40000000)!= 0)msg.isRemote = true; else msg.isRemote = false; msg.nLen = frame.len; if((frame.len<9)&&(frame.len>0))memcpy(msg.data,frame.data,frame.len); if(mMsgRecvBuf[i].size()=2500)break; memcpy(framesend[i].data,mMsgSendBuf[nch].at(i).data,8); framesend[i].can_id = mMsgSendBuf[nch].at(i).id; if(mMsgSendBuf[nch].at(i).isExtern) { framesend[i].can_id = framesend[i].can_id|0x80000000; } else { framesend[i].can_id = framesend[i].can_id&0x7ff; } if(mMsgSendBuf[nch].at(i).isRemote) { framesend[i].can_id= framesend[i].can_id|0x40000000; } framesend[i].len = mMsgSendBuf[nch].at(i).nLen; nsend++; } mMsgSendBuf[nch].clear(); mMutex.unlock(); if(nsend > 0) { for(i=0;ierror("write error 1"); perror("write error 1."); continue; } } } } for (i=0; iSetFaultState(1, 0, "can closed"); mivlog->error("can is closed at %d",xTime.elapsed()); break; } } } int nvcan::GetMessage(const int nch,basecan_msg *pMsg, const int nCap) { if((nch>1)||(nch < 0))return -1; if(mMsgRecvBuf[nch].size() == 0)return 0; int nRtn; nRtn = nCap; mMutex.lock(); if(nRtn > mMsgRecvBuf[nch].size())nRtn = mMsgRecvBuf[nch].size(); int i; for(i=0;i::iterator iter; iter = mMsgRecvBuf[nch].begin(); for(i=0;i1)||(nch < 0))return -1; if(mMsgSendBuf[nch].size() > BUF_SIZE)return -2; mMutex.lock(); mMsgSendBuf[nch].push_back(*pMsg); mMutex.unlock(); return 0; } void nvcan::onMsg(bool bCAN, int nR, const char *strres) { mivlog->verbose("msg is %s ",strres); } bool nvcan::IsOpen() { return mbCANOpen; }