Lely core libraries 2.3.4
can_rt.hpp
Go to the documentation of this file.
1
24#ifndef LELY_IO2_CAN_RT_HPP_
25#define LELY_IO2_CAN_RT_HPP_
26
27#include <lely/io2/can.hpp>
28#include <lely/io2/can_rt.h>
29
30#include <utility>
31
32namespace lely {
33namespace io {
34
35namespace detail {
36
37template <class F>
39 public:
42 id, static_cast<uint_least8_t>(flags),
43 [](ev_task* task) noexcept {
45 auto msg = read->r.msg;
46 ::std::error_code ec;
47 if (!msg) ec = util::make_error_code(read->r.errc);
48 auto self = static_cast<CanRouterReadFrameWrapper*>(read);
49 compat::invoke(::std::move(self->func_), msg, ec);
50 delete self;
51 }),
52 func_(::std::forward<F>(f)) {}
53
55
57 delete;
58
59 operator ev_task&() & noexcept { return task; }
60
61 private:
62 typename ::std::decay<F>::type func_;
63};
64
65} // namespace detail
66
72template <class F>
73inline typename ::std::enable_if<
77 return new detail::CanRouterReadFrameWrapper<F>(id, flags,
78 ::std::forward<F>(f));
79}
80
88 public:
89 using Signature = void(const can_msg*, ::std::error_code);
90
92 template <class F>
96 [](ev_task* task) noexcept {
98 auto self = static_cast<CanRouterReadFrame*>(read);
99 if (self->func_) {
100 auto msg = read->r.msg;
101 ::std::error_code ec;
102 if (!msg) ec = util::make_error_code(read->r.errc);
103 self->func_(msg, ec);
104 }
105 }),
106 func_(::std::forward<F>(f)) {}
107
108 CanRouterReadFrame(const CanRouterReadFrame&) = delete;
109
110 CanRouterReadFrame& operator=(const CanRouterReadFrame&) = delete;
111
112 operator ev_task&() & noexcept { return task; }
113
115 ev::Executor
117 return ev::Executor(task.exec);
118 }
119
120 private:
121 ::std::function<Signature> func_;
122};
123
124namespace detail {
125
126template <class F>
127class CanRouterReadErrorWrapper : public io_can_rt_read_err {
128 public:
129 CanRouterReadErrorWrapper(F&& f)
132 auto err = read->r.err;
133 ::std::error_code ec;
134 if (!err) ec = util::make_error_code(read->r.errc);
135 auto self = static_cast<CanRouterReadErrorWrapper*>(read);
136 compat::invoke(::std::move(self->func_), err, ec);
137 delete self;
138 }),
139 func_(::std::forward<F>(f)) {}
140
141 CanRouterReadErrorWrapper(const CanRouterReadErrorWrapper&) = delete;
142
143 CanRouterReadErrorWrapper& operator=(const CanRouterReadErrorWrapper&) =
144 delete;
145
146 operator ev_task&() & noexcept { return task; }
147
148 private:
149 typename ::std::decay<F>::type func_;
150};
151
152} // namespace detail
153
159template <class F>
160inline typename ::std::enable_if<
161 compat::is_invocable<F, const can_err*, ::std::error_code>::value,
162 detail::CanRouterReadErrorWrapper<F>*>::type
164 return new detail::CanRouterReadErrorWrapper<F>(::std::forward<F>(f));
165}
166
174 public:
175 using Signature = void(const can_err*, ::std::error_code);
176
178 template <class F>
182 auto self = static_cast<CanRouterReadError*>(read);
183 if (self->func_) {
184 auto err = read->r.err;
185 ::std::error_code ec;
186 if (!err) ec = util::make_error_code(read->r.errc);
187 self->func_(err, ec);
188 }
189 }),
190 func_(::std::forward<F>(f)) {}
191
192 CanRouterReadError(const CanRouterReadError&) = delete;
193
194 CanRouterReadError& operator=(const CanRouterReadError&) = delete;
195
196 operator ev_task&() & noexcept { return task; }
197
199 ev::Executor
201 return ev::Executor(task.exec);
202 }
203
204 private:
205 ::std::function<Signature> func_;
206};
207
209class CanRouter : public Device {
210 public:
211 using Device::operator io_dev_t*;
212
215 : Device(nullptr), rt_(io_can_rt_create(chan, exec)) {
216 if (rt_)
217 dev = io_can_rt_get_dev(*this);
218 else
219 util::throw_errc("CanRouter");
220 }
221
222 CanRouter(const CanRouter&) = delete;
223
224 CanRouter(CanRouter&& other) noexcept : Device(other.dev), rt_(other.rt_) {
225 other.rt_ = nullptr;
226 other.dev = nullptr;
227 }
228
229 CanRouter& operator=(const CanRouter&) = delete;
230
231 CanRouter&
232 operator=(CanRouter&& other) noexcept {
233 using ::std::swap;
234 swap(rt_, other.rt_);
235 swap(dev, other.dev);
236 return *this;
237 }
238
241
242 operator io_can_rt_t*() const noexcept { return rt_; }
243
245 CanChannelBase
249
251 void
252 submit_read_frame(struct io_can_rt_read_msg& read_msg) noexcept {
253 io_can_rt_submit_read_msg(*this, &read_msg);
254 }
255
257 template <class F>
258 void
260 submit_read_frame(
261 *make_can_router_read_frame_wrapper(id, flags, ::std::forward<F>(f)));
262 }
263
265 bool
266 cancel_read_frame(struct io_can_rt_read_msg& read_msg) noexcept {
267 return io_can_rt_cancel_read_msg(*this, &read_msg) != 0;
268 }
269
271 bool
272 abort_read_frame(struct io_can_rt_read_msg& read_msg) noexcept {
273 return io_can_rt_abort_read_msg(*this, &read_msg) != 0;
274 }
275
279 struct io_can_rt_read_msg** pread_msg = nullptr) {
280 auto future = io_can_rt_async_read_msg(
281 *this, id, static_cast<uint_least8_t>(flags), pread_msg);
282 if (!future) util::throw_errc("async_read_frame");
283 return ev::Future<const can_msg*, int>(future);
284 }
285
287 void
288 submit_read_error(struct io_can_rt_read_err& read_err) noexcept {
289 io_can_rt_submit_read_err(*this, &read_err);
290 }
291
293 template <class F>
294 typename ::std::enable_if<!::std::is_base_of<
295 io_can_rt_read_err, typename ::std::decay<F>::type>::value>::type
297 submit_read_error(
298 *make_can_router_read_error_wrapper(::std::forward<F>(f)));
299 }
300
302 bool
303 cancel_read_error(struct io_can_rt_read_err& read_err) noexcept {
304 return io_can_rt_cancel_read_err(*this, &read_err) != 0;
305 }
306
308 bool
309 abort_read_error(struct io_can_rt_read_err& read_err) noexcept {
310 return io_can_rt_abort_read_err(*this, &read_err) != 0;
311 }
312
316 auto future = io_can_rt_async_read_err(*this, pread_err);
317 if (!future) util::throw_errc("async_read_error");
318 return ev::Future<const can_err*, int>(future);
319 }
320
324 auto future = io_can_rt_async_shutdown(*this);
325 if (!future) util::throw_errc("async_shutdown");
326 return ev::Future<void, void>(future);
327 }
328
329 private:
330 io_can_rt_t* rt_{nullptr};
331};
332
333} // namespace io
334} // namespace lely
335
336#endif // !LELY_IO2_CAN_RT_HPP_
This header file is part of the I/O library; it contains the CAN frame router declarations.
io_can_rt_t * io_can_rt_create(io_can_chan_t *chan, ev_exec_t *exec)
Creates a new CAN frame router.
Definition can_rt.c:225
size_t io_can_rt_cancel_read_err(io_can_rt_t *rt, struct io_can_rt_read_err *read_err)
Cancels the specified CAN error frame read operation if it is pending.
Definition can_rt.c:425
struct io_can_rt_read_err * io_can_rt_read_err_from_task(struct ev_task *task)
Obtains a pointer to a CAN error frame read operation from a pointer to its completion task.
Definition can_rt.c:522
void io_can_rt_submit_read_err(io_can_rt_t *rt, struct io_can_rt_read_err *read_err)
Submits a CAN error frame read operation to a CAN frame router.
Definition can_rt.c:391
#define IO_CAN_RT_READ_MSG_INIT(id, flags, func)
The static initializer for io_can_rt_read_msg.
Definition can_rt.h:77
io_dev_t * io_can_rt_get_dev(const io_can_rt_t *rt)
Returns a pointer to the abstract I/O device representing the CAN frame router.
Definition can_rt.c:261
io_can_chan_t * io_can_rt_get_chan(const io_can_rt_t *rt)
Returns a pointer to the CAN channel used by the CAN frame router.
Definition can_rt.c:269
struct io_can_rt_read_msg * io_can_rt_read_msg_from_task(struct ev_task *task)
Obtains a pointer to a CAN frame read operation from a pointer to its completion task.
Definition can_rt.c:516
size_t io_can_rt_abort_read_err(io_can_rt_t *rt, struct io_can_rt_read_err *read_err)
Aborts the specified CAN error frame read operation if it is pending.
Definition can_rt.c:448
size_t io_can_rt_abort_read_msg(io_can_rt_t *rt, struct io_can_rt_read_msg *read_msg)
Aborts the specified CAN frame read operation if it is pending.
Definition can_rt.c:343
void io_can_rt_destroy(io_can_rt_t *rt)
Destroys a CAN frame router.
Definition can_rt.c:252
void io_can_rt_submit_read_msg(io_can_rt_t *rt, struct io_can_rt_read_msg *read_msg)
Submits a CAN frame read operation to a CAN frame router.
Definition can_rt.c:277
#define IO_CAN_RT_READ_ERR_INIT(func)
The static initializer for io_can_rt_read_err.
Definition can_rt.h:111
size_t io_can_rt_cancel_read_msg(io_can_rt_t *rt, struct io_can_rt_read_msg *read_msg)
Cancels the specified CAN frame read operation if it is pending.
Definition can_rt.c:320
typename::std::enable_if< compat::is_invocable< F, constcan_msg *,::std::error_code >::value, detail::CanRouterReadFrameWrapper< F > * >::type make_can_router_read_frame_wrapper(uint_least32_t id, CanFlag flags, F &&f)
Creates a CAN frame read operation with a completion task.
Definition can_rt.hpp:76
typename::std::enable_if< compat::is_invocable< F, constcan_err *,::std::error_code >::value, detail::CanRouterReadErrorWrapper< F > * >::type make_can_router_read_error_wrapper(F &&f)
Creates a CAN error frame read operation with a completion task.
Definition can_rt.hpp:163
A CANopen value.
Definition val.hpp:42
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition exec.hpp:38
A future.
Definition future.hpp:384
A reference to an abstract CAN channel.
Definition can.hpp:430
A CAN error frame read operation suitable for use with a CAN frame router.
Definition can_rt.hpp:173
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition can_rt.hpp:200
CanRouterReadError(F &&f)
Constructs a CAN error frame read operation with a completion task.
Definition can_rt.hpp:179
A CAN frame read operation suitable for use with a CAN frame router.
Definition can_rt.hpp:87
CanRouterReadFrame(uint_least32_t id, CanFlag flags, F &&f)
Constructs a CAN frame read operation with a completion task.
Definition can_rt.hpp:93
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition can_rt.hpp:116
A CAN frame rounter. This class is a wrapper around #io_can_rt_t*.
Definition can_rt.hpp:209
void submit_read_frame(struct io_can_rt_read_msg &read_msg) noexcept
Definition can_rt.hpp:252
CanRouter(io_can_chan_t *chan, ev_exec_t *exec)
Definition can_rt.hpp:214
void submit_read_frame(uint_least32_t id, CanFlag flags, F &&f)
Definition can_rt.hpp:259
bool abort_read_error(struct io_can_rt_read_err &read_err) noexcept
Definition can_rt.hpp:309
ev::Future< const can_err *, int > async_read_error(struct io_can_rt_read_err **pread_err=nullptr)
Definition can_rt.hpp:315
ev::Future< const can_msg *, int > async_read_frame(uint_least32_t id, CanFlag flags, struct io_can_rt_read_msg **pread_msg=nullptr)
Definition can_rt.hpp:278
typename::std::enable_if<!::std::is_base_of< io_can_rt_read_err, typename::std::decay< F >::type >::value >::type submit_read_error(F &&f)
Definition can_rt.hpp:296
ev::Future< void, void > async_shutdown()
Definition can_rt.hpp:323
bool cancel_read_frame(struct io_can_rt_read_msg &read_msg) noexcept
Definition can_rt.hpp:266
bool abort_read_frame(struct io_can_rt_read_msg &read_msg) noexcept
Definition can_rt.hpp:272
CanChannelBase get_channel() const noexcept
Definition can_rt.hpp:246
void submit_read_error(struct io_can_rt_read_err &read_err) noexcept
Definition can_rt.hpp:288
bool cancel_read_error(struct io_can_rt_read_err &read_err) noexcept
Definition can_rt.hpp:303
An abstract I/O device. This class is a wrapper around #io_dev_t*.
Definition dev.hpp:35
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition ev.h:29
const struct io_can_chan_vtbl *const io_can_chan_t
An abstract CAN channel.
Definition can.h:59
This header file is part of the I/O library; it contains the C++ interface for the abstract CAN bus.
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
Definition dev.h:35
CanFlag
The error flags of a CAN bus, which are not mutually exclusive.
Definition msg.hpp:33
A CAN error frame.
Definition err.h:28
A CAN or CAN FD format frame.
Definition msg.h:87
An executable task.
Definition task.h:41
const struct can_err * err
A pointer to the received CAN error frame, or NULL on error (or if the operation is canceled).
Definition can_rt.h:94
A CAN error frame read operation suitable for use with a CAN frame router.
Definition can_rt.h:100
struct io_can_rt_read_err_result r
The result of the read operation.
Definition can_rt.h:107
const struct can_msg * msg
A pointer to the received CAN frame, or NULL on error (or if the operation is canceled).
Definition can_rt.h:46
A CAN frame read operation suitable for use with a CAN frame router.
Definition can_rt.h:52
uint_least32_t id
The identifier of the CAN frame to be received.
Definition can_rt.h:57
struct io_can_rt_read_msg_result r
The result of the read operation.
Definition can_rt.h:71
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
Definition can_rt.h:69
uint_least8_t flags
The flags of the CAN frame to be received (any combination of CAN_FLAG_IDE, CAN_FLAG_RTR,...
Definition can_rt.h:64
Determines whether F can be invoked with the arguments Args....