26 #if !LELY_NO_STDIO && defined(__linux__)
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)
86 impl->ctrl_vptr = NULL;
88 return &impl->ctrl_vptr;
92 io_can_ctrl_free(
void *ptr)
95 free(io_can_ctrl_impl_from_ctrl(ptr));
99 io_can_ctrl_init(
io_can_ctrl_t *ctrl,
unsigned int index,
size_t txlen)
106 impl->ctrl_vptr = &io_can_ctrl_impl_vtbl;
110 memset(impl->name, 0, IF_NAMESIZE);
111 if (!if_indextoname(impl->index, impl->name))
119 if (io_can_attr_get(&attr, impl->index) == -1 && errno != ENOTSUP)
123 impl->flags = attr.flags;
125 if (io_if_set_txqlen(ARPHRD_CAN, impl->index, txlen) == -1)
140 unsigned int index = if_nametoindex(name);
167 io_can_ctrl_free((
void *)ctrl);
177 io_can_ctrl_fini(ctrl);
178 io_can_ctrl_free((
void *)ctrl);
212 return ifr_set_flags(impl->name, &flags, IFF_UP);
220 int flags = ifr_get_flags(impl->name);
221 return flags == -1 ? -1 : !(flags & IFF_UP);
230 return ifr_set_flags(impl->name, &flags, IFF_UP);
234 io_can_ctrl_impl_get_bitrate(
240 if (io_can_attr_get(&attr, impl->index) == -1)
244 *pnominal = attr.nominal;
257 io_can_ctrl_impl_set_bitrate(
io_can_ctrl_t *ctrl,
int nominal,
int data)
262 struct rtattr *linkinfo = (
struct rtattr *)buf;
263 *linkinfo = (
struct rtattr){ .rta_len = RTA_LENGTH(0),
264 .rta_type = IFLA_LINKINFO };
266 struct rtattr *info_kind =
RTA_TAIL(linkinfo);
267 *info_kind = (
struct rtattr){ .rta_len = RTA_LENGTH(strlen(
"can")),
268 .rta_type = IFLA_INFO_KIND };
269 strcpy(RTA_DATA(info_kind),
"can");
271 linkinfo->rta_len += RTA_ALIGN(info_kind->rta_len);
273 struct rtattr *info_data =
RTA_TAIL(info_kind);
274 *info_data = (
struct rtattr){ .rta_len = RTA_LENGTH(0),
275 .rta_type = IFLA_INFO_DATA };
276 struct rtattr *rta = RTA_DATA(info_data);
278 *rta = (
struct rtattr){ .rta_len = RTA_LENGTH(
279 sizeof(
struct can_bittiming)),
280 .rta_type = IFLA_CAN_BITTIMING };
281 *(
struct can_bittiming *)RTA_DATA(rta) =
282 (
struct can_bittiming){ .bitrate = nominal };
283 info_data->rta_len += RTA_ALIGN(rta->rta_len);
290 *rta = (
struct rtattr){ .rta_len = RTA_LENGTH(
sizeof(
291 struct can_bittiming)),
292 .rta_type = IFLA_CAN_DATA_BITTIMING };
293 *(
struct can_bittiming *)RTA_DATA(rta) =
294 (
struct can_bittiming){ .bitrate = data };
295 info_data->rta_len += RTA_ALIGN(rta->rta_len);
300 linkinfo->rta_len += RTA_ALIGN(info_data->rta_len);
305 if (ifr_set_flags(impl->name, &flags, IFF_UP) == -1) {
307 goto error_ifr_set_flags;
311 if (rtnl_open(&rth) == -1) {
313 goto error_rtnl_open;
317 if (rtnl_send_newlink_request(&rth, AF_UNSPEC, ARPHRD_CAN, impl->index,
318 flags, linkinfo, RTA_ALIGN(linkinfo->rta_len)) == -1) {
321 goto error_rtnl_send_newlink_request;
324 if (rtnl_recv_ack(&rth) == -1) {
326 goto error_rtnl_recv_ack;
333 error_rtnl_send_newlink_request:
346 int flags = ifr_get_flags(impl->name);
349 if (!(flags & IFF_UP))
353 if (io_can_attr_get(&attr, impl->index) == -1)
367 #endif // !LELY_NO_STDIO && __linux__