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)