24 #ifndef _GNU_SOURCE // needed for asprintf to avoid warning
32 #include <linux/can/raw.h>
35 #include <semaphore.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
53 #define SOCKET_TIMEOUT 1
57 #define SOCKET_TIMEOUT_US 0
67 static void PrintCanFrame(
struct can_frame* frame);
77 static int SetupInterface(
char* InterfaceName_cp, uint32_t InterfaceBitrate_u32);
91 int ReceiverThreadShouldRunCAN_b();
106 static struct can_frame ReadFrame();
117 static sem_t socket_sem;
121 static void (*
ReadCallback)(
struct can_frame* frame) = NULL;
123 static pthread_mutex_t mutex_socket_receiver = PTHREAD_MUTEX_INITIALIZER;
125 static bool ConnectedToSocket_b =
false;
130 void RegisterReadCallback(
void (*Callback)(
struct can_frame* frame))
132 MPRINTF(
"RegisterReadCallback\n");
136 static struct can_frame ReadFrame()
138 struct can_frame frame = {0};
139 if (read(s, &frame,
sizeof(
struct can_frame)) < 0)
146 int WriteFrame(
struct can_frame* frame)
149 if (ConnectedToSocket_b)
152 if (write(s, frame,
sizeof(
struct can_frame)) !=
sizeof(
struct can_frame))
158 PrintCanFrame(frame);
162 "An attempt was made to send CAN messages via a socket that has not yet been configured.\n");
166 static void PrintCanFrame(
struct can_frame* frame)
168 MPRINTF(
"0x%03X [%d] ", frame->can_id, frame->can_dlc);
170 for (
int i = 0; i < frame->can_dlc; i++)
172 MPRINTF(
"%02X ", frame->data[i]);
177 static int SetupInterface(
char* InterfaceName_cp, uint32_t InterfaceBitrate_u32)
180 char* init_command = NULL;
181 char* down_command = NULL;
182 if (asprintf(&init_command,
"ip link set %s up type can bitrate %d dbitrate %d fd off",
183 InterfaceName_cp, InterfaceBitrate_u32, InterfaceBitrate_u32) == -1)
187 if (asprintf(&down_command,
"ifconfig %s down", InterfaceName_cp) == -1)
195 if (system(init_command) != 0)
198 "Interface Setup failed on first try.\nTrying to disable can0 interface and try "
204 if (system(down_command) == 0)
209 if (system(init_command) != 0)
227 MPRINTF(
"---------------Warning---------------\n");
229 "Current User is not root - will not attempt to configure the interface. Please take care of "
230 "proper interface setup yourself!\n");
231 MPRINTF(
"-------------------------------------\n");
237 int SetupSocket(
char* InterfaceName_cp, uint32_t InterfaceBitrate_u32)
239 MPRINTF(
"SetupSocket for interface %s / %d\n", InterfaceName_cp, InterfaceBitrate_u32);
242 MPRINTF(
"Interface setup successful\n");
246 MPRINTF(
"Interface setup failed\n");
249 struct sockaddr_can addr = {0};
252 tv.tv_sec = SOCKET_TIMEOUT;
253 tv.tv_usec = SOCKET_TIMEOUT_US;
255 if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
260 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (
const char*)&tv,
sizeof tv);
261 strncpy(ifr.ifr_name,
"can0", IFNAMSIZ);
262 ioctl(s, SIOCGIFINDEX, &ifr);
264 addr.can_family = AF_CAN;
265 addr.can_ifindex = ifr.ifr_ifindex;
267 if (bind(s, (
struct sockaddr*)&addr,
sizeof(addr)) < 0)
272 sem_init(&socket_sem, 0, 1);
274 pthread_mutex_lock(&mutex_socket_receiver);
276 pthread_mutex_unlock(&mutex_socket_receiver);
282 ConnectedToSocket_b =
true;
293 pthread_mutex_lock(&mutex_socket_receiver);
295 pthread_mutex_unlock(&mutex_socket_receiver);
302 MPRINTF(
"StartReceiverThread\n");
307 MPRINTF(
"\ncan't create thread :[%s]", strerror(err));
311 MPRINTF(
"\nCAN-Receiver Thread created successfully\n");
316 int ReceiverThreadShouldRunCAN_b()
320 pthread_mutex_lock(&mutex_socket_receiver);
322 pthread_mutex_unlock(&mutex_socket_receiver);
330 while (ReceiverThreadShouldRunCAN_b())
333 struct can_frame frame = ReadFrame();
334 if (frame.can_dlc > 0)