28 #include <linux/can.h> 29 #include <linux/can/raw.h> 36 #include <sys/ioctl.h> 37 #include <sys/socket.h> 45 #define err_abort(code, text) \ 47 fprintf(stderr, "%s at \"%s\":%d: %s\n\r", text, __FILE__, __LINE__, strerror(code)); \ 51 #define errno_abort(text) \ 53 fprintf(stderr, "%s at \"%s\":%d: %s\n\r", text, __FILE__, __LINE__, strerror(errno)); \ 62 unsigned char buf[XCP_COMM_BUFLEN];
66 int locate_interface(
int socket,
char const* name) {
69 strcpy(ifr.ifr_name, name);
70 if (ioctl(socket, SIOCGIFINDEX, &ifr) == -1) {
71 errno_abort(
"locate_interface::ioctl()");
74 return ifr.ifr_ifindex;
77 void XcpTl_Init(
void) {
78 int enable_sockopt = 1;
80 struct sockaddr_can addr;
81 struct can_filter rfilter[2];
85 XcpTl_Connection.can_socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
86 if (XcpTl_Connection.can_socket == -1) {
87 errno_abort(
"XcpTl_Init::socket()");
90 if (setsockopt(XcpTl_Connection.can_socket, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_sockopt,
sizeof(enable_sockopt)) ==
92 errno_abort(
"Your kernel doesn't supports CAN-FD.\n\r");
96 flags = fcntl(XcpTl_Connection.can_socket, F_GETFL, 0);
98 errno_abort(
"fcntl(F_GETFL)");
101 if (fcntl(XcpTl_Connection.can_socket, F_SETFL, flags) == -1) {
102 errno_abort(
"fcntl(F_SETFL)");
105 if (setsockopt(XcpTl_Connection.can_socket, SOL_SOCKET, SO_TIMESTAMP, &enable_sockopt,
sizeof(enable_sockopt)) < 0) {
107 errno_abort(
"setsockopt(SO_TIMESTAMP)");
111 addr.can_family = AF_CAN;
112 addr.can_ifindex = locate_interface(XcpTl_Connection.can_socket, Xcp_Options.interface);
113 bind(XcpTl_Connection.can_socket, (
struct sockaddr*)&addr,
sizeof(addr));
114 if (XcpTl_Connection.can_socket == -1) {
115 errno_abort(
"XcpTl_Init::bind()");
118 rfilter[0].can_id = XCP_ON_CAN_INBOUND_IDENTIFIER;
119 rfilter[0].can_mask = XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(XCP_ON_CAN_INBOUND_IDENTIFIER) ? CAN_EFF_FLAG : CAN_SFF_MASK;
120 rfilter[1].can_id = XCP_ON_CAN_BROADCAST_IDENTIFIER;
121 rfilter[1].can_mask = XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(XCP_ON_CAN_BROADCAST_IDENTIFIER) ? CAN_EFF_FLAG : CAN_SFF_MASK;
123 setsockopt(XcpTl_Connection.can_socket, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
sizeof(rfilter));
126 void XcpTl_DeInit(
void) { close(XcpTl_Connection.can_socket); }
128 void* XcpTl_Thread(
void* param) {
129 XCP_FOREVER { XcpTl_MainFunction(); }
133 void XcpTl_MainFunction(
void) {
134 if (XcpTl_FrameAvailable(0, 1000) > 0) {
139 void XcpTl_RxHandler(
void) {
140 struct canfd_frame frame;
143 nbytes = read(XcpTl_Connection.can_socket, &frame, CANFD_MTU);
145 if (nbytes == CANFD_MTU) {
148 }
else if (nbytes == CAN_MTU) {
151 errno_abort(
"can raw socket read");
155 Xcp_CtoIn.len = frame.len;
158 XcpUtl_MemCopy(Xcp_CtoIn.data, &frame.data, frame.len);
160 Xcp_DispatchCommand(&Xcp_CtoIn);
165 void XcpTl_TxHandler(
void) {}
167 int16_t XcpTl_FrameAvailable(uint32_t sec, uint32_t usec) {
169 struct timeval timeout;
173 timeout.tv_sec = sec;
174 timeout.tv_usec = usec;
177 FD_SET(XcpTl_Connection.can_socket, &fds);
183 res = select(0, &fds, 0, 0, &timeout);
185 printf(
"sel: %d\r\n", res);
188 XcpHw_ErrorMsg(
"XcpTl_FrameAvailable:select()", errno);
196 void XcpTl_Send(uint8_t
const* buf, uint16_t len) {
197 struct can_frame frame = {0};
198 struct canfd_frame frame_fd = {0};
200 XCP_TL_ENTER_CRITICAL();
201 if (Xcp_Options.fd) {
203 frame_fd.can_id = XCP_ON_CAN_OUTBOUND_IDENTIFIER;
204 memcpy(frame_fd.data, buf, len);
205 (void)write(XcpTl_Connection.can_socket, &frame_fd,
sizeof(
struct canfd_frame));
208 frame.can_id = XCP_ON_CAN_OUTBOUND_IDENTIFIER;
209 memcpy(frame.data, buf, len);
210 (void)write(XcpTl_Connection.can_socket, &frame,
sizeof(
struct can_frame));
212 XCP_TL_LEAVE_CRITICAL();
215 void XcpTl_SaveConnection(
void) { XcpTl_Connection.connected = XCP_TRUE; }
217 void XcpTl_ReleaseConnection(
void) { XcpTl_Connection.connected = XCP_FALSE; }
219 bool XcpTl_VerifyConnection(
void) {
return XCP_TRUE; }
221 void XcpTl_PrintConnectionInformation(
void) {
222 printf(
"\n\rXCPonCan\n\r");
224 printf(
"\nXCPonCan -- Listening on port %s / %s [%s]\n\r",
226 Xcp_Options.tcp ?
"TCP" :
"UDP",
227 Xcp_Options.ipv6 ?
"IPv6" :
"IPv4"