24#ifndef LELY_IO2_CAN_HPP_
25#define LELY_IO2_CAN_HPP_
49 NONE = IO_CAN_BUS_FLAG_NONE,
50 MASK = IO_CAN_BUS_FLAG_MASK
54operator~(CanBusFlag
rhs) {
59operator&(CanBusFlag lhs, CanBusFlag rhs) {
60 return static_cast<CanBusFlag
>(
static_cast<int>(lhs) &
static_cast<int>(rhs));
64operator^(CanBusFlag lhs, CanBusFlag rhs) {
65 return static_cast<CanBusFlag>(
static_cast<int>(lhs) ^
static_cast<int>(rhs));
69operator|(CanBusFlag lhs, CanBusFlag rhs) {
70 return static_cast<CanBusFlag>(
static_cast<int>(lhs) |
static_cast<int>(rhs));
74operator&=(CanBusFlag& lhs, CanBusFlag rhs) {
75 return lhs = lhs & rhs;
79operator^=(CanBusFlag& lhs, CanBusFlag rhs) {
80 return lhs = lhs ^ rhs;
84operator|=(CanBusFlag& lhs, CanBusFlag rhs) {
85 return lhs = lhs | rhs;
99 auto result = read->r.result;
100 ::std::error_code ec;
101 if (result == -1) ec = util::make_error_code(read->r.errc);
103 if (self->dp_) *self->dp_ = util::from_timespec(self->ts_);
104 compat::invoke(::std::move(self->func_), result, ec);
108 func_(::std::forward<F>(f)) {}
118 ::std::chrono::nanoseconds* dp_{
nullptr};
119 typename ::std::decay<F>::type func_;
130inline typename ::std::enable_if<
137 ::std::forward<F>(f));
147 using Signature =
void(
int, ::std::error_code);
159 *self->dp_ = util::from_timespec(self->ts_);
161 auto result = read->r.result;
162 ::std::error_code ec;
164 ec = util::make_error_code(read->r.errc);
165 self->func_(result, ec);
169 func_(::std::forward<F>(f)) {}
181 operator ev_task&() &
noexcept {
return task; }
191 ::std::chrono::nanoseconds* dp_{
nullptr};
192 ::std::function<Signature> func_;
205 ::std::error_code ec = util::make_error_code(write->errc);
206 auto self =
static_cast<CanChannelWriteWrapper*
>(write);
207 compat::invoke(::std::move(self->func_), ec);
210 func_(::std::forward<F>(f)) {}
212 CanChannelWriteWrapper(
const CanChannelWriteWrapper&) =
delete;
214 CanChannelWriteWrapper& operator=(
const CanChannelWriteWrapper&) =
delete;
217 typename ::std::decay<F>::type func_;
229inline typename ::std::enable_if<
230 compat::is_invocable<F, ::std::error_code>::value,
231 detail::CanChannelWriteWrapper<F>*>::type
234 return new detail::CanChannelWriteWrapper<F>(msg, exec, ::std::forward<F>(f));
244 using Signature =
void(::std::error_code);
255 ::std::error_code ec = util::make_error_code(write->errc);
259 func_(::std::forward<F>(f)) {}
270 operator ev_task&() &
noexcept {
return task; }
279 ::std::function<Signature> func_;
294 stop(::std::error_code& ec)
noexcept {
300 ec = util::make_error_code();
307 ::std::error_code ec;
309 if (ec) throw ::std::system_error(ec,
"stop");
314 stopped(::std::error_code& ec)
const noexcept {
321 ec = util::make_error_code();
331 ::std::error_code ec;
332 auto result = stopped(ec);
333 if (ec) throw ::std::system_error(ec,
"stopped");
345 ec = util::make_error_code();
352 ::std::error_code ec;
354 if (ec) throw ::std::system_error(ec,
"restart");
365 ec = util::make_error_code();
372 ::std::error_code ec;
374 if (ec) throw ::std::system_error(ec,
"get_bitrate");
379 set_bitrate(
int nominal,
int data, ::std::error_code& ec)
noexcept {
385 ec = util::make_error_code();
392 ::std::error_code ec;
393 set_bitrate(nominal, data, ec);
394 if (ec) throw ::std::system_error(ec,
"set_bitrate");
406 ec = util::make_error_code();
410 return static_cast<CanState>(state);
416 ::std::error_code ec;
417 auto result = get_state(ec);
418 if (ec) throw ::std::system_error(ec,
"get_state");
443 if (flags == -1) util::throw_errc(
"get_flags");
450 ::std::error_code& ec)
noexcept {
458 ec = util::make_error_code();
459 if (
dp) *
dp = util::from_timespec(ts);
467 ::std::chrono::nanoseconds*
dp =
nullptr,
int timeout = -1) {
468 ::std::error_code ec;
469 int result = read(msg, err,
dp, timeout, ec);
470 if (result < 0) throw ::std::system_error(ec,
"read");
486 ::std::forward<F>(f)));
494 submit_read(msg, err,
dp,
nullptr, ::std::forward<F>(f));
522 return async_read(
nullptr, msg, err, tp, pread);
527 write(
const can_msg& msg,
int timeout, ::std::error_code& ec)
noexcept {
533 ec = util::make_error_code();
540 ::std::error_code ec;
541 write(msg, timeout, ec);
542 if (ec) throw ::std::system_error(ec,
"write");
563 submit_write(msg,
nullptr, ::std::forward<F>(f));
583 if (!future) util::throw_errc(
"async_write");
590 return async_write(
nullptr, msg, pwrite);
An abstract task executor. This class is a wrapper around #ev_exec_t*.
A reference to an abstract CAN channel.
void submit_write(const can_msg &msg, ev_exec_t *exec, F &&f)
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
bool read(can_msg *msg, can_err *err=nullptr, ::std::chrono::nanoseconds *dp=nullptr, int timeout=-1)
CanBusFlag get_flags() const
ev::Future< void, int > async_write(ev_exec_t *exec, const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
void write(const can_msg &msg, int timeout=-1)
ev::Future< void, int > async_write(const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
void submit_read(struct io_can_chan_read &read) noexcept
void submit_write(struct io_can_chan_write &write) noexcept
ev::Future< int, int > async_read(ev_exec_t *exec, can_msg *msg, can_err *err=nullptr, timespec *tp=nullptr, struct io_can_chan_read **pread=nullptr)
bool abort_read(struct io_can_chan_read &read) noexcept
bool abort_write(struct io_can_chan_write &write) noexcept
void write(const can_msg &msg, int timeout, ::std::error_code &ec) noexcept
void submit_write(const can_msg &msg, F &&f)
int read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, int timeout, ::std::error_code &ec) noexcept
bool cancel_read(struct io_can_chan_read &read) noexcept
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
bool cancel_write(struct io_can_chan_write &write) noexcept
ev::Future< int, int > async_read(can_msg *msg, can_err *err=nullptr, timespec *tp=nullptr, struct io_can_chan_read **pread=nullptr)
A read operation suitable for use with a CAN channel.
CanChannelRead(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
Constructs a read operation with a completion task.
CanChannelRead(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
Constructs a read operation with a completion task.
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
A write operation suitable for use with a CAN channel.
CanChannelWrite(const can_msg &msg, F &&f)
Constructs a write operation with a completion task.
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
CanChannelWrite(const can_msg &msg, ev_exec_t *exec, F &&f)
Constructs a write operation with a completion task.
A reference to an abstract CAN controller.
CanState get_state() const
void stop(::std::error_code &ec) noexcept
void set_bitrate(int nominal, int data=0)
bool stopped(::std::error_code &ec) const noexcept
void set_bitrate(int nominal, int data, ::std::error_code &ec) noexcept
void get_bitrate(int *pnominal, int *pdata, ::std::error_code &ec) const noexcept
CanState get_state(::std::error_code &ec) const noexcept
void restart(::std::error_code &ec) noexcept
void get_bitrate(int *pnominal, int *pdata=nullptr) const
An abstract I/O device. This class is a wrapper around #io_dev_t*.
This header file is part of the I/O library; it contains the C++ CAN bus error definitions.
CanState
The states of a CAN node, depending on the TX/RX error count.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
This header file is part of the event library; it contains the C++ interface for the futures and prom...
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
This header file is part of the I/O library; it contains the abstract CAN bus interface.
int io_can_ctrl_stopped(const io_can_ctrl_t *ctrl)
Returns 1 in the CAN controller is stopped, 0 if not, and -1 on error.
const struct io_can_chan_vtbl *const io_can_chan_t
An abstract CAN channel.
static size_t io_can_chan_abort_write(io_can_chan_t *chan, struct io_can_chan_write *write)
Aborts the specified CAN channel write operation if it is pending.
struct io_can_chan_read * io_can_chan_read_from_task(struct ev_task *task)
Obtains a pointer to a CAN channel read operation from a pointer to its completion task.
static size_t io_can_chan_abort_read(io_can_chan_t *chan, struct io_can_chan_read *read)
Aborts the specified CAN channel read operation if it is pending.
struct io_can_chan_write * io_can_chan_write_from_task(struct ev_task *task)
Obtains a pointer to a CAN channel write operation from a pointer to its completion task.
const struct io_can_ctrl_vtbl *const io_can_ctrl_t
An abstract CAN controller.
static size_t io_can_chan_cancel_read(io_can_chan_t *chan, struct io_can_chan_read *read)
Cancels the specified CAN channel read operation if it is pending.
io_dev_t * io_can_chan_get_dev(const io_can_chan_t *chan)
Returns a pointer to the abstract I/O device representing the CAN channel.
void io_can_chan_submit_write(io_can_chan_t *chan, struct io_can_chan_write *write)
Submits a write operation to a CAN channel.
int io_can_ctrl_get_state(const io_can_ctrl_t *ctrl)
Returns the state of the CAN controller: one of CAN_STATE_ACTIVE, CAN_STATE_PASSIVE,...
int io_can_ctrl_stop(io_can_ctrl_t *ctrl)
Stops a CAN controller.
void io_can_chan_submit_read(io_can_chan_t *chan, struct io_can_chan_read *read)
Submits a read operation to a CAN channel.
#define IO_CAN_CHAN_WRITE_INIT(msg, exec, func)
The static initializer for io_can_chan_write.
int io_can_chan_get_flags(const io_can_chan_t *chan)
Returns the flafs of the CAN bus: any combination of IO_CAN_BUS_FLAG_ERR, IO_CAN_BUS_FLAG_FDF and IO_...
#define IO_CAN_CHAN_READ_INIT(msg, err, tp, exec, func)
The static initializer for io_can_chan_read.
int io_can_ctrl_set_bitrate(io_can_ctrl_t *ctrl, int nominal, int data)
Configures the bitrate(s) of a CAN controller.
@ IO_CAN_BUS_FLAG_BRS
Bit Rate Switch support is enabled.
@ IO_CAN_BUS_FLAG_FDF
FD Format (formerly Extended Data Length) support is enabled.
@ IO_CAN_BUS_FLAG_ERR
Reception of error frames is enabled.
int io_can_ctrl_get_bitrate(const io_can_ctrl_t *ctrl, int *pnominal, int *pdata)
Obtains the bitrate(s) of a CAN controller.
int io_can_ctrl_restart(io_can_ctrl_t *ctrl)
(Re)starts a CAN contoller.
static size_t io_can_chan_cancel_write(io_can_chan_t *chan, struct io_can_chan_write *write)
Cancels the specified CAN channel write operation if it is pending.
typename::std::enable_if< compat::is_invocable< F,::std::error_code >::value, detail::CanChannelWriteWrapper< F > * >::type make_can_channel_write_wrapper(const can_msg &msg, ev_exec_t *exec, F &&f)
Creates a CAN channel write operation with a completion task.
typename::std::enable_if< compat::is_invocable< F, int,::std::error_code >::value, detail::CanChannelReadWrapper< F > * >::type make_can_channel_read_wrapper(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
Creates a CAN channel read operation with a completion task.
CanBusFlag
The CAN bus flags.
@ BRS
Bit Rate Switch support is enabled.
@ FDF
FD Format (formerly Extended Data Length) support is enabled.
@ ERR
Reception of error frames is enabled.
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
This header file is part of the I/O library; it contains the C++ interface for the abstract I/O devic...
This header file is part of the I/O library; it contains the C++ CAN frame declarations.
A CAN or CAN FD format frame.
A CAN channel read operation.
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
struct can_msg * msg
The address at which to store the CAN frame.
struct can_err * err
The address at which to store the CAN error frame.
A CAN channel write operation.
Determines whether F can be invoked with the arguments Args....
A time type with nanosecond resolution.
This header file is part of the utilities library; it contains the time function declarations.