87 lines
1.8 KiB
C
87 lines
1.8 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <hexagram/can.h>
|
|
|
|
struct _hexagram_can_if {
|
|
struct sockaddr_can addr;
|
|
struct ifreq ifr;
|
|
int sock;
|
|
};
|
|
|
|
hexagram_can_if *hexagram_can_if_open(const char *name) {
|
|
hexagram_can_if *can_if;
|
|
|
|
if (name == NULL) {
|
|
errno = EINVAL;
|
|
|
|
goto error_no_name;
|
|
}
|
|
|
|
if ((can_if = malloc(sizeof(*can_if))) == NULL) {
|
|
goto error_malloc;
|
|
}
|
|
|
|
if ((can_if->sock = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
|
|
goto error_socket;
|
|
}
|
|
|
|
strcpy(can_if->ifr.ifr_name, name);
|
|
|
|
if (ioctl(can_if->sock, SIOCGIFINDEX, &can_if->ifr) < 0) {
|
|
goto error_ioctl_siocgifindex;
|
|
}
|
|
|
|
memset(&can_if->addr, '\0', sizeof(can_if->addr));
|
|
|
|
can_if->addr.can_family = AF_CAN;
|
|
can_if->addr.can_ifindex = can_if->ifr.ifr_ifindex;
|
|
|
|
if (bind(can_if->sock, (struct sockaddr *)&can_if->addr, sizeof(struct sockaddr)) < 0) {
|
|
goto error_bind;
|
|
}
|
|
|
|
return can_if;
|
|
|
|
error_bind:
|
|
error_ioctl_siocgifindex:
|
|
close(can_if->sock);
|
|
|
|
error_socket:
|
|
free(can_if);
|
|
|
|
error_malloc:
|
|
error_no_name:
|
|
return NULL;
|
|
}
|
|
|
|
void hexagram_can_if_close(hexagram_can_if *can_if) {
|
|
close(can_if->sock);
|
|
|
|
free(can_if);
|
|
}
|
|
|
|
int hexagram_can_if_read(hexagram_can_if *can_if,
|
|
struct can_frame *frame) {
|
|
return read(can_if->sock, frame, sizeof(*frame));
|
|
}
|
|
|
|
int hexagram_can_if_write(hexagram_can_if *can_if,
|
|
struct can_frame *frame) {
|
|
return write(can_if->sock, frame, sizeof(*frame));
|
|
}
|
|
|
|
int hexagram_can_if_fd(hexagram_can_if *can_if) {
|
|
return can_if->sock;
|
|
}
|
|
|
|
void hexagram_can_if_fd_set(hexagram_can_if *can_if, fd_set *fds) {
|
|
FD_SET(can_if->sock, fds);
|
|
}
|
|
|
|
int hexagram_can_if_fd_isset(hexagram_can_if *can_if, fd_set *fds) {
|
|
return FD_ISSET(can_if->sock, fds);
|
|
}
|