38 #define LELY_IO_IFREQ_DOMAIN AF_CAN 39 #define LELY_IO_IFREQ_TYPE SOCK_RAW 40 #define LELY_IO_IFREQ_PROTOCOL CAN_RAW 44 #ifndef LELY_IO_CAN_TXLEN 45 #define LELY_IO_CAN_TXLEN 128 50 static int io_can_ctrl_impl_stopped(
const io_can_ctrl_t *ctrl);
52 static int io_can_ctrl_impl_get_bitrate(
54 static int io_can_ctrl_impl_set_bitrate(
56 static int io_can_ctrl_impl_get_state(
const io_can_ctrl_t *ctrl);
60 &io_can_ctrl_impl_stop,
61 &io_can_ctrl_impl_stopped,
62 &io_can_ctrl_impl_restart,
63 &io_can_ctrl_impl_get_bitrate,
64 &io_can_ctrl_impl_set_bitrate,
65 &io_can_ctrl_impl_get_state
72 char name[IF_NAMESIZE];
80 io_can_ctrl_alloc(
void)
84 return impl ? &impl->ctrl_vptr : NULL;
88 io_can_ctrl_free(
void *ptr)
91 free(io_can_ctrl_impl_from_ctrl(ptr));
95 io_can_ctrl_init(
io_can_ctrl_t *ctrl,
unsigned int index,
size_t txlen)
102 impl->ctrl_vptr = &io_can_ctrl_impl_vtbl;
106 memset(impl->name, 0, IF_NAMESIZE);
107 if (!if_indextoname(impl->index, impl->name))
111 if (io_can_attr_get(&attr, impl->index) == -1)
114 impl->flags = attr.flags;
116 if (io_if_set_txqlen(ARPHRD_CAN, impl->index, txlen) == -1)
131 unsigned int index = if_nametoindex(name);
158 io_can_ctrl_free((
void *)ctrl);
168 io_can_ctrl_fini(ctrl);
169 io_can_ctrl_free((
void *)ctrl);
203 return ifr_set_flags(impl->name, &flags, IFF_UP);
211 int flags = ifr_get_flags(impl->name);
212 return flags == -1 ? -1 : !(flags & IFF_UP);
221 return ifr_set_flags(impl->name, &flags, IFF_UP);
225 io_can_ctrl_impl_get_bitrate(
231 if (io_can_attr_get(&attr, impl->index) == -1)
235 *pnominal = attr.nominal;
248 io_can_ctrl_impl_set_bitrate(
io_can_ctrl_t *ctrl,
int nominal,
int data)
253 struct rtattr *linkinfo = (
struct rtattr *)buf;
254 *linkinfo = (
struct rtattr){ .rta_len = RTA_LENGTH(0),
255 .rta_type = IFLA_LINKINFO };
257 struct rtattr *info_kind =
RTA_TAIL(linkinfo);
258 *info_kind = (
struct rtattr){ .rta_len = RTA_LENGTH(strlen(
"can")),
259 .rta_type = IFLA_INFO_KIND };
260 strcpy(RTA_DATA(info_kind),
"can");
262 linkinfo->rta_len += RTA_ALIGN(info_kind->rta_len);
264 struct rtattr *info_data =
RTA_TAIL(info_kind);
265 *info_data = (
struct rtattr){ .rta_len = RTA_LENGTH(0),
266 .rta_type = IFLA_INFO_DATA };
267 struct rtattr *rta = RTA_DATA(info_data);
269 *rta = (
struct rtattr){ .rta_len = RTA_LENGTH(
270 sizeof(
struct can_bittiming)),
271 .rta_type = IFLA_CAN_BITTIMING };
272 *(
struct can_bittiming *)RTA_DATA(rta) =
273 (
struct can_bittiming){ .bitrate = nominal };
274 info_data->rta_len += RTA_ALIGN(rta->rta_len);
281 *rta = (
struct rtattr){ .rta_len = RTA_LENGTH(
sizeof(
282 struct can_bittiming)),
283 .rta_type = IFLA_CAN_DATA_BITTIMING };
284 *(
struct can_bittiming *)RTA_DATA(rta) =
285 (
struct can_bittiming){ .bitrate = data };
286 info_data->rta_len += RTA_ALIGN(rta->rta_len);
291 linkinfo->rta_len += RTA_ALIGN(info_data->rta_len);
296 if (ifr_set_flags(impl->name, &flags, IFF_UP) == -1) {
298 goto error_ifr_set_flags;
302 if (rtnl_open(&rth) == -1) {
304 goto error_rtnl_open;
308 if (rtnl_send_newlink_request(&rth, AF_UNSPEC, ARPHRD_CAN, impl->index,
309 flags, linkinfo, RTA_ALIGN(linkinfo->rta_len)) == -1) {
312 goto error_rtnl_send_newlink_request;
315 if (rtnl_recv_ack(&rth) == -1) {
317 goto error_rtnl_recv_ack;
324 error_rtnl_send_newlink_request:
337 int flags = ifr_get_flags(impl->name);
340 if (!(flags & IFF_UP))
344 if (io_can_attr_get(&attr, impl->index) == -1)
This is the internal header file of the ioctl network device configuration functions.
const char * io_can_ctrl_get_name(const io_can_ctrl_t *ctrl)
Returns the interface name of a CAN controller.
#define LELY_IO_CAN_TXLEN
The default SocketCAN transmit queue length (in number of CAN frames).
unsigned int io_can_ctrl_get_index(const io_can_ctrl_t *ctrl)
Returns the interface index of a CAN controller.
void io_can_ctrl_destroy(io_can_ctrl_t *ctrl)
Destroys a CAN controller.
int io_can_ctrl_get_flags(const io_can_ctrl_t *ctrl)
Returns the flags specifying which CAN bus features are enabled.
This is the internal header file of the Linux-specific I/O declarations.
This is the internal header file of the SocketCAN rtnetlink attributes functions. ...
Bit Rate Switch support is enabled.
io_can_ctrl_t * io_can_ctrl_create_from_name(const char *name, size_t txlen)
Creates a new CAN controller from an interface name.
This header file is part of the I/O library; it contains the CAN bus declarations for Linux...
This is the internal header file of the rtnetlink network interface functions.
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
#define RTA_TAIL(rta)
Returns the address of the next attribute.
const struct io_can_ctrl_vtbl *const io_can_ctrl_t
An abstract CAN controller.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
This is the public header file of the utilities library.
io_can_ctrl_t * io_can_ctrl_create_from_index(unsigned int index, size_t txlen)
Creates a new CAN controller from an interface index.